diff options
author | jeff <jeff@FreeBSD.org> | 2005-04-03 10:29:55 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2005-04-03 10:29:55 +0000 |
commit | e0e3d6c9e0bacdabaa648ddcc3816c52f4202318 (patch) | |
tree | da22c8781a691553230baf1e17a9c265f03ffb7c /sys/ufs/ffs | |
parent | 3c5b12f96d65ec3bb22fd15b3de2833eadff0616 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r-- | sys/ufs/ffs/ffs_extern.h | 1 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 29 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 23 |
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); } |