summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-03-19 21:43:36 +0000
committertegge <tegge@FreeBSD.org>2006-03-19 21:43:36 +0000
commitb09da81e5f139fa2e5002e7ff28a20fc429279d7 (patch)
tree62885f3310d59355548c73b75827ccf24f094ff4 /sys/ufs/ffs
parent1ca5876d84247d6404476edeb824b6794e4df4e0 (diff)
downloadFreeBSD-src-b09da81e5f139fa2e5002e7ff28a20fc429279d7.zip
FreeBSD-src-b09da81e5f139fa2e5002e7ff28a20fc429279d7.tar.gz
Let snapshots make a copy of old contents for all buffers taking part in a
cluster instead of just the first buffer. Delay buf_start() calls until snapshots have a copy of old content. PR: kern/93942
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 2cc5018..fbc143c 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1758,27 +1758,54 @@ ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
{
struct vnode *vp;
int error;
+#ifdef SOFTUPDATES
+ struct buf *tbp;
+#endif
vp = bo->__bo_vnode;
if (bp->b_iocmd == BIO_WRITE) {
-#ifdef SOFTUPDATES
- if (LIST_FIRST(&bp->b_dep) != NULL)
- buf_start(bp);
-#endif
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("ffs_geom_strategy: bad I/O");
bp->b_flags &= ~B_VALIDSUSPWRT;
if ((vp->v_vflag & VV_COPYONWRITE) &&
- vp->v_rdev->si_snapdata != NULL &&
- (error = (ffs_copyonwrite)(vp, bp)) != 0 &&
- error != EOPNOTSUPP) {
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return;
+ vp->v_rdev->si_snapdata != NULL) {
+ if ((bp->b_flags & B_CLUSTER) != 0) {
+ TAILQ_FOREACH(tbp, &bp->b_cluster.cluster_head,
+ b_cluster.cluster_entry) {
+ error = ffs_copyonwrite(vp, tbp);
+ if (error != 0 &&
+ error != EOPNOTSUPP) {
+ bp->b_error = error;
+ bp->b_ioflags |= BIO_ERROR;
+ bufdone(bp);
+ return;
+ }
+ }
+ } else {
+ error = ffs_copyonwrite(vp, bp);
+ if (error != 0 && error != EOPNOTSUPP) {
+ bp->b_error = error;
+ bp->b_ioflags |= BIO_ERROR;
+ bufdone(bp);
+ return;
+ }
+ }
}
+#ifdef SOFTUPDATES
+ if ((bp->b_flags & B_CLUSTER) != 0) {
+ TAILQ_FOREACH(tbp, &bp->b_cluster.cluster_head,
+ b_cluster.cluster_entry) {
+ if (LIST_FIRST(&tbp->b_dep) != NULL)
+ buf_start(tbp);
+ }
+ } else {
+ if (LIST_FIRST(&bp->b_dep) != NULL)
+ buf_start(bp);
+ }
+
+#endif
}
g_vfs_strategy(bo, bp);
}
OpenPOWER on IntegriCloud