aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ec5019fa552f..03d1bbb78a2f 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1565,7 +1565,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
1565 * This routine returns max. credits that the extent tree can consume. 1565 * This routine returns max. credits that the extent tree can consume.
1566 * It should be OK for low-performance paths like ->writepage() 1566 * It should be OK for low-performance paths like ->writepage()
1567 * To allow many writing processes to fit into a single transaction, 1567 * To allow many writing processes to fit into a single transaction,
1568 * the caller should calculate credits under truncate_mutex and 1568 * the caller should calculate credits under i_data_sem and
1569 * pass the actual path. 1569 * pass the actual path.
1570 */ 1570 */
1571int ext4_ext_calc_credits_for_insert(struct inode *inode, 1571int ext4_ext_calc_credits_for_insert(struct inode *inode,
@@ -2131,7 +2131,8 @@ out:
2131 2131
2132/* 2132/*
2133 * Need to be called with 2133 * Need to be called with
2134 * mutex_lock(&EXT4_I(inode)->truncate_mutex); 2134 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
2135 * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
2135 */ 2136 */
2136int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 2137int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2137 ext4_lblk_t iblock, 2138 ext4_lblk_t iblock,
@@ -2350,7 +2351,7 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2350 if (page) 2351 if (page)
2351 ext4_block_truncate_page(handle, page, mapping, inode->i_size); 2352 ext4_block_truncate_page(handle, page, mapping, inode->i_size);
2352 2353
2353 mutex_lock(&EXT4_I(inode)->truncate_mutex); 2354 down_write(&EXT4_I(inode)->i_data_sem);
2354 ext4_ext_invalidate_cache(inode); 2355 ext4_ext_invalidate_cache(inode);
2355 2356
2356 /* 2357 /*
@@ -2386,7 +2387,7 @@ out_stop:
2386 if (inode->i_nlink) 2387 if (inode->i_nlink)
2387 ext4_orphan_del(handle, inode); 2388 ext4_orphan_del(handle, inode);
2388 2389
2389 mutex_unlock(&EXT4_I(inode)->truncate_mutex); 2390 up_write(&EXT4_I(inode)->i_data_sem);
2390 ext4_journal_stop(handle); 2391 ext4_journal_stop(handle);
2391} 2392}
2392 2393
@@ -2450,7 +2451,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
2450 * modify 1 super block, 1 block bitmap and 1 group descriptor. 2451 * modify 1 super block, 1 block bitmap and 1 group descriptor.
2451 */ 2452 */
2452 credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; 2453 credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
2453 mutex_lock(&EXT4_I(inode)->truncate_mutex) 2454 down_write((&EXT4_I(inode)->i_data_sem));
2454retry: 2455retry:
2455 while (ret >= 0 && ret < max_blocks) { 2456 while (ret >= 0 && ret < max_blocks) {
2456 block = block + ret; 2457 block = block + ret;
@@ -2507,7 +2508,7 @@ retry:
2507 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 2508 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
2508 goto retry; 2509 goto retry;
2509 2510
2510 mutex_unlock(&EXT4_I(inode)->truncate_mutex) 2511 up_write((&EXT4_I(inode)->i_data_sem));
2511 /* 2512 /*
2512 * Time to update the file size. 2513 * Time to update the file size.
2513 * Update only when preallocation was requested beyond the file size. 2514 * Update only when preallocation was requested beyond the file size.