diff options
author | Ryan Ding <ryan.ding@oracle.com> | 2016-03-25 17:21:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-25 19:37:42 -0400 |
commit | 28888681b4f641ce9a96478ce4683577cd3abbff (patch) | |
tree | 48f10b475c7f9b9fc96957e88928f163ee6012f8 | |
parent | ce170828e24959c69e7a40364731edc0535c550f (diff) |
ocfs2: fix a deadlock issue in ocfs2_dio_end_io_write()
The code should call ocfs2_free_alloc_context() to free meta_ac &
data_ac before calling ocfs2_run_deallocs(). Because
ocfs2_run_deallocs() will acquire the system inode's i_mutex hold by
meta_ac. So try to release the lock before ocfs2_run_deallocs().
Fixes: af1310367f41 ("ocfs2: fix sparse file & data ordering issue in direct io.")
Signed-off-by: Ryan Ding <ryan.ding@oracle.com>
Acked-by: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <joseph.qi@huawei.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/ocfs2/aops.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 328ac7f99d52..1581240a7ca0 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -2341,6 +2341,10 @@ static void ocfs2_dio_end_io_write(struct inode *inode, | |||
2341 | 2341 | ||
2342 | ret = ocfs2_lock_allocators(inode, &et, 0, dwc->dw_zero_count*2, | 2342 | ret = ocfs2_lock_allocators(inode, &et, 0, dwc->dw_zero_count*2, |
2343 | &data_ac, &meta_ac); | 2343 | &data_ac, &meta_ac); |
2344 | if (ret) { | ||
2345 | mlog_errno(ret); | ||
2346 | goto unlock; | ||
2347 | } | ||
2344 | 2348 | ||
2345 | credits = ocfs2_calc_extend_credits(inode->i_sb, &di->id2.i_list); | 2349 | credits = ocfs2_calc_extend_credits(inode->i_sb, &di->id2.i_list); |
2346 | 2350 | ||
@@ -2380,14 +2384,14 @@ unlock: | |||
2380 | ocfs2_inode_unlock(inode, 1); | 2384 | ocfs2_inode_unlock(inode, 1); |
2381 | brelse(di_bh); | 2385 | brelse(di_bh); |
2382 | out: | 2386 | out: |
2383 | ocfs2_run_deallocs(osb, &dealloc); | ||
2384 | if (locked) | ||
2385 | mutex_unlock(&inode->i_mutex); | ||
2386 | ocfs2_dio_free_write_ctx(inode, dwc); | ||
2387 | if (data_ac) | 2387 | if (data_ac) |
2388 | ocfs2_free_alloc_context(data_ac); | 2388 | ocfs2_free_alloc_context(data_ac); |
2389 | if (meta_ac) | 2389 | if (meta_ac) |
2390 | ocfs2_free_alloc_context(meta_ac); | 2390 | ocfs2_free_alloc_context(meta_ac); |
2391 | ocfs2_run_deallocs(osb, &dealloc); | ||
2392 | if (locked) | ||
2393 | mutex_unlock(&inode->i_mutex); | ||
2394 | ocfs2_dio_free_write_ctx(inode, dwc); | ||
2391 | } | 2395 | } |
2392 | 2396 | ||
2393 | /* | 2397 | /* |