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>
This commit is contained in:
@@ -1080,6 +1080,7 @@ static void ocfs2_clear_inode(struct inode *inode)
|
||||
{
|
||||
int status;
|
||||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
clear_inode(inode);
|
||||
trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno,
|
||||
@@ -1096,9 +1097,9 @@ static void ocfs2_clear_inode(struct inode *inode)
|
||||
|
||||
/* Do these before all the other work so that we don't bounce
|
||||
* the downconvert thread while waiting to destroy the locks. */
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_rw_lockres);
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_inode_lockres);
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_open_lockres);
|
||||
ocfs2_mark_lockres_freeing(osb, &oi->ip_rw_lockres);
|
||||
ocfs2_mark_lockres_freeing(osb, &oi->ip_inode_lockres);
|
||||
ocfs2_mark_lockres_freeing(osb, &oi->ip_open_lockres);
|
||||
|
||||
ocfs2_resv_discard(&OCFS2_SB(inode->i_sb)->osb_la_resmap,
|
||||
&oi->ip_la_data_resv);
|
||||
|
Reference in New Issue
Block a user