summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.de>2013-08-06 14:42:48 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:04:57 -0400
commit77fe20dc6291e10c3594124b4505161e701a3cc4 (patch)
tree6edc6e3638d09d7d8dd462528f26f6e78f030610 /fs/btrfs/ioctl.c
parenta4fdb61e81e73991d919ff0396d256e9e67d2475 (diff)
btrfs: abtract out range locking in clone ioctl()
The range locking in btrfs_ioctl_clone is trivially broken out into it's own function. This reduces the complexity of btrfs_ioctl_clone() by a small bit and makes that locking code available to future functions in fs/btrfs/ioctl.c Signed-off-by: Mark Fasheh <mfasheh@suse.de> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 556b3d5b18da..76c7657a7f53 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2470,6 +2470,26 @@ out:
2470 return ret; 2470 return ret;
2471} 2471}
2472 2472
2473static inline void lock_extent_range(struct inode *inode, u64 off, u64 len)
2474{
2475 /* do any pending delalloc/csum calc on src, one way or
2476 another, and lock file content */
2477 while (1) {
2478 struct btrfs_ordered_extent *ordered;
2479 lock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
2480 ordered = btrfs_lookup_first_ordered_extent(inode,
2481 off + len - 1);
2482 if (!ordered &&
2483 !test_range_bit(&BTRFS_I(inode)->io_tree, off,
2484 off + len - 1, EXTENT_DELALLOC, 0, NULL))
2485 break;
2486 unlock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
2487 if (ordered)
2488 btrfs_put_ordered_extent(ordered);
2489 btrfs_wait_ordered_range(inode, off, len);
2490 }
2491}
2492
2473static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, 2493static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2474 u64 off, u64 olen, u64 destoff) 2494 u64 off, u64 olen, u64 destoff)
2475{ 2495{
@@ -2598,21 +2618,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2598 truncate_inode_pages_range(&inode->i_data, destoff, 2618 truncate_inode_pages_range(&inode->i_data, destoff,
2599 PAGE_CACHE_ALIGN(destoff + len) - 1); 2619 PAGE_CACHE_ALIGN(destoff + len) - 1);
2600 2620
2601 /* do any pending delalloc/csum calc on src, one way or 2621 lock_extent_range(src, off, len);
2602 another, and lock file content */
2603 while (1) {
2604 struct btrfs_ordered_extent *ordered;
2605 lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
2606 ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
2607 if (!ordered &&
2608 !test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
2609 EXTENT_DELALLOC, 0, NULL))
2610 break;
2611 unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
2612 if (ordered)
2613 btrfs_put_ordered_extent(ordered);
2614 btrfs_wait_ordered_range(src, off, len);
2615 }
2616 2622
2617 /* clone data */ 2623 /* clone data */
2618 key.objectid = btrfs_ino(src); 2624 key.objectid = btrfs_ino(src);