From 3b88b0f403c14a37086d6bc0f64e2727d63455e0 Mon Sep 17 00:00:00 2001 From: das Date: Fri, 25 Mar 2005 17:30:31 +0000 Subject: When the softupdates worklist gets too long, threads that attempt to add more work are forced to process two worklist items first. However, processing an item may generate additional work, causing the unlucky thread to recursively process the worklist. Add a per-thread flag to detect this situation and avoid the recursion. This should fix the stack overflows that could occur while removing large directory trees. Tested by: kris Reviewed by: mckusick --- sys/ufs/ffs/ffs_softdep.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sys/ufs') 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); } -- cgit v1.1