diff options
author | Jan Kara <jack@suse.cz> | 2014-04-03 17:46:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:20:55 -0400 |
commit | 84d86f83f9d0e8431a3c9eae4c47e9d7ff49a411 (patch) | |
tree | f8708771a3316e70468d98691d14d1873ae69213 /fs/ocfs2/inode.c | |
parent | e3a767b60fd8a9f5e133f42f4970cff77ec43173 (diff) |
ocfs2: avoid blocking in ocfs2_mark_lockres_freeing() in downconvert thread
If we are dropping last inode reference from downconvert thread, we will
end up calling ocfs2_mark_lockres_freeing() which can block if the lock
we are freeing is queued thus creating an A-A deadlock. Luckily, since
we are the downconvert thread, we can immediately dequeue the lock and
thus avoid waiting in this case.
Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Mark Fasheh <mfasheh@suse.de>
Reviewed-by: Srinivas Eeda <srinivas.eeda@oracle.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/inode.c')
-rw-r--r-- | fs/ocfs2/inode.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 809b5d57a6b8..d437f3ba90b0 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -1080,6 +1080,7 @@ static void ocfs2_clear_inode(struct inode *inode) | |||
1080 | { | 1080 | { |
1081 | int status; | 1081 | int status; |
1082 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1082 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
1083 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1083 | 1084 | ||
1084 | clear_inode(inode); | 1085 | clear_inode(inode); |
1085 | trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno, | 1086 | trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno, |
@@ -1096,9 +1097,9 @@ static void ocfs2_clear_inode(struct inode *inode) | |||
1096 | 1097 | ||
1097 | /* Do these before all the other work so that we don't bounce | 1098 | /* Do these before all the other work so that we don't bounce |
1098 | * the downconvert thread while waiting to destroy the locks. */ | 1099 | * the downconvert thread while waiting to destroy the locks. */ |
1099 | ocfs2_mark_lockres_freeing(&oi->ip_rw_lockres); | 1100 | ocfs2_mark_lockres_freeing(osb, &oi->ip_rw_lockres); |
1100 | ocfs2_mark_lockres_freeing(&oi->ip_inode_lockres); | 1101 | ocfs2_mark_lockres_freeing(osb, &oi->ip_inode_lockres); |
1101 | ocfs2_mark_lockres_freeing(&oi->ip_open_lockres); | 1102 | ocfs2_mark_lockres_freeing(osb, &oi->ip_open_lockres); |
1102 | 1103 | ||
1103 | ocfs2_resv_discard(&OCFS2_SB(inode->i_sb)->osb_la_resmap, | 1104 | ocfs2_resv_discard(&OCFS2_SB(inode->i_sb)->osb_la_resmap, |
1104 | &oi->ip_la_data_resv); | 1105 | &oi->ip_la_data_resv); |