aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/extents.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 46b5c9fdc96..cd0c7ed0677 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2569,10 +2569,10 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
2569{ 2569{
2570 struct super_block *sb = inode->i_sb; 2570 struct super_block *sb = inode->i_sb;
2571 int depth = ext_depth(inode); 2571 int depth = ext_depth(inode);
2572 struct ext4_ext_path *path; 2572 struct ext4_ext_path *path = NULL;
2573 ext4_fsblk_t partial_cluster = 0; 2573 ext4_fsblk_t partial_cluster = 0;
2574 handle_t *handle; 2574 handle_t *handle;
2575 int i, err; 2575 int i = 0, err;
2576 2576
2577 ext_debug("truncate since %u to %u\n", start, end); 2577 ext_debug("truncate since %u to %u\n", start, end);
2578 2578
@@ -2605,8 +2605,12 @@ again:
2605 } 2605 }
2606 depth = ext_depth(inode); 2606 depth = ext_depth(inode);
2607 ex = path[depth].p_ext; 2607 ex = path[depth].p_ext;
2608 if (!ex) 2608 if (!ex) {
2609 ext4_ext_drop_refs(path);
2610 kfree(path);
2611 path = NULL;
2609 goto cont; 2612 goto cont;
2613 }
2610 2614
2611 ee_block = le32_to_cpu(ex->ee_block); 2615 ee_block = le32_to_cpu(ex->ee_block);
2612 2616
@@ -2636,8 +2640,6 @@ again:
2636 if (err < 0) 2640 if (err < 0)
2637 goto out; 2641 goto out;
2638 } 2642 }
2639 ext4_ext_drop_refs(path);
2640 kfree(path);
2641 } 2643 }
2642cont: 2644cont:
2643 2645
@@ -2646,19 +2648,27 @@ cont:
2646 * after i_size and walking into the tree depth-wise. 2648 * after i_size and walking into the tree depth-wise.
2647 */ 2649 */
2648 depth = ext_depth(inode); 2650 depth = ext_depth(inode);
2649 path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS); 2651 if (path) {
2650 if (path == NULL) { 2652 int k = i = depth;
2651 ext4_journal_stop(handle); 2653 while (--k > 0)
2652 return -ENOMEM; 2654 path[k].p_block =
2653 } 2655 le16_to_cpu(path[k].p_hdr->eh_entries)+1;
2654 path[0].p_depth = depth; 2656 } else {
2655 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);
2656 2665
2657 if (ext4_ext_check(inode, path[0].p_hdr, depth)) { 2666 if (ext4_ext_check(inode, path[0].p_hdr, depth)) {
2658 err = -EIO; 2667 err = -EIO;
2659 goto out; 2668 goto out;
2669 }
2660 } 2670 }
2661 i = err = 0; 2671 err = 0;
2662 2672
2663 while (i >= 0 && err == 0) { 2673 while (i >= 0 && err == 0) {
2664 if (i == depth) { 2674 if (i == depth) {
@@ -2772,8 +2782,10 @@ cont:
2772out: 2782out:
2773 ext4_ext_drop_refs(path); 2783 ext4_ext_drop_refs(path);
2774 kfree(path); 2784 kfree(path);
2775 if (err == -EAGAIN) 2785 if (err == -EAGAIN) {
2786 path = NULL;
2776 goto again; 2787 goto again;
2788 }
2777 ext4_journal_stop(handle); 2789 ext4_journal_stop(handle);
2778 2790
2779 return err; 2791 return err;