When I was a kid my work table was one cluttered mess an cleaning it up
were a rather overwhelming task. I soon learned that if you don't know where you're going to store something, at least try to pile it next to something slightly related in the hope that a pattern emerges. Apply the same principle to the ffs/snapshot/softupdates code which have leaked into specfs: Add yet a buf-quasi-method and call it from the only two places I can see it can make a difference and implement the magic in ffs_softdep.c where it belongs. It's not pretty, but at least it's one less layer violated.
This commit is contained in:
parent
f52d98a820
commit
ae79c36301
@ -463,7 +463,6 @@ static int
|
||||
spec_xstrategy(struct vnode *vp, struct buf *bp)
|
||||
{
|
||||
struct mount *mp;
|
||||
int error;
|
||||
struct cdevsw *dsw;
|
||||
struct thread *td = curthread;
|
||||
|
||||
@ -481,25 +480,6 @@ spec_xstrategy(struct vnode *vp, struct buf *bp)
|
||||
PPAUSE | PCATCH | PDROP, "ioslow",
|
||||
td->td_ksegrp->kg_nice);
|
||||
}
|
||||
if (bp->b_iocmd == BIO_WRITE) {
|
||||
if ((bp->b_flags & B_VALIDSUSPWRT) == 0 &&
|
||||
bp->b_vp != NULL && bp->b_vp->v_mount != NULL &&
|
||||
(bp->b_vp->v_mount->mnt_kern_flag & MNTK_SUSPENDED) != 0)
|
||||
panic("spec_strategy: bad I/O");
|
||||
bp->b_flags &= ~B_VALIDSUSPWRT;
|
||||
if (LIST_FIRST(&bp->b_dep) != NULL)
|
||||
buf_start(bp);
|
||||
mp_fixme("This should require the vnode lock.");
|
||||
if ((vp->v_vflag & VV_COPYONWRITE) &&
|
||||
vp->v_rdev->si_copyonwrite &&
|
||||
(error = (*vp->v_rdev->si_copyonwrite)(vp, bp)) != 0 &&
|
||||
error != EOPNOTSUPP) {
|
||||
bp->b_io.bio_error = error;
|
||||
bp->b_io.bio_flags |= BIO_ERROR;
|
||||
biodone(&bp->b_io);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Collect statistics on synchronous and asynchronous read
|
||||
* and write counts for disks that have associated filesystems.
|
||||
|
@ -886,10 +886,12 @@ ibwrite(struct buf * bp)
|
||||
if (oldflags & B_ASYNC)
|
||||
BUF_KERNPROC(bp);
|
||||
bp->b_iooffset = dbtob(bp->b_blkno);
|
||||
if (bp->b_vp->v_type == VCHR)
|
||||
VOP_SPECSTRATEGY(bp->b_vp, bp);
|
||||
else
|
||||
if (bp->b_vp->v_type == VCHR) {
|
||||
if (!buf_prewrite(bp->b_vp, bp))
|
||||
VOP_SPECSTRATEGY(bp->b_vp, bp);
|
||||
} else {
|
||||
VOP_STRATEGY(bp->b_vp, bp);
|
||||
}
|
||||
|
||||
if ((oldflags & B_ASYNC) == 0) {
|
||||
int rtval = bufwait(bp);
|
||||
|
@ -62,6 +62,7 @@ LIST_HEAD(workhead, worklist);
|
||||
* to each buffer.
|
||||
*/
|
||||
extern struct bio_ops {
|
||||
int (*io_prewrite)(struct vnode *, struct buf *);
|
||||
void (*io_start)(struct buf *);
|
||||
void (*io_complete)(struct buf *);
|
||||
void (*io_deallocate)(struct buf *);
|
||||
@ -404,6 +405,15 @@ struct cluster_save {
|
||||
#ifdef _KERNEL
|
||||
|
||||
|
||||
static __inline int
|
||||
buf_prewrite(struct vnode *vp, struct buf *bp)
|
||||
{
|
||||
if (bioops.io_start)
|
||||
return (*bioops.io_prewrite)(vp, bp);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
buf_start(struct buf *bp)
|
||||
{
|
||||
|
@ -202,6 +202,7 @@ static void add_to_worklist(struct worklist *);
|
||||
/*
|
||||
* Exported softdep operations.
|
||||
*/
|
||||
static int softdep_disk_prewrite(struct vnode *vp, struct buf *bp);
|
||||
static void softdep_disk_io_initiation(struct buf *);
|
||||
static void softdep_disk_write_complete(struct buf *);
|
||||
static void softdep_deallocate_dependencies(struct buf *);
|
||||
@ -1152,6 +1153,7 @@ softdep_initialize()
|
||||
softdep_fsync_hook = softdep_fsync;
|
||||
|
||||
/* initialise bioops hack */
|
||||
bioops.io_prewrite = softdep_disk_prewrite;
|
||||
bioops.io_start = softdep_disk_io_initiation;
|
||||
bioops.io_complete = softdep_disk_write_complete;
|
||||
bioops.io_deallocate = softdep_deallocate_dependencies;
|
||||
@ -3413,6 +3415,34 @@ handle_workitem_freefile(freefile)
|
||||
WORKITEM_FREE(freefile, D_FREEFILE);
|
||||
}
|
||||
|
||||
static int
|
||||
softdep_disk_prewrite(struct vnode *vp, struct buf *bp)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (bp->b_iocmd != BIO_WRITE)
|
||||
return (0);
|
||||
if ((bp->b_flags & B_VALIDSUSPWRT) == 0 &&
|
||||
bp->b_vp != NULL && bp->b_vp->v_mount != NULL &&
|
||||
(vp->v_mount->mnt_kern_flag & MNTK_SUSPENDED) != 0)
|
||||
panic("softdep_disk_prewrite: bad I/O");
|
||||
bp->b_flags &= ~B_VALIDSUSPWRT;
|
||||
if (LIST_FIRST(&bp->b_dep) != NULL)
|
||||
buf_start(bp);
|
||||
mp_fixme("This should require the vnode lock.");
|
||||
if ((vp->v_vflag & VV_COPYONWRITE) &&
|
||||
vp->v_rdev->si_copyonwrite &&
|
||||
(error = (*vp->v_rdev->si_copyonwrite)(vp, bp)) != 0 &&
|
||||
error != EOPNOTSUPP) {
|
||||
bp->b_io.bio_error = error;
|
||||
bp->b_io.bio_flags |= BIO_ERROR;
|
||||
biodone(&bp->b_io);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disk writes.
|
||||
*
|
||||
|
@ -1971,7 +1971,8 @@ ufs_strategy(ap)
|
||||
vp = ip->i_devvp;
|
||||
bp->b_dev = vp->v_rdev;
|
||||
bp->b_iooffset = dbtob(bp->b_blkno);
|
||||
VOP_SPECSTRATEGY(vp, bp);
|
||||
if (!buf_prewrite(vp, bp))
|
||||
VOP_SPECSTRATEGY(vp, bp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user