diff options
author | kib <kib@FreeBSD.org> | 2014-07-14 08:34:54 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-07-14 08:34:54 +0000 |
commit | 2f41c9023ee776d0ffcb0703f1246098fbf5054e (patch) | |
tree | be7a3e638a2f72e4bb601f1af70678e77135e970 /sys/fs | |
parent | d84e7ad50cb906e22de70bedccb9c8c5a54abb1f (diff) | |
download | FreeBSD-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.c | 57 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_lookup.c | 80 |
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 |