|
@@ -360,8 +360,10 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
|
|
{
|
|
{
|
|
ext4_fsblk_t block = ext4_ext_pblock(ext);
|
|
ext4_fsblk_t block = ext4_ext_pblock(ext);
|
|
int len = ext4_ext_get_actual_len(ext);
|
|
int len = ext4_ext_get_actual_len(ext);
|
|
|
|
+ ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
|
|
|
|
+ ext4_lblk_t last = lblock + len - 1;
|
|
|
|
|
|
- if (len == 0)
|
|
|
|
|
|
+ if (lblock > last)
|
|
return 0;
|
|
return 0;
|
|
return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
|
|
return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
|
|
}
|
|
}
|
|
@@ -387,11 +389,26 @@ static int ext4_valid_extent_entries(struct inode *inode,
|
|
if (depth == 0) {
|
|
if (depth == 0) {
|
|
/* leaf entries */
|
|
/* leaf entries */
|
|
struct ext4_extent *ext = EXT_FIRST_EXTENT(eh);
|
|
struct ext4_extent *ext = EXT_FIRST_EXTENT(eh);
|
|
|
|
+ struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
|
|
|
|
+ ext4_fsblk_t pblock = 0;
|
|
|
|
+ ext4_lblk_t lblock = 0;
|
|
|
|
+ ext4_lblk_t prev = 0;
|
|
|
|
+ int len = 0;
|
|
while (entries) {
|
|
while (entries) {
|
|
if (!ext4_valid_extent(inode, ext))
|
|
if (!ext4_valid_extent(inode, ext))
|
|
return 0;
|
|
return 0;
|
|
|
|
+
|
|
|
|
+ /* Check for overlapping extents */
|
|
|
|
+ lblock = le32_to_cpu(ext->ee_block);
|
|
|
|
+ len = ext4_ext_get_actual_len(ext);
|
|
|
|
+ if ((lblock <= prev) && prev) {
|
|
|
|
+ pblock = ext4_ext_pblock(ext);
|
|
|
|
+ es->s_last_error_block = cpu_to_le64(pblock);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
ext++;
|
|
ext++;
|
|
entries--;
|
|
entries--;
|
|
|
|
+ prev = lblock + len - 1;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
struct ext4_extent_idx *ext_idx = EXT_FIRST_INDEX(eh);
|
|
struct ext4_extent_idx *ext_idx = EXT_FIRST_INDEX(eh);
|