Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/ufs/lfs pullup the fixes from the trunk to not hold...



details:   https://anonhg.NetBSD.org/src/rev/e7348c5387d6
branches:  netbsd-1-5
changeset: 488370:e7348c5387d6
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Mon Jul 03 18:33:55 2000 +0000

description:
pullup the fixes from the trunk to not hold ufs_hashlock across
getnewvnode()

diffstat:

 sys/ufs/lfs/lfs_alloc.c    |   32 +++++---------
 sys/ufs/lfs/lfs_extern.h   |    4 +-
 sys/ufs/lfs/lfs_syscalls.c |  100 ++++++++++++++++++++++++++++----------------
 sys/ufs/lfs/lfs_vfsops.c   |   22 ++++++---
 4 files changed, 91 insertions(+), 67 deletions(-)

diffs (271 lines):

diff -r d116860ad0d5 -r e7348c5387d6 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Mon Jul 03 17:52:57 2000 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Mon Jul 03 18:33:55 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_alloc.c,v 1.34.2.2 2000/06/28 22:27:22 perseant Exp $      */
+/*     $NetBSD: lfs_alloc.c,v 1.34.2.3 2000/07/03 18:33:55 fvdl Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -206,12 +206,13 @@
        
        lfs_segunlock(fs);
 
+       if ((error = getnewvnode(VT_LFS, ap->a_pvp->v_mount,
+           lfs_vnodeop_p, &vp)) != 0)
+               return (error);
+
        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);
-               return (error);
-       }
+       /* Create an inode to associate with the vnode. */
+       lfs_vcreate(ap->a_pvp->v_mount, new_ino, vp);
        
        ip = VTOI(vp);
        /* Zero out the direct and indirect block addresses. */
@@ -251,33 +252,25 @@
 }
 
 /* Create a new vnode/inode pair and initialize what fields we can. */
-int
-lfs_vcreate(mp, ino, vpp)
+void
+lfs_vcreate(mp, ino, vp)
        struct mount *mp;
        ino_t ino;
-       struct vnode **vpp;
+       struct vnode *vp;
 {
-       extern int (**lfs_vnodeop_p) __P((void *));
        struct inode *ip;
        struct ufsmount *ump;
-       int error;
 #ifdef QUOTA
        int i;
 #endif
        
-       /* Create the vnode. */
-       if ((error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, vpp)) != 0) {
-               *vpp = NULL;
-               return (error);
-       }
-       
        /* Get a pointer to the private mount structure. */
        ump = VFSTOUFS(mp);
        
        /* Initialize the inode. */
        ip = pool_get(&lfs_inode_pool, PR_WAITOK);
-       (*vpp)->v_data = ip;
-       ip->i_vnode = *vpp;
+       vp->v_data = ip;
+       ip->i_vnode = vp;
        ip->i_devvp = ump->um_devvp;
        ip->i_flag = IN_MODIFIED;
        ip->i_dev = ump->um_dev;
@@ -293,7 +286,6 @@
        ip->i_ffs_size = 0;
        ip->i_ffs_blocks = 0;
        ++ump->um_lfs->lfs_uinodes;
-       return (0);
 }
 
 /* Free an inode. */
diff -r d116860ad0d5 -r e7348c5387d6 sys/ufs/lfs/lfs_extern.h
--- a/sys/ufs/lfs/lfs_extern.h  Mon Jul 03 17:52:57 2000 +0000
+++ b/sys/ufs/lfs/lfs_extern.h  Mon Jul 03 18:33:55 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_extern.h,v 1.17 2000/03/16 18:08:33 jdolecek Exp $ */
+/*     $NetBSD: lfs_extern.h,v 1.17.4.1 2000/07/03 18:33:55 fvdl Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -107,7 +107,7 @@
 
 __BEGIN_DECLS
 /* lfs_alloc.c */
-int lfs_vcreate __P((struct mount *, ino_t, struct vnode **));
+void lfs_vcreate __P((struct mount *, ino_t, struct vnode *));
 /* lfs_bio.c */
 int lfs_bwrite_ext __P((struct buf *, int));
 void lfs_flush_fs __P((struct mount *, int));
diff -r d116860ad0d5 -r e7348c5387d6 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c        Mon Jul 03 17:52:57 2000 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c        Mon Jul 03 18:33:55 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_syscalls.c,v 1.41.4.1 2000/06/22 20:26:19 perseant Exp $   */
+/*     $NetBSD: lfs_syscalls.c,v 1.41.4.2 2000/07/03 18:33:56 fvdl Exp $       */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -96,6 +96,7 @@
 #define FVG_PUT           0x02   /* Needs to be vput() */
 
 struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
+int lfs_fasthashget __P((dev_t, ino_t, int *, struct vnode **));
 
 int debug_cleaner = 0; 
 int clean_vnlocked = 0;
@@ -888,6 +889,51 @@
 extern struct lock ufs_hashlock;
 
 int
+lfs_fasthashget(dev, ino, need_unlock, vpp)
+       dev_t dev;
+       ino_t ino;
+       int *need_unlock;
+       struct vnode **vpp;
+{
+       struct inode *ip;
+
+       /*
+        * This is playing fast and loose.  Someone may have the inode
+        * locked, in which case they are going to be distinctly unhappy
+        * if we trash something.
+        */
+       if ((*vpp = ufs_ihashlookup(dev, ino)) != NULL) {
+               if ((*vpp)->v_flag & VXLOCK) {
+                       printf("lfs_fastvget: vnode VXLOCKed for ino %d\n",ino);
+                       clean_vnlocked++;
+#ifdef LFS_EAGAIN_FAIL
+                       return EAGAIN;
+#endif
+               }
+               ip = VTOI(*vpp);
+               if (lfs_vref(*vpp)) {
+                       clean_inlocked++;
+                       return EAGAIN;
+               }
+               if (VOP_ISLOCKED(*vpp)) {
+                       printf("lfs_fastvget: ino %d inlocked by pid %d\n",
+                           ip->i_number, (*vpp)->v_lock.lk_lockholder);
+                       clean_inlocked++;
+#ifdef LFS_EAGAIN_FAIL
+                       lfs_vunref(*vpp);
+                       return EAGAIN;
+#endif /* LFS_EAGAIN_FAIL */
+               } else {
+                       VOP_LOCK(*vpp,LK_EXCLUSIVE);
+                       *need_unlock |= FVG_UNLOCK;
+               }
+       } else
+               *vpp = NULL;
+
+       return (0);
+}
+
+int
 lfs_fastvget(mp, ino, daddr, vpp, dinp, need_unlock)
        struct mount *mp;
        ino_t ino;
@@ -906,47 +952,27 @@
        ump = VFSTOUFS(mp);
        dev = ump->um_dev;
        *need_unlock = 0;
-       /*
-        * This is playing fast and loose.  Someone may have the inode
-        * locked, in which case they are going to be distinctly unhappy
-        * if we trash something.
-        */
+
+       error = lfs_fasthashget(dev, ino, need_unlock, vpp);
+       if (error != 0 || *vpp != NULL)
+               return (error);
+
+       if ((error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, &vp)) != 0) {
+               *vpp = NULL;
+               return (error);
+       }
+
        do {
-               if ((*vpp = ufs_ihashlookup(dev, ino)) != NULL) {
-                       if ((*vpp)->v_flag & VXLOCK) {
-                               printf("lfs_fastvget: vnode VXLOCKed for ino %d\n",ino);
-                               clean_vnlocked++;
-#ifdef LFS_EAGAIN_FAIL
-                               return EAGAIN;
-#endif
-                       }
-                       ip = VTOI(*vpp);
-                       if (lfs_vref(*vpp)) {
-                               clean_inlocked++;
-                               return EAGAIN;
-                       }
-                       if (VOP_ISLOCKED(*vpp)) {
-                               printf("lfs_fastvget: ino %d inlocked by pid %d\n",ip->i_number,
-                                      (*vpp)->v_lock.lk_lockholder);
-                               clean_inlocked++;
-#ifdef LFS_EAGAIN_FAIL
-                               lfs_vunref(*vpp);
-                               return EAGAIN;
-#endif /* LFS_EAGAIN_FAIL */
-                       } else {
-                               VOP_LOCK(*vpp,LK_EXCLUSIVE);
-                               *need_unlock |= FVG_UNLOCK;
-                       }
-                       return (0);
+               error = lfs_fasthashget(dev, ino, need_unlock, vpp);
+               if (error != 0 || *vpp != NULL) {
+                       ungetnewvnode(vp);
+                       return (error);
                }
        } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
 
        /* Allocate new vnode/inode. */
-       if ((error = lfs_vcreate(mp, ino, &vp)) != 0) {
-               *vpp = NULL;
-               lockmgr(&ufs_hashlock, LK_RELEASE, 0);
-               return (error);
-       }
+       lfs_vcreate(mp, ino, vp);
+
        /*
         * Put it onto its hash chain and lock it so that other requests for
         * this inode will block if they arrive while we are sleeping waiting
diff -r d116860ad0d5 -r e7348c5387d6 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Mon Jul 03 17:52:57 2000 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Mon Jul 03 18:33:55 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vfsops.c,v 1.52 2000/05/27 00:19:53 perseant Exp $ */
+/*     $NetBSD: lfs_vfsops.c,v 1.52.4.1 2000/07/03 18:33:56 fvdl Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -676,9 +676,19 @@
        ump = VFSTOUFS(mp);
        dev = ump->um_dev;
 
+       if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+               return (0);
+
+       if ((error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, &vp)) != 0) {
+               *vpp = NULL;
+                return (error);
+       }
+
        do {
-               if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+               if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) {
+                       ungetnewvnode(vp);
                        return (0);
+               }
        } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
 
        /* Translate the inode number to a disk address. */
@@ -698,12 +708,8 @@
                }
        }
 
-       /* Allocate new vnode/inode. */
-       if ((error = lfs_vcreate(mp, ino, &vp)) != 0) {
-               *vpp = NULL;
-               lockmgr(&ufs_hashlock, LK_RELEASE, 0);
-               return (error);
-       }
+       /* Allocate/init new vnode/inode. */
+       lfs_vcreate(mp, ino, vp);
 
        /*
         * Put it onto its hash chain and lock it so that other requests for



Home | Main Index | Thread Index | Old Index