aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-01-28 23:58:27 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-01-28 23:58:27 -0500
commitc278bfecebfb1ed67c326ef472660878baa745cd (patch)
tree7207594cef5bd04ea7333a8321d78aefee01a540 /fs/ext4/extents.c
parent01f4adc04480a4e0395906d0268c056cf09c39c0 (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.c9
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 */
2132int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 2136int 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)
2452retry: 2454retry:
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.