Btrfs: fix delalloc checks in clone ioctl
authorSage Weil <sage@newdream.net>
Fri, 29 Oct 2010 19:37:33 +0000 (15:37 -0400)
committerChris Mason <chris.mason@oracle.com>
Fri, 29 Oct 2010 19:37:33 +0000 (15:37 -0400)
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: Yehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ioctl.c

index 60f662c4778b582dfe28360abb7dd75b4f3f5f41..d94bef5179fceac61073ba350d72b0b5165118aa 100644 (file)
@@ -1520,13 +1520,15 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
        while (1) {
                struct btrfs_ordered_extent *ordered;
                lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
-               ordered = btrfs_lookup_first_ordered_extent(inode, off+len);
-               if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered)
+               ordered = btrfs_lookup_first_ordered_extent(src, off+len);
+               if (!ordered &&
+                   !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
+                                  EXTENT_DELALLOC, 0, NULL))
                        break;
                unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
                if (ordered)
                        btrfs_put_ordered_extent(ordered);
-               btrfs_wait_ordered_range(src, off, off+len);
+               btrfs_wait_ordered_range(src, off, len);
        }
 
        /* clone data */