diff options
author | Mark Fasheh <mfasheh@suse.de> | 2013-08-06 14:42:48 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-09-01 08:04:57 -0400 |
commit | 77fe20dc6291e10c3594124b4505161e701a3cc4 (patch) | |
tree | 6edc6e3638d09d7d8dd462528f26f6e78f030610 /fs/btrfs/ioctl.c | |
parent | a4fdb61e81e73991d919ff0396d256e9e67d2475 (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.c | 36 |
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 | ||
2473 | static 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 | |||
2473 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | 2493 | static 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); |