aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorTor Egge <tegge@FreeBSD.org>2006-01-09 19:16:56 +0000
committerTor Egge <tegge@FreeBSD.org>2006-01-09 19:16:56 +0000
commitc8c7711d660afa6cffed4aee7cfec28590c7fe9e (patch)
tree5c3e84b0bb12f0994c9f2c681612124c4aa94018 /sys/ufs
parenta2800e245a46f5e80b459b8b7638b96be9b13a06 (diff)
downloadsrc-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.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 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);
}
/*