diff options
| -rw-r--r-- | fs/btrfs/ioctl.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index b3d249d6eba7..028a4b8c12cd 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -2333,14 +2333,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 2333 | 2333 | ||
| 2334 | if (type == BTRFS_FILE_EXTENT_REG || | 2334 | if (type == BTRFS_FILE_EXTENT_REG || |
| 2335 | type == BTRFS_FILE_EXTENT_PREALLOC) { | 2335 | type == BTRFS_FILE_EXTENT_PREALLOC) { |
| 2336 | /* | ||
| 2337 | * a | --- range to clone ---| b | ||
| 2338 | * | ------------- extent ------------- | | ||
| 2339 | */ | ||
| 2340 | |||
| 2341 | /* substract range b */ | ||
| 2342 | if (key.offset + datal > off + len) | ||
| 2343 | datal = off + len - key.offset; | ||
| 2344 | |||
| 2345 | /* substract range a */ | ||
| 2336 | if (off > key.offset) { | 2346 | if (off > key.offset) { |
| 2337 | datao += off - key.offset; | 2347 | datao += off - key.offset; |
| 2338 | datal -= off - key.offset; | 2348 | datal -= off - key.offset; |
| 2339 | } | 2349 | } |
| 2340 | 2350 | ||
| 2341 | if (key.offset + datal > off + len) | ||
| 2342 | datal = off + len - key.offset; | ||
| 2343 | |||
| 2344 | ret = btrfs_drop_extents(trans, inode, | 2351 | ret = btrfs_drop_extents(trans, inode, |
| 2345 | new_key.offset, | 2352 | new_key.offset, |
| 2346 | new_key.offset + datal, | 2353 | new_key.offset + datal, |
