diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d38981567e4e74adf8760e7f3c8d59802148b6f2..0770c91586ca694e1f9c142fb653cf02c02dd686 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3588,6 +3588,20 @@ static int btrfs_clone(struct inode *src, struct inode *inode, u64 trim = 0; u64 aligned_end = 0; + /* + * Don't copy an inline extent into an offset + * greater than zero. Having an inline extent + * at such an offset results in chaos as btrfs + * isn't prepared for such cases. Just skip + * this case for the same reasons as commented + * at btrfs_ioctl_clone(). + */ + if (last_dest_end > 0) { + ret = -EOPNOTSUPP; + btrfs_end_transaction(trans, root); + goto out; + } + if (off > key.offset) { skip = off - key.offset; new_key.offset += skip;