Skip to contentSkip to conversation

cloner: add support for clone_file_range for cifs

PATCH New Ronnie Sahlberg 3 participants 4 messages Sep 11, 2018

lore
Share & tools
lore
#0 lore raw

cover cloner: add support for clone_file_range for cifs

This is a trivial patch that adds support for copy_file_range for cifs. This uses the copy_file_range interface which cifs.ko supports.

Note that cloner.c uses an ioctl() for copying an entire file. This is an older interface from before cifs.ko added proper copy_file_range support but both interfaces eventually end up in the same codepaths and use the same SMB2 commands on the wire.
Could argue that we could/should use copy_file_range() for the whole file case as well but there is no harm leaving it as-is using the older interface.

#1 lore raw

PATCH 1/1 cloner: add support for clone_file_range for cifs

---
 src/cloner.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
src/cloner.c +15 -1
index ffad82f0..9f9156e5 100644
@@ -120,6 +120,18 @@ clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off,
 }
 
 static int
+clone_file_range_cifs(int fd_in, int fd_out, loff_t off_in,
+		      loff_t off_out, size_t len)
+{
+	int ret;
+
+	ret = copy_file_range(fd_in, &off_in, fd_out, &off_out, len, 0);
+	if (ret < 0)
+		ret = errno;
+	return 0;
+}
+
+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 +140,9 @@ 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);
 	default:
 		return ENOTSUP;
 		break;
Signature · 1 line
2.13.3
#2 lore raw
Quoted 13 lines · Ronnie Sahlberg
---
 src/cloner.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
src/cloner.c +0 -0
index ffad82f0..9f9156e5 100644
@@ -120,6 +120,18 @@ clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off,
 }
 
 static int

src/cloner.c clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off, · line 132

Quoted 10 lines
src/cloner.c +10 -0
+clone_file_range_cifs(int fd_in, int fd_out, loff_t off_in,
+		      loff_t off_out, size_t len)
+{
+	int ret;
+
+	ret = copy_file_range(fd_in, &off_in, fd_out, &off_out, len, 0);
+	if (ret < 0)
+		ret = errno;
+	return 0;
+}

This is weird. cloner seems to test clone, in which case it should test FICLONE (BTRFS_IOC_CLONE) / FICLONERANGE(BTRFS_IOC_CLONE_RANGE).

But it seems to check file system magic numbers which is rather bogus to start with. I think the right fix here is to remove all the magic number checks, always try FICLONE, and also remove support for the odd legacy cifs ioctl.

src/cloner.c clone_file_range(unsigned int fs_type, int src_fd, int dst_fd, uint64_t src_off, · line 148

Quoted 12 lines
src/cloner.c +3 -1
 {
@@ -128,7 +140,9 @@ 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);
 	default:
 		return ENOTSUP;
 		break;

And independent break after a return is just insane. Someone needs to fix this program to stop the eye bleeding..

#3 lore raw
Quoted 28 lines · Christoph Hellwig
Quoted 13 lines · Ronnie Sahlberg
---
 src/cloner.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
src/cloner.c +0 -0
index ffad82f0..9f9156e5 100644
@@ -120,6 +120,18 @@ clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off,
 }
 
 static int

src/cloner.c clone_file_range_btrfs(int src_fd, int dst_fd, uint64_t src_off, · line 132

Quoted 10 lines
src/cloner.c +10 -0
+clone_file_range_cifs(int fd_in, int fd_out, loff_t off_in,
+                   loff_t off_out, size_t len)
+{
+     int ret;
+
+     ret = copy_file_range(fd_in, &off_in, fd_out, &off_out, len, 0);
+     if (ret < 0)
+             ret = errno;
+     return 0;
+}

This is weird. cloner seems to test clone, in which case it should test FICLONE (BTRFS_IOC_CLONE) / FICLONERANGE(BTRFS_IOC_CLONE_RANGE).

Quoted 4 lines

But it seems to check file system magic numbers which is rather bogus to start with. I think the right fix here is to remove all the magic number checks, always try FICLONE, and also remove support for the odd legacy cifs ioctl.

Thanks. That is a lot bigger change but it is the right thing to do.

Please disregard this patch and I will make a new patch with your suggestions.

Quoted 16 lines

src/cloner.c clone_file_range(unsigned int fs_type, int src_fd, int dst_fd, uint64_t src_off, · line 148

Quoted 13 lines
src/cloner.c +3 -1
 {
@@ -128,7 +140,9 @@ 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);
      default:
              return ENOTSUP;
              break;

And independent break after a return is just insane. Someone needs to fix this program to stop the eye bleeding..