cifsd: add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE
Add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE in smb2 ioctl. Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
8602c3e2ce
commit
eb817368f5
|
@ -4622,7 +4622,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
|
||||||
FILE_PERSISTENT_ACLS |
|
FILE_PERSISTENT_ACLS |
|
||||||
FILE_UNICODE_ON_DISK |
|
FILE_UNICODE_ON_DISK |
|
||||||
FILE_CASE_PRESERVED_NAMES |
|
FILE_CASE_PRESERVED_NAMES |
|
||||||
FILE_CASE_SENSITIVE_SEARCH);
|
FILE_CASE_SENSITIVE_SEARCH |
|
||||||
|
FILE_SUPPORTS_BLOCK_REFCOUNTING);
|
||||||
|
|
||||||
info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
|
info->Attributes |= cpu_to_le32(server_conf.share_fake_fscaps);
|
||||||
|
|
||||||
|
@ -7330,6 +7331,55 @@ int smb2_ioctl(struct ksmbd_work *work)
|
||||||
nbytes = sizeof(struct reparse_data_buffer);
|
nbytes = sizeof(struct reparse_data_buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FSCTL_DUPLICATE_EXTENTS_TO_FILE:
|
||||||
|
{
|
||||||
|
struct ksmbd_file *fp_in, *fp_out = NULL;
|
||||||
|
struct duplicate_extents_to_file *dup_ext;
|
||||||
|
loff_t src_off, dst_off, length, cloned;
|
||||||
|
|
||||||
|
dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0];
|
||||||
|
|
||||||
|
fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
|
||||||
|
dup_ext->PersistentFileHandle);
|
||||||
|
if (!fp_in) {
|
||||||
|
ksmbd_err("not found file handle in duplicate extent to file\n");
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_out = ksmbd_lookup_fd_fast(work, id);
|
||||||
|
if (!fp_out) {
|
||||||
|
ksmbd_err("not found fp\n");
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto dup_ext_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_off = le64_to_cpu(dup_ext->SourceFileOffset);
|
||||||
|
dst_off = le64_to_cpu(dup_ext->TargetFileOffset);
|
||||||
|
length = le64_to_cpu(dup_ext->ByteCount);
|
||||||
|
cloned = vfs_clone_file_range(fp_in->filp, src_off, fp_out->filp,
|
||||||
|
dst_off, length, 0);
|
||||||
|
if (cloned == -EXDEV || cloned == -EOPNOTSUPP) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
goto dup_ext_out;
|
||||||
|
} else if (cloned != length) {
|
||||||
|
cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off,
|
||||||
|
fp_out->filp, dst_off, length);
|
||||||
|
if (cloned != length) {
|
||||||
|
if (cloned < 0)
|
||||||
|
ret = cloned;
|
||||||
|
else
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dup_ext_out:
|
||||||
|
ksmbd_fd_put(work, fp_in);
|
||||||
|
ksmbd_fd_put(work, fp_out);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
|
ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
|
||||||
cnt_code);
|
cnt_code);
|
||||||
|
|
|
@ -851,6 +851,14 @@ struct smb2_write_rsp {
|
||||||
|
|
||||||
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001
|
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001
|
||||||
|
|
||||||
|
struct duplicate_extents_to_file {
|
||||||
|
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
|
||||||
|
__u64 VolatileFileHandle;
|
||||||
|
__le64 SourceFileOffset;
|
||||||
|
__le64 TargetFileOffset;
|
||||||
|
__le64 ByteCount; /* Bytes to be copied */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct smb2_ioctl_req {
|
struct smb2_ioctl_req {
|
||||||
struct smb2_hdr hdr;
|
struct smb2_hdr hdr;
|
||||||
__le16 StructureSize; /* Must be 57 */
|
__le16 StructureSize; /* Must be 57 */
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */
|
#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */
|
||||||
#define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF /* BB add struct */
|
#define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF /* BB add struct */
|
||||||
#define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */
|
#define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */
|
||||||
|
#define FSCTL_DUPLICATE_EXTENTS_TO_FILE 0x00098344
|
||||||
#define FSCTL_SIS_LINK_FILES 0x0009C104
|
#define FSCTL_SIS_LINK_FILES 0x0009C104
|
||||||
#define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */
|
#define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */
|
||||||
#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 /* BB add struct */
|
#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 /* BB add struct */
|
||||||
|
|
|
@ -1789,7 +1789,7 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
||||||
struct file *file_out, loff_t pos_out, size_t len)
|
struct file *file_out, loff_t pos_out, size_t len)
|
||||||
{
|
{
|
||||||
struct inode *inode_in = file_inode(file_in);
|
struct inode *inode_in = file_inode(file_in);
|
||||||
|
|
|
@ -218,7 +218,8 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
|
||||||
struct srv_copychunk *chunks, unsigned int chunk_count,
|
struct srv_copychunk *chunks, unsigned int chunk_count,
|
||||||
unsigned int *chunk_count_written,
|
unsigned int *chunk_count_written,
|
||||||
unsigned int *chunk_size_written, loff_t *total_size_written);
|
unsigned int *chunk_size_written, loff_t *total_size_written);
|
||||||
|
int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
||||||
|
struct file *file_out, loff_t pos_out, size_t len);
|
||||||
ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
|
ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
|
||||||
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
|
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
|
||||||
char **xattr_buf);
|
char **xattr_buf);
|
||||||
|
|
Loading…
Reference in New Issue