Commit 9a019196 authored by Sage Weil's avatar Sage Weil Committed by Chris Mason

Btrfs: fix delalloc checks in clone ioctl

The lookup_first_ordered_extent() was done on the wrong inode, and the
->delalloc_bytes test was wrong, as the following
btrfs_wait_ordered_range() would only invoke a range write and wouldn't
write the entire file data range. Also, a bad parameter was passed to
btrfs_wait_ordered_range().
Signed-off-by: default avatarYehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent d8e39c45
...@@ -1520,13 +1520,15 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -1520,13 +1520,15 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
while (1) { while (1) {
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
ordered = btrfs_lookup_first_ordered_extent(inode, off+len); ordered = btrfs_lookup_first_ordered_extent(src, off+len);
if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered) if (!ordered &&
!test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
EXTENT_DELALLOC, 0, NULL))
break; break;
unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
if (ordered) if (ordered)
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
btrfs_wait_ordered_range(src, off, off+len); btrfs_wait_ordered_range(src, off, len);
} }
/* clone data */ /* clone data */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment