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>
This commit is contained in:
parent
a4fdb61e81
commit
77fe20dc62
@ -2470,6 +2470,26 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void lock_extent_range(struct inode *inode, u64 off, u64 len)
|
||||||
|
{
|
||||||
|
/* do any pending delalloc/csum calc on src, one way or
|
||||||
|
another, and lock file content */
|
||||||
|
while (1) {
|
||||||
|
struct btrfs_ordered_extent *ordered;
|
||||||
|
lock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
|
||||||
|
ordered = btrfs_lookup_first_ordered_extent(inode,
|
||||||
|
off + len - 1);
|
||||||
|
if (!ordered &&
|
||||||
|
!test_range_bit(&BTRFS_I(inode)->io_tree, off,
|
||||||
|
off + len - 1, EXTENT_DELALLOC, 0, NULL))
|
||||||
|
break;
|
||||||
|
unlock_extent(&BTRFS_I(inode)->io_tree, off, off + len - 1);
|
||||||
|
if (ordered)
|
||||||
|
btrfs_put_ordered_extent(ordered);
|
||||||
|
btrfs_wait_ordered_range(inode, off, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||||
u64 off, u64 olen, u64 destoff)
|
u64 off, u64 olen, u64 destoff)
|
||||||
{
|
{
|
||||||
@ -2598,21 +2618,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
|||||||
truncate_inode_pages_range(&inode->i_data, destoff,
|
truncate_inode_pages_range(&inode->i_data, destoff,
|
||||||
PAGE_CACHE_ALIGN(destoff + len) - 1);
|
PAGE_CACHE_ALIGN(destoff + len) - 1);
|
||||||
|
|
||||||
/* do any pending delalloc/csum calc on src, one way or
|
lock_extent_range(src, off, len);
|
||||||
another, and lock file content */
|
|
||||||
while (1) {
|
|
||||||
struct btrfs_ordered_extent *ordered;
|
|
||||||
lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
|
|
||||||
ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
|
|
||||||
if (!ordered &&
|
|
||||||
!test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
|
|
||||||
EXTENT_DELALLOC, 0, NULL))
|
|
||||||
break;
|
|
||||||
unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
|
|
||||||
if (ordered)
|
|
||||||
btrfs_put_ordered_extent(ordered);
|
|
||||||
btrfs_wait_ordered_range(src, off, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clone data */
|
/* clone data */
|
||||||
key.objectid = btrfs_ino(src);
|
key.objectid = btrfs_ino(src);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user