Skip to content

Commit c20988c

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: copy overlapped range within the same file
cifs.ko request to copy overlapped range within the same file. ksmbd is using vfs_copy_file_range for this, vfs_copy_file_range() does not allow overlapped copying within the same file. This patch use do_splice_direct() if offset and length are overlapped. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 3677ca6 commit c20988c

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

fs/smb/server/vfs.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/sched/xacct.h>
2121
#include <linux/crc32c.h>
2222
#include <linux/namei.h>
23+
#include <linux/splice.h>
2324

2425
#include "glob.h"
2526
#include "oplock.h"
@@ -1829,8 +1830,19 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
18291830
if (src_off + len > src_file_size)
18301831
return -E2BIG;
18311832

1832-
ret = vfs_copy_file_range(src_fp->filp, src_off,
1833-
dst_fp->filp, dst_off, len, 0);
1833+
/*
1834+
* vfs_copy_file_range does not allow overlapped copying
1835+
* within the same file.
1836+
*/
1837+
if (file_inode(src_fp->filp) == file_inode(dst_fp->filp) &&
1838+
dst_off + len > src_off &&
1839+
dst_off < src_off + len)
1840+
ret = do_splice_direct(src_fp->filp, &src_off,
1841+
dst_fp->filp, &dst_off,
1842+
min_t(size_t, len, MAX_RW_COUNT), 0);
1843+
else
1844+
ret = vfs_copy_file_range(src_fp->filp, src_off,
1845+
dst_fp->filp, dst_off, len, 0);
18341846
if (ret == -EOPNOTSUPP || ret == -EXDEV)
18351847
ret = vfs_copy_file_range(src_fp->filp, src_off,
18361848
dst_fp->filp, dst_off, len,

0 commit comments

Comments
 (0)