summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2010-05-07 08:45:21 +0000
committerjeff <jeff@FreeBSD.org>2010-05-07 08:45:21 +0000
commit8fb90eedbcf5ec98d5bdc0ac4fd9e9813889a7ca (patch)
tree22b3b84f815b2567c222e5eceb5519a48e02dfd9 /sys/ufs
parent0b3e023908811e6f4c304045b5b8e993f712b6af (diff)
downloadFreeBSD-src-8fb90eedbcf5ec98d5bdc0ac4fd9e9813889a7ca.zip
FreeBSD-src-8fb90eedbcf5ec98d5bdc0ac4fd9e9813889a7ca.tar.gz
- 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 <vova@fbsd.ru>
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c8
-rw-r--r--sys/ufs/ffs/ffs_softdep.c3
2 files changed, 10 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 11362cf..f6548a3 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 @@ retry:
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 90ed314..49510a7 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) {
OpenPOWER on IntegriCloud