diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2008-01-28 23:58:27 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-28 23:58:27 -0500 |
commit | c278bfecebfb1ed67c326ef472660878baa745cd (patch) | |
tree | 7207594cef5bd04ea7333a8321d78aefee01a540 /fs/ext4/extents.c | |
parent | 01f4adc04480a4e0395906d0268c056cf09c39c0 (diff) |
ext4: Make ext4_get_blocks_wrap take the truncate_mutex early.
When doing a migrate from ext3 to ext4 inode we need to make sure the test
for inode type and walking inode data happens inside lock. To make this
happen move truncate_mutex early before checking the i_flags.
This actually should enable us to remove the verify_chain().
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 8593e59020fe..ec5019fa552f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2129,6 +2129,10 @@ out: | |||
2129 | return err ? err : allocated; | 2129 | return err ? err : allocated; |
2130 | } | 2130 | } |
2131 | 2131 | ||
2132 | /* | ||
2133 | * Need to be called with | ||
2134 | * mutex_lock(&EXT4_I(inode)->truncate_mutex); | ||
2135 | */ | ||
2132 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2136 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
2133 | ext4_lblk_t iblock, | 2137 | ext4_lblk_t iblock, |
2134 | unsigned long max_blocks, struct buffer_head *bh_result, | 2138 | unsigned long max_blocks, struct buffer_head *bh_result, |
@@ -2144,7 +2148,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2144 | __clear_bit(BH_New, &bh_result->b_state); | 2148 | __clear_bit(BH_New, &bh_result->b_state); |
2145 | ext_debug("blocks %u/%lu requested for inode %u\n", | 2149 | ext_debug("blocks %u/%lu requested for inode %u\n", |
2146 | iblock, max_blocks, inode->i_ino); | 2150 | iblock, max_blocks, inode->i_ino); |
2147 | mutex_lock(&EXT4_I(inode)->truncate_mutex); | ||
2148 | 2151 | ||
2149 | /* check in cache */ | 2152 | /* check in cache */ |
2150 | goal = ext4_ext_in_cache(inode, iblock, &newex); | 2153 | goal = ext4_ext_in_cache(inode, iblock, &newex); |
@@ -2318,8 +2321,6 @@ out2: | |||
2318 | ext4_ext_drop_refs(path); | 2321 | ext4_ext_drop_refs(path); |
2319 | kfree(path); | 2322 | kfree(path); |
2320 | } | 2323 | } |
2321 | mutex_unlock(&EXT4_I(inode)->truncate_mutex); | ||
2322 | |||
2323 | return err ? err : allocated; | 2324 | return err ? err : allocated; |
2324 | } | 2325 | } |
2325 | 2326 | ||
@@ -2449,6 +2450,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
2449 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | 2450 | * modify 1 super block, 1 block bitmap and 1 group descriptor. |
2450 | */ | 2451 | */ |
2451 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; | 2452 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; |
2453 | mutex_lock(&EXT4_I(inode)->truncate_mutex) | ||
2452 | retry: | 2454 | retry: |
2453 | while (ret >= 0 && ret < max_blocks) { | 2455 | while (ret >= 0 && ret < max_blocks) { |
2454 | block = block + ret; | 2456 | block = block + ret; |
@@ -2505,6 +2507,7 @@ retry: | |||
2505 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 2507 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
2506 | goto retry; | 2508 | goto retry; |
2507 | 2509 | ||
2510 | mutex_unlock(&EXT4_I(inode)->truncate_mutex) | ||
2508 | /* | 2511 | /* |
2509 | * Time to update the file size. | 2512 | * Time to update the file size. |
2510 | * Update only when preallocation was requested beyond the file size. | 2513 | * Update only when preallocation was requested beyond the file size. |