From 8ef48de8882c9d0aaab7baf256dfb52c2d29e423 Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Fri, 7 May 2010 08:45:21 +0000 Subject: [PATCH] - Call softdep_prealloc() before any of the balloc routines in the snapshot code. - Don't fsync() vnodes in prealloc if copy on write is in progress. It is not safe to recurse back into the write path here. Reported by: Vladimir Grebenschikov --- sys/ufs/ffs/ffs_snapshot.c | 8 ++++++++ sys/ufs/ffs/ffs_softdep.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index 11362cfbc755..f6548a385eb2 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -1002,6 +1002,8 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) if (lbn < NDADDR) { blkno = VTOI(snapvp)->i_din1->di_db[lbn]; } else { + if (DOINGSOFTDEP(snapvp)) + softdep_prealloc(snapvp, MNT_WAIT); td->td_pflags |= TDP_COWINPROGRESS; error = ffs_balloc_ufs1(snapvp, lblktosize(fs, (off_t)lbn), fs->fs_bsize, KERNCRED, BA_METAONLY, &bp); @@ -1283,6 +1285,8 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) if (lbn < NDADDR) { blkno = VTOI(snapvp)->i_din2->di_db[lbn]; } else { + if (DOINGSOFTDEP(snapvp)) + softdep_prealloc(snapvp, MNT_WAIT); td->td_pflags |= TDP_COWINPROGRESS; error = ffs_balloc_ufs2(snapvp, lblktosize(fs, (off_t)lbn), fs->fs_bsize, KERNCRED, BA_METAONLY, &bp); @@ -1746,6 +1750,8 @@ ffs_snapblkfree(fs, devvp, bno, size, inum) goto retry; TAILQ_FOREACH(ip, &sn->sn_head, i_nextsnap) { vp = ITOV(ip); + if (DOINGSOFTDEP(vp)) + softdep_prealloc(vp, MNT_WAIT); /* * Lookup block being written. */ @@ -2268,6 +2274,8 @@ ffs_copyonwrite(devvp, bp) } TAILQ_FOREACH(ip, &sn->sn_head, i_nextsnap) { vp = ITOV(ip); + if (DOINGSOFTDEP(vp)) + softdep_prealloc(vp, MNT_WAIT); /* * We ensure that everything of our own that needs to be * copied will be done at the time that ffs_snapshot is diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 90ed314d3b84..49510a714027 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -2475,7 +2475,8 @@ softdep_prealloc(vp, waitok) * Attempt to sync this vnode once to flush any journal * work attached to it. */ - ffs_syncvnode(vp, waitok); + if ((curthread->td_pflags & TDP_COWINPROGRESS) == 0) + ffs_syncvnode(vp, waitok); ACQUIRE_LOCK(&lk); process_removes(vp); if (journal_space(ump, 0) == 0) {