diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2011-01-26 14:10:43 +0800 |
---|---|---|
committer | Li Zefan <lizf@cn.fujitsu.com> | 2011-01-27 01:11:18 +0800 |
commit | 4d728ec7aefdca5419d2ebfb28c147e81a4b59f4 (patch) | |
tree | 19dc56836d053c04d796ddca126dd60232175bb0 | |
parent | b897abec032deb7cc3ce67392a1f544ac965ddea (diff) | |
download | blackbird-op-linux-4d728ec7aefdca5419d2ebfb28c147e81a4b59f4.tar.gz blackbird-op-linux-4d728ec7aefdca5419d2ebfb28c147e81a4b59f4.zip |
Btrfs: Fix file clone when source offset is not 0
Suppose:
- the source extent is: [0, 100]
- the src offset is 10
- the clone length is 90
- the dest offset is 0
This statement:
new_key.offset = key.offset + destoff - off
will produce such an extent for the dest file:
[ino, BTRFS_EXTENT_DATA_KEY, -10]
, which is obviously wrong.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
-rw-r--r-- | fs/btrfs/ioctl.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f87552a1d7ea..1b61dab64062 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1788,7 +1788,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, memcpy(&new_key, &key, sizeof(new_key)); new_key.objectid = inode->i_ino; - new_key.offset = key.offset + destoff - off; + if (off <= key.offset) + new_key.offset = key.offset + destoff - off; + else + new_key.offset = destoff; trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { |