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

ext4: fix hole length detection in ext4_ind_map_blocks()

When ext4_ind_map_blocks() computes a length of a hole, it doesn't count
with the fact that mapped offset may be somewhere in the middle of the
completely empty subtree. In such case it will return too large length
of the hole which then results in lseek(SEEK_DATA) to end up returning
an incorrect offset beyond the end of the hole.

Fix the problem by correctly taking offset within a subtree into account
when computing a length of a hole.

Fixes: facab4d9
CC: stable@vger.kernel.org
Reported-by: NJeff Mahoney <jeffm@suse.com>
Signed-off-by: NJan Kara <jack@suse.cz>
Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
上级 736dedbb
...@@ -561,10 +561,16 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, ...@@ -561,10 +561,16 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
unsigned epb = inode->i_sb->s_blocksize / sizeof(u32); unsigned epb = inode->i_sb->s_blocksize / sizeof(u32);
int i; int i;
/* Count number blocks in a subtree under 'partial' */ /*
count = 1; * Count number blocks in a subtree under 'partial'. At each
for (i = 0; partial + i != chain + depth - 1; i++) * level we count number of complete empty subtrees beyond
count *= epb; * current offset and then descend into the subtree only
* partially beyond current offset.
*/
count = 0;
for (i = partial - chain + 1; i < depth; i++)
count = count * epb + (epb - offsets[i] - 1);
count++;
/* Fill in size of a hole we found */ /* Fill in size of a hole we found */
map->m_pblk = 0; map->m_pblk = 0;
map->m_len = min_t(unsigned int, map->m_len, count); map->m_len = min_t(unsigned int, map->m_len, count);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册