summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index d16da43..088b4fe 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);
}
/*
OpenPOWER on IntegriCloud