aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-04-23 08:59:35 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-04-23 08:59:35 -0400
commit0d606e2c9fccdd4e67febf1e2da500e1bfe9e045 (patch)
tree9b908af21c968176149bbbf4016306fa50774055 /fs/ext4/inode.c
parent3f8a6411fbada1fa482276591e037f3b1adcf55b (diff)
ext4: fix type-widening bug in inode table readahead code
Due to a missing cast, the high 32-bits of a 64-bit block number used when calculating the readahead block for inode tables can get lost. This means we can end up fetching the wrong blocks for readahead for file systems > 16TB. Linus found this when experimenting with an enhacement to the sparse static code checker which checks for missing widening casts before binary "not" operators. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d7518e2728f1..793d44b84d7f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4011,13 +4011,14 @@ make_io:
4011 if (EXT4_SB(sb)->s_inode_readahead_blks) { 4011 if (EXT4_SB(sb)->s_inode_readahead_blks) {
4012 ext4_fsblk_t b, end, table; 4012 ext4_fsblk_t b, end, table;
4013 unsigned num; 4013 unsigned num;
4014 __u32 ra_blks = EXT4_SB(sb)->s_inode_readahead_blks;
4014 4015
4015 table = ext4_inode_table(sb, gdp); 4016 table = ext4_inode_table(sb, gdp);
4016 /* s_inode_readahead_blks is always a power of 2 */ 4017 /* s_inode_readahead_blks is always a power of 2 */
4017 b = block & ~(EXT4_SB(sb)->s_inode_readahead_blks-1); 4018 b = block & ~((ext4_fsblk_t) ra_blks - 1);
4018 if (table > b) 4019 if (table > b)
4019 b = table; 4020 b = table;
4020 end = b + EXT4_SB(sb)->s_inode_readahead_blks; 4021 end = b + ra_blks;
4021 num = EXT4_INODES_PER_GROUP(sb); 4022 num = EXT4_INODES_PER_GROUP(sb);
4022 if (ext4_has_group_desc_csum(sb)) 4023 if (ext4_has_group_desc_csum(sb))
4023 num -= ext4_itable_unused_count(sb, gdp); 4024 num -= ext4_itable_unused_count(sb, gdp);