summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/ufs/ffs/ffs_softdep.c7
2 files changed, 6 insertions, 2 deletions
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index e6875e1..5f95865 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -375,6 +375,7 @@ struct thread {
#define TDP_SCHED3 0x00004000 /* Reserved for scheduler private use */
#define TDP_SCHED4 0x00008000 /* Reserved for scheduler private use */
#define TDP_GEOM 0x00010000 /* Settle GEOM before finishing syscall */
+#define TDP_SOFTDEP 0x00020000 /* Stuck processing softdep worklist */
/*
* Reasons that the current thread can not be run yet.
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 3169475..1d0cd15 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -5528,18 +5528,21 @@ request_cleanup(resource)
/*
* We never hold up the filesystem syncer process.
*/
- if (td == filesys_syncer)
+ if (td == filesys_syncer || (td->td_pflags & TDP_SOFTDEP))
return (0);
/*
* First check to see if the work list has gotten backlogged.
* If it has, co-opt this process to help clean up two entries.
* Because this process may hold inodes locked, we cannot
* handle any remove requests that might block on a locked
- * inode as that could lead to deadlock.
+ * inode as that could lead to deadlock. We set TDP_SOFTDEP
+ * to avoid recursively processing the worklist.
*/
if (num_on_worklist > max_softdeps / 10) {
+ 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;
return(1);
}
OpenPOWER on IntegriCloud