diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/cd9660/cd9660_vnops.c | 2 | ||||
-rw-r--r-- | sys/fs/hpfs/hpfs_vnops.c | 2 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_vnops.c | 2 | ||||
-rw-r--r-- | sys/fs/specfs/spec_vnops.c | 41 | ||||
-rw-r--r-- | sys/fs/udf/udf_vnops.c | 2 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vnops.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 15 | ||||
-rw-r--r-- | sys/kern/vfs_default.c | 25 | ||||
-rw-r--r-- | sys/kern/vnode_if.src | 9 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 2 | ||||
-rw-r--r-- | sys/vm/vm_swap.c | 2 |
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; } |