diff options
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_snapshot.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index 3e7e231..5c62d02 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -1969,6 +1969,7 @@ ffs_copyonwrite(devvp, bp) struct vnode *vp = 0; ufs2_daddr_t lbn, blkno, *snapblklist; int lower, upper, mid, indiroff, snapshot_locked = 0, error = 0; + int launched_async_io, prev_norunningbuf; if (td->td_pflags & TDP_COWINPROGRESS) panic("ffs_copyonwrite: recursive call"); @@ -1997,6 +1998,8 @@ ffs_copyonwrite(devvp, bp) VI_UNLOCK(devvp); return (0); } + launched_async_io = 0; + prev_norunningbuf = td->td_pflags & TDP_NORUNNINGBUF; /* * Since I/O on bp isn't yet in progress and it may be blocked * for a long time waiting on snaplk, back it out of @@ -2101,6 +2104,8 @@ retry: bawrite(cbp); if (dopersistence && ip->i_effnlink > 0) (void) ffs_syncvnode(vp, MNT_WAIT); + else + launched_async_io = 1; continue; } /* @@ -2111,6 +2116,8 @@ retry: bawrite(cbp); if (dopersistence && ip->i_effnlink > 0) (void) ffs_syncvnode(vp, MNT_WAIT); + else + launched_async_io = 1; break; } savedcbp = cbp; @@ -2125,12 +2132,17 @@ retry: bawrite(savedcbp); if (dopersistence && VTOI(vp)->i_effnlink > 0) (void) ffs_syncvnode(vp, MNT_WAIT); + else + launched_async_io = 1; } if (snapshot_locked) { lockmgr(vp->v_vnlock, LK_RELEASE, NULL, td); - td->td_pflags &= ~TDP_NORUNNINGBUF; + td->td_pflags = (td->td_pflags & ~TDP_NORUNNINGBUF) | + prev_norunningbuf; } else VI_UNLOCK(devvp); + if (launched_async_io && (td->td_pflags & TDP_NORUNNINGBUF)) + waitrunningbufspace(); /* * I/O on bp will now be started, so count it in runningbufspace. */ |