VNode sequencing and locking - part 4/4 - subpart 1 of many.
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 19 Aug 2006 17:27:25 +0000 (17:27 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 19 Aug 2006 17:27:25 +0000 (17:27 +0000)
Move the vnode lock for VOP_READDIR out of the kernel upper layers and
into the filesystem.

17 files changed:
sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c
sys/emulation/linux/linux_file.c
sys/kern/vfs_cache.c
sys/kern/vfs_syscalls.c
sys/vfs/gnu/ext2fs/ext2_lookup.c
sys/vfs/hpfs/hpfs_vnops.c
sys/vfs/isofs/cd9660/cd9660_vnops.c
sys/vfs/msdosfs/msdosfs_vnops.c
sys/vfs/nfs/nfs_serv.c
sys/vfs/nfs/nfs_vnops.c
sys/vfs/ntfs/ntfs_vnops.c
sys/vfs/nwfs/nwfs_vnops.c
sys/vfs/procfs/procfs_vnops.c
sys/vfs/smbfs/smbfs_vnops.c
sys/vfs/udf/udf_vnops.c
sys/vfs/ufs/ufs_vnops.c
sys/vfs/union/union_vnops.c

index e87b5e5..1acb49b 100644 (file)
@@ -39,7 +39,7 @@
  *     @(#)procfs_vnops.c      8.18 (Berkeley) 5/21/95
  *
  * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_vnops.c,v 1.3.2.5 2001/08/12 14:29:19 rwatson Exp $
- * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c,v 1.33 2006/08/12 00:26:19 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c,v 1.34 2006/08/19 17:27:22 dillon Exp $
  */
 
 /*
@@ -788,31 +788,31 @@ linprocfs_readdir(struct vop_readdir_args *ap)
                return (EINVAL);
 
        pfs = VTOPFS(ap->a_vp);
+       if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
 
        switch (pfs->pfs_type) {
-       /*
-        * this is for the process-specific sub-directories.
-        * all that is needed to is copy out all the entries
-        * from the procent[] table (top of this file).
-        */
        case Pproc:
+               /*
+                * This is for the process-specific sub-directories.
+                * all that is needed to is copy out all the entries
+                * from the procent[] table (top of this file).
+                */
                error = linprocfs_readdir_proc(ap);
                break;
-
-       /*
-        * this is for the root of the procfs filesystem
-        * what is needed is a special entry for "self"
-        * followed by an entry for each process on allproc
-        */
-
        case Proot:
+               /*
+                * This is for the root of the procfs filesystem
+                * what is needed is a special entry for "self"
+                * followed by an entry for each process on allproc
+                */
                error = linprocfs_readdir_root(ap);
                break;
-
        default:
                error = ENOTDIR;
                break;
        }
+       vn_unlock(ap->a_vp);
 
        return (error);
 }
index 48fc759..1a5d021 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_file.c,v 1.41.2.6 2003/01/06 09:19:43 fjoe Exp $
- * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.34 2006/08/12 00:26:19 dillon Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.35 2006/08/19 17:27:20 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -296,7 +296,6 @@ getdents_common(struct linux_getdents64_args *args, int is64bit)
        buflen = max(LINUX_DIRBLKSIZ, nbytes);
        buflen = min(buflen, MAXBSIZE);
        buf = malloc(buflen, M_TEMP, M_WAITOK);
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 
 again:
        aiov.iov_base = buf;
@@ -435,7 +434,6 @@ out:
        if (cookies)
                free(cookies, M_TEMP);
 
-       vn_unlock(vp);
        free(buf, M_TEMP);
 done:
        fdrop(fp);
index 8fbf6bc..68cda72 100644 (file)
@@ -67,7 +67,7 @@
  *
  *     @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
  * $FreeBSD: src/sys/kern/vfs_cache.c,v 1.42.2.6 2001/10/05 20:07:03 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_cache.c,v 1.74 2006/08/12 00:26:20 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_cache.c,v 1.75 2006/08/19 17:27:23 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -1238,7 +1238,7 @@ cache_inefficient_scan(struct namecache *ncp, struct ucred *cred,
        vat.va_blocksize = 0;
        if ((error = VOP_GETATTR(dvp, &vat)) != 0)
                return (error);
-       if ((error = cache_vget(ncp, cred, LK_SHARED, &pvp)) != 0)
+       if ((error = cache_vref(ncp, cred, &pvp)) != 0)
                return (error);
        if (ncvp_debug)
                printf("inefficient_scan: directory iosize %ld vattr fileid = %ld\n", vat.va_blocksize, (long)vat.va_fileid);
@@ -1283,7 +1283,6 @@ again:
                                }
                                nlc.nlc_nameptr = den->d_name;
                                nlc.nlc_namelen = den->d_namlen;
-                               vn_unlock(pvp);
                                rncp = cache_nlookup(ncp, &nlc);
                                KKASSERT(rncp != NULL);
                                break;
@@ -1294,8 +1293,8 @@ again:
                if (rncp == NULL && eofflag == 0 && uio.uio_resid != blksize)
                        goto again;
        }
+       vrele(pvp);
        if (rncp) {
-               vrele(pvp);
                if (rncp->nc_flag & NCF_UNRESOLVED) {
                        cache_setvp(rncp, dvp);
                        if (ncvp_debug >= 2) {
@@ -1315,7 +1314,6 @@ again:
        } else {
                printf("cache_inefficient_scan: dvp %p NOT FOUND in %s\n",
                        dvp, ncp->nc_name);
-               vput(pvp);
                error = ENOENT;
        }
        free(rbuf, M_TEMP);
index 9b86e84..24bf88d 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.100 2006/08/12 00:26:20 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.101 2006/08/19 17:27:23 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -2951,12 +2951,9 @@ unionread:
        auio.uio_segflg = direction;
        auio.uio_td = td;
        auio.uio_resid = count;
-       /* vn_lock(vp, LK_SHARED | LK_RETRY); */
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
        loff = auio.uio_offset = fp->f_offset;
        error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL);
        fp->f_offset = auio.uio_offset;
-       vn_unlock(vp);
        if (error)
                goto done;
        if (count == auio.uio_resid) {
index fd42278..6e30176 100644 (file)
@@ -5,7 +5,7 @@
  *  University of Utah, Department of Computer Science
  *
  * $FreeBSD: src/sys/gnu/ext2fs/ext2_lookup.c,v 1.21.2.3 2002/11/17 02:02:42 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_lookup.c,v 1.24 2006/08/12 00:26:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_lookup.c,v 1.25 2006/08/19 17:27:24 dillon Exp $
  */
 /*
  * Copyright (c) 1989, 1993
@@ -137,7 +137,6 @@ ext2_readdir(struct vop_readdir_args *ap)
 {
         struct uio *uio = ap->a_uio;
         int count, error;
-
        struct ext2_dir_entry_2 *edp, *dp;
        int ncookies;
        struct uio auio;
@@ -147,6 +146,9 @@ ext2_readdir(struct vop_readdir_args *ap)
        int readcnt, retval;
        off_t startoffset = uio->uio_offset;
 
+       if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return(error);
+
        count = uio->uio_resid;
        /*
         * Avoid complications for partial directory entries by adjusting
@@ -244,6 +246,7 @@ ext2_readdir(struct vop_readdir_args *ap)
        FREE(dirbuf, M_TEMP);
        if (ap->a_eofflag)
                *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
+       vn_unlock(ap->a_vp);
         return (error);
 }
 
index fd23e49..76f6aa6 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $
- * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.37 2006/08/12 00:26:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.38 2006/08/19 17:27:24 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -848,16 +848,18 @@ hpfs_readdir(struct vop_readdir_args *ap)
         */
        if (uio->uio_offset < 0 || uio->uio_offset > INT_MAX)
                return(EINVAL);
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
+
        num = uio->uio_offset;
        cnum = 0;
 
        if( num <= cnum ) {
                dprintf((". faked, "));
                if (vop_write_dirent(&error, uio, hp->h_no, DT_DIR, 1, "."))
-                       return (0);
-               if(error)
-                       return (error);
-
+                       goto done;
+               if (error)
+                       goto done;
                ncookies ++;
        }
        cnum++;
@@ -866,9 +868,8 @@ hpfs_readdir(struct vop_readdir_args *ap)
                dprintf((".. faked, "));
                if (vop_write_dirent(&error, uio, hp->h_fn.fn_parent, DT_DIR, 2, ".."))
                        goto readdone;
-               if(error)
-                       return (error);
-
+               if (error)
+                       goto done;
                ncookies ++;
        }
        cnum++;
@@ -883,14 +884,15 @@ dive:
        error = bread(hp->h_devvp, dbtodoff(lsn), D_BSIZE, &bp);
        if (error) {
                brelse(bp);
-               return (error);
+               goto done;
        }
 
        dp = (struct dirblk *) bp->b_data;
        if (dp->d_magic != D_MAGIC) {
                printf("hpfs_readdir: MAGIC DOESN'T MATCH\n");
                brelse(bp);
-               return (EINVAL);
+               error = EINVAL;
+               goto done;
        }
 
        dep = D_DIRENT(dp);
@@ -918,7 +920,7 @@ dive:
                                        }
                                        if (error) {
                                                brelse (bp);
-                                               return (error);
+                                               goto done;
                                        }
                                        ncookies++;
                                }
@@ -929,7 +931,8 @@ dive:
                } else {
                        printf("hpfs_readdir: ERROR! oLSN not found\n");
                        brelse(bp);
-                       return (EINVAL);
+                       error = EINVAL;
+                       goto done;
                }
        }
 
@@ -952,7 +955,7 @@ dive:
                                }
                                if (error) {
                                        brelse (bp);
-                                       return (error);
+                                       goto done;
                                }
                                ncookies++;
                        }
@@ -1016,7 +1019,9 @@ readdone:
                *ap->a_cookies = cookies;
        }
 
-       return (0);
+done:
+       vn_unlock(ap->a_vp);
+       return (error);
 }
 
 /*
index 65ae8bd..14087f1 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)cd9660_vnops.c      8.19 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $
- * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.30 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.31 2006/08/19 17:27:24 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -481,6 +481,9 @@ cd9660_readdir(struct vop_readdir_args *ap)
        imp = dp->i_mnt;
        bmask = imp->im_bmask;
 
+       if ((error = vn_lock(vdp, LK_EXCLUSIVE|LK_RETRY)) != 0)
+               return (error);
+
        MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
        idp->saveent.de.d_namlen = idp->assocent.de.d_namlen = 0;
        /*
@@ -513,7 +516,7 @@ cd9660_readdir(struct vop_readdir_args *ap)
        if ((entryoffsetinblock = idp->curroff & bmask) &&
            (error = cd9660_devblkatoff(vdp, (off_t)idp->curroff, NULL, &bp))) {
                FREE(idp, M_TEMP);
-               return (error);
+               goto done;
        }
        endsearch = dp->i_size;
 
@@ -639,6 +642,8 @@ cd9660_readdir(struct vop_readdir_args *ap)
 
        FREE(idp, M_TEMP);
 
+done:
+       vn_unlock(vdp);
        return (error);
 }
 
index 0d927fb..ed5b591 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.40 2006/08/12 00:26:21 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.41 2006/08/19 17:27:24 dillon Exp $ */
 /*     $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $   */
 
 /*-
@@ -1557,8 +1557,8 @@ msdosfs_readdir(struct vop_readdir_args *ap)
        long bias = 0;
        daddr_t bn, lbn;
        struct buf *bp;
-       struct denode *dep = VTODE(ap->a_vp);
-       struct msdosfsmount *pmp = dep->de_pmp;
+       struct denode *dep;
+       struct msdosfsmount *pmp;
        struct direntry *dentp;
        struct uio *uio = ap->a_uio;
        u_long *cookies = NULL;
@@ -1571,6 +1571,12 @@ msdosfs_readdir(struct vop_readdir_args *ap)
        char *d_name_storage = NULL;
        char *d_name;
 
+       if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
+
+       dep = VTODE(ap->a_vp);
+       pmp = dep->de_pmp;
+
 #ifdef MSDOSFS_DEBUG
        printf("msdosfs_readdir(): vp %p, uio %p, cred %p, eofflagp %p\n",
            ap->a_vp, uio, ap->a_cred, ap->a_eofflag);
@@ -1582,8 +1588,10 @@ msdosfs_readdir(struct vop_readdir_args *ap)
         * retrieve the wrong block from the buffer cache for a plain file.
         * So, fail attempts to readdir() on a plain file.
         */
-       if ((dep->de_Attributes & ATTR_DIRECTORY) == 0)
-               return (ENOTDIR);
+       if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) {
+               error = ENOTDIR;
+               goto done;
+       }
 
        /*
         * If the user buffer is smaller than the size of one dos directory
@@ -1592,8 +1600,10 @@ msdosfs_readdir(struct vop_readdir_args *ap)
         */
        off = offset = uio->uio_offset;
        if (uio->uio_resid < sizeof(struct direntry) ||
-           (offset & (sizeof(struct direntry) - 1)))
-               return (EINVAL);
+           (offset & (sizeof(struct direntry) - 1))) {
+               error = EINVAL;
+               goto done;
+       }
 
        if (ap->a_ncookies) {
                ncookies = uio->uio_resid / 16 + 1;
@@ -1671,7 +1681,7 @@ msdosfs_readdir(struct vop_readdir_args *ap)
                if (error) {
                        brelse(bp);
                        free(d_name_storage, M_TEMP);
-                       return (error);
+                       goto done;
                }
                n = min(n, blsize - bp->b_resid);
 
@@ -1796,6 +1806,8 @@ out:
                else
                        *ap->a_eofflag = 0;
        }
+done:
+       vn_unlock(ap->a_vp);
        return (error);
 }
 
index 884245b..7fad687 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_serv.c  8.8 (Berkeley) 7/31/95
  * $FreeBSD: src/sys/nfs/nfs_serv.c,v 1.93.2.6 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.37 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.38 2006/08/19 17:27:24 dillon Exp $
  */
 
 /*
@@ -2869,7 +2869,6 @@ again:
        io.uio_rw = UIO_READ;
        io.uio_td = NULL;
        eofflag = 0;
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
        if (cookies) {
                free((caddr_t)cookies, M_TEMP);
                cookies = NULL;
@@ -2883,7 +2882,6 @@ again:
                if (!error)
                        error = getret;
        }
-       vn_unlock(vp);
        if (error) {
                vrele(vp);
                vp = NULL;
@@ -3146,7 +3144,6 @@ again:
        io.uio_rw = UIO_READ;
        io.uio_td = NULL;
        eofflag = 0;
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
        if (cookies) {
                free((caddr_t)cookies, M_TEMP);
                cookies = NULL;
@@ -3154,7 +3151,6 @@ again:
        error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
        off = (u_quad_t)io.uio_offset;
        getret = VOP_GETATTR(vp, &at);
-       vn_unlock(vp);
        if (!cookies && !error)
                error = NFSERR_PERM;
        if (!error)
index 1e52afc..197391f 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.64 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.65 2006/08/19 17:27:24 dillon Exp $
  */
 
 
@@ -2091,6 +2091,9 @@ nfs_readdir(struct vop_readdir_args *ap)
        if (vp->v_type != VDIR)
                return (EPERM);
 
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
+
        /*
         * If we have a valid EOF offset cache we must call VOP_GETATTR()
         * and then check that is still valid, or if this is an NQNFS mount
@@ -2103,7 +2106,7 @@ nfs_readdir(struct vop_readdir_args *ap)
                    (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0
                ) {
                        nfsstats.direofcache_hits++;
-                       return (0);
+                       goto done;
                }
        }
 
@@ -2116,6 +2119,8 @@ nfs_readdir(struct vop_readdir_args *ap)
 
        if (!error && uio->uio_resid == tresid)
                nfsstats.direofcache_misses++;
+done:
+       vn_unlock(vp);
        return (error);
 }
 
index 38e4b90..f5b15a9 100644 (file)
@@ -36,7 +36,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $
- * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.36 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.37 2006/08/19 17:27:24 dillon Exp $
  *
  */
 
@@ -570,6 +570,8 @@ ntfs_readdir(struct vop_readdir_args *ap)
 
        if (uio->uio_offset < 0 || uio->uio_offset > INT_MAX)
                return (EINVAL);
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
 
        /*
         * uio->uio_offset carries the number of the entry
@@ -589,9 +591,9 @@ ntfs_readdir(struct vop_readdir_args *ap)
        if (ip->i_number != NTFS_ROOTINO && num == 0) {
                if (vop_write_dirent(&error, uio, ip->i_number,
                    DT_DIR, 1, "."))
-                       return (0);
+                       goto done;
                if (error)
-                       return (error);
+                       goto done;
 
                num++;
                ncookies++;
@@ -603,8 +605,8 @@ ntfs_readdir(struct vop_readdir_args *ap)
                if (vop_write_dirent(&error, uio, NTFS_ROOTINO,
                    DT_DIR, 2, ".."))
                        goto readdone;
-               if(error)
-                       return (error);
+               if (error)
+                       goto done;
 
                num++;
                ncookies++;
@@ -621,8 +623,8 @@ ntfs_readdir(struct vop_readdir_args *ap)
                 */
                error = ntfs_ntreaddir(ntmp, fp, num - faked, &iep);
 
-               if(error)
-                       return (error);
+               if (error)
+                       goto done;
 
                if( NULL == iep )
                        break;
@@ -649,8 +651,8 @@ ntfs_readdir(struct vop_readdir_args *ap)
                                 (iep->ie_fflag & NTFS_FFLAG_DIR) ?
                                        "dir" : "reg"));
 
-                       if(error)
-                               return (error);
+                       if (error)
+                               goto done;
 
                        ncookies++;
                        num++;
@@ -693,8 +695,10 @@ readdone:
        }
 /*
        if (ap->a_eofflag)
-           *ap->a_eofflag = VTONT(ap->a_vp)->i_size <= uio->uio_offset;
+           *ap->a_eofflag = VTONT(vp)->i_size <= uio->uio_offset;
 */
+done:
+       vn_unlock(vp);
        return (error);
 }
 
index f179486..fdfb8ff 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_vnops.c,v 1.6.2.3 2001/03/14 11:26:59 bp Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.32 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_vnops.c,v 1.33 2006/08/19 17:27:24 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -677,8 +677,10 @@ nwfs_readdir(struct vop_readdir_args *ap)
                printf("nwfs_readdir: no support for cookies now...");
                return (EOPNOTSUPP);
        }
-
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
        error = nwfs_readvnode(vp, uio, ap->a_cred);
+       vn_unlock(vp);
        return error;
 }
 
index a3f56ce..c9d8ca2 100644 (file)
@@ -37,7 +37,7 @@
  *     @(#)procfs_vnops.c      8.18 (Berkeley) 5/21/95
  *
  * $FreeBSD: src/sys/miscfs/procfs/procfs_vnops.c,v 1.76.2.7 2002/01/22 17:22:59 nectar Exp $
- * $DragonFly: src/sys/vfs/procfs/procfs_vnops.c,v 1.35 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/procfs/procfs_vnops.c,v 1.36 2006/08/19 17:27:24 dillon Exp $
  */
 
 /*
@@ -832,34 +832,33 @@ procfs_readdir(struct vop_readdir_args *ap)
 
        if (ap->a_uio->uio_offset < 0 || ap->a_uio->uio_offset > INT_MAX)
                return (EINVAL);
-
+       if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
        pfs = VTOPFS(ap->a_vp);
 
        switch (pfs->pfs_type) {
-       /*
-        * this is for the process-specific sub-directories.
-        * all that is needed to is copy out all the entries
-        * from the procent[] table (top of this file).
-        */
        case Pproc:
+               /*
+                * this is for the process-specific sub-directories.
+                * all that is needed to is copy out all the entries
+                * from the procent[] table (top of this file).
+                */
                error = procfs_readdir_proc(ap);
                break;
-
-       /*
-        * this is for the root of the procfs filesystem
-        * what is needed is a special entry for "curproc"
-        * followed by an entry for each process on allproc
-        */
-
        case Proot:
+               /*
+                * this is for the root of the procfs filesystem
+                * what is needed is a special entry for "curproc"
+                * followed by an entry for each process on allproc
+                */
                error = procfs_readdir_root(ap);
                break;
-
        default:
                error = ENOTDIR;
                break;
        }
 
+       vn_unlock(ap->a_vp);
        return (error);
 }
 
index 257d4f9..a58ad26 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_vnops.c,v 1.2.2.8 2003/04/04 08:57:23 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.34 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_vnops.c,v 1.35 2006/08/19 17:27:24 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -726,7 +726,10 @@ smbfs_readdir(struct vop_readdir_args *ap)
                return (EOPNOTSUPP);
        }
 #endif
-       error = smbfs_readvnode(vp, uio, ap->a_cred);
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) == 0) {
+               error = smbfs_readvnode(vp, uio, ap->a_cred);
+               vn_unlock(vp);
+       }
        return error;
 }
 
index d17f083..c3ccef6 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.33 2003/12/07 05:04:49 scottl Exp $
- * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.24 2006/08/12 00:26:21 dillon Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.25 2006/08/19 17:27:25 dillon Exp $
  */
 
 /* udf_vnops.c */
@@ -696,6 +696,10 @@ udf_readdir(struct vop_readdir_args *a)
        char *name;
 
        vp = a->a_vp;
+
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
+
        uio = a->a_uio;
        node = VTON(vp);
        udfmp = node->udfmp;
@@ -826,6 +830,7 @@ udf_readdir(struct vop_readdir_args *a)
                }
        }
 
+       vn_unlock(vp);
        return(error);
 }
 
index 57d915b..c250330 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.54 2006/08/12 00:26:22 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.55 2006/08/19 17:27:25 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -1674,6 +1674,9 @@ ufs_readdir(struct vop_readdir_args *ap)
        }
        cookie_index = 0;
 
+       if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+               return (error);
+
        /*
         * Past or at EOF
         */
@@ -1684,7 +1687,7 @@ ufs_readdir(struct vop_readdir_args *ap)
                        *ap->a_ncookies = cookie_index;
                        *ap->a_cookies = cookies;
                }
-               return(0);
+               goto done;
        }
 
        /*
@@ -1773,6 +1776,8 @@ ufs_readdir(struct vop_readdir_args *ap)
                        *ap->a_cookies = cookies;
                }
        }
+done:
+       vn_unlock(vp);
         return (error);
 }
 
index 5d9c696..502d7aa 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     @(#)union_vnops.c       8.32 (Berkeley) 6/23/95
  * $FreeBSD: src/sys/miscfs/union/union_vnops.c,v 1.72 1999/12/15 23:02:14 eivind Exp $
- * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.33 2006/08/12 00:26:22 dillon Exp $
+ * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.34 2006/08/19 17:27:25 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -119,6 +119,22 @@ union_lock_upper(struct union_node *un, struct thread *td)
        return(uppervp);
 }
 
+static __inline
+struct vnode *
+union_ref_upper(struct union_node *un)
+{
+       struct vnode *uppervp;
+
+       if ((uppervp = un->un_uppervp) != NULL) {
+               vref(uppervp);
+               if (uppervp->v_flag & VRECLAIMED) {
+                       vrele(uppervp);
+                       return (NULLVP);
+               }
+       }
+       return (uppervp);
+}
+
 static __inline
 void
 union_unlock_upper(struct vnode *uppervp, struct thread *td)
@@ -1567,11 +1583,11 @@ union_readdir(struct vop_readdir_args *ap)
        struct vnode *uvp;
        int error = 0;
 
-       if ((uvp = union_lock_upper(un, td)) != NULLVP) {
+       if ((uvp = union_ref_upper(un)) != NULLVP) {
                ap->a_head.a_ops = *uvp->v_ops;
                ap->a_vp = uvp;
                error = vop_readdir_ap(ap);
-               union_unlock_upper(uvp, td);
+               vrele(uvp);
        }
        return(error);
 }