aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authoralex chen <alex.chen@huawei.com>2015-02-10 17:09:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 17:30:29 -0500
commit15eba0fe3eeaeb1b80489c1ebb9d47d6d7003f57 (patch)
tree1e83f68ee33bc709a53c0f9a1fd4a4ab1d8ee612 /fs/ocfs2
parent95671c63d5ef3b8794fc9a05d44f0162cc5db425 (diff)
ocfs2: fix journal commit deadlock in ocfs2_convert_inline_data_to_extents
Similar to ocfs2_write_end_nolock() which is metioned at commit 136f49b91710 ("ocfs2: fix journal commit deadlock"), we should unlock pages before ocfs2_commit_trans() in ocfs2_convert_inline_data_to_extents. Otherwise, it will cause a deadlock with journal commit threads. Signed-off-by: Alex Chen <alex.chen@huawei.com> Reviewed-by: Joseph Qi <joseph.qi@huawei.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/alloc.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index fcae9ef1a328..044158bd22be 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6873,7 +6873,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
6873 if (IS_ERR(handle)) { 6873 if (IS_ERR(handle)) {
6874 ret = PTR_ERR(handle); 6874 ret = PTR_ERR(handle);
6875 mlog_errno(ret); 6875 mlog_errno(ret);
6876 goto out_unlock; 6876 goto out;
6877 } 6877 }
6878 6878
6879 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, 6879 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
@@ -6931,7 +6931,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
6931 if (ret) { 6931 if (ret) {
6932 mlog_errno(ret); 6932 mlog_errno(ret);
6933 need_free = 1; 6933 need_free = 1;
6934 goto out_commit; 6934 goto out_unlock;
6935 } 6935 }
6936 6936
6937 page_end = PAGE_CACHE_SIZE; 6937 page_end = PAGE_CACHE_SIZE;
@@ -6964,12 +6964,16 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
6964 if (ret) { 6964 if (ret) {
6965 mlog_errno(ret); 6965 mlog_errno(ret);
6966 need_free = 1; 6966 need_free = 1;
6967 goto out_commit; 6967 goto out_unlock;
6968 } 6968 }
6969 6969
6970 inode->i_blocks = ocfs2_inode_sector_count(inode); 6970 inode->i_blocks = ocfs2_inode_sector_count(inode);
6971 } 6971 }
6972 6972
6973out_unlock:
6974 if (pages)
6975 ocfs2_unlock_and_free_pages(pages, num_pages);
6976
6973out_commit: 6977out_commit:
6974 if (ret < 0 && did_quota) 6978 if (ret < 0 && did_quota)
6975 dquot_free_space_nodirty(inode, 6979 dquot_free_space_nodirty(inode,
@@ -6989,15 +6993,11 @@ out_commit:
6989 6993
6990 ocfs2_commit_trans(osb, handle); 6994 ocfs2_commit_trans(osb, handle);
6991 6995
6992out_unlock: 6996out:
6993 if (data_ac) 6997 if (data_ac)
6994 ocfs2_free_alloc_context(data_ac); 6998 ocfs2_free_alloc_context(data_ac);
6995 6999 if (pages)
6996out:
6997 if (pages) {
6998 ocfs2_unlock_and_free_pages(pages, num_pages);
6999 kfree(pages); 7000 kfree(pages);
7000 }
7001 7001
7002 return ret; 7002 return ret;
7003} 7003}