Commit aa42ffd9 authored by Liu Bo's avatar Liu Bo Committed by Chris Mason

Btrfs: fix off-by-one in file clone

Btrfs uses inclusive range end for lock_extent(), unlock_extent() and
related functions, so we made off-by-one errors in file clone.

This fixes it and also fixes some style problems.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
parent 7e97b8da
...@@ -2481,13 +2481,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -2481,13 +2481,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
another, and lock file content */ another, and lock file content */
while (1) { while (1) {
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
lock_extent(&BTRFS_I(src)->io_tree, off, off+len); lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
ordered = btrfs_lookup_first_ordered_extent(src, off+len); ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
if (!ordered && if (!ordered &&
!test_range_bit(&BTRFS_I(src)->io_tree, off, off+len, !test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
EXTENT_DELALLOC, 0, NULL)) EXTENT_DELALLOC, 0, NULL))
break; break;
unlock_extent(&BTRFS_I(src)->io_tree, off, off+len); unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
if (ordered) if (ordered)
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
btrfs_wait_ordered_range(src, off, len); btrfs_wait_ordered_range(src, off, len);
...@@ -2561,7 +2561,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -2561,7 +2561,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
btrfs_release_path(path); btrfs_release_path(path);
if (key.offset + datal <= off || if (key.offset + datal <= off ||
key.offset >= off+len) key.offset >= off + len - 1)
goto next; goto next;
memcpy(&new_key, &key, sizeof(new_key)); memcpy(&new_key, &key, sizeof(new_key));
...@@ -2662,8 +2662,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -2662,8 +2662,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
new_key.offset += skip; new_key.offset += skip;
} }
if (key.offset + datal > off+len) if (key.offset + datal > off + len)
trim = key.offset + datal - (off+len); trim = key.offset + datal - (off + len);
if (comp && (skip || trim)) { if (comp && (skip || trim)) {
ret = -EINVAL; ret = -EINVAL;
...@@ -2740,7 +2740,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ...@@ -2740,7 +2740,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
ret = 0; ret = 0;
out: out:
btrfs_release_path(path); btrfs_release_path(path);
unlock_extent(&BTRFS_I(src)->io_tree, off, off+len); unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
out_unlock: out_unlock:
mutex_unlock(&src->i_mutex); mutex_unlock(&src->i_mutex);
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment