Re: [PATCH] cifs: add ioctl for SRV_COPYCHUNK range

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux