summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-07-14 08:34:54 +0000
committerkib <kib@FreeBSD.org>2014-07-14 08:34:54 +0000
commit2f41c9023ee776d0ffcb0703f1246098fbf5054e (patch)
treebe7a3e638a2f72e4bb601f1af70678e77135e970 /sys/fs
parentd84e7ad50cb906e22de70bedccb9c8c5a54abb1f (diff)
downloadFreeBSD-src-2f41c9023ee776d0ffcb0703f1246098fbf5054e.zip
FreeBSD-src-2f41c9023ee776d0ffcb0703f1246098fbf5054e.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/cd9660/cd9660_lookup.c57
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c80
2 files changed, 52 insertions, 85 deletions
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c
index 590fc19..274fb3e 100644
--- a/sys/fs/cd9660/cd9660_lookup.c
+++ b/sys/fs/cd9660/cd9660_lookup.c
@@ -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) {
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 27c76e1..3704915 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -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_args *ap)
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, struct vnode **vpp,
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
OpenPOWER on IntegriCloud