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.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7097b0f680e6..a61873808f76 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2835,6 +2835,9 @@ again:
2835 err = -EIO; 2835 err = -EIO;
2836 break; 2836 break;
2837 } 2837 }
2838 /* Yield here to deal with large extent trees.
2839 * Should be a no-op if we did IO above. */
2840 cond_resched();
2838 if (WARN_ON(i + 1 > depth)) { 2841 if (WARN_ON(i + 1 > depth)) {
2839 err = -EIO; 2842 err = -EIO;
2840 break; 2843 break;
@@ -4261,8 +4264,8 @@ got_allocated_blocks:
4261 /* not a good idea to call discard here directly, 4264 /* not a good idea to call discard here directly,
4262 * but otherwise we'd need to call it every free() */ 4265 * but otherwise we'd need to call it every free() */
4263 ext4_discard_preallocations(inode); 4266 ext4_discard_preallocations(inode);
4264 ext4_free_blocks(handle, inode, NULL, ext4_ext_pblock(&newex), 4267 ext4_free_blocks(handle, inode, NULL, newblock,
4265 ext4_ext_get_actual_len(&newex), fb_flags); 4268 EXT4_C2B(sbi, allocated_clusters), fb_flags);
4266 goto out2; 4269 goto out2;
4267 } 4270 }
4268 4271
@@ -4382,8 +4385,9 @@ out2:
4382 } 4385 }
4383 4386
4384out3: 4387out3:
4385 trace_ext4_ext_map_blocks_exit(inode, flags, map, err ? err : allocated); 4388 trace_ext4_ext_map_blocks_exit(inode, flags, map,
4386 4389 err ? err : allocated);
4390 ext4_es_lru_add(inode);
4387 return err ? err : allocated; 4391 return err ? err : allocated;
4388} 4392}
4389 4393
@@ -4405,9 +4409,20 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode)
4405 4409
4406 last_block = (inode->i_size + sb->s_blocksize - 1) 4410 last_block = (inode->i_size + sb->s_blocksize - 1)
4407 >> EXT4_BLOCK_SIZE_BITS(sb); 4411 >> EXT4_BLOCK_SIZE_BITS(sb);
4412retry:
4408 err = ext4_es_remove_extent(inode, last_block, 4413 err = ext4_es_remove_extent(inode, last_block,
4409 EXT_MAX_BLOCKS - last_block); 4414 EXT_MAX_BLOCKS - last_block);
4415 if (err == ENOMEM) {
4416 cond_resched();
4417 congestion_wait(BLK_RW_ASYNC, HZ/50);
4418 goto retry;
4419 }
4420 if (err) {
4421 ext4_std_error(inode->i_sb, err);
4422 return;
4423 }
4410 err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); 4424 err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
4425 ext4_std_error(inode->i_sb, err);
4411} 4426}
4412 4427
4413static void ext4_falloc_update_inode(struct inode *inode, 4428static void ext4_falloc_update_inode(struct inode *inode,