diff options
Diffstat (limited to 'fs/ext4/extents.c')
| -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,  	stop = le32_to_cpu(extent->ee_block);         /* -	 * In case of left shift, Don't start shifting extents until we make -	 * sure the hole is big enough to accommodate the shift. +	* For left shifts, make sure the hole on the left is big enough to +	* accommodate the shift.  For right shifts, make sure the last extent +	* won't be shifted beyond EXT_MAX_BLOCKS.  	*/  	if (SHIFT == SHIFT_LEFT) {  		path = ext4_find_extent(inode, start - 1, &path, @@ -5350,9 +5351,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,  		if ((start == ex_start && shift > ex_start) ||  		    (shift > start - ex_end)) { -			ext4_ext_drop_refs(path); -			kfree(path); -			return -EINVAL; +			ret = -EINVAL; +			goto out; +		} +	} else { +		if (shift > EXT_MAX_BLOCKS - +		    (stop + ext4_ext_get_actual_len(extent))) { +			ret = -EINVAL; +			goto out;  		}  	}  |