Module Name: src
Committed By: ttoth
Date: Fri Aug 10 09:26:58 UTC 2012
Modified Files:
src/sys/ufs/chfs: chfs.h chfs_build.c chfs_gc.c chfs_malloc.c
chfs_nodeops.c chfs_readinode.c chfs_scan.c chfs_subr.c
chfs_vfsops.c chfs_vnode.c chfs_vnode_cache.c chfs_vnops.c
chfs_write.c ebh.c
Log Message:
chfs bugfix [node was obsoleted twice]
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/ufs/chfs/chfs.h
cvs rdiff -u -r1.3 -r1.4 src/sys/ufs/chfs/chfs_build.c \
src/sys/ufs/chfs/chfs_write.c
cvs rdiff -u -r1.2 -r1.3 src/sys/ufs/chfs/chfs_gc.c \
src/sys/ufs/chfs/chfs_malloc.c src/sys/ufs/chfs/chfs_readinode.c \
src/sys/ufs/chfs/chfs_scan.c src/sys/ufs/chfs/ebh.c
cvs rdiff -u -r1.1 -r1.2 src/sys/ufs/chfs/chfs_nodeops.c \
src/sys/ufs/chfs/chfs_vnode_cache.c
cvs rdiff -u -r1.4 -r1.5 src/sys/ufs/chfs/chfs_subr.c \
src/sys/ufs/chfs/chfs_vfsops.c
cvs rdiff -u -r1.5 -r1.6 src/sys/ufs/chfs/chfs_vnode.c
cvs rdiff -u -r1.8 -r1.9 src/sys/ufs/chfs/chfs_vnops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/ufs/chfs/chfs.h
diff -u src/sys/ufs/chfs/chfs.h:1.6 src/sys/ufs/chfs/chfs.h:1.7
--- src/sys/ufs/chfs/chfs.h:1.6 Fri Apr 13 14:50:35 2012
+++ src/sys/ufs/chfs/chfs.h Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs.h,v 1.6 2012/04/13 14:50:35 ttoth Exp $ */
+/* $NetBSD: chfs.h,v 1.7 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -494,6 +494,10 @@ int chfs_update_eb_dirty(struct chfs_mou
struct chfs_eraseblock *, uint32_t);
void chfs_add_node_to_list(struct chfs_mount *, struct chfs_vnode_cache *,
struct chfs_node_ref *, struct chfs_node_ref **);
+void chfs_remove_node_from_list(struct chfs_mount *, struct chfs_vnode_cache *,
+ struct chfs_node_ref *, struct chfs_node_ref **);
+void chfs_remove_and_obsolete(struct chfs_mount *, struct chfs_vnode_cache *,
+ struct chfs_node_ref *, struct chfs_node_ref **);
void chfs_add_fd_to_inode(struct chfs_mount *,
struct chfs_inode *, struct chfs_dirent *);
void chfs_add_vnode_ref_to_vc(struct chfs_mount *, struct chfs_vnode_cache *,
@@ -522,7 +526,6 @@ chfs_nref_to_vc(struct chfs_node_ref *nr
dbg("Empty!\n");
}
}
- //dbg("vno: %llu\n", ((struct chfs_vnode_cache *)(nref))->vno);
//dbg("NREF_TO_VC: GET IT\n");
//dbg("nref_next: %p, lnr: %u, ofs: %u\n", nref->nref_next, nref->nref_lnr, nref->nref_offset);
@@ -564,7 +567,9 @@ void chfs_free_tmp_dnode_info(struct chf
/* chfs_readinode.c */
int chfs_read_inode(struct chfs_mount *, struct chfs_inode *);
int chfs_read_inode_internal(struct chfs_mount *, struct chfs_inode *);
-void chfs_kill_fragtree(struct rb_tree *);
+void chfs_remove_frags_of_node(struct chfs_mount *, struct rb_tree *,
+ struct chfs_node_ref *);
+void chfs_kill_fragtree(struct chfs_mount *, struct rb_tree *);
uint32_t chfs_truncate_fragtree(struct chfs_mount *,
struct rb_tree *, uint32_t);
int chfs_add_full_dnode_to_inode(struct chfs_mount *,
@@ -653,8 +658,6 @@ void chfs_change_size_wasted(struct chfs
/* chfs_vnode_cache.c */
struct chfs_vnode_cache **chfs_vnocache_hash_init(void);
void chfs_vnocache_hash_destroy(struct chfs_vnode_cache **);
-void chfs_vnode_cache_set_state(struct chfs_mount *,
- struct chfs_vnode_cache *, int);
struct chfs_vnode_cache* chfs_vnode_cache_get(struct chfs_mount *, ino_t);
void chfs_vnode_cache_add(struct chfs_mount *, struct chfs_vnode_cache *);
void chfs_vnode_cache_remove(struct chfs_mount *, struct chfs_vnode_cache *);
Index: src/sys/ufs/chfs/chfs_build.c
diff -u src/sys/ufs/chfs/chfs_build.c:1.3 src/sys/ufs/chfs/chfs_build.c:1.4
--- src/sys/ufs/chfs/chfs_build.c:1.3 Thu Apr 12 15:31:01 2012
+++ src/sys/ufs/chfs/chfs_build.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_build.c,v 1.3 2012/04/12 15:31:01 ttoth Exp $ */
+/* $NetBSD: chfs_build.c,v 1.4 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -67,11 +67,11 @@ void
chfs_build_set_vnodecache_nlink(struct chfs_mount *chmp,
struct chfs_vnode_cache *vc)
{
- struct chfs_dirent *fd;
+ struct chfs_dirent *fd, *tmpfd;
//dbg("set nlink\n");
// for (fd = vc->scan_dirents; fd; fd = fd->next) {
- TAILQ_FOREACH(fd, &vc->scan_dirents, fds) {
+ TAILQ_FOREACH_SAFE(fd, &vc->scan_dirents, fds, tmpfd) {
struct chfs_vnode_cache *child_vc;
if (!fd->vno)
@@ -82,6 +82,7 @@ chfs_build_set_vnodecache_nlink(struct c
mutex_exit(&chmp->chm_lock_vnocache);
if (!child_vc) {
chfs_mark_node_obsolete(chmp, fd->nref);
+ TAILQ_REMOVE(&vc->scan_dirents, fd, fds);
continue;
}
if (fd->type == CHT_DIR) {
@@ -122,8 +123,8 @@ chfs_build_remove_unlinked_vnode(struct
dbg("START\n");
dbg("vno: %llu\n", (unsigned long long)vc->vno);
- nref = vc->dnode;
KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
+ nref = vc->dnode;
// The vnode cache is at the end of the data node's chain
while (nref != (struct chfs_node_ref *)vc) {
struct chfs_node_ref *next = nref->nref_next;
@@ -131,6 +132,7 @@ chfs_build_remove_unlinked_vnode(struct
chfs_mark_node_obsolete(chmp, nref);
nref = next;
}
+ vc->dnode = (struct chfs_node_ref *)vc;
nref = vc->dirents;
// The vnode cache is at the end of the dirent node's chain
while (nref != (struct chfs_node_ref *)vc) {
@@ -139,6 +141,7 @@ chfs_build_remove_unlinked_vnode(struct
chfs_mark_node_obsolete(chmp, nref);
nref = next;
}
+ vc->dirents = (struct chfs_node_ref *)vc;
if (!TAILQ_EMPTY(&vc->scan_dirents)) {
TAILQ_FOREACH_SAFE(fd, &vc->scan_dirents, fds, tmpfd) {
// while (vc->scan_dirents) {
@@ -189,14 +192,14 @@ chfs_build_remove_unlinked_vnode(struct
nref = vc->v;
while ((struct chfs_vnode_cache *)nref != vc) {
- if (!CHFS_REF_OBSOLETE(nref))
- chfs_mark_node_obsolete(chmp, nref);
+ chfs_mark_node_obsolete(chmp, nref);
nref = nref->nref_next;
}
+ vc->v = (struct chfs_node_ref *)vc;
mutex_enter(&chmp->chm_lock_vnocache);
if (vc->vno != CHFS_ROOTINO)
- chfs_vnode_cache_set_state(chmp, vc, VNO_STATE_UNCHECKED);
+ vc->state = VNO_STATE_UNCHECKED;
mutex_exit(&chmp->chm_lock_vnocache);
dbg("END\n");
}
@@ -375,11 +378,8 @@ chfs_build_filesystem(struct chfs_mount
} else if (fd->type == CHT_DIR) {
//set state every non-VREG file's vc
mutex_enter(&chmp->chm_lock_vnocache);
- notregvc =
- chfs_vnode_cache_get(chmp,
- fd->vno);
- chfs_vnode_cache_set_state(chmp,
- notregvc, VNO_STATE_PRESENT);
+ notregvc = chfs_vnode_cache_get(chmp, fd->vno);
+ notregvc->state = VNO_STATE_PRESENT;
mutex_exit(&chmp->chm_lock_vnocache);
}
chfs_free_dirent(fd);
Index: src/sys/ufs/chfs/chfs_write.c
diff -u src/sys/ufs/chfs/chfs_write.c:1.3 src/sys/ufs/chfs/chfs_write.c:1.4
--- src/sys/ufs/chfs/chfs_write.c:1.3 Thu Apr 12 15:31:01 2012
+++ src/sys/ufs/chfs/chfs_write.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_write.c,v 1.3 2012/04/12 15:31:01 ttoth Exp $ */
+/* $NetBSD: chfs_write.c,v 1.4 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -139,7 +139,9 @@ retry:
&chmp->chm_blocks[nref->nref_lnr], CHFS_PAD(size));
mutex_exit(&chmp->chm_lock_sizes);
+ mutex_enter(&chmp->chm_lock_vnocache);
chfs_add_vnode_ref_to_vc(chmp, chvc, nref);
+ mutex_exit(&chmp->chm_lock_vnocache);
KASSERT(chmp->chm_blocks[nref->nref_lnr].used_size <= chmp->chm_ebh->eb_size);
out:
chfs_free_flash_vnode(fvnode);
@@ -248,10 +250,13 @@ retry:
&chmp->chm_blocks[nref->nref_lnr], CHFS_PAD(size));
mutex_exit(&chmp->chm_lock_sizes);
KASSERT(chmp->chm_blocks[nref->nref_lnr].used_size <= chmp->chm_ebh->eb_size);
+
fd->nref = nref;
if (prio != ALLOC_DELETION) {
+ mutex_enter(&chmp->chm_lock_vnocache);
chfs_add_node_to_list(chmp,
pdir->chvc, nref, &pdir->chvc->dirents);
+ mutex_exit(&chmp->chm_lock_vnocache);
}
out:
chfs_free_flash_dirent(fdirent);
@@ -324,7 +329,6 @@ chfs_write_flash_dnode(struct chfs_mount
vec[1].iov_base = tmpbuf;
vec[1].iov_len = CHFS_PAD(size) - sizeof(*dnode);
- fd->frags = 0;
fd->ofs = ofs;
fd->size = len;
@@ -382,9 +386,16 @@ retry:
&chmp->chm_blocks[nref->nref_lnr], CHFS_PAD(size));
mutex_exit(&chmp->chm_lock_sizes);
+ mutex_enter(&chmp->chm_lock_vnocache);
+ if (fd->nref != NULL) {
+ chfs_remove_frags_of_node(chmp, &ip->fragtree, fd->nref);
+ chfs_remove_and_obsolete(chmp, ip->chvc, fd->nref, &ip->chvc->dnode);
+ }
+
KASSERT(chmp->chm_blocks[nref->nref_lnr].used_size <= chmp->chm_ebh->eb_size);
fd->nref = nref;
chfs_add_node_to_list(chmp, ip->chvc, nref, &ip->chvc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
out:
chfs_free_flash_dnode(dnode);
if (CHFS_PAD(size) - sizeof(*dnode)) {
@@ -488,6 +499,9 @@ chfs_do_unlink(struct chfs_inode *ip,
if (fd->vno == ip->ino &&
fd->nsize == namelen &&
!memcmp(fd->name, name, fd->nsize)) {
+
+ chfs_kill_fragtree(chmp, &ip->fragtree);
+
if (fd->type == CHT_DIR && ip->chvc->nlink == 2)
ip->chvc->nlink = 0;
else
@@ -497,45 +511,41 @@ chfs_do_unlink(struct chfs_inode *ip,
TAILQ_REMOVE(&parent->dents, fd, fds);
- /* remove nref from dirents list */
- nref = parent->chvc->dirents;
- if (nref == fd->nref) {
- nref->nref_next = fd->nref->nref_next;
- } else {
- while (nref->nref_next && nref->nref_next != fd->nref)
- nref = nref->nref_next;
- if (nref->nref_next)
- nref->nref_next = fd->nref->nref_next;
- }
+ mutex_enter(&chmp->chm_lock_vnocache);
- //dbg("FD->NREF vno: %llu, lnr: %u, ofs: %u\n",
- // fd->vno, fd->nref->nref_lnr, fd->nref->nref_offset);
- chfs_mark_node_obsolete(chmp, fd->nref);
+ dbg("FD->NREF vno: %llu, lnr: %u, ofs: %u\n",
+ fd->vno, fd->nref->nref_lnr, fd->nref->nref_offset);
+ chfs_remove_and_obsolete(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
error = chfs_write_flash_dirent(chmp,
parent, ip, fd, 0, ALLOC_DELETION);
- //dbg("FD->NREF vno: %llu, lnr: %u, ofs: %u\n",
- // fd->vno, fd->nref->nref_lnr, fd->nref->nref_offset);
- chfs_mark_node_obsolete(chmp, fd->nref);
-
- nref = ip->chvc->dnode;
- while (nref != (struct chfs_node_ref *)ip->chvc) {
- //dbg("DATA NREF\n");
- chfs_mark_node_obsolete(chmp, nref);
- nref = nref->nref_next;
+ dbg("FD->NREF vno: %llu, lnr: %u, ofs: %u\n",
+ fd->vno, fd->nref->nref_lnr, fd->nref->nref_offset);
+ // set nref_next field
+ chfs_add_node_to_list(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
+ // remove from the list
+ chfs_remove_and_obsolete(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
+
+ // clean dnode list
+ while (ip->chvc->dnode != (struct chfs_node_ref *)ip->chvc) {
+ nref = ip->chvc->dnode;
+ chfs_remove_frags_of_node(chmp, &ip->fragtree, nref);
+ chfs_remove_and_obsolete(chmp, ip->chvc, nref, &ip->chvc->dnode);
}
- ip->chvc->dnode = (struct chfs_node_ref *)ip->chvc;
- nref = ip->chvc->v;
- while (nref != (struct chfs_node_ref *)ip->chvc) {
- //dbg("V NREF\n");
- chfs_mark_node_obsolete(chmp, nref);
- nref = nref->nref_next;
+ // clean v list
+ while (ip->chvc->v != (struct chfs_node_ref *)ip->chvc) {
+ nref = ip->chvc->v;
+ chfs_remove_and_obsolete(chmp, ip->chvc, nref, &ip->chvc->v);
}
- ip->chvc->v = ip->chvc->v->nref_next;
parent->chvc->nlink--;
+
+ mutex_exit(&chmp->chm_lock_vnocache);
//TODO: if error
}
}
Index: src/sys/ufs/chfs/chfs_gc.c
diff -u src/sys/ufs/chfs/chfs_gc.c:1.2 src/sys/ufs/chfs/chfs_gc.c:1.3
--- src/sys/ufs/chfs/chfs_gc.c:1.2 Thu Nov 24 21:09:37 2011
+++ src/sys/ufs/chfs/chfs_gc.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_gc.c,v 1.2 2011/11/24 21:09:37 agc Exp $ */
+/* $NetBSD: chfs_gc.c,v 1.3 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -92,6 +92,7 @@ chfs_gc_thread(void *data)
if (chfs_gc_thread_should_wake(chmp)) {
// mutex_exit(&chmp->chm_lock_mountfields);
if (chfs_gcollect_pass(chmp) == ENOSPC) {
+ mutex_exit(&chmp->chm_lock_mountfields);
dbg_gc("No space for garbage collection\n");
panic("No space for garbage collection\n");
/* XXX why break here? i have added a panic
@@ -100,7 +101,7 @@ chfs_gc_thread(void *data)
break;
}
/* XXX gcollect_pass drops the mutex */
- mutex_enter(&chmp->chm_lock_mountfields);
+ //mutex_enter(&chmp->chm_lock_mountfields);
}
cv_timedwait_sig(&gc->gcth_wakeup,
@@ -254,6 +255,8 @@ extern rb_tree_ops_t frag_rbtree_ops;
int
chfs_check(struct chfs_mount *chmp, struct chfs_vnode_cache *chvc)
{
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+
struct chfs_inode *ip;
struct vnode *vp;
int ret;
@@ -273,7 +276,9 @@ chfs_check(struct chfs_mount *chmp, stru
rb_tree_init(&ip->fragtree, &frag_rbtree_ops);
TAILQ_INIT(&ip->dents);
+ mutex_exit(&chmp->chm_lock_vnocache);
ret = chfs_read_inode_internal(chmp, ip);
+ mutex_enter(&chmp->chm_lock_vnocache);
if (!ret) {
chfs_clear_inode(chmp, ip);
}
@@ -286,52 +291,39 @@ chfs_check(struct chfs_mount *chmp, stru
void
chfs_clear_inode(struct chfs_mount *chmp, struct chfs_inode *ip)
{
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+
struct chfs_dirent *fd, *tmpfd;
struct chfs_vnode_cache *chvc;
+ struct chfs_node_ref *nref;
-
- /* XXX not sure if this is the correct locking */
-// mutex_enter(&chmp->chm_lock_vnocache);
chvc = ip->chvc;
/* shouldnt this be: */
//bool deleted = (chvc && !(chvc->pvno || chvc->nlink));
int deleted = (chvc && !(chvc->pvno | chvc->nlink));
if (chvc && chvc->state != VNO_STATE_CHECKING) {
-// chfs_vnode_cache_state_set(chmp, chvc, VNO_STATE_CLEARING);
chvc->state = VNO_STATE_CLEARING;
}
- if (chvc->v && ((struct chfs_vnode_cache *)chvc->v != chvc)) {
- if (deleted)
- chfs_mark_node_obsolete(chmp, chvc->v);
- //chfs_free_refblock(chvc->v);
- }
-// mutex_enter(&chmp->chm_lock_vnocache);
-
- chfs_kill_fragtree(&ip->fragtree);
-/*
- fd = TAILQ_FIRST(&ip->dents);
- while (fd) {
- TAILQ_REMOVE(&ip->dents, fd, fds);
- chfs_free_dirent(fd);
- fd = TAILQ_FIRST(&ip->dents);
+ while (deleted && chvc->v != (struct chfs_node_ref *)chvc) {
+ nref = chvc->v;
+ chfs_remove_and_obsolete(chmp, chvc, nref, &chvc->v);
}
-*/
+
+ chfs_kill_fragtree(chmp, &ip->fragtree);
TAILQ_FOREACH_SAFE(fd, &ip->dents, fds, tmpfd) {
chfs_free_dirent(fd);
}
if (chvc && chvc->state == VNO_STATE_CHECKING) {
- chfs_vnode_cache_set_state(chmp,
- chvc, VNO_STATE_CHECKEDABSENT);
+ chvc->state = VNO_STATE_CHECKEDABSENT;
if ((struct chfs_vnode_cache *)chvc->v == chvc &&
(struct chfs_vnode_cache *)chvc->dirents == chvc &&
(struct chfs_vnode_cache *)chvc->dnode == chvc)
chfs_vnode_cache_remove(chmp, chvc);
}
-
}
struct chfs_eraseblock *
@@ -427,7 +419,6 @@ chfs_gcollect_pass(struct chfs_mount *ch
KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
-// mutex_enter(&chmp->chm_lock_mountfields);
for (;;) {
mutex_enter(&chmp->chm_lock_sizes);
@@ -437,7 +428,6 @@ chfs_gcollect_pass(struct chfs_mount *ch
if (chmp->chm_checked_vno > chmp->chm_max_vno) {
mutex_exit(&chmp->chm_lock_sizes);
- mutex_exit(&chmp->chm_lock_mountfields);
dbg_gc("checked_vno (#%llu) > max_vno (#%llu)\n",
(unsigned long long)chmp->chm_checked_vno,
(unsigned long long)chmp->chm_max_vno);
@@ -474,7 +464,6 @@ chfs_gcollect_pass(struct chfs_mount *ch
case VNO_STATE_GC:
case VNO_STATE_CHECKING:
mutex_exit(&chmp->chm_lock_vnocache);
- mutex_exit(&chmp->chm_lock_mountfields);
dbg_gc("VNO_STATE GC or CHECKING\n");
panic("CHFS BUG - vc state gc or checking\n");
@@ -486,12 +475,10 @@ chfs_gcollect_pass(struct chfs_mount *ch
// sleep_on_spinunlock(&chmp->chm_lock_vnocache);
// KASSERT(!mutex_owned(&chmp->chm_lock_vnocache));
- mutex_exit(&chmp->chm_lock_mountfields);
return 0;
default:
mutex_exit(&chmp->chm_lock_vnocache);
- mutex_exit(&chmp->chm_lock_mountfields);
dbg_gc("default\n");
panic("CHFS BUG - vc state is other what we"
" checked\n");
@@ -500,19 +487,16 @@ chfs_gcollect_pass(struct chfs_mount *ch
;
}
- chfs_vnode_cache_set_state(chmp, vc, VNO_STATE_CHECKING);
+ vc->state = VNO_STATE_CHECKING;
/* XXX check if this is too heavy to call under
* chm_lock_vnocache
*/
ret = chfs_check(chmp, vc);
dbg_gc("set state\n");
- chfs_vnode_cache_set_state(chmp,
- vc, VNO_STATE_CHECKEDABSENT);
+ vc->state = VNO_STATE_CHECKEDABSENT;
mutex_exit(&chmp->chm_lock_vnocache);
- mutex_exit(&chmp->chm_lock_mountfields);
-
return ret;
}
@@ -527,11 +511,9 @@ chfs_gcollect_pass(struct chfs_mount *ch
dbg_gc("!eb\n");
if (!TAILQ_EMPTY(&chmp->chm_erase_pending_queue)) {
mutex_exit(&chmp->chm_lock_sizes);
- mutex_exit(&chmp->chm_lock_mountfields);
return EAGAIN;
}
mutex_exit(&chmp->chm_lock_sizes);
- mutex_exit(&chmp->chm_lock_mountfields);
return EIO;
}
@@ -557,7 +539,6 @@ chfs_gcollect_pass(struct chfs_mount *ch
//dbg_gc("!nref\n");
eb->gc_node = nref;
mutex_exit(&chmp->chm_lock_sizes);
- mutex_exit(&chmp->chm_lock_mountfields);
panic("CHFS BUG - nref is NULL)\n");
}
}
@@ -576,19 +557,19 @@ chfs_gcollect_pass(struct chfs_mount *ch
goto lock_size;
}
- dbg_gc("nref lnr: %u - offset: %u\n", nref->nref_lnr, nref->nref_offset);
- vc = chfs_nref_to_vc(nref);
-
mutex_exit(&chmp->chm_lock_sizes);
//dbg_gc("enter vnocache lock on #%llu\n", vc->vno);
mutex_enter(&chmp->chm_lock_vnocache);
+ dbg_gc("nref lnr: %u - offset: %u\n", nref->nref_lnr, nref->nref_offset);
+ vc = chfs_nref_to_vc(nref);
+
dbg_gc("switch\n");
switch(vc->state) {
case VNO_STATE_CHECKEDABSENT:
if (CHFS_REF_FLAGS(nref) == CHFS_PRISTINE_NODE_MASK) {
- chfs_vnode_cache_set_state(chmp, vc, VNO_STATE_GC);
+ vc->state = VNO_STATE_GC;
}
break;
@@ -599,7 +580,6 @@ chfs_gcollect_pass(struct chfs_mount *ch
case VNO_STATE_CHECKING:
case VNO_STATE_GC:
mutex_exit(&chmp->chm_lock_vnocache);
- mutex_exit(&chmp->chm_lock_mountfields);
panic("CHFS BUG - vc state unchecked,"
" checking or gc (vno #%llu, num #%d)\n",
(unsigned long long)vc->vno, vc->state);
@@ -611,19 +591,15 @@ chfs_gcollect_pass(struct chfs_mount *ch
// sleep_on_spinunlock(&chmp->chm_lock_vnocache);
// KASSERT(!mutex_owned(&chmp->chm_lock_vnocache));
- mutex_exit(&chmp->chm_lock_mountfields);
return 0;
}
if (vc->state == VNO_STATE_GC) {
dbg_gc("vc->state == VNO_STATE_GC\n");
+ vc->state = VNO_STATE_CHECKEDABSENT;
mutex_exit(&chmp->chm_lock_vnocache);
ret = chfs_gcollect_pristine(chmp, eb, NULL, nref);
-// chfs_vnode_cache_state_set(chmp,
-// vc, VNO_STATE_CHECKEDABSENT);
- /* XXX locking? */
- vc->state = VNO_STATE_CHECKEDABSENT;
//TODO wake_up(&chmp->chm_vnocache_wq);
if (ret != EBADF)
goto test_gcnode;
@@ -691,7 +667,6 @@ eraseit:
}
mutex_exit(&chmp->chm_lock_sizes);
- mutex_exit(&chmp->chm_lock_mountfields);
dbg_gc("return\n");
return ret;
}
@@ -814,8 +789,10 @@ retry:
mutex_exit(&chmp->chm_lock_sizes);
//TODO should we set free_size?
- chfs_mark_node_obsolete(chmp, nref);
+ //chfs_mark_node_obsolete(chmp, nref);
+ mutex_enter(&chmp->chm_lock_vnocache);
chfs_add_vnode_ref_to_vc(chmp, chvc, newnref);
+ mutex_exit(&chmp->chm_lock_vnocache);
return 0;
}
@@ -881,7 +858,7 @@ chfs_gcollect_live(struct chfs_mount *ch
}
- /* It's a dirent? */
+ /* Is it a dirent? */
dbg_gc("find full dirent\n");
is_dirent = false;
TAILQ_FOREACH(fd, &ip->dents, fds) {
@@ -928,7 +905,6 @@ chfs_gcollect_dirent(struct chfs_mount *
{
struct vnode *vnode = NULL;
struct chfs_inode *ip;
- struct chfs_node_ref *prev;
dbg_gc("gcollect_dirent\n");
vnode = chfs_vnode_lookup(chmp, fd->vno);
@@ -940,23 +916,11 @@ chfs_gcollect_dirent(struct chfs_mount *
ip = VTOI(vnode);
- prev = parent->chvc->dirents;
- if (prev == fd->nref) {
- parent->chvc->dirents = prev->nref_next;
- dbg_gc("fd nref removed from dirents list\n");
- prev = NULL;
- }
- while (prev) {
- if (prev->nref_next == fd->nref) {
- prev->nref_next = fd->nref->nref_next;
- dbg_gc("fd nref removed from dirents list\n");
- break;
- }
- prev = prev->nref_next;
- }
+ mutex_enter(&chmp->chm_lock_vnocache);
+ chfs_remove_and_obsolete(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
+ mutex_exit(&chmp->chm_lock_vnocache);
- prev = fd->nref;
- chfs_mark_node_obsolete(chmp, fd->nref);
return chfs_write_flash_dirent(chmp,
parent, ip, fd, fd->vno, ALLOC_GC);
}
@@ -1048,7 +1012,11 @@ chfs_gcollect_deletion_dirent(struct chf
// kmem_free(chfdn, nref_len);
- chfs_mark_node_obsolete(chmp, fd->nref);
+ mutex_enter(&chmp->chm_lock_vnocache);
+ chfs_remove_and_obsolete(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
+ mutex_exit(&chmp->chm_lock_vnocache);
+ //chfs_mark_node_obsolete(chmp, fd->nref);
return chfs_write_flash_dirent(chmp,
parent, NULL, fd, fd->vno, ALLOC_GC);
}
@@ -1065,7 +1033,8 @@ chfs_gcollect_dnode(struct chfs_mount *c
struct chfs_eraseblock *orig_cheb, struct chfs_inode *ip,
struct chfs_full_dnode *fn, uint32_t orig_start, uint32_t orig_end)
{
- struct chfs_node_ref *nref, *prev;
+ struct chfs_node_ref *nref;
+ //struct chfs_node_ref *prev;
struct chfs_full_dnode *newfn;
struct chfs_flash_data_node *fdnode;
int ret = 0, retries = 0;
@@ -1211,26 +1180,16 @@ retry:
newfn->nref = nref;
newfn->ofs = fn->ofs;
newfn->size = fn->size;
- newfn->frags = fn->frags;
+ newfn->frags = 0;
- //TODO should we remove fd from dnode list?
-
- prev = ip->chvc->dnode;
- if (prev == fn->nref) {
- ip->chvc->dnode = prev->nref_next;
- prev = NULL;
- }
- while (prev) {
- if (prev->nref_next == fn->nref) {
- prev->nref_next = fn->nref->nref_next;
- break;
- }
- prev = prev->nref_next;
- }
+ mutex_enter(&chmp->chm_lock_vnocache);
+ chfs_remove_frags_of_node(chmp, &ip->fragtree, fn->nref);
+ chfs_remove_and_obsolete(chmp, ip->chvc, fn->nref, &ip->chvc->dnode);
chfs_add_full_dnode_to_inode(chmp, ip, newfn);
chfs_add_node_to_list(chmp,
ip->chvc, newfn->nref, &ip->chvc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
out:
kmem_free(data, totlen);
Index: src/sys/ufs/chfs/chfs_malloc.c
diff -u src/sys/ufs/chfs/chfs_malloc.c:1.2 src/sys/ufs/chfs/chfs_malloc.c:1.3
--- src/sys/ufs/chfs/chfs_malloc.c:1.2 Tue Feb 28 02:48:39 2012
+++ src/sys/ufs/chfs/chfs_malloc.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_malloc.c,v 1.2 2012/02/28 02:48:39 christos Exp $ */
+/* $NetBSD: chfs_malloc.c,v 1.3 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -297,6 +297,8 @@ chfs_alloc_full_dnode(void)
{
struct chfs_full_dnode *ret;
ret = kmem_alloc(sizeof(struct chfs_full_dnode), KM_SLEEP);
+ ret->nref = NULL;
+ ret->frags = 0;
return ret;
}
Index: src/sys/ufs/chfs/chfs_readinode.c
diff -u src/sys/ufs/chfs/chfs_readinode.c:1.2 src/sys/ufs/chfs/chfs_readinode.c:1.3
--- src/sys/ufs/chfs/chfs_readinode.c:1.2 Thu Nov 24 21:09:37 2011
+++ src/sys/ufs/chfs/chfs_readinode.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_readinode.c,v 1.2 2011/11/24 21:09:37 agc Exp $ */
+/* $NetBSD: chfs_readinode.c,v 1.3 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -201,7 +201,7 @@ chfs_check_td_data(struct chfs_mount *ch
return 1;
}
- nref->nref_offset = CHFS_GET_OFS(nref->nref_offset) | CHFS_NORMAL_NODE_MASK;
+ CHFS_MARK_REF_NORMAL(nref);
totlen = CHFS_PAD(sizeof(struct chfs_flash_data_node) + len);
mutex_enter(&chmp->chm_lock_sizes);
@@ -225,9 +225,6 @@ chfs_check_td_node(struct chfs_mount *ch
return 0;
ret = chfs_check_td_data(chmp, td);
- if (ret == 1) {
- chfs_mark_node_obsolete(chmp, td->node->nref);
- }
return ret;
}
@@ -289,9 +286,12 @@ static void
chfs_kill_td(struct chfs_mount *chmp,
struct chfs_tmp_dnode *td)
{
- /* check if we need to mark as obsolete, to avoid double mark */
- if (!CHFS_REF_OBSOLETE(td->node->nref)) {
- chfs_mark_node_obsolete(chmp, td->node->nref);
+ struct chfs_vnode_cache *vc;
+ if (td->node) {
+ mutex_enter(&chmp->chm_lock_vnocache);
+ vc = chfs_nref_to_vc(td->node->nref);
+ chfs_remove_and_obsolete(chmp, vc, td->node->nref, &vc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
}
chfs_free_tmp_dnode(td);
@@ -422,8 +422,8 @@ chfs_add_tmp_dnode_to_tree(struct chfs_m
obsoleted by an earlier node. Insert into the tree */
struct chfs_tmp_dnode_info *tmp_tdi = rb_tree_insert_node(&rii->tdi_root, newtdi);
if (tmp_tdi != newtdi) {
+ chfs_remove_tmp_dnode_from_tdi(newtdi, newtd);
chfs_add_tmp_dnode_to_tdi(tmp_tdi, newtd);
- newtdi->tmpnode = NULL;
chfs_kill_tdi(chmp, newtdi);
}
@@ -473,6 +473,9 @@ new_fragment(struct chfs_full_dnode *fdn
newfrag->ofs = ofs;
newfrag->size = size;
newfrag->node = fdn;
+ if (newfrag->node) {
+ newfrag->node->frags++;
+ }
} else {
chfs_err("cannot allocate a chfs_node_frag object\n");
}
@@ -544,8 +547,6 @@ chfs_add_frag_to_fragtree(struct chfs_mo
this->ofs + this->size - newfrag->ofs - newfrag->size);
if (!newfrag2)
return ENOMEM;
- if (this->node)
- this->node->frags++;
this->size = newfrag->ofs - this->ofs;
@@ -597,17 +598,34 @@ chfs_add_frag_to_fragtree(struct chfs_mo
}
void
-chfs_kill_fragtree(struct rb_tree *fragtree)
+chfs_remove_frags_of_node(struct chfs_mount *chmp, struct rb_tree *fragtree,
+ struct chfs_node_ref *nref)
+{
+ KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
+ struct chfs_node_frag *this, *next;
+
+ this = (struct chfs_node_frag *)RB_TREE_MIN(fragtree);
+ while (this) {
+ next = frag_next(fragtree, this);
+ if (this->node->nref == nref) {
+ rb_tree_remove_node(fragtree, this);
+ }
+ this = next;
+ }
+}
+
+void
+chfs_kill_fragtree(struct chfs_mount *chmp, struct rb_tree *fragtree)
{
+ KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
struct chfs_node_frag *this, *next;
//dbg("start\n");
this = (struct chfs_node_frag *)RB_TREE_MIN(fragtree);
while (this) {
- //for (this = (struct chfs_node_frag *)RB_TREE_MIN(&fragtree); this != NULL; this = (struct chfs_node_frag *)rb_tree_iterate(&fragtree, &this->rb_node, RB_DIR_RIGHT)) {
next = frag_next(fragtree, this);
rb_tree_remove_node(fragtree, this);
- chfs_free_node_frag(this);
+ chfs_obsolete_node_frag(chmp, this);
//dbg("one frag killed\n");
this = next;
}
@@ -618,8 +636,8 @@ uint32_t
chfs_truncate_fragtree(struct chfs_mount *chmp,
struct rb_tree *fragtree, uint32_t size)
{
- struct chfs_node_frag *frag;
KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
+ struct chfs_node_frag *frag;
dbg("truncate to size: %u\n", size);
@@ -658,7 +676,8 @@ chfs_truncate_fragtree(struct chfs_mount
/* FIXME Should we check the postion of the last node? (PAGE_CACHE size, etc.) */
if (frag->node && (frag->ofs & (PAGE_SIZE - 1)) == 0) {
- frag->node->nref->nref_offset = CHFS_GET_OFS(frag->node->nref->nref_offset) | CHFS_PRISTINE_NODE_MASK;
+ frag->node->nref->nref_offset =
+ CHFS_GET_OFS(frag->node->nref->nref_offset) | CHFS_PRISTINE_NODE_MASK;
}
return size;
@@ -668,27 +687,21 @@ void
chfs_obsolete_node_frag(struct chfs_mount *chmp,
struct chfs_node_frag *this)
{
+ struct chfs_vnode_cache *vc;
KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
if (this->node) {
+ KASSERT(this->node->frags != 0);
this->node->frags--;
- if (!this->node->frags) {
- struct chfs_vnode_cache *vc = chfs_nref_to_vc(this->node->nref);
- chfs_mark_node_obsolete(chmp, this->node->nref);
-
- if (vc->dnode == this->node->nref) {
- vc->dnode = this->node->nref->nref_next;
- } else {
- struct chfs_node_ref *tmp = vc->dnode;
- while (tmp->nref_next != (struct chfs_node_ref*) vc
- && tmp->nref_next != this->node->nref) {
- tmp = tmp->nref_next;
- }
- if (tmp->nref_next == this->node->nref) {
- tmp->nref_next = this->node->nref->nref_next;
- }
- // FIXME should we free here the this->node->nref?
- }
-
+ if (this->node->frags == 0) {
+ KASSERT(!CHFS_REF_OBSOLETE(this->node->nref));
+ mutex_enter(&chmp->chm_lock_vnocache);
+ vc = chfs_nref_to_vc(this->node->nref);
+ dbg("[MARK] lnr: %u ofs: %u\n", this->node->nref->nref_lnr,
+ this->node->nref->nref_offset);
+
+ chfs_remove_and_obsolete(chmp, vc, this->node->nref, &vc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
+
chfs_free_full_dnode(this->node);
} else {
CHFS_MARK_REF_NORMAL(this->node->nref);
@@ -713,8 +726,6 @@ chfs_add_full_dnode_to_inode(struct chfs
if (unlikely(!newfrag))
return ENOMEM;
- newfrag->node->frags = 1;
-
ret = chfs_add_frag_to_fragtree(chmp, &ip->fragtree, newfrag);
if (ret)
return ret;
@@ -815,6 +826,7 @@ chfs_get_data_nodes(struct chfs_mount *c
td->data_crc = le32toh(dnode->data_crc);
td->node->nref = nref;
td->node->size = le32toh(dnode->data_length);
+ td->node->frags = 1;
td->overlapped = 0;
if (td->version > rii->highest_version) {
@@ -892,6 +904,7 @@ chfs_build_fragtree(struct chfs_mount *c
if (chfs_check_td_node(chmp, tmp_td)) {
if (next_td) {
chfs_remove_tmp_dnode_from_tdi(this, tmp_td);
+ chfs_kill_td(chmp, tmp_td);
} else {
break;
}
@@ -908,13 +921,10 @@ chfs_build_fragtree(struct chfs_mount *c
vers_next = (struct chfs_tmp_dnode_info *)rb_tree_iterate(&ver_tree, this, RB_DIR_LEFT);
while (tmp_td) {
next_td = tmp_td->next;
- if (chfs_check_td_node(chmp, tmp_td) > 1) {
- chfs_mark_node_obsolete(chmp,
- tmp_td->node->nref);
- }
+
chfs_free_full_dnode(tmp_td->node);
chfs_remove_tmp_dnode_from_tdi(this, tmp_td);
- chfs_free_tmp_dnode(tmp_td);
+ chfs_kill_td(chmp, tmp_td);
tmp_td = next_td;
}
chfs_free_tmp_dnode_info(this);
@@ -922,12 +932,15 @@ chfs_build_fragtree(struct chfs_mount *c
if (!this)
break;
rb_tree_remove_node(&ver_tree, vers_next);
+ chfs_kill_tdi(chmp, vers_next);
}
return ret;
}
chfs_remove_tmp_dnode_from_tdi(this, tmp_td);
chfs_free_tmp_dnode(tmp_td);
+ // shouldn't obsolete tmp_td here,
+ // because tmp_td->node was added to the inode
}
tmp_td = next_td;
}
@@ -946,16 +959,15 @@ int chfs_read_inode(struct chfs_mount *c
KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
retry:
- /* XXX locking */
- //mutex_enter(&chmp->chm_lock_vnocache);
+ mutex_enter(&chmp->chm_lock_vnocache);
switch (vc->state) {
case VNO_STATE_UNCHECKED:
case VNO_STATE_CHECKEDABSENT:
-// chfs_vnode_cache_set_state(chmp, vc, VNO_STATE_READING);
vc->state = VNO_STATE_READING;
break;
case VNO_STATE_CHECKING:
case VNO_STATE_GC:
+ mutex_exit(&chmp->chm_lock_vnocache);
//sleep_on_spinunlock(&chmp->chm_lock_vnocache);
//KASSERT(!mutex_owned(&chmp->chm_lock_vnocache));
goto retry;
@@ -970,7 +982,7 @@ retry:
default:
panic("BUG() Bad vno cache state.");
}
- //mutex_exit(&chmp->chm_lock_vnocache);
+ mutex_exit(&chmp->chm_lock_vnocache);
return chfs_read_inode_internal(chmp, ip);
}
Index: src/sys/ufs/chfs/chfs_scan.c
diff -u src/sys/ufs/chfs/chfs_scan.c:1.2 src/sys/ufs/chfs/chfs_scan.c:1.3
--- src/sys/ufs/chfs/chfs_scan.c:1.2 Thu Nov 24 21:09:37 2011
+++ src/sys/ufs/chfs/chfs_scan.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_scan.c,v 1.2 2011/11/24 21:09:37 agc Exp $ */
+/* $NetBSD: chfs_scan.c,v 1.3 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -64,17 +64,12 @@ chfs_scan_make_vnode_cache(struct chfs_m
vc = chfs_vnode_cache_alloc(vno);
- //mutex_enter(&chmp->chm_lock_vnocache);
-
chfs_vnode_cache_add(chmp, vc);
- //mutex_exit(&chmp->chm_lock_vnocache);
-
if (vno == CHFS_ROOTINO) {
vc->nlink = 2;
vc->pvno = CHFS_ROOTINO;
- chfs_vnode_cache_set_state(chmp,
- vc, VNO_STATE_CHECKEDABSENT);
+ vc->state = VNO_STATE_CHECKEDABSENT;
}
return vc;
@@ -152,7 +147,6 @@ chfs_scan_check_vnode(struct chfs_mount
return ENOMEM;
}
}
- mutex_exit(&chmp->chm_lock_vnocache);
nref = chfs_alloc_node_ref(cheb);
@@ -179,6 +173,7 @@ chfs_scan_check_vnode(struct chfs_mount
*vc->vno_version = le64toh(vnode->version);
chfs_add_vnode_ref_to_vc(chmp, vc, nref);
}
+ mutex_exit(&chmp->chm_lock_vnocache);
mutex_enter(&chmp->chm_lock_sizes);
//dbg("B:lnr: %d |free_size: %d node's size: %d\n", cheb->lnr, cheb->free_size, le32toh(vnode->length));
@@ -228,15 +223,15 @@ chfs_scan_mark_dirent_obsolete(struct ch
if (prev && prev == nref) {
vc->dirents = prev->nref_next;
} else if (prev && prev != (void *)vc) {
- while (prev->nref_next && prev->nref_next !=
- (void *)vc && prev->nref_next != nref) {
+ while (prev->nref_next && prev->nref_next != (void *)vc) {
+ if (prev->nref_next == nref) {
+ prev->nref_next = nref->nref_next;
+ break;
+ }
prev = prev->nref_next;
}
-
- if (prev->nref_next == nref) {
- prev->nref_next = nref->nref_next;
- }
}
+
/*dbg("XXX - start\n");
//nref = vc->dirents;
struct chfs_dirent *tmp;
@@ -366,7 +361,7 @@ chfs_scan_check_dirent_node(struct chfs_
int err, namelen;
uint32_t crc;
struct chfs_dirent *fd;
- struct chfs_vnode_cache *vc;
+ struct chfs_vnode_cache *parentvc;
struct chfs_flash_dirent_node *dirent = buf;
//struct chfs_node_ref *tmp;
@@ -406,17 +401,17 @@ chfs_scan_check_dirent_node(struct chfs_
/* Check vnode_cache of parent node */
mutex_enter(&chmp->chm_lock_vnocache);
- vc = chfs_scan_make_vnode_cache(chmp, le64toh(dirent->pvno));
- mutex_exit(&chmp->chm_lock_vnocache);
- if (!vc) {
+ parentvc = chfs_scan_make_vnode_cache(chmp, le64toh(dirent->pvno));
+ if (!parentvc) {
chfs_free_dirent(fd);
return ENOMEM;
}
fd->nref->nref_offset = ofs;
- dbg("add dirent to #%llu\n", (unsigned long long)vc->vno);
- chfs_add_node_to_list(chmp, vc, fd->nref, &vc->dirents);
+ dbg("add dirent to #%llu\n", (unsigned long long)parentvc->vno);
+ chfs_add_node_to_list(chmp, parentvc, fd->nref, &parentvc->dirents);
+ mutex_exit(&chmp->chm_lock_vnocache);
/*tmp = vc->dirents;
dbg("START|vno: %d dirents dump\n", vc->vno);
while (tmp) {
@@ -440,7 +435,7 @@ chfs_scan_check_dirent_node(struct chfs_
dbg(" ->name: %s\n", fd->name);
dbg(" ->type: %d\n", fd->type);*/
- chfs_add_fd_to_list(chmp, fd, vc);
+ chfs_add_fd_to_list(chmp, fd, parentvc);
/*struct chfs_node_ref *tmp;
tmp = vc->dirents;
@@ -503,7 +498,7 @@ chfs_scan_check_data_node(struct chfs_mo
if (!nref)
return ENOMEM;
- nref->nref_offset = ofs | CHFS_UNCHECKED_NODE_MASK;
+ nref->nref_offset = CHFS_GET_OFS(ofs) | CHFS_UNCHECKED_NODE_MASK;
KASSERT(nref->nref_lnr == cheb->lnr);
@@ -515,8 +510,8 @@ chfs_scan_check_data_node(struct chfs_mo
if (!vc)
return ENOMEM;
}
- mutex_exit(&chmp->chm_lock_vnocache);
chfs_add_node_to_list(chmp, vc, nref, &vc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
dbg("chmpfree: %u, chebfree: %u, dnode: %u\n", chmp->chm_free_size, cheb->free_size, dnode->length);
Index: src/sys/ufs/chfs/ebh.c
diff -u src/sys/ufs/chfs/ebh.c:1.2 src/sys/ufs/chfs/ebh.c:1.3
--- src/sys/ufs/chfs/ebh.c:1.2 Fri Nov 25 11:15:24 2011
+++ src/sys/ufs/chfs/ebh.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ebh.c,v 1.2 2011/11/25 11:15:24 ahoka Exp $ */
+/* $NetBSD: ebh.c,v 1.3 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -1730,6 +1730,7 @@ ebh_read_leb(struct chfs_ebh *ebh, int l
err = leb_read_lock(ebh, lnr);
if (err)
return err;
+
pebnr = ebh->lmap[lnr];
/* If PEB is not mapped the buffer is filled with 0xFF */
if (EBH_LEB_UNMAPPED == pebnr) {
@@ -1747,9 +1748,6 @@ ebh_read_leb(struct chfs_ebh *ebh, int l
KASSERT(len == *retlen);
- leb_read_unlock(ebh, lnr);
- return err;
-
out_free:
leb_read_unlock(ebh, lnr);
return err;
Index: src/sys/ufs/chfs/chfs_nodeops.c
diff -u src/sys/ufs/chfs/chfs_nodeops.c:1.1 src/sys/ufs/chfs/chfs_nodeops.c:1.2
--- src/sys/ufs/chfs/chfs_nodeops.c:1.1 Thu Nov 24 15:51:31 2011
+++ src/sys/ufs/chfs/chfs_nodeops.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_nodeops.c,v 1.1 2011/11/24 15:51:31 ahoka Exp $ */
+/* $NetBSD: chfs_nodeops.c,v 1.2 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -80,6 +80,8 @@ chfs_add_node_to_list(struct chfs_mount
struct chfs_vnode_cache *vc,
struct chfs_node_ref *new, struct chfs_node_ref **list)
{
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+
struct chfs_node_ref *nextref = *list;
struct chfs_node_ref *prevref = NULL;
@@ -104,10 +106,13 @@ chfs_add_node_to_list(struct chfs_mount
CHFS_GET_OFS(nextref->nref_offset) ==
CHFS_GET_OFS(new->nref_offset)) {
new->nref_next = nextref->nref_next;
+ chfs_mark_node_obsolete(chmp, nextref);
} else {
new->nref_next = nextref;
}
+ KASSERT(new->nref_next != NULL);
+
if (prevref) {
prevref->nref_next = new;
} else {
@@ -115,6 +120,60 @@ chfs_add_node_to_list(struct chfs_mount
}
}
+/*
+ * Removes a node from a list. Usually used for removing data nodes.
+ */
+void
+chfs_remove_node_from_list(struct chfs_mount *chmp,
+ struct chfs_vnode_cache *vc,
+ struct chfs_node_ref *old_nref, struct chfs_node_ref **list)
+{
+ KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+
+ struct chfs_node_ref *tmpnref;
+
+ if (*list == (struct chfs_node_ref *)vc) {
+ return;
+ }
+
+ KASSERT(old_nref->nref_next != NULL);
+
+ if (*list == old_nref) {
+ *list = old_nref->nref_next;
+ } else {
+ tmpnref = *list;
+ while (tmpnref->nref_next &&
+ tmpnref->nref_next != (struct chfs_node_ref *)vc) {
+ if (tmpnref->nref_next == old_nref) {
+ tmpnref->nref_next = old_nref->nref_next;
+ break;
+ }
+ tmpnref = tmpnref->nref_next;
+ }
+ }
+}
+
+/*
+ * Removes a node from a list and obsoletes the nref.
+ * We should use this function carefully on data nodes,
+ * because removing a frag will obsolete the node ref.
+ */
+void
+chfs_remove_and_obsolete(struct chfs_mount *chmp,
+ struct chfs_vnode_cache *vc,
+ struct chfs_node_ref *old_nref, struct chfs_node_ref **list)
+{
+ KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+
+ chfs_remove_node_from_list(chmp, vc, old_nref, list);
+
+ dbg("[MARK] vno: %llu lnr: %u ofs: %u\n", vc->vno, old_nref->nref_lnr,
+ old_nref->nref_offset);
+ chfs_mark_node_obsolete(chmp, old_nref);
+}
+
void
chfs_add_fd_to_inode(struct chfs_mount *chmp,
struct chfs_inode *parent, struct chfs_dirent *new)
@@ -140,8 +199,10 @@ chfs_add_fd_to_inode(struct chfs_mount *
TAILQ_INSERT_BEFORE(fd, new, fds);
TAILQ_REMOVE(&parent->dents, fd, fds);
if (fd->nref) {
- chfs_mark_node_obsolete(chmp,
- fd->nref);
+ mutex_enter(&chmp->chm_lock_vnocache);
+ chfs_remove_and_obsolete(chmp, parent->chvc, fd->nref,
+ &parent->chvc->dirents);
+ mutex_exit(&chmp->chm_lock_vnocache);
}
chfs_free_dirent(fd);
// *prev = new;//XXX
@@ -186,12 +247,15 @@ void
chfs_add_vnode_ref_to_vc(struct chfs_mount *chmp,
struct chfs_vnode_cache *vc, struct chfs_node_ref *new)
{
- if ((struct chfs_vnode_cache*)(vc->v) != vc) {
- chfs_mark_node_obsolete(chmp, vc->v);
- new->nref_next = vc->v->nref_next;
- } else {
- new->nref_next = vc->v;
+ KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
+ struct chfs_node_ref *nref;
+
+ while (vc->v != (struct chfs_node_ref *)vc) {
+ nref = vc->v;
+ chfs_remove_and_obsolete(chmp, vc, nref, &vc->v);
}
+
+ new->nref_next = (struct chfs_node_ref *)vc;
vc->v = new;
}
@@ -456,8 +520,6 @@ chfs_reserve_space_normal(struct chfs_mo
mutex_exit(&chmp->chm_lock_sizes);
ret = chfs_gcollect_pass(chmp);
- /* gcollect_pass exits chm_lock_mountfields */
- mutex_enter(&chmp->chm_lock_mountfields);
mutex_enter(&chmp->chm_lock_sizes);
if (chmp->chm_nr_erasable_blocks ||
Index: src/sys/ufs/chfs/chfs_vnode_cache.c
diff -u src/sys/ufs/chfs/chfs_vnode_cache.c:1.1 src/sys/ufs/chfs/chfs_vnode_cache.c:1.2
--- src/sys/ufs/chfs/chfs_vnode_cache.c:1.1 Thu Nov 24 15:51:32 2011
+++ src/sys/ufs/chfs/chfs_vnode_cache.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_vnode_cache.c,v 1.1 2011/11/24 15:51:32 ahoka Exp $ */
+/* $NetBSD: chfs_vnode_cache.c,v 1.2 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -43,21 +43,6 @@ chfs_vnocache_hash_init(void)
}
/**
- * chfs_set_vnode_cache_state - set state of a vnode_cache
- * @chmp: fs super block info
- * @vc: vnode_cache
- * @state: new state
- */
-void
-chfs_vnode_cache_set_state(struct chfs_mount *chmp,
- struct chfs_vnode_cache* vc, int state)
-{
- /* XXX do we really need locking here? */
- KASSERT(mutex_owned(&chmp->chm_lock_vnocache));
- vc->state = state;
-}
-
-/**
* chfs_get_vnode_cache - get a vnode_cache from the vnocache_hash
* @chmp: fs super block info
* @ino: inode for search
Index: src/sys/ufs/chfs/chfs_subr.c
diff -u src/sys/ufs/chfs/chfs_subr.c:1.4 src/sys/ufs/chfs/chfs_subr.c:1.5
--- src/sys/ufs/chfs/chfs_subr.c:1.4 Thu Apr 12 15:31:01 2012
+++ src/sys/ufs/chfs/chfs_subr.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_subr.c,v 1.4 2012/04/12 15:31:01 ttoth Exp $ */
+/* $NetBSD: chfs_subr.c,v 1.5 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -295,7 +295,12 @@ chfs_chsize(struct vnode *vp, u_quad_t s
struct chfs_node_frag *lastfrag = frag_last(&ip->fragtree);
fd = lastfrag->node;
- chfs_mark_node_obsolete(chmp, fd->nref);
+
+ // remove from the list
+ mutex_enter(&chmp->chm_lock_vnocache);
+ chfs_remove_frags_of_node(chmp, &ip->fragtree, fd->nref);
+ chfs_remove_and_obsolete(chmp, ip->chvc, fd->nref, &ip->chvc->dnode);
+ mutex_exit(&chmp->chm_lock_vnocache);
blknum = lastfrag->ofs / PAGE_SIZE;
lastfrag->size = append > PAGE_SIZE ? PAGE_SIZE : size % PAGE_SIZE;
Index: src/sys/ufs/chfs/chfs_vfsops.c
diff -u src/sys/ufs/chfs/chfs_vfsops.c:1.4 src/sys/ufs/chfs/chfs_vfsops.c:1.5
--- src/sys/ufs/chfs/chfs_vfsops.c:1.4 Mon Apr 30 22:51:28 2012
+++ src/sys/ufs/chfs/chfs_vfsops.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_vfsops.c,v 1.4 2012/04/30 22:51:28 rmind Exp $ */
+/* $NetBSD: chfs_vfsops.c,v 1.5 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -539,8 +539,7 @@ retry:
if (ino == CHFS_ROOTINO) {
chvc->nlink = 2;
chvc->pvno = CHFS_ROOTINO;
- chfs_vnode_cache_set_state(chmp,
- chvc, VNO_STATE_CHECKEDABSENT);
+ chvc->state = VNO_STATE_CHECKEDABSENT;
}
chfs_vnode_cache_add(chmp, chvc);
mutex_exit(&chmp->chm_lock_vnocache);
Index: src/sys/ufs/chfs/chfs_vnode.c
diff -u src/sys/ufs/chfs/chfs_vnode.c:1.5 src/sys/ufs/chfs/chfs_vnode.c:1.6
--- src/sys/ufs/chfs/chfs_vnode.c:1.5 Fri Apr 13 14:50:35 2012
+++ src/sys/ufs/chfs/chfs_vnode.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_vnode.c,v 1.5 2012/04/13 14:50:35 ttoth Exp $ */
+/* $NetBSD: chfs_vnode.c,v 1.6 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -211,7 +211,6 @@ chfs_makeinode(int mode, struct vnode *d
mutex_enter(&chmp->chm_lock_vnocache);
chvc = chfs_vnode_cache_get(chmp, vno);
- mutex_exit(&chmp->chm_lock_vnocache);
chvc->pvno = pdir->ino;
chvc->vno_version = kmem_alloc(sizeof(uint64_t), KM_SLEEP);
@@ -220,8 +219,8 @@ chfs_makeinode(int mode, struct vnode *d
chvc->nlink = 1;
else
chvc->nlink = 2;
-// chfs_vnode_cache_set_state(chmp, chvc, VNO_STATE_CHECKEDABSENT);
chvc->state = VNO_STATE_CHECKEDABSENT;
+ mutex_exit(&chmp->chm_lock_vnocache);
ip = VTOI(vp);
ip->ino = vno;
Index: src/sys/ufs/chfs/chfs_vnops.c
diff -u src/sys/ufs/chfs/chfs_vnops.c:1.8 src/sys/ufs/chfs/chfs_vnops.c:1.9
--- src/sys/ufs/chfs/chfs_vnops.c:1.8 Sun Jul 22 00:53:22 2012
+++ src/sys/ufs/chfs/chfs_vnops.c Fri Aug 10 09:26:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_vnops.c,v 1.8 2012/07/22 00:53:22 rmind Exp $ */
+/* $NetBSD: chfs_vnops.c,v 1.9 2012/08/10 09:26:58 ttoth Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -661,7 +661,6 @@ chfs_read(void *v)
goto out;
}
-
dbg("start reading\n");
for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
bytesinfile = ip->size - uio->uio_offset;
@@ -706,10 +705,14 @@ chfs_read(void *v)
break;
brelse(bp, 0);
}
+
if (bp != NULL)
brelse(bp, 0);
out:
+ // FIXME HACK
+ ip->ino = ip->chvc->vno;
+
if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
ip->iflag |= IN_ACCESS;
if ((ap->a_ioflag & IO_SYNC) == IO_SYNC) {
@@ -725,6 +728,7 @@ out:
dbg("[END]\n");
fstrans_done(vp->v_mount);
+
return (error);
}
@@ -989,7 +993,7 @@ out:
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC) == IO_SYNC)
error = UFS_UPDATE(vp, NULL, NULL, UPDATE_WAIT);
- //XXX hack, i write the next line after i know ip->i_size and vp->v_size don't equal
+ //FIXME HACK
chfs_set_vnode_size(vp, vp->v_size);
@@ -1492,22 +1496,18 @@ chfs_reclaim(void *v)
//dbg("reclaim() | ino: %llu\n", (unsigned long long)ip->ino);
//mutex_enter(&ip->inode_lock);
+ mutex_enter(&chmp->chm_lock_mountfields);
mutex_enter(&chmp->chm_lock_vnocache);
- chfs_vnode_cache_set_state(chmp,
- ip->chvc, VNO_STATE_CHECKEDABSENT);
+ ip->chvc->state = VNO_STATE_CHECKEDABSENT;
mutex_exit(&chmp->chm_lock_vnocache);
chfs_update(vp, NULL, NULL, UPDATE_CLOSE);
- if (ip->ch_type == CHT_REG || ip->ch_type == CHT_LNK ||
- ip->ch_type == CHT_CHR || ip->ch_type == CHT_BLK ||
- ip->ch_type == CHT_FIFO || ip->ch_type == CHT_SOCK) {
- chfs_kill_fragtree(&ip->fragtree);
- }
+ chfs_kill_fragtree(chmp, &ip->fragtree);
fd = TAILQ_FIRST(&ip->dents);
- while(fd) {
+ while (fd) {
TAILQ_REMOVE(&ip->dents, fd, fds);
chfs_free_dirent(fd);
fd = TAILQ_FIRST(&ip->dents);
@@ -1525,6 +1525,9 @@ chfs_reclaim(void *v)
genfs_node_destroy(vp);
pool_put(&chfs_inode_pool, vp->v_data);
vp->v_data = NULL;
+
+ mutex_exit(&chmp->chm_lock_mountfields);
+
return (0);
}
@@ -1570,16 +1573,17 @@ chfs_strategy(void *v)
if (read) {
err = chfs_read_data(chmp, vp, bp);
} else {
- fd = chfs_alloc_full_dnode();
-
mutex_enter(&chmp->chm_lock_mountfields);
+ fd = chfs_alloc_full_dnode();
+
err = chfs_write_flash_dnode(chmp, vp, bp, fd);
if (err) {
mutex_exit(&chmp->chm_lock_mountfields);
goto out;
}
+ ip = VTOI(vp);
err = chfs_add_full_dnode_to_inode(chmp, ip, fd);
/*if (err) {
mutex_exit(&chmp->chm_lock_mountfields);