Tiny patch to generate copychunk ioctl's ----- Original Message ----- From: "ronnie sahlberg" <ronniesahlberg@xxxxxxxxx> To: "Steve French" <smfrench@xxxxxxxxx> Cc: "Ronnie Sahlberg" <lsahlber@xxxxxxxxxx>, "CIFS" <linux-cifs@xxxxxxxxxxxxxxx> Sent: Tuesday, 4 September, 2018 7:58:29 AM Subject: Re: [PATCH] cifs: add ioctl for SRV_COPYCHUNK range I updated cloner that is part of xfstest. Once this goes in I will submit a change to xfstest.. On Tue, Sep 4, 2018 at 12:23 AM, Steve French <smfrench@xxxxxxxxx> wrote: > tentatively merged into cifs-2.6.git for-next (along with the updated > compounding series) > On Mon, Sep 3, 2018 at 1:57 AM Ronnie Sahlberg <lsahlber@xxxxxxxxxx> wrote: >> >> Add a new ioctl for COPYCHUNK that copies a region. The existing >> COPYCHUNK can only be used to copy a whole file. >> >> Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx> >> --- >> fs/cifs/cifs_ioctl.h | 8 ++++++++ >> fs/cifs/ioctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------ >> 2 files changed, 55 insertions(+), 6 deletions(-) >> >> diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h >> index 57ff0756e30c..b40b9b608dde 100644 >> --- a/fs/cifs/cifs_ioctl.h >> +++ b/fs/cifs/cifs_ioctl.h >> @@ -43,8 +43,16 @@ struct smb_snapshot_array { >> /* snapshots[]; */ >> } __packed; >> >> +struct smb_srv_copychunk { >> + __u32 src_fd; >> + __u32 length; >> + __u64 src_offset; >> + __u64 dst_offset; >> +} __packed; >> + >> #define CIFS_IOCTL_MAGIC 0xCF >> #define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) >> #define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4) >> #define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info) >> #define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array) >> +#define CIFS_IOC_COPYCHUNK _IOW(CIFS_IOCTL_MAGIC, 7, struct smb_srv_copychunk) >> diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c >> index 54f32f9143a9..91f87ea01be0 100644 >> --- a/fs/cifs/ioctl.c >> +++ b/fs/cifs/ioctl.c >> @@ -34,14 +34,13 @@ >> #include "cifs_ioctl.h" >> #include <linux/btrfs.h> >> >> -static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> - unsigned long srcfd) >> +static long _cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> + struct smb_srv_copychunk *cc) >> { >> int rc; >> struct fd src_file; >> struct inode *src_inode; >> >> - cifs_dbg(FYI, "ioctl copychunk range\n"); >> /* the destination must be opened for writing */ >> if (!(dst_file->f_mode & FMODE_WRITE)) { >> cifs_dbg(FYI, "file target not open for write\n"); >> @@ -55,7 +54,7 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> return rc; >> } >> >> - src_file = fdget(srcfd); >> + src_file = fdget(cc->src_fd); >> if (!src_file.file) { >> rc = -EBADF; >> goto out_drop_write; >> @@ -72,8 +71,9 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> if (S_ISDIR(src_inode->i_mode)) >> goto out_fput; >> >> - rc = cifs_file_copychunk_range(xid, src_file.file, 0, dst_file, 0, >> - src_inode->i_size, 0); >> + rc = cifs_file_copychunk_range(xid, src_file.file, cc->src_offset, >> + dst_file, cc->dst_offset, >> + cc->length, 0); >> if (rc > 0) >> rc = 0; >> out_fput: >> @@ -83,6 +83,44 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> return rc; >> } >> >> +static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, >> + unsigned long p) >> +{ >> + void __user *arg = (void __user *)p; >> + struct smb_srv_copychunk cc; >> + >> + cifs_dbg(FYI, "ioctl copychunk range\n"); >> + >> + if (copy_from_user(&cc, arg, sizeof(cc))) >> + return -EFAULT; >> + >> + return _cifs_ioctl_copychunk(xid, dst_file, &cc); >> +} >> + >> +static long cifs_ioctl_copychunk_file(unsigned int xid, struct file *dst_file, >> + unsigned long srcfd) >> +{ >> + struct smb_srv_copychunk cc; >> + struct fd src_file; >> + struct inode *src_inode; >> + >> + cifs_dbg(FYI, "ioctl copychunk file\n"); >> + >> + src_file = fdget(srcfd); >> + if (!src_file.file) { >> + mnt_drop_write_file(dst_file); >> + return -EBADF; >> + } >> + src_inode = file_inode(src_file.file); >> + >> + memset(&cc, 0, sizeof(struct smb_srv_copychunk)); >> + cc.src_fd = srcfd; >> + cc.length = src_inode->i_size; >> + fdput(src_file); >> + >> + return _cifs_ioctl_copychunk(xid, dst_file, &cc); >> +} >> + >> static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, >> void __user *arg) >> { >> @@ -194,6 +232,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) >> } >> break; >> case CIFS_IOC_COPYCHUNK_FILE: >> + rc = cifs_ioctl_copychunk_file(xid, filep, arg); >> + break; >> + case CIFS_IOC_COPYCHUNK: >> rc = cifs_ioctl_copychunk(xid, filep, arg); >> break; >> case CIFS_IOC_SET_INTEGRITY: >> -- >> 2.13.3 >> > > > -- > Thanks, > > Steve
From c324ff8b759e1733e23cfcd299028f924521f158 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg <lsahlber@xxxxxxxxxx> Date: Tue, 4 Sep 2018 20:56:04 +1000 Subject: [PATCH] cifs: copychunk range support Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx> --- src/cloner.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/cloner.c b/src/cloner.c index ffad82f0..8274dcaf 100644 --- a/src/cloner.c +++ b/src/cloner.c @@ -40,9 +40,18 @@ struct btrfs_ioctl_clone_range_args { #define CIFS_IOCTL_MAGIC 0xCF #define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) - #endif +struct smb_srv_copychunk { + uint32_t src_fd; + uint32_t length; + uint64_t src_offset; + uint64_t dst_offset; +}; + +#define CIFS_IOC_COPYCHUNK _IOW(CIFS_IOCTL_MAGIC, 7, \ + struct smb_srv_copychunk) + #ifndef BTRFS_SUPER_MAGIC #define BTRFS_SUPER_MAGIC 0x9123683E #endif @@ -120,6 +129,24 @@ clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off, } static int +clone_file_range_cifs(int src_fd, int dst_fd, uint64_t src_off, + uint64_t dst_off, uint64_t len) +{ + struct smb_srv_copychunk cc_args; + int ret; + + memset(&cc_args, 0, sizeof(cc_args)); + cc_args.src_fd = src_fd; + cc_args.src_offset = src_off; + cc_args.length = len; + cc_args.dst_offset = dst_off; + ret = ioctl(dst_fd, CIFS_IOC_COPYCHUNK, &cc_args); + if (ret != 0) + ret = errno; + return ret; +} + +static int clone_file_range(unsigned int fs_type, int src_fd, int dst_fd, uint64_t src_off, uint64_t dst_off, uint64_t len) { @@ -128,7 +155,10 @@ clone_file_range(unsigned int fs_type, int src_fd, int dst_fd, uint64_t src_off, return clone_file_range_btrfs(src_fd, dst_fd, src_off, dst_off, len); break; - case CIFS_MAGIC_NUMBER: /* only supports full file server-side copies */ + case CIFS_MAGIC_NUMBER: + return clone_file_range_cifs(src_fd, dst_fd, src_off, dst_off, + len); + break; default: return ENOTSUP; break; -- 2.13.3