summaryrefslogtreecommitdiff
path: root/fs/ext2
diff options
context:
space:
mode:
authorZhang Yi <yi.zhang@huawei.com>2022-02-12 08:05:32 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-08 15:40:18 +0300
commit9ffa07c699a72fc351620ee3cf6797d1a8abe37f (patch)
treecd662db7882c32541fe6e952b87201f729d653b1 /fs/ext2
parent60605acf5bf857a93938ae5174be9836874b4608 (diff)
downloadlinux-9ffa07c699a72fc351620ee3cf6797d1a8abe37f.tar.xz
ext2: correct max file size computing
[ Upstream commit 50b3a818991074177a56c87124c7a7bdf5fa4f67 ] We need to calculate the max file size accurately if the total blocks that can address by block tree exceed the upper_limit. But this check is not correct now, it only compute the total data blocks but missing metadata blocks are needed. So in the case of "data blocks < upper_limit && total blocks > upper_limit", we will get wrong result. Fortunately, this case could not happen in reality, but it's confused and better to correct the computing. bits data blocks metadatablocks upper_limit 10 16843020 66051 2147483647 11 134480396 263171 1073741823 12 1074791436 1050627 536870911 (*) 13 8594130956 4198403 268435455 (*) 14 68736258060 16785411 134217727 (*) 15 549822930956 67125251 67108863 (*) 16 4398314962956 268468227 33554431 (*) [*] Need to calculate in depth. Fixes: 1c2d14212b15 ("ext2: Fix underflow in ext2_max_size()") Link: https://lore.kernel.org/r/20220212050532.179055-1-yi.zhang@huawei.com Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/super.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 09f1fe676972..b6314d3c6a87 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -756,8 +756,12 @@ static loff_t ext2_max_size(int bits)
res += 1LL << (bits-2);
res += 1LL << (2*(bits-2));
res += 1LL << (3*(bits-2));
+ /* Compute how many metadata blocks are needed */
+ meta_blocks = 1;
+ meta_blocks += 1 + ppb;
+ meta_blocks += 1 + ppb + ppb * ppb;
/* Does block tree limit file size? */
- if (res < upper_limit)
+ if (res + meta_blocks <= upper_limit)
goto check_lfs;
res = upper_limit;