diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2014-07-14 08:34:54 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2014-07-14 08:34:54 +0000 |
commit | a69452162a1036e0b2b086e43afb2a68634078bf (patch) | |
tree | be7a3e638a2f72e4bb601f1af70678e77135e970 /sys/kern/vfs_vnops.c | |
parent | fca015d30184282217d50d29f5c3d906ea726b0d (diff) | |
download | src-a69452162a1036e0b2b086e43afb2a68634078bf.tar.gz src-a69452162a1036e0b2b086e43afb2a68634078bf.zip |
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
Notes
Notes:
svn path=/head/; revision=268606
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index d97e56f8a47e..e7e0f9ecde29 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -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); - 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); |