summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-04-03 10:29:55 +0000
committerjeff <jeff@FreeBSD.org>2005-04-03 10:29:55 +0000
commite0e3d6c9e0bacdabaa648ddcc3816c52f4202318 (patch)
treeda22c8781a691553230baf1e17a9c265f03ffb7c
parent3c5b12f96d65ec3bb22fd15b3de2833eadff0616 (diff)
downloadFreeBSD-src-e0e3d6c9e0bacdabaa648ddcc3816c52f4202318.zip
FreeBSD-src-e0e3d6c9e0bacdabaa648ddcc3816c52f4202318.tar.gz
- Move the contents of softdep_disk_prewrite into ffs_geom_strategy to fix
two bugs. - ffs_disk_prewrite was pulling the vp from the buf and checking for COPYONWRITE, when really it wanted the vp from the bufobj that we're writing to, which is the devvp. This lead to us skipping the copy on write to all file data, which significantly broke snapshots for the last few months. - When the SOFTUPDATES option was not included in the kernel config we would also skip the copy on write check, which would effectively disable snapshots. - Remove an invalid mp_fixme(). Debugging tips from: mckusick Reported by: iedowse, others Discussed with: phk
-rw-r--r--sys/ufs/ffs/ffs_extern.h1
-rw-r--r--sys/ufs/ffs/ffs_softdep.c29
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c23
3 files changed, 21 insertions, 32 deletions
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index cdc838e..470e513 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -118,7 +118,6 @@ 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 vnode *);
-int softdep_disk_prewrite(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 1d0cd15..00e63b0 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -3496,35 +3496,6 @@ handle_workitem_freefile(freefile)
WORKITEM_FREE(freefile, D_FREEFILE);
}
-int
-softdep_disk_prewrite(struct buf *bp)
-{
- int error;
- struct vnode *vp = bp->b_vp;
-
- KASSERT(bp->b_iocmd == BIO_WRITE,
- ("softdep_disk_prewrite on non-BIO_WRITE buffer"));
- 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("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_snapdata != NULL &&
- (error = (ffs_copyonwrite)(vp, bp)) != 0 &&
- error != EOPNOTSUPP) {
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return (1);
- }
- return (0);
-}
-
-
/*
* Disk writes.
*
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 7874aff..529a59e 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1671,10 +1671,29 @@ ffs_bufwrite(struct buf *bp)
static void
ffs_geom_strategy(struct bufobj *bo, struct buf *bp)
{
+ struct vnode *vp;
+ int error;
+ vp = bo->__bo_vnode;
+ if (bp->b_iocmd == BIO_WRITE) {
#ifdef SOFTUPDATES
- if (bp->b_iocmd == BIO_WRITE && softdep_disk_prewrite(bp))
- return;
+ 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;
+ }
+ }
g_vfs_strategy(bo, bp);
}
OpenPOWER on IntegriCloud