Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs Rearrange code around getnewvnode as was already don...



details:   https://anonhg.NetBSD.org/src/rev/53e6efaa0429
branches:  trunk
changeset: 494078:53e6efaa0429
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Fri Jun 30 20:45:38 2000 +0000

description:
Rearrange code around getnewvnode as was already done for ffs, to avoid
locking against oneself because getnewvnode recycles a softdep-using vnode.

diffstat:

 sys/ufs/ext2fs/ext2fs_vfsops.c |   18 ++++--
 sys/ufs/lfs/lfs_alloc.c        |   32 ++++-------
 sys/ufs/lfs/lfs_extern.h       |    4 +-
 sys/ufs/lfs/lfs_syscalls.c     |  104 +++++++++++++++++++++++++---------------
 sys/ufs/lfs/lfs_vfsops.c       |   22 +++++---
 5 files changed, 105 insertions(+), 75 deletions(-)

diffs (truncated from 313 to 300 lines):

diff -r 0bd12a65c7fd -r 53e6efaa0429 sys/ufs/ext2fs/ext2fs_vfsops.c
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c    Fri Jun 30 19:46:05 2000 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c    Fri Jun 30 20:45:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_vfsops.c,v 1.36 2000/05/29 18:34:36 mycroft Exp $       */
+/*     $NetBSD: ext2fs_vfsops.c,v 1.37 2000/06/30 20:45:38 fvdl Exp $  */
 
 /*
  * Copyright (c) 1997 Manuel Bouyer.
@@ -836,17 +836,23 @@
 
        ump = VFSTOUFS(mp);
        dev = ump->um_dev;
-       do {
-               if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
-                       return (0);
-       } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
+       if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+               return (0);
 
        /* Allocate a new vnode/inode. */
        if ((error = getnewvnode(VT_EXT2FS, mp, ext2fs_vnodeop_p, &vp)) != 0) {
                *vpp = NULL;
-               lockmgr(&ufs_hashlock, LK_RELEASE, 0);
                return (error);
        }
+
+       do {
+               if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) {
+                       ungetnewvnode(vp);
+                       return (0);
+               }
+       } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
        ip = pool_get(&ext2fs_inode_pool, PR_WAITOK);
        memset((caddr_t)ip, 0, sizeof(struct inode));
        vp->v_data = ip;
diff -r 0bd12a65c7fd -r 53e6efaa0429 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Fri Jun 30 19:46:05 2000 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Fri Jun 30 20:45:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_alloc.c,v 1.39 2000/06/28 14:16:41 mrg Exp $       */
+/*     $NetBSD: lfs_alloc.c,v 1.40 2000/06/30 20:45:39 fvdl Exp $      */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -209,12 +209,13 @@
        
        lfs_segunlock(fs);
 
+       if ((error = getnewvnode(VT_LFS, ap->a_pvp->v_mount,
+           lfs_vnodeop_p, &vp)) != 0)
+               goto errout;
+
        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);
-               goto errout;
-       }
+       /* 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. */
@@ -266,33 +267,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;
@@ -308,7 +301,6 @@
        ip->i_ffs_size = 0;
        ip->i_ffs_blocks = 0;
        ++ump->um_lfs->lfs_uinodes;
-       return (0);
 }
 
 /* Free an inode. */
diff -r 0bd12a65c7fd -r 53e6efaa0429 sys/ufs/lfs/lfs_extern.h
--- a/sys/ufs/lfs/lfs_extern.h  Fri Jun 30 19:46:05 2000 +0000
+++ b/sys/ufs/lfs/lfs_extern.h  Fri Jun 30 20:45:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_extern.h,v 1.18 2000/06/27 20:57:13 perseant Exp $ */
+/*     $NetBSD: lfs_extern.h,v 1.19 2000/06/30 20:45:39 fvdl Exp $     */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -108,7 +108,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 lfs *, int));
diff -r 0bd12a65c7fd -r 53e6efaa0429 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c        Fri Jun 30 19:46:05 2000 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c        Fri Jun 30 20:45:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_syscalls.c,v 1.43 2000/06/27 20:57:16 perseant Exp $       */
+/*     $NetBSD: lfs_syscalls.c,v 1.44 2000/06/30 20:45:39 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;
@@ -870,6 +871,53 @@
 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)) {
+#ifdef DEBUG_LFS
+                       printf("lfs_fastvget: ino %d inlocked by pid %d\n",
+                           ip->i_number, (*vpp)->v_lock.lk_lockholder);
+#endif
+                       clean_inlocked++;
+#ifdef LFS_EAGAIN_FAIL
+                       lfs_vunref(*vpp);
+                       return EAGAIN;
+#endif /* LFS_EAGAIN_FAIL */
+               } else {
+                       vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
+                       *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;
@@ -888,49 +936,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, vpp)) != 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)) {
-#ifdef DEBUG_LFS
-                               printf("lfs_fastvget: ino %d inlocked by pid %d\n",ip->i_number,
-                                      (*vpp)->v_lock.lk_lockholder);
-#endif
-                               clean_inlocked++;
-#ifdef LFS_EAGAIN_FAIL
-                               lfs_vunref(*vpp);
-                               return EAGAIN;
-#endif /* LFS_EAGAIN_FAIL */
-                       } else {
-                               vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
-                               *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 0bd12a65c7fd -r 53e6efaa0429 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Fri Jun 30 19:46:05 2000 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Fri Jun 30 20:45:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vfsops.c,v 1.54 2000/06/28 14:11:35 mrg Exp $      */
+/*     $NetBSD: lfs_vfsops.c,v 1.55 2000/06/30 20:45:40 fvdl Exp $     */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -660,9 +660,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. */
@@ -682,12 +692,8 @@
                }



Home | Main Index | Thread Index | Old Index