diff options
author | Tor Egge <tegge@FreeBSD.org> | 2006-01-09 19:16:56 +0000 |
---|---|---|
committer | Tor Egge <tegge@FreeBSD.org> | 2006-01-09 19:16:56 +0000 |
commit | c8c7711d660afa6cffed4aee7cfec28590c7fe9e (patch) | |
tree | 5c3e84b0bb12f0994c9f2c681612124c4aa94018 /sys/ufs | |
parent | a2800e245a46f5e80b459b8b7638b96be9b13a06 (diff) | |
download | src-c8c7711d660afa6cffed4aee7cfec28590c7fe9e.tar.gz src-c8c7711d660afa6cffed4aee7cfec28590c7fe9e.zip |
Broaden scope of softdep_worklist_busy rwlock protection of softdep processing
to avoid some dependencies being missed by softdep_flushworklist().
Reviewed by: truckman
Notes
Notes:
svn path=/head/; revision=154149
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index d16da435fc40..088b4fea2c05 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -5526,13 +5526,26 @@ softdep_request_cleanup(fs, vp) return (0); UFS_UNLOCK(ump); ACQUIRE_LOCK(&lk); + if (softdep_worklist_busy < 0) { + request_cleanup(FLUSH_REMOVE_WAIT); + FREE_LOCK(&lk); + UFS_LOCK(ump); + return (0); + } + softdep_worklist_busy += 1; if (num_on_worklist > 0 && process_worklist_item(NULL, LK_NOWAIT) != -1) { stat_worklist_push += 1; + softdep_worklist_busy -= 1; + if (softdep_worklist_req && softdep_worklist_busy == 0) + wakeup(&softdep_worklist_req); FREE_LOCK(&lk); UFS_LOCK(ump); continue; } + softdep_worklist_busy -= 1; + if (softdep_worklist_req && softdep_worklist_busy == 0) + wakeup(&softdep_worklist_req); request_cleanup(FLUSH_REMOVE_WAIT); FREE_LOCK(&lk); UFS_LOCK(ump); @@ -5564,12 +5577,17 @@ request_cleanup(resource) * inode as that could lead to deadlock. We set TDP_SOFTDEP * to avoid recursively processing the worklist. */ - if (num_on_worklist > max_softdeps / 10) { + if (num_on_worklist > max_softdeps / 10 && + softdep_worklist_busy >= 0) { + softdep_worklist_busy += 1; td->td_pflags |= TDP_SOFTDEP; process_worklist_item(NULL, LK_NOWAIT); process_worklist_item(NULL, LK_NOWAIT); td->td_pflags &= ~TDP_SOFTDEP; stat_worklist_push += 2; + softdep_worklist_busy -= 1; + if (softdep_worklist_req && softdep_worklist_busy == 0) + wakeup(&softdep_worklist_req); return(1); } /* |