Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/lfs Changes to stabilize LFS. The first two of thes...



details:   https://anonhg.NetBSD.org/src/rev/a588e66ddd60
branches:  trunk
changeset: 480735:a588e66ddd60
user:      perseant <perseant%NetBSD.org@localhost>
date:      Wed Jan 19 00:03:04 2000 +0000

description:
Changes to stabilize LFS.  The first two of these should also apply to the
1.4 branch.

* Use a separate per-fs lock, instead of ufs_hashlock, to protect the Inode
  free list.  This seems to prevent the "lockmgr: %d, not exclusive lock holder
  %d, unlocking" message I was mis-attributing last night to an unlocked vnode
  being passed to vrele.

* Change calling semantics of lfs_ifind, to give better error reporting:
  If fed a struct buf, it can report the block number of the offending inode
  block as well as the inode number.

* Back out rev 1.10 of lfs_subr.c, since the replacement code was slightly
  uglier while being functionally identical.

* Make lfs_vunref use the same free list convention as vrele/vput, so that
  vget does not remove vnodes from a hash list they are not on.

diffstat:

 sys/ufs/lfs/lfs.h          |   3 ++-
 sys/ufs/lfs/lfs_alloc.c    |  24 ++++++++++--------------
 sys/ufs/lfs/lfs_extern.h   |   4 ++--
 sys/ufs/lfs/lfs_inode.c    |   9 ++++++---
 sys/ufs/lfs/lfs_segment.c  |   7 +++++--
 sys/ufs/lfs/lfs_subr.c     |   9 ++++-----
 sys/ufs/lfs/lfs_syscalls.c |   4 ++--
 sys/ufs/lfs/lfs_vfsops.c   |   5 +++--
 8 files changed, 34 insertions(+), 31 deletions(-)

diffs (248 lines):

diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs.h Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs.h,v 1.19 1999/12/15 07:10:34 perseant Exp $        */
+/*     $NetBSD: lfs.h,v 1.20 2000/01/19 00:03:04 perseant Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -314,6 +314,7 @@
 #endif
        struct vnode *lfs_flushvp;      /* vnode being flushed */
        u_int32_t lfs_diropwait;        /* # procs waiting on dirop flush */
+       struct lock lfs_freelock;
 };
 
 /*
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_alloc.c,v 1.30 1999/12/15 07:19:07 perseant Exp $  */
+/*     $NetBSD: lfs_alloc.c,v 1.31 2000/01/19 00:03:04 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -122,11 +122,9 @@
        fs = VTOI(ap->a_pvp)->i_lfs;
        
        /*
-        * Prevent a race getting lfs_free.  We use
-        * the ufs_hashlock here because we need that anyway for
-        * the hash insertion later.
+        * Prevent a race getting lfs_free.
         */
-       lockmgr(&ufs_hashlock, LK_EXCLUSIVE, 0);
+       lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE, 0);
 
        /* Get the head of the freelist. */
        new_ino = fs->lfs_free;
@@ -164,8 +162,9 @@
                ip = VTOI(vp);
                blkno = lblkno(fs, ip->i_ffs_size);
                if ((error = VOP_BALLOC(vp, ip->i_ffs_size, fs->lfs_bsize,
-                   NULL, 0, &bp)) != 0)
+                   NULL, 0, &bp)) != 0) {
                        return (error);
+               }
                ip->i_ffs_size += fs->lfs_bsize;
                uvm_vnp_setsize(vp, ip->i_ffs_size);
                (void)uvm_vnp_uncache(vp);
@@ -187,16 +186,17 @@
                ifp->if_nextfree = LFS_UNUSED_INUM;
                VOP_UNLOCK(vp,0);
                if ((error = VOP_BWRITE(bp)) != 0) {
-                       lockmgr(&ufs_hashlock, LK_RELEASE, 0);
                        return (error);
                }
        }
-
 #ifdef DIAGNOSTIC
        if(fs->lfs_free == LFS_UNUSED_INUM)
                panic("inode 0 allocated [3]");
 #endif /* DIAGNOSTIC */
        
+       lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
+
+       lockmgr(&ufs_hashlock, LK_EXCLUSIVE, 0);
        /* Create a vnode to associate with the inode. */
        if ((error = lfs_vcreate(ap->a_pvp->v_mount, new_ino, &vp)) != 0) {
                lockmgr(&ufs_hashlock, LK_RELEASE, 0);
@@ -301,7 +301,6 @@
        struct lfs *fs;
        ufs_daddr_t old_iaddr;
        ino_t ino;
-       int already_locked;
        extern int lfs_dirvcount;
        
        /* Get the inode number and file system. */
@@ -310,11 +309,9 @@
        fs = ip->i_lfs;
        ino = ip->i_number;
        
-       /* If we already hold ufs_hashlock, don't panic, just do it anyway */
-       already_locked = lockstatus(&ufs_hashlock) && ufs_hashlock.lk_lockholder == curproc->p_pid;
        while(WRITEINPROG(vp)
              || fs->lfs_seglock
-             || (!already_locked && lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0)))
+             || lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0))
        {
                if (WRITEINPROG(vp)) {
                        tsleep(vp, (PRIBIO+1), "lfs_vfree", 0);
@@ -376,8 +373,7 @@
                sup->su_nbytes -= DINODE_SIZE;
                (void) VOP_BWRITE(bp);
        }
-       if(!already_locked)
-               lockmgr(&ufs_hashlock, LK_RELEASE, 0);
+       lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
        
        /* Set superblock modified bit and decrement file count. */
        fs->lfs_fmod = 1;
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_extern.h
--- a/sys/ufs/lfs/lfs_extern.h  Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_extern.h  Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_extern.h,v 1.15 1999/11/15 18:49:14 fvdl Exp $     */
+/*     $NetBSD: lfs_extern.h,v 1.16 2000/01/19 00:03:04 perseant Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
 
 /* lfs_inode.c */
 void lfs_init __P((void));
-struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct dinode *));
+struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct buf *));
 
 /* lfs_segment.c */
 void lfs_imtime __P((struct lfs *));
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c   Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_inode.c   Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_inode.c,v 1.29 2000/01/16 05:56:14 perseant Exp $  */
+/*     $NetBSD: lfs_inode.c,v 1.30 2000/01/19 00:03:04 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -98,18 +98,21 @@
 
 /* Search a block for a specific dinode. */
 struct dinode *
-lfs_ifind(fs, ino, dip)
+lfs_ifind(fs, ino, bp)
        struct lfs *fs;
        ino_t ino;
-       register struct dinode *dip;
+       struct buf *bp;
 {
        register int cnt;
+       register struct dinode *dip = (struct dinode *)bp->b_data;
        register struct dinode *ldip;
        
        for (cnt = INOPB(fs), ldip = dip + (cnt - 1); cnt--; --ldip)
                if (ldip->di_inumber == ino)
                        return (ldip);
        
+       printf("offset is %d (seg %d)\n", fs->lfs_offset, datosn(fs,fs->lfs_offset));
+       printf("block is %d (seg %d)\n", bp->b_blkno, datosn(fs,bp->b_blkno));
        panic("lfs_ifind: dinode %u not found", ino);
        /* NOTREACHED */
 }
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_segment.c,v 1.39 2000/01/16 05:56:14 perseant Exp $        */
+/*     $NetBSD: lfs_segment.c,v 1.40 2000/01/19 00:03:04 perseant Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -1679,7 +1679,10 @@
         * insert at tail of LRU list
         */
        simple_lock(&vnode_free_list_slock);
-       TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
+       if (vp->v_holdcnt > 0)
+               TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
+       else
+               TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
        simple_unlock(&vnode_free_list_slock);
        simple_unlock(&vp->v_interlock);
 }
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_subr.c
--- a/sys/ufs/lfs/lfs_subr.c    Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_subr.c    Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_subr.c,v 1.11 2000/01/16 09:15:51 perseant Exp $   */
+/*     $NetBSD: lfs_subr.c,v 1.12 2000/01/19 00:03:05 perseant Exp $   */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -203,7 +203,7 @@
                for (; vp && vp != BEG_OF_VLIST; vp = BACK_VP(vp)) {
 #else
        loop:
-               for (vp = mp->mnt_vnodelist.lh_first;
+                for (vp = mp->mnt_vnodelist.lh_first;
                     vp != NULL;
                     vp = vp->v_mntvnodes.le_next) {
 #endif
@@ -217,9 +217,8 @@
                                vp->v_flag &= ~VDIROP;
                                wakeup(&lfs_dirvcount);
                                if(vp->v_usecount == 1) {
-                                       /* vput will VOP_INACTIVE */
-                                       VOP_LOCK(vp,LK_EXCLUSIVE);
-                                       vput(vp);
+                                       /* vrele may call VOP_INACTIVE */
+                                       vrele(vp);
                                } else
                                        lfs_vunref(vp);
 
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c        Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c        Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_syscalls.c,v 1.39 2000/01/16 04:57:08 perseant Exp $       */
+/*     $NetBSD: lfs_syscalls.c,v 1.40 2000/01/19 00:03:05 perseant Exp $       */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -993,7 +993,7 @@
                        return (error);
                }
                ip->i_din.ffs_din =
-                       *lfs_ifind(ump->um_lfs, ino, (struct dinode *)bp->b_data);
+                       *lfs_ifind(ump->um_lfs, ino, bp);
                brelse(bp);
        }
        ip->i_ffs_effnlink = ip->i_ffs_nlink;
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vfsops.c,v 1.45 1999/11/21 19:25:32 perseant Exp $ */
+/*     $NetBSD: lfs_vfsops.c,v 1.46 2000/01/19 00:03:05 perseant Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -417,6 +417,7 @@
        fs->lfs_writer = 0;
        fs->lfs_dirops = 0;
        fs->lfs_seglock = 0;
+       lockinit(&fs->lfs_freelock, PINOD, "lfs_freelock", 0, 0);
 
        /* Set the file system readonly/modify bits. */
        fs->lfs_ronly = ronly;
@@ -716,7 +717,7 @@
                *vpp = NULL;
                return (error);
        }
-       ip->i_din.ffs_din = *lfs_ifind(fs, ino, (struct dinode *)bp->b_data);
+       ip->i_din.ffs_din = *lfs_ifind(fs, ino, bp);
        ip->i_ffs_effnlink = ip->i_ffs_nlink;
 #ifdef LFS_ATIME_IFILE
        ip->i_ffs_atime = ts.tv_sec;



Home | Main Index | Thread Index | Old Index