ACK: [PATCH][SRU][TRUSTY] Btrfs: fix a crash of clone with inline extents's split

Colin Ian King colin.king at canonical.com
Wed Jan 21 13:07:57 UTC 2015


On 21/01/15 13:07, Chris J Arges wrote:
> Clean cherry-pick, and in v3.15-rc3~3^2~33.
> Is this going to stable?

I don't see any reason not too.
> 
> Acked-by: Chris J Arges <chris.j.arges at canonical.com>
> 
> On 01/21/2015 04:01 AM, Colin King wrote:
>> From: Liu Bo <bo.li.liu at oracle.com>
>>
>> BugLink: http://bugs.launchpad.net/bugs/1413129
>>
>> xfstests's btrfs/035 triggers a BUG_ON, which we use to detect the split
>> of inline extents in __btrfs_drop_extents().
>>
>> For inline extents, we cannot duplicate another EXTENT_DATA item, because
>> it breaks the rule of inline extents, that is, 'start offset' needs to be 0.
>>
>> We have set limitations for the source inode's compressed inline extents,
>> because it needs to decompress and recompress.  Now the destination inode's
>> inline extents also need similar limitations.
>>
>> With this, xfstests btrfs/035 doesn't run into panic.
>>
>> Signed-off-by: Liu Bo <bo.li.liu at oracle.com>
>> Signed-off-by: Chris Mason <clm at fb.com>
>> (cherry picked from commit 00fdf13a2e9f313a044288aa59d3b8ec29ff904a)
>> Signed-off-by: Colin Ian King <colin.king at canonical.com>
>> ---
>>  fs/btrfs/file.c  |   15 ++++++++++++---
>>  fs/btrfs/ioctl.c |   10 ++++++----
>>  2 files changed, 18 insertions(+), 7 deletions(-)
>>
>> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
>> index 82d0342..3d42eba 100644
>> --- a/fs/btrfs/file.c
>> +++ b/fs/btrfs/file.c
>> @@ -791,7 +791,10 @@ next_slot:
>>  		 */
>>  		if (start > key.offset && end < extent_end) {
>>  			BUG_ON(del_nr > 0);
>> -			BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
>> +			if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
>> +				ret = -EINVAL;
>> +				break;
>> +			}
>>  
>>  			memcpy(&new_key, &key, sizeof(new_key));
>>  			new_key.offset = start;
>> @@ -834,7 +837,10 @@ next_slot:
>>  		 *      | -------- extent -------- |
>>  		 */
>>  		if (start <= key.offset && end < extent_end) {
>> -			BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
>> +			if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
>> +				ret = -EINVAL;
>> +				break;
>> +			}
>>  
>>  			memcpy(&new_key, &key, sizeof(new_key));
>>  			new_key.offset = end;
>> @@ -857,7 +863,10 @@ next_slot:
>>  		 */
>>  		if (start > key.offset && end >= extent_end) {
>>  			BUG_ON(del_nr > 0);
>> -			BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE);
>> +			if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
>> +				ret = -EINVAL;
>> +				break;
>> +			}
>>  
>>  			btrfs_set_file_extent_num_bytes(leaf, fi,
>>  							start - key.offset);
>> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
>> index 043d6cd..f2a5472 100644
>> --- a/fs/btrfs/ioctl.c
>> +++ b/fs/btrfs/ioctl.c
>> @@ -3041,8 +3041,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
>>  							 new_key.offset + datal,
>>  							 1);
>>  				if (ret) {
>> -					btrfs_abort_transaction(trans, root,
>> -								ret);
>> +					if (ret != -EINVAL)
>> +						btrfs_abort_transaction(trans,
>> +								root, ret);
>>  					btrfs_end_transaction(trans, root);
>>  					goto out;
>>  				}
>> @@ -3127,8 +3128,9 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
>>  	 *   decompress into destination's address_space (the file offset
>>  	 *   may change, so source mapping won't do), then recompress (or
>>  	 *   otherwise reinsert) a subrange.
>> -	 * - allow ranges within the same file to be cloned (provided
>> -	 *   they don't overlap)?
>> +	 *
>> +	 * - split destination inode's inline extents.  The inline extents can
>> +	 *   be either compressed or non-compressed.
>>  	 */
>>  
>>  	/* the destination must be opened for writing */
>>
> 





More information about the kernel-team mailing list