summaryrefslogtreecommitdiffstats
path: root/sys/fs/nullfs/null_vnops.c
diff options
context:
space:
mode:
authorbp <bp@FreeBSD.org>2000-09-05 09:02:07 +0000
committerbp <bp@FreeBSD.org>2000-09-05 09:02:07 +0000
commit64ac0aa678e382d03d7bad1b3c1401222e4bc7e7 (patch)
treee7cfe6afe4dacc7a1ef0b7d39a7453db9fee0a61 /sys/fs/nullfs/null_vnops.c
parent106f8e14c88b3d49326a76d131a37eaaf6f29ed4 (diff)
downloadFreeBSD-src-64ac0aa678e382d03d7bad1b3c1401222e4bc7e7.zip
FreeBSD-src-64ac0aa678e382d03d7bad1b3c1401222e4bc7e7.tar.gz
Various cleanups towards make nullfs functional (it is still broken
at this point): Replace all '#ifdef DEBUG' with '#ifdef NULLFS_DEBUG' and add NULLFSDEBUG macro. Protect nullfs hash table with lockmgr. Use proper order of operations when freeing mnt_data. Return correct fsid in the null_getattr(). Add null_open() function to catch MNT_NODEV (obtained from NetBSD). Add null_rename() to catch cross-fs rename operations (submitted by Ustimenko Semen <semen@iclub.nsu.ru>) Remove duplicate $FreeBSD$ tags.
Diffstat (limited to 'sys/fs/nullfs/null_vnops.c')
-rw-r--r--sys/fs/nullfs/null_vnops.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index 8329d5e..5692df6 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -37,7 +37,6 @@
*
* Ancestors:
* @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92
- * $FreeBSD$
* ...and...
* @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
*
@@ -193,8 +192,10 @@ static int null_getattr(struct vop_getattr_args *ap);
static int null_inactive(struct vop_inactive_args *ap);
static int null_lock(struct vop_lock_args *ap);
static int null_lookup(struct vop_lookup_args *ap);
+static int null_open(struct vop_open_args *ap);
static int null_print(struct vop_print_args *ap);
static int null_reclaim(struct vop_reclaim_args *ap);
+static int null_rename(struct vop_rename_args *ap);
static int null_setattr(struct vop_setattr_args *ap);
static int null_unlock(struct vop_unlock_args *ap);
@@ -448,6 +449,8 @@ null_getattr(ap)
if ((error = null_bypass((struct vop_generic_args *)ap)) != 0)
return (error);
+
+ ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
return (0);
}
@@ -484,6 +487,66 @@ null_access(ap)
}
/*
+ * We must handle open to be able to catch MNT_NODEV and friends.
+ */
+static int
+null_open(ap)
+ struct vop_open_args /* {
+ struct vnode *a_vp;
+ int a_mode;
+ struct ucred *a_cred;
+ struct proc *a_p;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+ struct vnode *lvp = NULLVPTOLOWERVP(ap->a_vp);
+
+ if ((vp->v_mount->mnt_flag & MNT_NODEV) &&
+ (lvp->v_type == VBLK || lvp->v_type == VCHR))
+ return ENXIO;
+
+ return (null_bypass((struct vop_generic_args *)ap));
+}
+
+/*
+ * We handle this to eliminate null FS to lower FS
+ * file moving. Don't know why we don't allow this,
+ * possibly we should.
+ */
+static int
+null_rename(ap)
+ struct vop_rename_args /* {
+ struct vnode *a_fdvp;
+ struct vnode *a_fvp;
+ struct componentname *a_fcnp;
+ struct vnode *a_tdvp;
+ struct vnode *a_tvp;
+ struct componentname *a_tcnp;
+ } */ *ap;
+{
+ struct vnode *tdvp = ap->a_tdvp;
+ struct vnode *fvp = ap->a_fvp;
+ struct vnode *fdvp = ap->a_fdvp;
+ struct vnode *tvp = ap->a_tvp;
+
+ /* Check for cross-device rename. */
+ if ((fvp->v_mount != tdvp->v_mount) ||
+ (tvp && (fvp->v_mount != tvp->v_mount))) {
+ if (tdvp == tvp)
+ vrele(tdvp);
+ else
+ vput(tdvp);
+ if (tvp)
+ vput(tvp);
+ vrele(fdvp);
+ vrele(fvp);
+ return (EXDEV);
+ }
+
+ return (null_bypass((struct vop_generic_args *)ap));
+}
+
+/*
* We need to process our own vnode lock and then clear the
* interlock flag as it applies only to our vnode, not the
* vnodes below us on the stack.
@@ -568,7 +631,9 @@ null_reclaim(ap)
*/
/* After this assignment, this node will not be re-used. */
xp->null_lowervp = NULLVP;
+ lockmgr(&null_hashlock, LK_EXCLUSIVE, NULL, ap->a_p);
LIST_REMOVE(xp, null_hash);
+ lockmgr(&null_hashlock, LK_RELEASE, NULL, ap->a_p);
FREE(vp->v_data, M_TEMP);
vp->v_data = NULL;
vrele (lowervp);
@@ -593,13 +658,18 @@ vop_t **null_vnodeop_p;
static struct vnodeopv_entry_desc null_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) null_bypass },
{ &vop_access_desc, (vop_t *) null_access },
+ { &vop_bmap_desc, (vop_t *) vop_eopnotsupp },
{ &vop_getattr_desc, (vop_t *) null_getattr },
+ { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount},
{ &vop_inactive_desc, (vop_t *) null_inactive },
{ &vop_lock_desc, (vop_t *) null_lock },
{ &vop_lookup_desc, (vop_t *) null_lookup },
+ { &vop_open_desc, (vop_t *) null_open },
{ &vop_print_desc, (vop_t *) null_print },
{ &vop_reclaim_desc, (vop_t *) null_reclaim },
+ { &vop_rename_desc, (vop_t *) null_rename },
{ &vop_setattr_desc, (vop_t *) null_setattr },
+ { &vop_strategy_desc, (vop_t *) vop_eopnotsupp },
{ &vop_unlock_desc, (vop_t *) null_unlock },
{ NULL, NULL }
};
OpenPOWER on IntegriCloud