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