Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77fe20dc authored by Mark Fasheh's avatar Mark Fasheh Committed by Chris Mason
Browse files

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: default avatarMark Fasheh <mfasheh@suse.de>
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
parent a4fdb61e
Loading
Loading
Loading
Loading
+21 −15
Original line number Diff line number Diff line
@@ -2470,6 +2470,26 @@ static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg)
	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,
				       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,
				   PAGE_CACHE_ALIGN(destoff + len) - 1);

	/* 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(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);
	}
	lock_extent_range(src, off, len);

	/* clone data */
	key.objectid = btrfs_ino(src);