Messages in this thread Patch in this message | | | From | Greg Kroah-Hartman <> | Subject | [ 01/33] vfs: dcache: fix deadlock in tree traversal | Date | Thu, 4 Oct 2012 14:26:23 -0700 |
| |
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <miklos@szeredi.hu>
commit 8110e16d42d587997bcaee0c864179e6d93603fe upstream.
IBM reported a deadlock in select_parent(). This was found to be caused by taking rename_lock when already locked when restarting the tree traversal.
There are two cases when the traversal needs to be restarted:
1) concurrent d_move(); this can only happen when not already locked, since taking rename_lock protects against concurrent d_move().
2) racing with final d_put() on child just at the moment of ascending to parent; rename_lock doesn't protect against this rare race, so it can happen when already locked.
Because of case 2, we need to be able to handle restarting the traversal when rename_lock is already held. This patch fixes all three callers of try_to_ascend().
IBM reported that the deadlock is gone with this patch.
[ I rewrote the patch to be smaller and just do the "goto again" if the lock was already held, but credit goes to Miklos for the real work. - Linus ]
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Cc: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- fs/dcache.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/dcache.c +++ b/fs/dcache.c @@ -1101,6 +1101,8 @@ positive: return 1; rename_retry: + if (locked) + goto again; locked = 1; write_seqlock(&rename_lock); goto again; @@ -1203,6 +1205,8 @@ out: rename_retry: if (found) return found; + if (locked) + goto again; locked = 1; write_seqlock(&rename_lock); goto again; @@ -2990,6 +2994,8 @@ resume: return; rename_retry: + if (locked) + goto again; locked = 1; write_seqlock(&rename_lock); goto again;
| |