Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/union Add missing parts to mount devices from a union...
details: https://anonhg.NetBSD.org/src/rev/bb9a5952a742
branches: trunk
changeset: 768239:bb9a5952a742
user: hannken <hannken%NetBSD.org@localhost>
date: Fri Aug 12 14:36:29 2011 +0000
description:
Add missing parts to mount devices from a union file system:
- union_close() has to lock/unlock the lower vnode.
- union_fsync() has to call spec_fsync() for the union vnode.
- union_strategy() must allow writes to devices on the lower file system.
- union_bwrite() was completely missing.
diffstat:
sys/fs/union/union_vnops.c | 103 ++++++++++++++++++++++++++------------------
1 files changed, 61 insertions(+), 42 deletions(-)
diffs (223 lines):
diff -r 6d84785600ba -r bb9a5952a742 sys/fs/union/union_vnops.c
--- a/sys/fs/union/union_vnops.c Fri Aug 12 12:59:13 2011 +0000
+++ b/sys/fs/union/union_vnops.c Fri Aug 12 14:36:29 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $ */
+/* $NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.44 2011/08/12 14:36:29 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -91,6 +91,7 @@
#include <fs/union/union.h>
#include <miscfs/genfs/genfs.h>
+#include <miscfs/specfs/specdev.h>
int union_lookup(void *);
int union_create(void *);
@@ -128,6 +129,7 @@
int union_pathconf(void *);
int union_advlock(void *);
int union_strategy(void *);
+int union_bwrite(void *);
int union_getpages(void *);
int union_putpages(void *);
int union_kqfilter(void *);
@@ -175,6 +177,7 @@
{ &vop_unlock_desc, union_unlock }, /* unlock */
{ &vop_bmap_desc, union_bmap }, /* bmap */
{ &vop_strategy_desc, union_strategy }, /* strategy */
+ { &vop_bwrite_desc, union_bwrite }, /* bwrite */
{ &vop_print_desc, union_print }, /* print */
{ &vop_islocked_desc, union_islocked }, /* islocked */
{ &vop_pathconf_desc, union_pathconf }, /* pathconf */
@@ -182,9 +185,6 @@
{ &vop_getpages_desc, union_getpages }, /* getpages */
{ &vop_putpages_desc, union_putpages }, /* putpages */
{ &vop_kqfilter_desc, union_kqfilter }, /* kqfilter */
-#ifdef notdef
- { &vop_bwrite_desc, union_bwrite }, /* bwrite */
-#endif
{ NULL, NULL }
};
const struct vnodeopv_desc union_vnodeop_opv_desc =
@@ -195,6 +195,9 @@
union_fixup(un); \
} \
}
+#define NODE_IS_SPECIAL(vp) \
+ ((vp)->v_type == VBLK || (vp)->v_type == VCHR || \
+ (vp)->v_type == VSOCK || (vp)->v_type == VFIFO)
static void
union_fixup(struct union_node *un)
@@ -695,24 +698,28 @@
} */ *ap = v;
struct union_node *un = VTOUNION(ap->a_vp);
struct vnode *vp;
+ int error;
+ bool do_lock;
vp = un->un_uppervp;
- if (vp == NULLVP) {
-#ifdef UNION_DIAGNOSTIC
- if (un->un_openl <= 0)
- panic("union: un_openl cnt");
-#endif
+ if (vp != NULLVP) {
+ do_lock = false;
+ } else {
+ KASSERT(un->un_openl > 0);
--un->un_openl;
vp = un->un_lowervp;
+ do_lock = true;
}
-#ifdef DIAGNOSTIC
- if (vp == NULLVP)
- panic("union_close empty union vnode");
-#endif
+ KASSERT(vp != NULLVP);
+ ap->a_vp = vp;
+ if (do_lock)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ error = VCALL(vp, VOFFSET(vop_close), ap);
+ if (do_lock)
+ VOP_UNLOCK(vp);
- ap->a_vp = vp;
- return (VCALL(vp, VOFFSET(vop_close), ap));
+ return error;
}
/*
@@ -944,20 +951,14 @@
union_newsize(ap->a_vp, vap->va_size, VNOVAL);
} else {
KASSERT(un->un_lowervp != NULLVP);
- switch (un->un_lowervp->v_type) {
- case VCHR:
- case VBLK:
- case VSOCK:
- case VFIFO:
+ if (NODE_IS_SPECIAL(un->un_lowervp)) {
if (size_only &&
(vap->va_size == 0 || vap->va_size == VNOVAL))
error = 0;
else
error = EROFS;
- break;
- default:
+ } else {
error = EROFS;
- break;
}
}
@@ -1023,20 +1024,14 @@
vp = UPPERVP(ap->a_vp);
if (vp == NULLVP) {
vp = LOWERVP(ap->a_vp);
- KASSERT(vp != NULL);
- switch (vp->v_type) {
- case VBLK:
- case VCHR:
- case VSOCK:
- case VFIFO:
+ if (NODE_IS_SPECIAL(vp)) {
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag,
ap->a_cred);
VOP_UNLOCK(vp);
return error;
- default:
- panic("union: missing upper layer in write");
}
+ panic("union: missing upper layer in write");
}
FIXUP(un);
@@ -1137,11 +1132,16 @@
* they're locked; otherwise, pass it through to the
* underlying layer.
*/
+ if (ap->a_vp->v_type == VBLK || ap->a_vp->v_type == VCHR) {
+ error = spec_fsync(v);
+ if (error)
+ return error;
+ }
+
if (ap->a_flags & FSYNC_RECLAIM)
return 0;
targetvp = OTHERVP(ap->a_vp);
-
if (targetvp != NULLVP) {
int dolock = (targetvp == LOWERVP(ap->a_vp));
@@ -1885,12 +1885,6 @@
return (VCALL(ovp, VOFFSET(vop_advlock), ap));
}
-
-/*
- * XXX - vop_strategy must be hand coded because it has no
- * vnode in its arguments.
- * This goes away with a merged VM/buffer cache.
- */
int
union_strategy(void *v)
{
@@ -1904,15 +1898,40 @@
#ifdef DIAGNOSTIC
if (ovp == NULLVP)
panic("union_strategy: nil vp");
- if (((bp->b_flags & B_READ) == 0) &&
- (ovp == LOWERVP(bp->b_vp)))
- panic("union_strategy: writing to lowervp");
+ if (!NODE_IS_SPECIAL(ovp)) {
+ if (((bp->b_flags & B_READ) == 0) &&
+ (ovp == LOWERVP(bp->b_vp)))
+ panic("union_strategy: writing to lowervp");
+ }
#endif
return (VOP_STRATEGY(ovp, bp));
}
int
+union_bwrite(void *v)
+{
+ struct vop_bwrite_args /* {
+ struct vnode *a_vp;
+ struct buf *a_bp;
+ } */ *ap = v;
+ struct vnode *ovp = OTHERVP(ap->a_vp);
+ struct buf *bp = ap->a_bp;
+
+#ifdef DIAGNOSTIC
+ if (ovp == NULLVP)
+ panic("union_bwrite: nil vp");
+ if (!NODE_IS_SPECIAL(ovp)) {
+ if (((bp->b_flags & B_READ) == 0) &&
+ (ovp == LOWERVP(bp->b_vp)))
+ panic("union_strategy: writing to lowervp");
+ }
+#endif
+
+ return (VOP_BWRITE(ovp, bp));
+}
+
+int
union_getpages(void *v)
{
struct vop_getpages_args /* {
Home |
Main Index |
Thread Index |
Old Index