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.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 91341ec6e06a..cd0c7ed06772 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1891,11 +1891,10 @@ has_space:
1891 nearex->ee_len = newext->ee_len; 1891 nearex->ee_len = newext->ee_len;
1892 1892
1893merge: 1893merge:
1894 /* try to merge extents to the right */ 1894 /* try to merge extents */
1895 if (!(flag & EXT4_GET_BLOCKS_PRE_IO)) 1895 if (!(flag & EXT4_GET_BLOCKS_PRE_IO))
1896 ext4_ext_try_to_merge(inode, path, nearex); 1896 ext4_ext_try_to_merge(inode, path, nearex);
1897 1897
1898 /* try to merge extents to the left */
1899 1898
1900 /* time to correct all indexes above */ 1899 /* time to correct all indexes above */
1901 err = ext4_ext_correct_indexes(handle, inode, path); 1900 err = ext4_ext_correct_indexes(handle, inode, path);
@@ -2570,10 +2569,10 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
2570{ 2569{
2571 struct super_block *sb = inode->i_sb; 2570 struct super_block *sb = inode->i_sb;
2572 int depth = ext_depth(inode); 2571 int depth = ext_depth(inode);
2573 struct ext4_ext_path *path; 2572 struct ext4_ext_path *path = NULL;
2574 ext4_fsblk_t partial_cluster = 0; 2573 ext4_fsblk_t partial_cluster = 0;
2575 handle_t *handle; 2574 handle_t *handle;
2576 int i, err; 2575 int i = 0, err;
2577 2576
2578 ext_debug("truncate since %u to %u\n", start, end); 2577 ext_debug("truncate since %u to %u\n", start, end);
2579 2578
@@ -2606,8 +2605,12 @@ again:
2606 } 2605 }
2607 depth = ext_depth(inode); 2606 depth = ext_depth(inode);
2608 ex = path[depth].p_ext; 2607 ex = path[depth].p_ext;
2609 if (!ex) 2608 if (!ex) {
2609 ext4_ext_drop_refs(path);
2610 kfree(path);
2611 path = NULL;
2610 goto cont; 2612 goto cont;
2613 }
2611 2614
2612 ee_block = le32_to_cpu(ex->ee_block); 2615 ee_block = le32_to_cpu(ex->ee_block);
2613 2616
@@ -2637,8 +2640,6 @@ again:
2637 if (err < 0) 2640 if (err < 0)
2638 goto out; 2641 goto out;
2639 } 2642 }
2640 ext4_ext_drop_refs(path);
2641 kfree(path);
2642 } 2643 }
2643cont: 2644cont:
2644 2645
@@ -2647,19 +2648,27 @@ cont:
2647 * after i_size and walking into the tree depth-wise. 2648 * after i_size and walking into the tree depth-wise.
2648 */ 2649 */
2649 depth = ext_depth(inode); 2650 depth = ext_depth(inode);
2650 path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS); 2651 if (path) {
2651 if (path == NULL) { 2652 int k = i = depth;
2652 ext4_journal_stop(handle); 2653 while (--k > 0)
2653 return -ENOMEM; 2654 path[k].p_block =
2654 } 2655 le16_to_cpu(path[k].p_hdr->eh_entries)+1;
2655 path[0].p_depth = depth; 2656 } else {
2656 path[0].p_hdr = ext_inode_hdr(inode); 2657 path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1),
2658 GFP_NOFS);
2659 if (path == NULL) {
2660 ext4_journal_stop(handle);
2661 return -ENOMEM;
2662 }
2663 path[0].p_depth = depth;
2664 path[0].p_hdr = ext_inode_hdr(inode);
2657 2665
2658 if (ext4_ext_check(inode, path[0].p_hdr, depth)) { 2666 if (ext4_ext_check(inode, path[0].p_hdr, depth)) {
2659 err = -EIO; 2667 err = -EIO;
2660 goto out; 2668 goto out;
2669 }
2661 } 2670 }
2662 i = err = 0; 2671 err = 0;
2663 2672
2664 while (i >= 0 && err == 0) { 2673 while (i >= 0 && err == 0) {
2665 if (i == depth) { 2674 if (i == depth) {
@@ -2773,8 +2782,10 @@ cont:
2773out: 2782out:
2774 ext4_ext_drop_refs(path); 2783 ext4_ext_drop_refs(path);
2775 kfree(path); 2784 kfree(path);
2776 if (err == -EAGAIN) 2785 if (err == -EAGAIN) {
2786 path = NULL;
2777 goto again; 2787 goto again;
2788 }
2778 ext4_journal_stop(handle); 2789 ext4_journal_stop(handle);
2779 2790
2780 return err; 2791 return err;
@@ -4420,6 +4431,8 @@ retry:
4420 ext4_falloc_update_inode(inode, mode, new_size, 4431 ext4_falloc_update_inode(inode, mode, new_size,
4421 (map.m_flags & EXT4_MAP_NEW)); 4432 (map.m_flags & EXT4_MAP_NEW));
4422 ext4_mark_inode_dirty(handle, inode); 4433 ext4_mark_inode_dirty(handle, inode);
4434 if ((file->f_flags & O_SYNC) && ret >= max_blocks)
4435 ext4_handle_sync(handle);
4423 ret2 = ext4_journal_stop(handle); 4436 ret2 = ext4_journal_stop(handle);
4424 if (ret2) 4437 if (ret2)
4425 break; 4438 break;