From 58121bb4f14414abd78d43e50206c7b0e4994c5c Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 15 Jun 2015 00:24:18 -0400 Subject: [PATCH] add patch recalculate-journal-credits-as-inode-depth-changes --- recalculate-journal-credits-as-inode-depth-changes | 66 ++++++++++++++++++++++ series | 1 + timestamps | 7 ++- 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 recalculate-journal-credits-as-inode-depth-changes diff --git a/recalculate-journal-credits-as-inode-depth-changes b/recalculate-journal-credits-as-inode-depth-changes new file mode 100644 index 00000000..76390e30 --- /dev/null +++ b/recalculate-journal-credits-as-inode-depth-changes @@ -0,0 +1,66 @@ +ext4: recalculate journal credits as inode depth changes + +From: Lukas Czerner + +Currently in ext4_alloc_file_blocks() the number of credits is +calculated only once before we enter the allocation loop. However within +the allocation loop the extent tree depth can change, hence the number +of credits needed can increase potentially exceeding the number of credits +reserved in the handle which can cause journal failures. + +Fix this by recalculating number of credits when the inode depth +changes. Note that even though ext4_alloc_file_blocks() is only +currently used by extent base inodes we will avoid recalculating number +of credits unnecessarily in the case of indirect based inodes. + +Signed-off-by: Lukas Czerner +Signed-off-by: Theodore Ts'o +--- + fs/ext4/extents.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index e003a1e..13c5ebf 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4663,6 +4663,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + int ret = 0; + int ret2 = 0; + int retries = 0; ++ int depth = 0; + struct ext4_map_blocks map; + unsigned int credits; + loff_t epos; +@@ -4681,9 +4682,24 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + * credits to insert 1 extent into extent tree + */ + credits = ext4_chunk_trans_blocks(inode, len); ++ /* ++ * We can only call ext_depth() on extent based inodes ++ */ ++ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) ++ depth = ext_depth(inode); ++ else ++ depth = -1; + + retry: + while (ret >= 0 && len) { ++ /* ++ * Recalculate credits when extent tree depth changes. ++ */ ++ if (depth >= 0 && depth != ext_depth(inode)) { ++ credits = ext4_chunk_trans_blocks(inode, len); ++ depth = ext_depth(inode); ++ } ++ + handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, + credits); + if (IS_ERR(handle)) { +-- +1.8.3.1 + +-- +To unsubscribe from this list: send the line "unsubscribe linux-ext4" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html + diff --git a/series b/series index fce0cc96..3a925b5f 100644 --- a/series +++ b/series @@ -48,6 +48,7 @@ fix-race-between-truncate-and-ext4_journalled_writepage use-swap-in-memswap use-swap-in-mext_page_double_lock use_GFP_NOFS_in_jbd2_cleanup_journal_tail +recalculate-journal-credits-as-inode-depth-changes ########################################## # unstable patches diff --git a/timestamps b/timestamps index d72db15b..2e5f927b 100755 --- a/timestamps +++ b/timestamps @@ -63,7 +63,8 @@ touch -d @1434332622 add-blkdiscard-ioctl touch -d @1434332682 block-dio-during-truncate touch -d @1434335672 use-swap-in-memswap touch -d @1434341049 use-swap-in-mext_page_double_lock -touch -d @1434341862 series -touch -d @1434341882 status touch -d @1434341882 use_GFP_NOFS_in_jbd2_cleanup_journal_tail -touch -d @1434341887 timestamps +touch -d @1434342046 recalculate-journal-credits-as-inode-depth-changes +touch -d @1434342154 series +touch -d @1434342158 status +touch -d @1434342251 timestamps -- 2.11.4.GIT