aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2015-10-21 21:23:59 -0400
committerChris Mason <clm@fb.com>2015-10-21 21:23:59 -0400
commita408365c62762c30419018587cffd2b89836434e (patch)
tree4b2ddabcf60970141fa9758153493b2b1d95acfe
parenta0d58e48db58801a0e764e9b9c87e1782d390fcb (diff)
parent0305cd5f7fca85dae392b9ba85b116896eb7c1c7 (diff)
Merge branch 'integration-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.4
-rw-r--r--fs/btrfs/extent_io.c8
-rw-r--r--fs/btrfs/inode.c82
-rw-r--r--fs/btrfs/ioctl.c195
-rw-r--r--fs/btrfs/send.c210
4 files changed, 407 insertions, 88 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index ecb1204468c3..6e6df34d74f0 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3070,8 +3070,12 @@ static int __do_readpage(struct extent_io_tree *tree,
3070 3070
3071 set_extent_uptodate(tree, cur, cur + iosize - 1, 3071 set_extent_uptodate(tree, cur, cur + iosize - 1,
3072 &cached, GFP_NOFS); 3072 &cached, GFP_NOFS);
3073 unlock_extent_cached(tree, cur, cur + iosize - 1, 3073 if (parent_locked)
3074 &cached, GFP_NOFS); 3074 free_extent_state(cached);
3075 else
3076 unlock_extent_cached(tree, cur,
3077 cur + iosize - 1,
3078 &cached, GFP_NOFS);
3075 cur = cur + iosize; 3079 cur = cur + iosize;
3076 pg_offset += iosize; 3080 pg_offset += iosize;
3077 continue; 3081 continue;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8161afc32fa0..5ce55f6eefce 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4216,6 +4216,47 @@ static int truncate_space_check(struct btrfs_trans_handle *trans,
4216 4216
4217} 4217}
4218 4218
4219static int truncate_inline_extent(struct inode *inode,
4220 struct btrfs_path *path,
4221 struct btrfs_key *found_key,
4222 const u64 item_end,
4223 const u64 new_size)
4224{
4225 struct extent_buffer *leaf = path->nodes[0];
4226 int slot = path->slots[0];
4227 struct btrfs_file_extent_item *fi;
4228 u32 size = (u32)(new_size - found_key->offset);
4229 struct btrfs_root *root = BTRFS_I(inode)->root;
4230
4231 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
4232
4233 if (btrfs_file_extent_compression(leaf, fi) != BTRFS_COMPRESS_NONE) {
4234 loff_t offset = new_size;
4235 loff_t page_end = ALIGN(offset, PAGE_CACHE_SIZE);
4236
4237 /*
4238 * Zero out the remaining of the last page of our inline extent,
4239 * instead of directly truncating our inline extent here - that
4240 * would be much more complex (decompressing all the data, then
4241 * compressing the truncated data, which might be bigger than
4242 * the size of the inline extent, resize the extent, etc).
4243 * We release the path because to get the page we might need to
4244 * read the extent item from disk (data not in the page cache).
4245 */
4246 btrfs_release_path(path);
4247 return btrfs_truncate_page(inode, offset, page_end - offset, 0);
4248 }
4249
4250 btrfs_set_file_extent_ram_bytes(leaf, fi, size);
4251 size = btrfs_file_extent_calc_inline_size(size);
4252 btrfs_truncate_item(root, path, size, 1);
4253
4254 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
4255 inode_sub_bytes(inode, item_end + 1 - new_size);
4256
4257 return 0;
4258}
4259
4219/* 4260/*
4220 * this can truncate away extent items, csum items and directory items. 4261 * this can truncate away extent items, csum items and directory items.
4221 * It starts at a high offset and removes keys until it can't find 4262 * It starts at a high offset and removes keys until it can't find
@@ -4410,27 +4451,40 @@ search_again:
4410 * special encodings 4451 * special encodings
4411 */ 4452 */
4412 if (!del_item && 4453 if (!del_item &&
4413 btrfs_file_extent_compression(leaf, fi) == 0 &&
4414 btrfs_file_extent_encryption(leaf, fi) == 0 && 4454 btrfs_file_extent_encryption(leaf, fi) == 0 &&
4415 btrfs_file_extent_other_encoding(leaf, fi) == 0) { 4455 btrfs_file_extent_other_encoding(leaf, fi) == 0) {
4416 u32 size = new_size - found_key.offset;
4417
4418 if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
4419 inode_sub_bytes(inode, item_end + 1 -
4420 new_size);
4421 4456
4422 /* 4457 /*
4423 * update the ram bytes to properly reflect 4458 * Need to release path in order to truncate a
4424 * the new size of our item 4459 * compressed extent. So delete any accumulated
4460 * extent items so far.
4425 */ 4461 */
4426 btrfs_set_file_extent_ram_bytes(leaf, fi, size); 4462 if (btrfs_file_extent_compression(leaf, fi) !=
4427 size = 4463 BTRFS_COMPRESS_NONE && pending_del_nr) {
4428 btrfs_file_extent_calc_inline_size(size); 4464 err = btrfs_del_items(trans, root, path,
4429 btrfs_truncate_item(root, path, size, 1); 4465 pending_del_slot,
4466 pending_del_nr);
4467 if (err) {
4468 btrfs_abort_transaction(trans,
4469 root,
4470 err);
4471 goto error;
4472 }
4473 pending_del_nr = 0;
4474 }
4475
4476 err = truncate_inline_extent(inode, path,
4477 &found_key,
4478 item_end,
4479 new_size);
4480 if (err) {
4481 btrfs_abort_transaction(trans,
4482 root, err);
4483 goto error;
4484 }
4430 } else if (test_bit(BTRFS_ROOT_REF_COWS, 4485 } else if (test_bit(BTRFS_ROOT_REF_COWS,
4431 &root->state)) { 4486 &root->state)) {
4432 inode_sub_bytes(inode, item_end + 1 - 4487 inode_sub_bytes(inode, item_end + 1 - new_size);
4433 found_key.offset);
4434 } 4488 }
4435 } 4489 }
4436delete: 4490delete:
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a30d32b901da..685df7e1b24e 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3327,6 +3327,150 @@ static void clone_update_extent_map(struct inode *inode,
3327 &BTRFS_I(inode)->runtime_flags); 3327 &BTRFS_I(inode)->runtime_flags);
3328} 3328}
3329 3329
3330/*
3331 * Make sure we do not end up inserting an inline extent into a file that has
3332 * already other (non-inline) extents. If a file has an inline extent it can
3333 * not have any other extents and the (single) inline extent must start at the
3334 * file offset 0. Failing to respect these rules will lead to file corruption,
3335 * resulting in EIO errors on read/write operations, hitting BUG_ON's in mm, etc
3336 *
3337 * We can have extents that have been already written to disk or we can have
3338 * dirty ranges still in delalloc, in which case the extent maps and items are
3339 * created only when we run delalloc, and the delalloc ranges might fall outside
3340 * the range we are currently locking in the inode's io tree. So we check the
3341 * inode's i_size because of that (i_size updates are done while holding the
3342 * i_mutex, which we are holding here).
3343 * We also check to see if the inode has a size not greater than "datal" but has
3344 * extents beyond it, due to an fallocate with FALLOC_FL_KEEP_SIZE (and we are
3345 * protected against such concurrent fallocate calls by the i_mutex).
3346 *
3347 * If the file has no extents but a size greater than datal, do not allow the
3348 * copy because we would need turn the inline extent into a non-inline one (even
3349 * with NO_HOLES enabled). If we find our destination inode only has one inline
3350 * extent, just overwrite it with the source inline extent if its size is less
3351 * than the source extent's size, or we could copy the source inline extent's
3352 * data into the destination inode's inline extent if the later is greater then
3353 * the former.
3354 */
3355static int clone_copy_inline_extent(struct inode *src,
3356 struct inode *dst,
3357 struct btrfs_trans_handle *trans,
3358 struct btrfs_path *path,
3359 struct btrfs_key *new_key,
3360 const u64 drop_start,
3361 const u64 datal,
3362 const u64 skip,
3363 const u64 size,
3364 char *inline_data)
3365{
3366 struct btrfs_root *root = BTRFS_I(dst)->root;
3367 const u64 aligned_end = ALIGN(new_key->offset + datal,
3368 root->sectorsize);
3369 int ret;
3370 struct btrfs_key key;
3371
3372 if (new_key->offset > 0)
3373 return -EOPNOTSUPP;
3374
3375 key.objectid = btrfs_ino(dst);
3376 key.type = BTRFS_EXTENT_DATA_KEY;
3377 key.offset = 0;
3378 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
3379 if (ret < 0) {
3380 return ret;
3381 } else if (ret > 0) {
3382 if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
3383 ret = btrfs_next_leaf(root, path);
3384 if (ret < 0)
3385 return ret;
3386 else if (ret > 0)
3387 goto copy_inline_extent;
3388 }
3389 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
3390 if (key.objectid == btrfs_ino(dst) &&
3391 key.type == BTRFS_EXTENT_DATA_KEY) {
3392 ASSERT(key.offset > 0);
3393 return -EOPNOTSUPP;
3394 }
3395 } else if (i_size_read(dst) <= datal) {
3396 struct btrfs_file_extent_item *ei;
3397 u64 ext_len;
3398
3399 /*
3400 * If the file size is <= datal, make sure there are no other
3401 * extents following (can happen do to an fallocate call with
3402 * the flag FALLOC_FL_KEEP_SIZE).
3403 */
3404 ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
3405 struct btrfs_file_extent_item);
3406 /*
3407 * If it's an inline extent, it can not have other extents
3408 * following it.
3409 */
3410 if (btrfs_file_extent_type(path->nodes[0], ei) ==
3411 BTRFS_FILE_EXTENT_INLINE)
3412 goto copy_inline_extent;
3413
3414 ext_len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
3415 if (ext_len > aligned_end)
3416 return -EOPNOTSUPP;
3417
3418 ret = btrfs_next_item(root, path);
3419 if (ret < 0) {
3420 return ret;
3421 } else if (ret == 0) {
3422 btrfs_item_key_to_cpu(path->nodes[0], &key,
3423 path->slots[0]);
3424 if (key.objectid == btrfs_ino(dst) &&
3425 key.type == BTRFS_EXTENT_DATA_KEY)
3426 return -EOPNOTSUPP;
3427 }
3428 }
3429
3430copy_inline_extent:
3431 /*
3432 * We have no extent items, or we have an extent at offset 0 which may
3433 * or may not be inlined. All these cases are dealt the same way.
3434 */
3435 if (i_size_read(dst) > datal) {
3436 /*
3437 * If the destination inode has an inline extent...
3438 * This would require copying the data from the source inline
3439 * extent into the beginning of the destination's inline extent.
3440 * But this is really complex, both extents can be compressed
3441 * or just one of them, which would require decompressing and
3442 * re-compressing data (which could increase the new compressed
3443 * size, not allowing the compressed data to fit anymore in an
3444 * inline extent).
3445 * So just don't support this case for now (it should be rare,
3446 * we are not really saving space when cloning inline extents).
3447 */
3448 return -EOPNOTSUPP;
3449 }
3450
3451 btrfs_release_path(path);
3452 ret = btrfs_drop_extents(trans, root, dst, drop_start, aligned_end, 1);
3453 if (ret)
3454 return ret;
3455 ret = btrfs_insert_empty_item(trans, root, path, new_key, size);
3456 if (ret)
3457 return ret;
3458
3459 if (skip) {
3460 const u32 start = btrfs_file_extent_calc_inline_size(0);
3461
3462 memmove(inline_data + start, inline_data + start + skip, datal);
3463 }
3464
3465 write_extent_buffer(path->nodes[0], inline_data,
3466 btrfs_item_ptr_offset(path->nodes[0],
3467 path->slots[0]),
3468 size);
3469 inode_add_bytes(dst, datal);
3470
3471 return 0;
3472}
3473
3330/** 3474/**
3331 * btrfs_clone() - clone a range from inode file to another 3475 * btrfs_clone() - clone a range from inode file to another
3332 * 3476 *
@@ -3593,21 +3737,6 @@ process_slot:
3593 } else if (type == BTRFS_FILE_EXTENT_INLINE) { 3737 } else if (type == BTRFS_FILE_EXTENT_INLINE) {
3594 u64 skip = 0; 3738 u64 skip = 0;
3595 u64 trim = 0; 3739 u64 trim = 0;
3596 u64 aligned_end = 0;
3597
3598 /*
3599 * Don't copy an inline extent into an offset
3600 * greater than zero. Having an inline extent
3601 * at such an offset results in chaos as btrfs
3602 * isn't prepared for such cases. Just skip
3603 * this case for the same reasons as commented
3604 * at btrfs_ioctl_clone().
3605 */
3606 if (last_dest_end > 0) {
3607 ret = -EOPNOTSUPP;
3608 btrfs_end_transaction(trans, root);
3609 goto out;
3610 }
3611 3740
3612 if (off > key.offset) { 3741 if (off > key.offset) {
3613 skip = off - key.offset; 3742 skip = off - key.offset;
@@ -3625,42 +3754,22 @@ process_slot:
3625 size -= skip + trim; 3754 size -= skip + trim;
3626 datal -= skip + trim; 3755 datal -= skip + trim;
3627 3756
3628 aligned_end = ALIGN(new_key.offset + datal, 3757 ret = clone_copy_inline_extent(src, inode,
3629 root->sectorsize); 3758 trans, path,
3630 ret = btrfs_drop_extents(trans, root, inode, 3759 &new_key,
3631 drop_start, 3760 drop_start,
3632 aligned_end, 3761 datal,
3633 1); 3762 skip, size, buf);
3634 if (ret) { 3763 if (ret) {
3635 if (ret != -EOPNOTSUPP) 3764 if (ret != -EOPNOTSUPP)
3636 btrfs_abort_transaction(trans, 3765 btrfs_abort_transaction(trans,
3637 root, ret); 3766 root,
3638 btrfs_end_transaction(trans, root); 3767 ret);
3639 goto out;
3640 }
3641
3642 ret = btrfs_insert_empty_item(trans, root, path,
3643 &new_key, size);
3644 if (ret) {
3645 btrfs_abort_transaction(trans, root,
3646 ret);
3647 btrfs_end_transaction(trans, root); 3768 btrfs_end_transaction(trans, root);
3648 goto out; 3769 goto out;
3649 } 3770 }
3650
3651 if (skip) {
3652 u32 start =
3653 btrfs_file_extent_calc_inline_size(0);
3654 memmove(buf+start, buf+start+skip,
3655 datal);
3656 }
3657
3658 leaf = path->nodes[0]; 3771 leaf = path->nodes[0];
3659 slot = path->slots[0]; 3772 slot = path->slots[0];
3660 write_extent_buffer(leaf, buf,
3661 btrfs_item_ptr_offset(leaf, slot),
3662 size);
3663 inode_add_bytes(inode, datal);
3664 } 3773 }
3665 3774
3666 /* If we have an implicit hole (NO_HOLES feature). */ 3775 /* If we have an implicit hole (NO_HOLES feature). */
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index b5d47b9400ba..355a458cba1a 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1434,16 +1434,6 @@ verbose_printk(KERN_DEBUG "btrfs: find_extent_clone: data_offset=%llu, "
1434 } 1434 }
1435 1435
1436 if (cur_clone_root) { 1436 if (cur_clone_root) {
1437 if (compressed != BTRFS_COMPRESS_NONE) {
1438 /*
1439 * Offsets given by iterate_extent_inodes() are relative
1440 * to the start of the extent, we need to add logical
1441 * offset from the file extent item.
1442 * (See why at backref.c:check_extent_in_eb())
1443 */
1444 cur_clone_root->offset += btrfs_file_extent_offset(eb,
1445 fi);
1446 }
1447 *found = cur_clone_root; 1437 *found = cur_clone_root;
1448 ret = 0; 1438 ret = 0;
1449 } else { 1439 } else {
@@ -2353,8 +2343,14 @@ static int send_subvol_begin(struct send_ctx *sctx)
2353 } 2343 }
2354 2344
2355 TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen); 2345 TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen);
2356 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID, 2346
2357 sctx->send_root->root_item.uuid); 2347 if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid))
2348 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
2349 sctx->send_root->root_item.received_uuid);
2350 else
2351 TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
2352 sctx->send_root->root_item.uuid);
2353
2358 TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID, 2354 TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID,
2359 le64_to_cpu(sctx->send_root->root_item.ctransid)); 2355 le64_to_cpu(sctx->send_root->root_item.ctransid));
2360 if (parent_root) { 2356 if (parent_root) {
@@ -4687,6 +4683,171 @@ tlv_put_failure:
4687 return ret; 4683 return ret;
4688} 4684}
4689 4685
4686static int send_extent_data(struct send_ctx *sctx,
4687 const u64 offset,
4688 const u64 len)
4689{
4690 u64 sent = 0;
4691
4692 if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
4693 return send_update_extent(sctx, offset, len);
4694
4695 while (sent < len) {
4696 u64 size = len - sent;
4697 int ret;
4698
4699 if (size > BTRFS_SEND_READ_SIZE)
4700 size = BTRFS_SEND_READ_SIZE;
4701 ret = send_write(sctx, offset + sent, size);
4702 if (ret < 0)
4703 return ret;
4704 if (!ret)
4705 break;
4706 sent += ret;
4707 }
4708 return 0;
4709}
4710
4711static int clone_range(struct send_ctx *sctx,
4712 struct clone_root *clone_root,
4713 const u64 disk_byte,
4714 u64 data_offset,
4715 u64 offset,
4716 u64 len)
4717{
4718 struct btrfs_path *path;
4719 struct btrfs_key key;
4720 int ret;
4721
4722 path = alloc_path_for_send();
4723 if (!path)
4724 return -ENOMEM;
4725
4726 /*
4727 * We can't send a clone operation for the entire range if we find
4728 * extent items in the respective range in the source file that
4729 * refer to different extents or if we find holes.
4730 * So check for that and do a mix of clone and regular write/copy
4731 * operations if needed.
4732 *
4733 * Example:
4734 *
4735 * mkfs.btrfs -f /dev/sda
4736 * mount /dev/sda /mnt
4737 * xfs_io -f -c "pwrite -S 0xaa 0K 100K" /mnt/foo
4738 * cp --reflink=always /mnt/foo /mnt/bar
4739 * xfs_io -c "pwrite -S 0xbb 50K 50K" /mnt/foo
4740 * btrfs subvolume snapshot -r /mnt /mnt/snap
4741 *
4742 * If when we send the snapshot and we are processing file bar (which
4743 * has a higher inode number than foo) we blindly send a clone operation
4744 * for the [0, 100K[ range from foo to bar, the receiver ends up getting
4745 * a file bar that matches the content of file foo - iow, doesn't match
4746 * the content from bar in the original filesystem.
4747 */
4748 key.objectid = clone_root->ino;
4749 key.type = BTRFS_EXTENT_DATA_KEY;
4750 key.offset = clone_root->offset;
4751 ret = btrfs_search_slot(NULL, clone_root->root, &key, path, 0, 0);
4752 if (ret < 0)
4753 goto out;
4754 if (ret > 0 && path->slots[0] > 0) {
4755 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0] - 1);
4756 if (key.objectid == clone_root->ino &&
4757 key.type == BTRFS_EXTENT_DATA_KEY)
4758 path->slots[0]--;
4759 }
4760
4761 while (true) {
4762 struct extent_buffer *leaf = path->nodes[0];
4763 int slot = path->slots[0];
4764 struct btrfs_file_extent_item *ei;
4765 u8 type;
4766 u64 ext_len;
4767 u64 clone_len;
4768
4769 if (slot >= btrfs_header_nritems(leaf)) {
4770 ret = btrfs_next_leaf(clone_root->root, path);
4771 if (ret < 0)
4772 goto out;
4773 else if (ret > 0)
4774 break;
4775 continue;
4776 }
4777
4778 btrfs_item_key_to_cpu(leaf, &key, slot);
4779
4780 /*
4781 * We might have an implicit trailing hole (NO_HOLES feature
4782 * enabled). We deal with it after leaving this loop.
4783 */
4784 if (key.objectid != clone_root->ino ||
4785 key.type != BTRFS_EXTENT_DATA_KEY)
4786 break;
4787
4788 ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
4789 type = btrfs_file_extent_type(leaf, ei);
4790 if (type == BTRFS_FILE_EXTENT_INLINE) {
4791 ext_len = btrfs_file_extent_inline_len(leaf, slot, ei);
4792 ext_len = PAGE_CACHE_ALIGN(ext_len);
4793 } else {
4794 ext_len = btrfs_file_extent_num_bytes(leaf, ei);
4795 }
4796
4797 if (key.offset + ext_len <= clone_root->offset)
4798 goto next;
4799
4800 if (key.offset > clone_root->offset) {
4801 /* Implicit hole, NO_HOLES feature enabled. */
4802 u64 hole_len = key.offset - clone_root->offset;
4803
4804 if (hole_len > len)
4805 hole_len = len;
4806 ret = send_extent_data(sctx, offset, hole_len);
4807 if (ret < 0)
4808 goto out;
4809
4810 len -= hole_len;
4811 if (len == 0)
4812 break;
4813 offset += hole_len;
4814 clone_root->offset += hole_len;
4815 data_offset += hole_len;
4816 }
4817
4818 if (key.offset >= clone_root->offset + len)
4819 break;
4820
4821 clone_len = min_t(u64, ext_len, len);
4822
4823 if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte &&
4824 btrfs_file_extent_offset(leaf, ei) == data_offset)
4825 ret = send_clone(sctx, offset, clone_len, clone_root);
4826 else
4827 ret = send_extent_data(sctx, offset, clone_len);
4828
4829 if (ret < 0)
4830 goto out;
4831
4832 len -= clone_len;
4833 if (len == 0)
4834 break;
4835 offset += clone_len;
4836 clone_root->offset += clone_len;
4837 data_offset += clone_len;
4838next:
4839 path->slots[0]++;
4840 }
4841
4842 if (len > 0)
4843 ret = send_extent_data(sctx, offset, len);
4844 else
4845 ret = 0;
4846out:
4847 btrfs_free_path(path);
4848 return ret;
4849}
4850
4690static int send_write_or_clone(struct send_ctx *sctx, 4851static int send_write_or_clone(struct send_ctx *sctx,
4691 struct btrfs_path *path, 4852 struct btrfs_path *path,
4692 struct btrfs_key *key, 4853 struct btrfs_key *key,
@@ -4695,9 +4856,7 @@ static int send_write_or_clone(struct send_ctx *sctx,
4695 int ret = 0; 4856 int ret = 0;
4696 struct btrfs_file_extent_item *ei; 4857 struct btrfs_file_extent_item *ei;
4697 u64 offset = key->offset; 4858 u64 offset = key->offset;
4698 u64 pos = 0;
4699 u64 len; 4859 u64 len;
4700 u32 l;
4701 u8 type; 4860 u8 type;
4702 u64 bs = sctx->send_root->fs_info->sb->s_blocksize; 4861 u64 bs = sctx->send_root->fs_info->sb->s_blocksize;
4703 4862
@@ -4725,22 +4884,15 @@ static int send_write_or_clone(struct send_ctx *sctx,
4725 } 4884 }
4726 4885
4727 if (clone_root && IS_ALIGNED(offset + len, bs)) { 4886 if (clone_root && IS_ALIGNED(offset + len, bs)) {
4728 ret = send_clone(sctx, offset, len, clone_root); 4887 u64 disk_byte;
4729 } else if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA) { 4888 u64 data_offset;
4730 ret = send_update_extent(sctx, offset, len); 4889
4890 disk_byte = btrfs_file_extent_disk_bytenr(path->nodes[0], ei);
4891 data_offset = btrfs_file_extent_offset(path->nodes[0], ei);
4892 ret = clone_range(sctx, clone_root, disk_byte, data_offset,
4893 offset, len);
4731 } else { 4894 } else {
4732 while (pos < len) { 4895 ret = send_extent_data(sctx, offset, len);
4733 l = len - pos;
4734 if (l > BTRFS_SEND_READ_SIZE)
4735 l = BTRFS_SEND_READ_SIZE;
4736 ret = send_write(sctx, pos + offset, l);
4737 if (ret < 0)
4738 goto out;
4739 if (!ret)
4740 break;
4741 pos += ret;
4742 }
4743 ret = 0;
4744 } 4896 }
4745out: 4897out:
4746 return ret; 4898 return ret;