diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2014-07-27 22:28:15 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-07-27 22:28:15 -0400 |
commit | 4b1f1660710c2ddcefc08c289e66a32b6bc2a2e3 (patch) | |
tree | 915f9288771445a975f5253c6f95fa60d5f11b72 /fs/ext4 | |
parent | b27b1535acc0e97b7435bccf205b3fe9c782afac (diff) |
ext4: add i_data_sem sanity check
Each caller of ext4_ext_dirty must hold i_data_sem,
The only exception is migration code, let's make it convenient.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 2 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 7 |
2 files changed, 9 insertions, 0 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b30172dd55eb..ee93f82630c6 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -161,6 +161,8 @@ int __ext4_ext_dirty(const char *where, unsigned int line, handle_t *handle, | |||
161 | struct inode *inode, struct ext4_ext_path *path) | 161 | struct inode *inode, struct ext4_ext_path *path) |
162 | { | 162 | { |
163 | int err; | 163 | int err; |
164 | |||
165 | WARN_ON(!rwsem_is_locked(&EXT4_I(inode)->i_data_sem)); | ||
164 | if (path->p_bh) { | 166 | if (path->p_bh) { |
165 | ext4_extent_block_csum_set(inode, ext_block_hdr(path->p_bh)); | 167 | ext4_extent_block_csum_set(inode, ext_block_hdr(path->p_bh)); |
166 | /* path points to block */ | 168 | /* path points to block */ |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index ec092437d3e0..d3567f27bae7 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
@@ -39,6 +39,8 @@ static int finish_range(handle_t *handle, struct inode *inode, | |||
39 | newext.ee_block = cpu_to_le32(lb->first_block); | 39 | newext.ee_block = cpu_to_le32(lb->first_block); |
40 | newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1); | 40 | newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1); |
41 | ext4_ext_store_pblock(&newext, lb->first_pblock); | 41 | ext4_ext_store_pblock(&newext, lb->first_pblock); |
42 | /* Locking only for convinience since we are operating on temp inode */ | ||
43 | down_write(&EXT4_I(inode)->i_data_sem); | ||
42 | path = ext4_ext_find_extent(inode, lb->first_block, NULL, 0); | 44 | path = ext4_ext_find_extent(inode, lb->first_block, NULL, 0); |
43 | 45 | ||
44 | if (IS_ERR(path)) { | 46 | if (IS_ERR(path)) { |
@@ -61,7 +63,9 @@ static int finish_range(handle_t *handle, struct inode *inode, | |||
61 | */ | 63 | */ |
62 | if (needed && ext4_handle_has_enough_credits(handle, | 64 | if (needed && ext4_handle_has_enough_credits(handle, |
63 | EXT4_RESERVE_TRANS_BLOCKS)) { | 65 | EXT4_RESERVE_TRANS_BLOCKS)) { |
66 | up_write((&EXT4_I(inode)->i_data_sem)); | ||
64 | retval = ext4_journal_restart(handle, needed); | 67 | retval = ext4_journal_restart(handle, needed); |
68 | down_write((&EXT4_I(inode)->i_data_sem)); | ||
65 | if (retval) | 69 | if (retval) |
66 | goto err_out; | 70 | goto err_out; |
67 | } else if (needed) { | 71 | } else if (needed) { |
@@ -70,13 +74,16 @@ static int finish_range(handle_t *handle, struct inode *inode, | |||
70 | /* | 74 | /* |
71 | * IF not able to extend the journal restart the journal | 75 | * IF not able to extend the journal restart the journal |
72 | */ | 76 | */ |
77 | up_write((&EXT4_I(inode)->i_data_sem)); | ||
73 | retval = ext4_journal_restart(handle, needed); | 78 | retval = ext4_journal_restart(handle, needed); |
79 | down_write((&EXT4_I(inode)->i_data_sem)); | ||
74 | if (retval) | 80 | if (retval) |
75 | goto err_out; | 81 | goto err_out; |
76 | } | 82 | } |
77 | } | 83 | } |
78 | retval = ext4_ext_insert_extent(handle, inode, path, &newext, 0); | 84 | retval = ext4_ext_insert_extent(handle, inode, path, &newext, 0); |
79 | err_out: | 85 | err_out: |
86 | up_write((&EXT4_I(inode)->i_data_sem)); | ||
80 | if (path) { | 87 | if (path) { |
81 | ext4_ext_drop_refs(path); | 88 | ext4_ext_drop_refs(path); |
82 | kfree(path); | 89 | kfree(path); |