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