- 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:
parent
f0ddc75ed0
commit
153910e0f5
@ -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);
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user