- 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
This commit is contained in:
Jeff Roberson 2005-04-03 10:29:55 +00:00
parent f0ddc75ed0
commit 153910e0f5
3 changed files with 21 additions and 32 deletions

View File

@ -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);

View File

@ -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.
*

View File

@ -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);
}