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>
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,
31 struct ext4_map_blocks map;
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
37 credits = ext4_chunk_trans_blocks(inode, len);
39 + * We can only call ext_depth() on extent based inodes
41 + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
42 + depth = ext_depth(inode);
47 while (ret >= 0 && len) {
49 + * Recalculate credits when extent tree depth changes.
51 + if (depth >= 0 && depth != ext_depth(inode)) {
52 + credits = ext4_chunk_trans_blocks(inode, len);
53 + depth = ext_depth(inode);
56 handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
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