Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/chfs chfs bugfix [node was obsoleted twice]



details:   https://anonhg.NetBSD.org/src/rev/b7482798cabe
branches:  trunk
changeset: 780870:b7482798cabe
user:      ttoth <ttoth%NetBSD.org@localhost>
date:      Fri Aug 10 09:26:58 2012 +0000

description:
chfs bugfix [node was obsoleted twice]

diffstat:

 sys/ufs/chfs/chfs.h             |   13 ++-
 sys/ufs/chfs/chfs_build.c       |   24 +++---
 sys/ufs/chfs/chfs_gc.c          |  125 +++++++++++++--------------------------
 sys/ufs/chfs/chfs_malloc.c      |    4 +-
 sys/ufs/chfs/chfs_nodeops.c     |   82 +++++++++++++++++++++++---
 sys/ufs/chfs/chfs_readinode.c   |  102 ++++++++++++++++++--------------
 sys/ufs/chfs/chfs_scan.c        |   41 +++++-------
 sys/ufs/chfs/chfs_subr.c        |    9 ++-
 sys/ufs/chfs/chfs_vfsops.c      |    5 +-
 sys/ufs/chfs/chfs_vnode.c       |    5 +-
 sys/ufs/chfs/chfs_vnode_cache.c |   17 +-----
 sys/ufs/chfs/chfs_vnops.c       |   30 +++++----
 sys/ufs/chfs/chfs_write.c       |   70 ++++++++++++---------
 sys/ufs/chfs/ebh.c              |    6 +-
 14 files changed, 283 insertions(+), 250 deletions(-)

diffs (truncated from 1402 to 300 lines):

diff -r 94efd9c7f701 -r b7482798cabe sys/ufs/chfs/chfs.h
--- a/sys/ufs/chfs/chfs.h       Fri Aug 10 08:42:10 2012 +0000
+++ b/sys/ufs/chfs/chfs.h       Fri Aug 10 09:26:58 2012 +0000
@@ -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 @@
     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 @@
                        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 @@
 /* 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 @@
 /* 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 *);
diff -r 94efd9c7f701 -r b7482798cabe sys/ufs/chfs/chfs_build.c
--- a/sys/ufs/chfs/chfs_build.c Fri Aug 10 08:42:10 2012 +0000
+++ b/sys/ufs/chfs/chfs_build.c Fri Aug 10 09:26:58 2012 +0000
@@ -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 @@
 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 @@
                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 @@
        dbg("START\n");
        dbg("vno: %llu\n", (unsigned long long)vc->vno);
 
+       KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
        nref = vc->dnode;
-       KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
        // 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_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_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 @@
 
        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 @@
                                } 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);
diff -r 94efd9c7f701 -r b7482798cabe sys/ufs/chfs/chfs_gc.c
--- a/sys/ufs/chfs/chfs_gc.c    Fri Aug 10 08:42:10 2012 +0000
+++ b/sys/ufs/chfs/chfs_gc.c    Fri Aug 10 09:26:58 2012 +0000
@@ -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 @@
                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 @@
                                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 @@
 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 @@
        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 @@
 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);
+       while (deleted && chvc->v != (struct chfs_node_ref *)chvc) {
+               nref = chvc->v;
+               chfs_remove_and_obsolete(chmp, chvc, nref, &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);
-       }
-*/
+       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 @@
 
        KASSERT(mutex_owned(&chmp->chm_lock_mountfields));
 
-//     mutex_enter(&chmp->chm_lock_mountfields);
        for (;;) {
                mutex_enter(&chmp->chm_lock_sizes);
 
@@ -437,7 +428,6 @@
 
                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 @@
                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 @@
 
 //                     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_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;



Home | Main Index | Thread Index | Old Index