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
This commit is contained in:
parent
fca015d301
commit
a69452162a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268606
@ -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 @@ cd9660_lookup(ap)
|
||||
* 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) {
|
||||
|
@ -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 @@ msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
|
||||
*/
|
||||
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 @@ msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
|
||||
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
|
||||
|
@ -1953,12 +1953,30 @@ vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace,
|
||||
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, int lkflags, struct vnode **rvp)
|
||||
}
|
||||
}
|
||||
VOP_UNLOCK(vp, 0);
|
||||
error = VFS_VGET(mp, ino, lkflags, rvp);
|
||||
error = alloc(mp, alloc_arg, lkflags, rvp);
|
||||
vfs_unbusy(mp);
|
||||
if (*rvp != vp)
|
||||
vn_lock(vp, ltype | LK_RETRY);
|
||||
if (vp->v_iflag & VI_DOOMED) {
|
||||
if (error == 0)
|
||||
if (error == 0) {
|
||||
if (*rvp == vp)
|
||||
vunref(vp);
|
||||
else
|
||||
vput(*rvp);
|
||||
}
|
||||
error = ENOENT;
|
||||
}
|
||||
return (error);
|
||||
|
@ -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 ioflg, int attrnamespace,
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user