diff options
author | Eryu Guan <guaneryu@gmail.com> | 2013-02-22 15:27:47 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-02-22 15:27:47 -0500 |
commit | d43814721111041e26671a153e300e2054fb36fa (patch) | |
tree | cf9fd202aca4cae83989000219921ac99134f557 | |
parent | 1231b3a1eb5740192aeebf5344dd6d6da000febf (diff) |
ext4: no need to remove extent if len is 0 in ext4_es_remove_extent()
len is 0 means no extent needs to be removed, so return immediately.
Otherwise it could trigger the following BUG_ON() in
ext4_es_remove_extent()
end = lblk + len - 1;
BUG_ON(end < lblk);
This could be reproduced by a simple truncate(1) command by an
unprivileged user
truncate -s $(($((2**32 - 1)) * 4096)) /mnt/ext4/testfile
The same is true for __es_insert_extent().
Patched kernel passed xfstests regression test.
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
-rw-r--r-- | fs/ext4/extents_status.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 9f1380e05474..f768f4a98a2b 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c | |||
@@ -456,6 +456,9 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, | |||
456 | es_debug("add [%u/%u) %llu %llx to extent status tree of inode %lu\n", | 456 | es_debug("add [%u/%u) %llu %llx to extent status tree of inode %lu\n", |
457 | lblk, len, pblk, status, inode->i_ino); | 457 | lblk, len, pblk, status, inode->i_ino); |
458 | 458 | ||
459 | if (!len) | ||
460 | return 0; | ||
461 | |||
459 | BUG_ON(end < lblk); | 462 | BUG_ON(end < lblk); |
460 | 463 | ||
461 | newes.es_lblk = lblk; | 464 | newes.es_lblk = lblk; |
@@ -649,6 +652,9 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, | |||
649 | es_debug("remove [%u/%u) from extent status tree of inode %lu\n", | 652 | es_debug("remove [%u/%u) from extent status tree of inode %lu\n", |
650 | lblk, len, inode->i_ino); | 653 | lblk, len, inode->i_ino); |
651 | 654 | ||
655 | if (!len) | ||
656 | return err; | ||
657 | |||
652 | end = lblk + len - 1; | 658 | end = lblk + len - 1; |
653 | BUG_ON(end < lblk); | 659 | BUG_ON(end < lblk); |
654 | 660 | ||