diff options
| -rw-r--r-- | fs/ext4/extents.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0a7315961bac..c969275ce3ee 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -5329,8 +5329,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, | |||
| 5329 | stop = le32_to_cpu(extent->ee_block); | 5329 | stop = le32_to_cpu(extent->ee_block); |
| 5330 | 5330 | ||
| 5331 | /* | 5331 | /* |
| 5332 | * In case of left shift, Don't start shifting extents until we make | 5332 | * For left shifts, make sure the hole on the left is big enough to |
| 5333 | * sure the hole is big enough to accommodate the shift. | 5333 | * accommodate the shift. For right shifts, make sure the last extent |
| 5334 | * won't be shifted beyond EXT_MAX_BLOCKS. | ||
| 5334 | */ | 5335 | */ |
| 5335 | if (SHIFT == SHIFT_LEFT) { | 5336 | if (SHIFT == SHIFT_LEFT) { |
| 5336 | path = ext4_find_extent(inode, start - 1, &path, | 5337 | path = ext4_find_extent(inode, start - 1, &path, |
| @@ -5350,9 +5351,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, | |||
| 5350 | 5351 | ||
| 5351 | if ((start == ex_start && shift > ex_start) || | 5352 | if ((start == ex_start && shift > ex_start) || |
| 5352 | (shift > start - ex_end)) { | 5353 | (shift > start - ex_end)) { |
| 5353 | ext4_ext_drop_refs(path); | 5354 | ret = -EINVAL; |
| 5354 | kfree(path); | 5355 | goto out; |
| 5355 | return -EINVAL; | 5356 | } |
| 5357 | } else { | ||
| 5358 | if (shift > EXT_MAX_BLOCKS - | ||
| 5359 | (stop + ext4_ext_get_actual_len(extent))) { | ||
| 5360 | ret = -EINVAL; | ||
| 5361 | goto out; | ||
| 5356 | } | 5362 | } |
| 5357 | } | 5363 | } |
| 5358 | 5364 | ||
