aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2013-04-08 13:02:25 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-04-08 13:02:25 -0400
commite8238f9a8339b3578c85e4192a7a23bc2bdc0333 (patch)
treed33c573dc71982138d5fd71d6335ac664cb03bbc /fs/ext4
parent393d1d1d76933886d5e1ce603214c9987589c6d5 (diff)
ext4: fix incorrect lock ordering for ext4_ind_migrate
existing locking ordering: journal-> i_data_sem, but ext4_ind_migrate() grab locks in opposite order which may result in deadlock. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/extents.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 6c5a70a7b573..ea607f907232 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4735,6 +4735,10 @@ int ext4_ind_migrate(struct inode *inode)
4735 (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) 4735 (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
4736 return -EINVAL; 4736 return -EINVAL;
4737 4737
4738 handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
4739 if (IS_ERR(handle))
4740 return PTR_ERR(handle);
4741
4738 down_write(&EXT4_I(inode)->i_data_sem); 4742 down_write(&EXT4_I(inode)->i_data_sem);
4739 ret = ext4_ext_check_inode(inode); 4743 ret = ext4_ext_check_inode(inode);
4740 if (ret) 4744 if (ret)
@@ -4758,19 +4762,13 @@ int ext4_ind_migrate(struct inode *inode)
4758 } 4762 }
4759 } 4763 }
4760 4764
4761 handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
4762 if (IS_ERR(handle)) {
4763 ret = PTR_ERR(handle);
4764 goto errout;
4765 }
4766
4767 ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); 4765 ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
4768 memset(ei->i_data, 0, sizeof(ei->i_data)); 4766 memset(ei->i_data, 0, sizeof(ei->i_data));
4769 for (i=0; i < len; i++) 4767 for (i=0; i < len; i++)
4770 ei->i_data[i] = cpu_to_le32(blk++); 4768 ei->i_data[i] = cpu_to_le32(blk++);
4771 ext4_mark_inode_dirty(handle, inode); 4769 ext4_mark_inode_dirty(handle, inode);
4772 ext4_journal_stop(handle);
4773errout: 4770errout:
4771 ext4_journal_stop(handle);
4774 up_write(&EXT4_I(inode)->i_data_sem); 4772 up_write(&EXT4_I(inode)->i_data_sem);
4775 return ret; 4773 return ret;
4776} 4774}