Message ID | 20180903065733.28037-1-lsahlber@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | cifs: add ioctl for SRV_COPYCHUNK range | expand |
Maybe should update David Disseldorp's test tool as well so user space code to experiment with this easily On Mon, Sep 3, 2018 at 1:57 AM Ronnie Sahlberg <lsahlber@redhat.com> 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@redhat.com> > --- > 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 >
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@redhat.com> 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@redhat.com> > --- > 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 >
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@gmail.com> 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@redhat.com> 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@redhat.com> >> --- >> 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
thx On Mon, Sep 3, 2018 at 4:58 PM ronnie sahlberg <ronniesahlberg@gmail.com> wrote: > > 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@gmail.com> 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@redhat.com> 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@redhat.com> > >> --- > >> 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
Tiny patch to generate copychunk ioctl's ----- Original Message ----- From: "ronnie sahlberg" <ronniesahlberg@gmail.com> To: "Steve French" <smfrench@gmail.com> Cc: "Ronnie Sahlberg" <lsahlber@redhat.com>, "CIFS" <linux-cifs@vger.kernel.org> 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@gmail.com> 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@redhat.com> 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@redhat.com> >> --- >> 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@redhat.com> Date: Tue, 4 Sep 2018 20:56:04 +1000 Subject: [PATCH] cifs: copychunk range support Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> --- 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;
On Mon, Sep 03, 2018 at 04:57:33PM +1000, Ronnie Sahlberg wrote: > Add a new ioctl for COPYCHUNK that copies a region. The existing > COPYCHUNK can only be used to copy a whole file. Please don't add magic ioctls and reuse the existing kernel copy offload functionality.
On Tue, Sep 4, 2018 at 9:11 AM Christoph Hellwig <hch@infradead.org> wrote: > > On Mon, Sep 03, 2018 at 04:57:33PM +1000, Ronnie Sahlberg wrote: > > Add a new ioctl for COPYCHUNK that copies a region. The existing > > COPYCHUNK can only be used to copy a whole file. > > Please don't add magic ioctls and reuse the existing kernel copy > offload functionality. The existing kernel copy offload syscall does overlap the proposed ioctl, so until additional feature rich SMB3 copy offload mechanisms are added (ODX might be a good example) require interface features not supported by the syscall (and thus require a cifs specific ioctl), we might as well avoid confusion and drop this patch. Now if any useful copy tools (rsync, gio copy etc.) actually used the copy syscall that would be even better - but that is a different problem ...
patch removed On Wed, Sep 5, 2018 at 9:30 AM Steve French <smfrench@gmail.com> wrote: > > On Tue, Sep 4, 2018 at 9:11 AM Christoph Hellwig <hch@infradead.org> wrote: > > > > On Mon, Sep 03, 2018 at 04:57:33PM +1000, Ronnie Sahlberg wrote: > > > Add a new ioctl for COPYCHUNK that copies a region. The existing > > > COPYCHUNK can only be used to copy a whole file. > > > > Please don't add magic ioctls and reuse the existing kernel copy > > offload functionality. > > The existing kernel copy offload syscall does overlap the proposed > ioctl, so until > additional feature rich SMB3 copy offload mechanisms are added (ODX might > be a good example) require interface features not supported by the syscall > (and thus require a cifs specific ioctl), we might as well avoid confusion > and drop this patch. > > Now if any useful copy tools (rsync, gio copy etc.) actually used the copy > syscall that would be even better - but that is a different problem ... > -- > Thanks, > > Steve
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:
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@redhat.com> --- fs/cifs/cifs_ioctl.h | 8 ++++++++ fs/cifs/ioctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 6 deletions(-)