From 6e77a04170db6c8a1a87918dd1baff938ac3dc98 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Tue, 26 Oct 2004 10:44:10 +0000 Subject: [PATCH] The island council met and voted buf_prewrite() home. Give ffs it's own bufobj->bo_ops vector and create a private strategy routine, (currently misnamed for forwards compatibility), which is just a copy of the generic bufstrategy routine except we call softdep_disk_prewrite() directly instead of through the buf_prewrite() indirection. Teach UFS about the need for softdep_disk_prewrite() and call the function directly in FFS. Remove buf_prewrite() from the default bufstrategy() and from the global bio_ops method vector. --- sys/kern/vfs_bio.c | 8 +++----- sys/sys/buf.h | 10 ---------- sys/ufs/ffs/ffs_extern.h | 1 + sys/ufs/ffs/ffs_softdep.c | 4 +--- sys/ufs/ffs/ffs_vfsops.c | 36 ++++++++++++++++++++++++++++++++++++ sys/ufs/ufs/ufs_vnops.c | 10 ++++++++-- 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 4b23f51d50d..64231f2dd3d 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3777,12 +3777,10 @@ bufstrategy(struct bufobj *bo, struct buf *bp) KASSERT(vp->v_type != VCHR && vp->v_type != VBLK, ("Wrong vnode in bufstrategy(bp=%p, vp=%p)", bp, vp)); #endif - if (vp->v_type == VCHR) { - if (!buf_prewrite(bp->b_vp, bp)) - i = VOP_SPECSTRATEGY(vp, bp); - } else { + if (vp->v_type == VCHR) + i = VOP_SPECSTRATEGY(vp, bp); + else i = VOP_STRATEGY(vp, bp); - } KASSERT(i == 0, ("VOP_STRATEGY failed bp=%p vp=%p", bp, bp->b_vp)); } diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 796fd70619d..6accac62855 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -60,7 +60,6 @@ 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 *); @@ -416,15 +415,6 @@ bstrategy(struct buf *bp) bp->b_bufobj->bo_ops->bop_strategy(bp->b_bufobj, bp); } -static __inline int -buf_prewrite(struct vnode *vp, struct buf *bp) -{ - if (bioops.io_prewrite) - return (*bioops.io_prewrite)(vp, bp); - else - return (0); -} - static __inline void buf_start(struct buf *bp) { diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index 5c916e9187c..083d4c705fd 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -118,6 +118,7 @@ void softdep_setup_allocindir_page(struct inode *, ufs_lbn_t, struct buf *, int, ufs2_daddr_t, ufs2_daddr_t, struct buf *); void softdep_fsync_mountdev(struct vnode *); int softdep_sync_metadata(struct vop_fsync_args *); +int softdep_disk_prewrite(struct vnode *vp, struct buf *bp); /* XXX incorrectly moved to mount.h - should be indirect function */ #if 0 int softdep_fsync(struct vnode *vp); diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 61fd28b3eac..4ecec3c50d8 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -203,7 +203,6 @@ 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 *); @@ -1154,7 +1153,6 @@ 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; @@ -3417,7 +3415,7 @@ handle_workitem_freefile(freefile) WORKITEM_FREE(freefile, D_FREEFILE); } -static int +int softdep_disk_prewrite(struct vnode *vp, struct buf *bp) { int error; diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 259dc00154d..df066169b67 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include "opt_mac.h" #include "opt_quota.h" #include "opt_ufs.h" +#include "opt_ffs.h" #include #include @@ -97,6 +98,14 @@ static struct vfsops ufs_vfsops = { VFS_SET(ufs_vfsops, ufs, 0); +static b_strategy_t ffs_geom_strategy; + +static struct buf_ops ffs_ops = { + .bop_name = "FFS", + .bop_write = bufwrite, + .bop_strategy = ffs_geom_strategy, +}; + /* * ffs_omount * @@ -597,6 +606,8 @@ ffs_mountfs(devvp, mp, td) if (mp->mnt_iosize_max > MAXPHYS) mp->mnt_iosize_max = MAXPHYS; + devvp->v_bufobj.bo_ops = &ffs_ops; + bp = NULL; ump = NULL; fs = NULL; @@ -1526,3 +1537,28 @@ ffs_ifree(struct ufsmount *ump, struct inode *ip) uma_zfree(uma_ufs2, ip->i_din2); uma_zfree(uma_inode, ip); } + +void +ffs_geom_strategy(struct bufobj *bo, struct buf *bp) +{ + int i = 0; + struct vnode *vp; + + vp = bp->b_vp; +#if 0 + KASSERT(vp == bo->bo_vnode, ("Inconsistent vnode bufstrategy")); + KASSERT(vp->v_type != VCHR && vp->v_type != VBLK, + ("Wrong vnode in bufstrategy(bp=%p, vp=%p)", bp, vp)); +#endif + if (vp->v_type == VCHR) { +#ifdef SOFTUPDATES + if (bp->b_iocmd == BIO_WRITE && softdep_disk_prewrite(bp->b_vp, bp)) + return; +#endif + i = VOP_SPECSTRATEGY(vp, bp); + } else { + i = VOP_STRATEGY(vp, bp); + } + KASSERT(i == 0, ("VOP_STRATEGY failed bp=%p vp=%p", bp, bp->b_vp)); +} + diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 4406999f84d..407f2f94fcf 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include "opt_quota.h" #include "opt_suiddir.h" #include "opt_ufs.h" +#include "opt_ffs.h" #include #include @@ -81,6 +82,8 @@ __FBSDID("$FreeBSD$"); #include #endif +#include + static int ufs_access(struct vop_access_args *); static int ufs_advlock(struct vop_advlock_args *); static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); @@ -1950,8 +1953,11 @@ ufs_strategy(ap) vp = ip->i_devvp; bp->b_dev = vp->v_rdev; bp->b_iooffset = dbtob(bp->b_blkno); - if (!buf_prewrite(vp, bp)) - VOP_SPECSTRATEGY(vp, bp); +#ifdef SOFTUPDATES + if (bp->b_iocmd == BIO_WRITE && softdep_disk_prewrite(vp, bp)) + return (0); +#endif + VOP_SPECSTRATEGY(vp, bp); return (0); }