提交 a93cd4cf 编写于 作者: J Jan Kara 提交者: Theodore Ts'o

ext4: Fix hole punching for files with indirect blocks

Hole punching code for files with indirect blocks wrongly computed
number of blocks which need to be cleared when traversing the indirect
block tree. That could result in punching more blocks than actually
requested and thus effectively cause a data loss. For example:

fallocate -n -p 10240000 4096

will punch the range 10240000 - 12632064 instead of the range 1024000 -
10244096. Fix the calculation.

CC: stable@vger.kernel.org
Fixes: 8bad6fc8Signed-off-by: NJan Kara <jack@suse.cz>
Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
上级 77ea2a4b
...@@ -1316,16 +1316,24 @@ static int free_hole_blocks(handle_t *handle, struct inode *inode, ...@@ -1316,16 +1316,24 @@ static int free_hole_blocks(handle_t *handle, struct inode *inode,
blk = *i_data; blk = *i_data;
if (level > 0) { if (level > 0) {
ext4_lblk_t first2; ext4_lblk_t first2;
ext4_lblk_t count2;
bh = sb_bread(inode->i_sb, le32_to_cpu(blk)); bh = sb_bread(inode->i_sb, le32_to_cpu(blk));
if (!bh) { if (!bh) {
EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk), EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk),
"Read failure"); "Read failure");
return -EIO; return -EIO;
} }
first2 = (first > offset) ? first - offset : 0; if (first > offset) {
first2 = first - offset;
count2 = count;
} else {
first2 = 0;
count2 = count - (offset - first);
}
ret = free_hole_blocks(handle, inode, bh, ret = free_hole_blocks(handle, inode, bh,
(__le32 *)bh->b_data, level - 1, (__le32 *)bh->b_data, level - 1,
first2, count - offset, first2, count2,
inode->i_sb->s_blocksize >> 2); inode->i_sb->s_blocksize >> 2);
if (ret) { if (ret) {
brelse(bh); brelse(bh);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册