Author: kib
Date: Mon Jul 14 08:34:54 2014
New Revision: 268606
URL: http://svnweb.freebsd.org/changeset/base/268606

Log:
  Generalize vn_get_ino() to allow filesystems to use custom vnode
  producer, instead of hard-coding VFS_VGET().  New function, which
  takes callback, is called vn_get_ino_gen(), standard callback for
  vn_get_ino() is provided.
  
  Convert inline copies of vn_get_ino() in msdosfs and cd9660 into the
  uses of vn_get_ino_gen().
  
  Tested by:    pho
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks

Modified:
  head/sys/fs/cd9660/cd9660_lookup.c
  head/sys/fs/msdosfs/msdosfs_lookup.c
  head/sys/kern/vfs_vnops.c
  head/sys/sys/vnode.h

Modified: head/sys/fs/cd9660/cd9660_lookup.c
==============================================================================
--- head/sys/fs/cd9660/cd9660_lookup.c  Mon Jul 14 08:17:11 2014        
(r268605)
+++ head/sys/fs/cd9660/cd9660_lookup.c  Mon Jul 14 08:34:54 2014        
(r268606)
@@ -50,6 +50,23 @@ __FBSDID("$FreeBSD$");
 #include <fs/cd9660/cd9660_node.h>
 #include <fs/cd9660/iso_rrip.h>
 
+struct cd9660_ino_alloc_arg {
+       ino_t ino;
+       ino_t i_ino;
+       struct iso_directory_record *ep;
+};
+
+static int
+cd9660_ino_alloc(struct mount *mp, void *arg, int lkflags,
+    struct vnode **vpp)
+{
+       struct cd9660_ino_alloc_arg *dd_arg;
+
+       dd_arg = arg;
+       return (cd9660_vget_internal(mp, dd_arg->i_ino, lkflags, vpp,
+           dd_arg->i_ino != dd_arg->ino, dd_arg->ep));
+}
+
 /*
  * Convert a component of a pathname into a pointer to a locked inode.
  * This is a very central and rather complicated routine.
@@ -104,6 +121,7 @@ cd9660_lookup(ap)
        doff_t endsearch;               /* offset to end directory search */
        struct vnode *pdp;              /* saved dp during symlink work */
        struct vnode *tdp;              /* returned by cd9660_vget_internal */
+       struct cd9660_ino_alloc_arg dd_arg;
        u_long bmask;                   /* block offset mask */
        int error;
        ino_t ino, i_ino;
@@ -114,7 +132,6 @@ cd9660_lookup(ap)
        int res;
        int assoc, len;
        char *name;
-       struct mount *mp;
        struct vnode **vpp = ap->a_vpp;
        struct componentname *cnp = ap->a_cnp;
        int flags = cnp->cn_flags;
@@ -368,39 +385,13 @@ found:
         * it's a relocated directory.
         */
        if (flags & ISDOTDOT) {
-               /*
-                * Expanded copy of vn_vget_ino() so that we can use
-                * cd9660_vget_internal().
-                */
-               mp = pdp->v_mount;
-               ltype = VOP_ISLOCKED(pdp);
-               error = vfs_busy(mp, MBF_NOWAIT);
-               if (error != 0) {
-                       vfs_ref(mp);
-                       VOP_UNLOCK(pdp, 0);
-                       error = vfs_busy(mp, 0);
-                       vn_lock(pdp, ltype | LK_RETRY);
-                       vfs_rel(mp);
-                       if (error)
-                               return (ENOENT);
-                       if (pdp->v_iflag & VI_DOOMED) {
-                               vfs_unbusy(mp);
-                               return (ENOENT);
-                       }
-               }
-               VOP_UNLOCK(pdp, 0);
-               error = cd9660_vget_internal(vdp->v_mount, i_ino,
-                                            cnp->cn_lkflags, &tdp,
-                                            i_ino != ino, ep);
+               dd_arg.ino = ino;
+               dd_arg.i_ino = i_ino;
+               dd_arg.ep = ep;
+               error = vn_vget_ino_gen(pdp, cd9660_ino_alloc, &dd_arg,
+                   cnp->cn_lkflags, &tdp);
                free(ep2, M_TEMP);
-               vfs_unbusy(mp);
-               vn_lock(pdp, ltype | LK_RETRY);
-               if (pdp->v_iflag & VI_DOOMED) {
-                       if (error == 0)
-                               vput(tdp);
-                       error = ENOENT;
-               }
-               if (error)
+               if (error != 0)
                        return (error);
                *vpp = tdp;
        } else if (dp->i_number == i_ino) {

Modified: head/sys/fs/msdosfs/msdosfs_lookup.c
==============================================================================
--- head/sys/fs/msdosfs/msdosfs_lookup.c        Mon Jul 14 08:17:11 2014        
(r268605)
+++ head/sys/fs/msdosfs/msdosfs_lookup.c        Mon Jul 14 08:34:54 2014        
(r268606)
@@ -63,8 +63,6 @@
 
 static int msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
     struct componentname *cnp, u_int64_t *inum);
-static int msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
-    struct vnode **rvp);
 
 int
 msdosfs_lookup(struct vop_cachedlookup_args *ap)
@@ -73,6 +71,28 @@ msdosfs_lookup(struct vop_cachedlookup_a
        return (msdosfs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
 }
 
+struct deget_dotdot {
+       u_long cluster;
+       int blkoff;
+};
+
+static int
+msdosfs_deget_dotdot(struct mount *mp, void *arg, int lkflags,
+    struct vnode **rvp)
+{
+       struct deget_dotdot *dd_arg;
+       struct denode *rdp;
+       struct msdosfsmount *pmp;
+       int error;
+
+       pmp = VFSTOMSDOSFS(mp);
+       dd_arg = arg;
+       error = deget(pmp, dd_arg->cluster, dd_arg->blkoff,  &rdp);
+       if (error == 0)
+               *rvp = DETOV(rdp);
+       return (error);
+}
+
 /*
  * When we search a directory the blocks containing directory entries are
  * read and examined.  The directory entries contain information that would
@@ -110,6 +130,7 @@ msdosfs_lookup_(struct vnode *vdp, struc
        struct msdosfsmount *pmp;
        struct buf *bp = NULL;
        struct direntry *dep = NULL;
+       struct deget_dotdot dd_arg;
        u_char dosfilename[12];
        int flags = cnp->cn_flags;
        int nameiop = cnp->cn_nameiop;
@@ -524,8 +545,11 @@ foundroot:
         */
        pdp = vdp;
        if (flags & ISDOTDOT) {
-               error = msdosfs_deget_dotdot(pdp, cluster, blkoff, vpp);
-               if (error) {
+               dd_arg.cluster = cluster;
+               dd_arg.blkoff = blkoff;
+               error = vn_vget_ino_gen(vdp, msdosfs_deget_dotdot,
+                   &dd_arg, cnp->cn_lkflags, vpp);
+               if (error != 0) {
                        *vpp = NULL;
                        return (error);
                }
@@ -560,54 +584,6 @@ foundroot:
        return (0);
 }
 
-static int
-msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
-    struct vnode **rvp)
-{
-       struct mount *mp;
-       struct msdosfsmount *pmp;
-       struct denode *rdp;
-       int ltype, error;
-
-       mp = vp->v_mount;
-       pmp = VFSTOMSDOSFS(mp);
-       ltype = VOP_ISLOCKED(vp);
-       KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
-           ("msdosfs_deget_dotdot: vp not locked"));
-
-       error = vfs_busy(mp, MBF_NOWAIT);
-       if (error != 0) {
-               vfs_ref(mp);
-               VOP_UNLOCK(vp, 0);
-               error = vfs_busy(mp, 0);
-               vn_lock(vp, ltype | LK_RETRY);
-               vfs_rel(mp);
-               if (error != 0)
-                       return (ENOENT);
-               if (vp->v_iflag & VI_DOOMED) {
-                       vfs_unbusy(mp);
-                       return (ENOENT);
-               }
-       }
-       VOP_UNLOCK(vp, 0);
-       error = deget(pmp, cluster, blkoff,  &rdp);
-       vfs_unbusy(mp);
-       if (error == 0)
-               *rvp = DETOV(rdp);
-       if (*rvp != vp)
-               vn_lock(vp, ltype | LK_RETRY);
-       if (vp->v_iflag & VI_DOOMED) {
-               if (error == 0) {
-                       if (*rvp == vp)
-                               vunref(*rvp);
-                       else
-                               vput(*rvp);
-               }
-               error = ENOENT;
-       }
-       return (error);
-}
-
 /*
  * dep  - directory entry to copy into the directory
  * ddep - directory to add to

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c   Mon Jul 14 08:17:11 2014        (r268605)
+++ head/sys/kern/vfs_vnops.c   Mon Jul 14 08:34:54 2014        (r268606)
@@ -1953,12 +1953,30 @@ vn_extattr_rm(struct vnode *vp, int iofl
        return (error);
 }
 
+static int
+vn_get_ino_alloc_vget(struct mount *mp, void *arg, int lkflags,
+    struct vnode **rvp)
+{
+
+       return (VFS_VGET(mp, *(ino_t *)arg, lkflags, rvp));
+}
+
 int
 vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp)
 {
+
+       return (vn_vget_ino_gen(vp, vn_get_ino_alloc_vget, &ino,
+           lkflags, rvp));
+}
+
+int
+vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, void *alloc_arg,
+    int lkflags, struct vnode **rvp)
+{
        struct mount *mp;
        int ltype, error;
 
+       ASSERT_VOP_LOCKED(vp, "vn_vget_ino_get");
        mp = vp->v_mount;
        ltype = VOP_ISLOCKED(vp);
        KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
@@ -1978,12 +1996,17 @@ vn_vget_ino(struct vnode *vp, ino_t ino,
                }
        }
        VOP_UNLOCK(vp, 0);
-       error = VFS_VGET(mp, ino, lkflags, rvp);
+       error = alloc(mp, alloc_arg, lkflags, rvp);
        vfs_unbusy(mp);
-       vn_lock(vp, ltype | LK_RETRY);
+       if (*rvp != vp)
+               vn_lock(vp, ltype | LK_RETRY);
        if (vp->v_iflag & VI_DOOMED) {
-               if (error == 0)
-                       vput(*rvp);
+               if (error == 0) {
+                       if (*rvp == vp)
+                               vunref(vp);
+                       else
+                               vput(*rvp);
+               }
                error = ENOENT;
        }
        return (error);

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Mon Jul 14 08:17:11 2014        (r268605)
+++ head/sys/sys/vnode.h        Mon Jul 14 08:34:54 2014        (r268606)
@@ -593,6 +593,8 @@ struct uio;
 struct vattr;
 struct vnode;
 
+typedef int (*vn_get_ino_t)(struct mount *, void *, int, struct vnode **);
+
 /* cache_* may belong in namei.h. */
 #define        cache_enter(dvp, vp, cnp)                                       
\
        cache_enter_time(dvp, vp, cnp, NULL, NULL)
@@ -696,6 +698,8 @@ int vn_extattr_rm(struct vnode *vp, int 
            const char *attrname, struct thread *td);
 int    vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags,
            struct vnode **rvp);
+int    vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc,
+           void *alloc_arg, int lkflags, struct vnode **rvp);
 int    vn_utimes_perm(struct vnode *vp, struct vattr *vap,
            struct ucred *cred, struct thread *td);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to