summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-01-04 22:10:36 +0000
committerphk <phk@FreeBSD.org>2003-01-04 22:10:36 +0000
commit131885aa2f8d42ce9c721f66cd0c84ec7789ffc0 (patch)
treec7a5f4c248cdb6b6c66f82139acb14ed7ec6d6d0
parenta307536f906cea2e4ba4d10d51b320520f1a30c1 (diff)
downloadFreeBSD-src-131885aa2f8d42ce9c721f66cd0c84ec7789ffc0.zip
FreeBSD-src-131885aa2f8d42ce9c721f66cd0c84ec7789ffc0.tar.gz
Temporarily introduce a new VOP_SPECSTRATEGY operation while I try
to sort out disk-io from file-io in the vm/buffer/filesystem space. The intent is to sort VOP_STRATEGY calls into those which operate on "real" vnodes and those which operate on VCHR vnodes. For the latter kind, the call will be changed to VOP_SPECSTRATEGY, possibly conditionally for those places where dual-use happens. Add a default VOP_SPECSTRATEGY method which will call the normal VOP_STRATEGY. First time it is called it will print debugging information. This will only happen if a normal vnode is passed to VOP_SPECSTRATEGY by mistake. Add a real VOP_SPECSTRATEGY in specfs, which does what VOP_STRATEGY does on a VCHR vnode today. Add a new VOP_STRATEGY method in specfs to catch instances where the conversion to VOP_SPECSTRATEGY has not yet happened. Handle the request just like we always did, but first time called print debugging information. Apart up to two instances of console messages per boot, this amounts to a glorified no-op commit. If you get any of the messages on your console I would very much like a copy of them mailed to phk@freebsd.org
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c2
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c2
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c2
-rw-r--r--sys/fs/specfs/spec_vnops.c41
-rw-r--r--sys/fs/udf/udf_vnops.c2
-rw-r--r--sys/isofs/cd9660/cd9660_vnops.c2
-rw-r--r--sys/kern/vfs_bio.c15
-rw-r--r--sys/kern/vfs_default.c25
-rw-r--r--sys/kern/vnode_if.src9
-rw-r--r--sys/ufs/ufs/ufs_vnops.c2
-rw-r--r--sys/vm/vm_swap.c2
11 files changed, 92 insertions, 12 deletions
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index 1fae0f7..0b892e6 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/cd9660/cd9660_vnops.c
@@ -731,7 +731,7 @@ cd9660_strategy(ap)
}
vp = ip->i_devvp;
bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
+ VOP_SPECSTRATEGY(vp, bp);
return (0);
}
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
index c3ad1e7..7d10096 100644
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ b/sys/fs/hpfs/hpfs_vnops.c
@@ -706,7 +706,7 @@ hpfs_strategy(ap)
return (0);
}
bp->b_dev = hp->h_devvp->v_rdev;
- VOP_STRATEGY(hp->h_devvp, bp);
+ VOP_SPECSTRATEGY(hp->h_devvp, bp);
return (0);
}
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 06a677f..a326929 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -1820,7 +1820,7 @@ msdosfs_strategy(ap)
*/
vp = dep->de_devvp;
bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
+ VOP_SPECSTRATEGY(vp, bp);
return (0);
}
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c
index 61b4732..e0274bf 100644
--- a/sys/fs/specfs/spec_vnops.c
+++ b/sys/fs/specfs/spec_vnops.c
@@ -56,7 +56,6 @@
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
-
static int spec_advlock(struct vop_advlock_args *);
static int spec_close(struct vop_close_args *);
static int spec_freeblks(struct vop_freeblks_args *);
@@ -69,6 +68,8 @@ static int spec_poll(struct vop_poll_args *);
static int spec_print(struct vop_print_args *);
static int spec_read(struct vop_read_args *);
static int spec_strategy(struct vop_strategy_args *);
+static int spec_xstrategy(struct vop_strategy_args *);
+static int spec_specstrategy(struct vop_specstrategy_args *);
static int spec_write(struct vop_write_args *);
vop_t **spec_vnodeop_p;
@@ -104,6 +105,7 @@ static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_rename_desc, (vop_t *) vop_panic },
{ &vop_rmdir_desc, (vop_t *) vop_panic },
{ &vop_setattr_desc, (vop_t *) vop_ebadf },
+ { &vop_specstrategy_desc, (vop_t *) spec_specstrategy },
{ &vop_strategy_desc, (vop_t *) spec_strategy },
{ &vop_symlink_desc, (vop_t *) vop_panic },
{ &vop_unlock_desc, (vop_t *) vop_nounlock },
@@ -522,7 +524,7 @@ SYSCTL_INT(_debug, OID_AUTO, doslowdown, CTLFLAG_RW, &doslowdown, 0, "");
* Just call the device strategy routine
*/
static int
-spec_strategy(ap)
+spec_xstrategy(ap)
struct vop_strategy_args /* {
struct vnode *a_vp;
struct buf *a_bp;
@@ -609,6 +611,41 @@ spec_strategy(ap)
return (0);
}
+/*
+ * Decoy strategy routine. We should always come in via the specstrategy
+ * method, but in case some code has botched it, we have a strategy as
+ * well. We will deal with the request anyway and first time around we
+ * print some debugging useful information.
+ */
+
+static int
+spec_strategy(ap)
+ struct vop_strategy_args /* {
+ struct vnode *a_vp;
+ struct buf *a_bp;
+ } */ *ap;
+{
+ static int once;
+
+ if (!once) {
+ vprint("\nVOP_STRATEGY on VCHR\n", ap->a_vp);
+ backtrace();
+ once++;
+ }
+ return spec_xstrategy(ap);
+}
+
+static int
+spec_specstrategy(ap)
+ struct vop_specstrategy_args /* {
+ struct vnode *a_vp;
+ struct buf *a_bp;
+ } */ *ap;
+{
+
+ return spec_xstrategy((void *)ap);
+}
+
static int
spec_freeblks(ap)
struct vop_freeblks_args /* {
diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c
index 0670275..8d9be57 100644
--- a/sys/fs/udf/udf_vnops.c
+++ b/sys/fs/udf/udf_vnops.c
@@ -828,7 +828,7 @@ udf_strategy(struct vop_strategy_args *a)
}
vp = node->i_devvp;
bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
+ VOP_SPECSTRATEGY(vp, bp);
return (0);
}
diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c
index 1fae0f7..0b892e6 100644
--- a/sys/isofs/cd9660/cd9660_vnops.c
+++ b/sys/isofs/cd9660/cd9660_vnops.c
@@ -731,7 +731,7 @@ cd9660_strategy(ap)
}
vp = ip->i_devvp;
bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
+ VOP_SPECSTRATEGY(vp, bp);
return (0);
}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 65fcb33..784a5c0 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -701,7 +701,10 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
if (bp->b_rcred == NOCRED && cred != NOCRED)
bp->b_rcred = crhold(cred);
vfs_busy_pages(bp, 0);
- VOP_STRATEGY(vp, bp);
+ if (vp->v_type == VCHR)
+ VOP_SPECSTRATEGY(vp, bp);
+ else
+ VOP_STRATEGY(vp, bp);
++readwait;
}
@@ -721,7 +724,10 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
rabp->b_rcred = crhold(cred);
vfs_busy_pages(rabp, 0);
BUF_KERNPROC(rabp);
- VOP_STRATEGY(vp, rabp);
+ if (vp->v_type == VCHR)
+ VOP_SPECSTRATEGY(vp, bp);
+ else
+ VOP_STRATEGY(vp, bp);
} else {
brelse(rabp);
}
@@ -855,7 +861,10 @@ bwrite(struct buf * bp)
splx(s);
if (oldflags & B_ASYNC)
BUF_KERNPROC(bp);
- VOP_STRATEGY(bp->b_vp, bp);
+ if (bp->b_vp->v_type == VCHR)
+ VOP_SPECSTRATEGY(bp->b_vp, bp);
+ else
+ VOP_STRATEGY(bp->b_vp, bp);
if ((oldflags & B_ASYNC) == 0) {
int rtval = bufwait(bp);
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 85b8af9..f629b19 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -66,6 +66,7 @@
static int vop_nolookup(struct vop_lookup_args *);
static int vop_nostrategy(struct vop_strategy_args *);
+static int vop_nospecstrategy(struct vop_specstrategy_args *);
/*
* This vnode table stores what we want to do if the filesystem doesn't
@@ -98,6 +99,7 @@ static struct vnodeopv_entry_desc default_vnodeop_entries[] = {
{ &vop_putpages_desc, (vop_t *) vop_stdputpages },
{ &vop_readlink_desc, (vop_t *) vop_einval },
{ &vop_revoke_desc, (vop_t *) vop_revoke },
+ { &vop_specstrategy_desc, (vop_t *) vop_nospecstrategy },
{ &vop_strategy_desc, (vop_t *) vop_nostrategy },
{ &vop_unlock_desc, (vop_t *) vop_stdunlock },
{ NULL, NULL }
@@ -221,6 +223,29 @@ vop_nostrategy (struct vop_strategy_args *ap)
}
/*
+ * vop_nospecstrategy:
+ *
+ * This shouldn't happen. VOP_SPECSTRATEGY should always have a VCHR
+ * argument vnode, and thos have a method for specstrategy over in
+ * specfs, so we only ever get here if somebody botched it.
+ * Pass the call to VOP_STRATEGY() and get on with life.
+ * The first time we print some info useful for debugging.
+ */
+
+static int
+vop_nospecstrategy (struct vop_specstrategy_args *ap)
+{
+ static int once;
+
+ if (!once) {
+ vprint("\nVOP_SPECSTRATEGY on non-VCHR\n", ap->a_vp);
+ backtrace();
+ once++;
+ }
+ return VOP_STRATEGY(ap->a_vp, ap->a_bp);
+}
+
+/*
* vop_stdpathconf:
*
* Standard implementation of POSIX pathconf, to get information about limits
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 4fce819..f62d0ac 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -400,6 +400,15 @@ vop_strategy {
};
#
+# specstrategy vp L L L
+#! specstrategy pre vop_strategy_pre
+#
+vop_specstrategy {
+ IN struct vnode *vp;
+ IN struct buf *bp;
+};
+
+#
#% getwritemount vp = = =
#
vop_getwritemount {
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index a4adc9a..af65b36 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1968,7 +1968,7 @@ ufs_strategy(ap)
}
vp = ip->i_devvp;
bp->b_dev = vp->v_rdev;
- VOP_STRATEGY(vp, bp);
+ VOP_SPECSTRATEGY(vp, bp);
return (0);
}
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c
index 7edb969..f586d5d 100644
--- a/sys/vm/vm_swap.c
+++ b/sys/vm/vm_swap.c
@@ -164,7 +164,7 @@ swapdev_strategy(ap)
}
bp->b_vp = sp->sw_vp;
splx(s);
- VOP_STRATEGY(bp->b_vp, bp);
+ VOP_SPECSTRATEGY(bp->b_vp, bp);
return 0;
}
OpenPOWER on IntegriCloud