Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jul 2014 08:34:54 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r268606 - in head/sys: fs/cd9660 fs/msdosfs kern sys
Message-ID:  <201407140834.s6E8YsdY028323@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407140834.s6E8YsdY028323>