add patch recalculate-journal-credits-as-inode-depth-changes
[ext4-patch-queue.git] / recalculate-journal-credits-as-inode-depth-changes
blob76390e30f82c6b101736b5d1ddfb3de0dfff77f0
1 ext4: recalculate journal credits as inode depth changes
3 From: Lukas Czerner <lczerner@redhat.com>
5 Currently in ext4_alloc_file_blocks() the number of credits is
6 calculated only once before we enter the allocation loop. However within
7 the allocation loop the extent tree depth can change, hence the number
8 of credits needed can increase potentially exceeding the number of credits
9 reserved in the handle which can cause journal failures.
11 Fix this by recalculating number of credits when the inode depth
12 changes. Note that even though ext4_alloc_file_blocks() is only
13 currently used by extent base inodes we will avoid recalculating number
14 of credits unnecessarily in the case of indirect based inodes.
16 Signed-off-by: Lukas Czerner <lczerner@redhat.com>
17 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
18 ---
19  fs/ext4/extents.c | 16 ++++++++++++++++
20  1 file changed, 16 insertions(+)
22 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
23 index e003a1e..13c5ebf 100644
24 --- a/fs/ext4/extents.c
25 +++ b/fs/ext4/extents.c
26 @@ -4663,6 +4663,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
27         int ret = 0;
28         int ret2 = 0;
29         int retries = 0;
30 +       int depth = 0;
31         struct ext4_map_blocks map;
32         unsigned int credits;
33         loff_t epos;
34 @@ -4681,9 +4682,24 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
35          * credits to insert 1 extent into extent tree
36          */
37         credits = ext4_chunk_trans_blocks(inode, len);
38 +       /*
39 +        * We can only call ext_depth() on extent based inodes
40 +        */
41 +       if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
42 +               depth = ext_depth(inode);
43 +       else
44 +               depth = -1;
46  retry:
47         while (ret >= 0 && len) {
48 +               /*
49 +                * Recalculate credits when extent tree depth changes.
50 +                */
51 +               if (depth >= 0 && depth != ext_depth(inode)) {
52 +                       credits = ext4_chunk_trans_blocks(inode, len);
53 +                       depth = ext_depth(inode);
54 +               }
56                 handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
57                                             credits);
58                 if (IS_ERR(handle)) {
59 -- 
60 1.8.3.1
63 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
64 the body of a message to majordomo@vger.kernel.org
65 More majordomo info at  http://vger.kernel.org/majordomo-info.html