summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-07-28 00:53:26 +0000
committerkib <kib@FreeBSD.org>2014-07-28 00:53:26 +0000
commit49b4c6d03e4d643a1b50041ded7d073bc9ebbaf1 (patch)
tree6d5244c15970855e110042dcfb360ece4d7ecedd /sys/kern
parent35e4a7c8ff8e4a47c6a41caeb2c302c5b6717713 (diff)
downloadFreeBSD-src-49b4c6d03e4d643a1b50041ded7d073bc9ebbaf1.zip
FreeBSD-src-49b4c6d03e4d643a1b50041ded7d073bc9ebbaf1.tar.gz
MFC r268606:
Generalize vn_get_ino() to allow filesystems to use custom vnode producer. Convert inline copies of vn_get_ino() in msdosfs and cd9660 into the uses of vn_get_ino_gen().
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_vnops.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 29634c6..f1400f5 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);
OpenPOWER on IntegriCloud