linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
       [not found] ` <1440516829-116041-1-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
@ 2015-08-25 15:33   ` Peng Tao
  2015-08-26  1:40     ` Peng Tao
                       ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Peng Tao @ 2015-08-25 15:33 UTC (permalink / raw)
  To: linux-nfs-u79uwXL29TY76Z2rM5mHXA
  Cc: Trond Myklebust, Anna Schumaker, Christoph Hellwig, Zach Brown,
	Darren Hart, bfields-uC3wQj2KruNg9hUCZPvPmw, Jeff Layton,
	Peng Tao, linux-btrfs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA

Now that a few file systems are adding clone functionality, namingly
btrfs, NFS (later in the series) and XFS
(ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
to pull the ioctl to common code.

Add vfs_file_clone_range() helper and .clone_range file operation interface
to allow underlying filesystems to clone between regular files.

The change in do_vfs_ioctl() is defered to next patch where btrfs
.clone_range is added, just so that we don't break btrfs CLONE ioctl
with this patch.

Cc: linux-btrfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Peng Tao <tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
---
 fs/ioctl.c              | 24 ++++++++++++++++++++++++
 fs/read_write.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h      |  4 ++++
 include/uapi/linux/fs.h |  9 +++++++++
 4 files changed, 82 insertions(+)

diff --git a/fs/ioctl.c b/fs/ioctl.c
index 5d01d26..726c5d7 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -215,6 +215,30 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
 	return error;
 }
 
+static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
+			     u64 off, u64 olen, u64 destoff)
+{
+	struct fd src_file = fdget(srcfd);
+	int ret;
+
+	if (!src_file.file)
+		return -EBADF;
+	ret = vfs_file_clone_range(src_file.file, dst_file, off, olen, destoff);
+
+	fdput(src_file);
+	return ret;
+}
+
+static long ioctl_file_clone_range(struct file *file, void __user *argp)
+{
+	struct file_clone_range args;
+
+	if (copy_from_user(&args, argp, sizeof(args)))
+		return -EFAULT;
+	return ioctl_file_clone(file, args.src_fd, args.src_offset,
+				args.src_length, args.dest_offset);
+}
+
 #ifdef CONFIG_BLOCK
 
 static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
diff --git a/fs/read_write.c b/fs/read_write.c
index 819ef3f..beaad2c 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -16,6 +16,7 @@
 #include <linux/pagemap.h>
 #include <linux/splice.h>
 #include <linux/compat.h>
+#include <linux/mount.h>
 #include "internal.h"
 
 #include <asm/uaccess.h>
@@ -1327,3 +1328,47 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
 	return do_sendfile(out_fd, in_fd, NULL, count, 0);
 }
 #endif
+
+int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
+			 loff_t off, size_t len, loff_t dstoff)
+{
+	struct inode *src_ino;
+	struct inode *dst_ino;
+	ssize_t ret;
+
+	if (!(src_file->f_mode & FMODE_READ) ||
+	    !(dst_file->f_mode & FMODE_WRITE) ||
+	    (dst_file->f_flags & O_APPEND) ||
+	    !src_file->f_op || !src_file->f_op->clone_range)
+		return -EINVAL;
+
+	src_ino = file_inode(src_file);
+	dst_ino = file_inode(dst_file);
+
+        if (S_ISDIR(src_ino->i_mode) || S_ISDIR(dst_ino->i_mode))
+                return -EISDIR;
+
+	/* sanity check on offsets and length */
+	if (off + len < off || dstoff + len < dstoff ||
+	    off + len > i_size_read(src_ino))
+		return -EINVAL;
+
+	if (src_ino->i_sb != dst_ino->i_sb ||
+	    src_file->f_path.mnt != dst_file->f_path.mnt)
+		return -EXDEV;
+
+	ret = mnt_want_write_file(dst_file);
+	if (ret)
+		return ret;
+
+	ret = src_file->f_op->clone_range(src_file, dst_file, off, len, dstoff);
+	if (!ret) {
+		fsnotify_access(src_file);
+		fsnotify_modify(dst_file);
+	}
+
+	mnt_drop_write_file(dst_file);
+
+	return ret;
+}
+EXPORT_SYMBOL(vfs_file_clone_range);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cc008c3..612d7f4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1628,6 +1628,8 @@ struct file_operations {
 	long (*fallocate)(struct file *file, int mode, loff_t offset,
 			  loff_t len);
 	void (*show_fdinfo)(struct seq_file *m, struct file *f);
+	int (*clone_range)(struct file *src_file, struct file *dst_file,
+			   loff_t off, size_t len, loff_t dstoff);
 #ifndef CONFIG_MMU
 	unsigned (*mmap_capabilities)(struct file *);
 #endif
@@ -2678,6 +2680,8 @@ int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t,
 int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *);
 #define dax_mkwrite(vma, vmf, gb, iod)		dax_fault(vma, vmf, gb, iod)
 #define __dax_mkwrite(vma, vmf, gb, iod)	__dax_fault(vma, vmf, gb, iod)
+int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
+			 loff_t off, size_t len, loff_t dstoff);
 
 #ifdef CONFIG_BLOCK
 typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 9b964a5..ac7f1c5 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -39,6 +39,13 @@
 #define RENAME_EXCHANGE		(1 << 1)	/* Exchange source and dest */
 #define RENAME_WHITEOUT		(1 << 2)	/* Whiteout source */
 
+struct file_clone_range {
+	__s64 src_fd;
+	__u64 src_offset;
+	__u64 src_length;
+	__u64 dest_offset;
+};
+
 struct fstrim_range {
 	__u64 start;
 	__u64 len;
@@ -159,6 +166,8 @@ struct inodes_stat_t {
 #define FIFREEZE	_IOWR('X', 119, int)	/* Freeze */
 #define FITHAW		_IOWR('X', 120, int)	/* Thaw */
 #define FITRIM		_IOWR('X', 121, struct fstrim_range)	/* Trim */
+#define FICLONE		_IOW(0x94, 9, int)	/* Clone */
+#define FICLONERANGE	_IOW(0x94, 13, struct file_clone_range)	/* Clone range */
 
 #define	FS_IOC_GETFLAGS			_IOR('f', 1, long)
 #define	FS_IOC_SETFLAGS			_IOW('f', 2, long)
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation
       [not found] <1440516829-116041-1-git-send-email-tao.peng@primarydata.com>
       [not found] ` <1440516829-116041-1-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
@ 2015-08-25 15:33 ` Peng Tao
       [not found]   ` <1440516829-116041-3-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
  1 sibling, 1 reply; 11+ messages in thread
From: Peng Tao @ 2015-08-25 15:33 UTC (permalink / raw)
  To: linux-nfs
  Cc: Trond Myklebust, Anna Schumaker, Christoph Hellwig, Zach Brown,
	Darren Hart, bfields, Jeff Layton, Peng Tao, linux-btrfs,
	linux-fsdevel

Also add vfs callers in do_vfs_ioctl(). Now btrfs CLONE
ioctl goes through vfs_file_clone_range().

Cc: linux-btrfs@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Peng Tao <tao.peng@primarydata.com>
---
 fs/btrfs/ctree.h           |  2 ++
 fs/btrfs/file.c            |  1 +
 fs/btrfs/ioctl.c           | 68 +++++-----------------------------------------
 fs/ioctl.c                 |  6 ++++
 include/uapi/linux/btrfs.h | 10 -------
 5 files changed, 16 insertions(+), 71 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index aac314e..af3e224 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3969,6 +3969,8 @@ void btrfs_get_block_group_info(struct list_head *groups_list,
 				struct btrfs_ioctl_space_info *space);
 void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock,
 			       struct btrfs_ioctl_balance_args *bargs);
+int btrfs_file_clone_range(struct file *src_file, struct file *dst_file,
+			   loff_t off, size_t olen, loff_t destoff);
 
 
 /* file.c */
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index b823fac..c9170fd 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2813,6 +2813,7 @@ const struct file_operations btrfs_file_operations = {
 	.fsync		= btrfs_sync_file,
 	.fallocate	= btrfs_fallocate,
 	.unlocked_ioctl	= btrfs_ioctl,
+	.clone_range	= btrfs_file_clone_range,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= btrfs_ioctl,
 #endif
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 0770c91..3d026c8 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3719,13 +3719,12 @@ out:
 	return ret;
 }
 
-static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
-				       u64 off, u64 olen, u64 destoff)
+int btrfs_file_clone_range(struct file *src_file, struct file *dst_file,
+			   loff_t off, size_t olen, loff_t destoff)
 {
-	struct inode *inode = file_inode(file);
+	struct inode *inode = file_inode(dst_file);
 	struct btrfs_root *root = BTRFS_I(inode)->root;
-	struct fd src_file;
-	struct inode *src;
+	struct inode *src = file_inode(src_file);
 	int ret;
 	u64 len = olen;
 	u64 bs = root->fs_info->sb->s_blocksize;
@@ -3742,49 +3741,16 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
 	 *   be either compressed or non-compressed.
 	 */
 
-	/* the destination must be opened for writing */
-	if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND))
-		return -EINVAL;
-
 	if (btrfs_root_readonly(root))
 		return -EROFS;
 
-	ret = mnt_want_write_file(file);
-	if (ret)
-		return ret;
-
-	src_file = fdget(srcfd);
-	if (!src_file.file) {
-		ret = -EBADF;
-		goto out_drop_write;
-	}
-
-	ret = -EXDEV;
-	if (src_file.file->f_path.mnt != file->f_path.mnt)
-		goto out_fput;
-
-	src = file_inode(src_file.file);
-
-	ret = -EINVAL;
-	if (src == inode)
-		same_inode = 1;
-
-	/* the src must be open for reading */
-	if (!(src_file.file->f_mode & FMODE_READ))
-		goto out_fput;
-
 	/* don't make the dst file partly checksummed */
 	if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
 	    (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
-		goto out_fput;
-
-	ret = -EISDIR;
-	if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
-		goto out_fput;
+		return -EINVAL;
 
-	ret = -EXDEV;
-	if (src->i_sb != inode->i_sb)
-		goto out_fput;
+	if (src == inode)
+		same_inode = 1;
 
 	if (!same_inode) {
 		if (inode < src) {
@@ -3800,8 +3766,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
 
 	/* determine range to clone */
 	ret = -EINVAL;
-	if (off + len > src->i_size || off + len < off)
-		goto out_unlock;
 	if (len == 0)
 		olen = len = src->i_size - off;
 	/* if we extend to eof, continue to block boundary */
@@ -3877,23 +3841,9 @@ out_unlock:
 	} else {
 		mutex_unlock(&src->i_mutex);
 	}
-out_fput:
-	fdput(src_file);
-out_drop_write:
-	mnt_drop_write_file(file);
 	return ret;
 }
 
-static long btrfs_ioctl_clone_range(struct file *file, void __user *argp)
-{
-	struct btrfs_ioctl_clone_range_args args;
-
-	if (copy_from_user(&args, argp, sizeof(args)))
-		return -EFAULT;
-	return btrfs_ioctl_clone(file, args.src_fd, args.src_offset,
-				 args.src_length, args.dest_offset);
-}
-
 /*
  * there are many ways the trans_start and trans_end ioctls can lead
  * to deadlocks.  They should only be used by applications that
@@ -5433,10 +5383,6 @@ long btrfs_ioctl(struct file *file, unsigned int
 		return btrfs_ioctl_dev_info(root, argp);
 	case BTRFS_IOC_BALANCE:
 		return btrfs_ioctl_balance(file, NULL);
-	case BTRFS_IOC_CLONE:
-		return btrfs_ioctl_clone(file, arg, 0, 0, 0);
-	case BTRFS_IOC_CLONE_RANGE:
-		return btrfs_ioctl_clone_range(file, argp);
 	case BTRFS_IOC_TRANS_START:
 		return btrfs_ioctl_trans_start(file);
 	case BTRFS_IOC_TRANS_END:
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 726c5d7..41c6080 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -624,6 +624,12 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 	case FIGETBSZ:
 		return put_user(inode->i_sb->s_blocksize, argp);
 
+	case FICLONE:
+		return ioctl_file_clone(filp, arg, 0, 0, 0);
+
+	case FICLONERANGE:
+		return ioctl_file_clone_range(filp, argp);
+
 	default:
 		if (S_ISREG(inode->i_mode))
 			error = file_ioctl(filp, cmd, arg);
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index b6dec05..c3a23d3 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -316,12 +316,6 @@ struct btrfs_ioctl_search_args_v2 {
 	__u64 buf[0];                       /* out - found items */
 };
 
-struct btrfs_ioctl_clone_range_args {
-  __s64 src_fd;
-  __u64 src_offset, src_length;
-  __u64 dest_offset;
-};
-
 /* flags for the defrag range ioctl */
 #define BTRFS_DEFRAG_RANGE_COMPRESS 1
 #define BTRFS_DEFRAG_RANGE_START_IO 2
@@ -548,7 +542,6 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 #define BTRFS_IOC_TRANS_END    _IO(BTRFS_IOCTL_MAGIC, 7)
 #define BTRFS_IOC_SYNC         _IO(BTRFS_IOCTL_MAGIC, 8)
 
-#define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)
 #define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, \
@@ -556,9 +549,6 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
 #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
 				   struct btrfs_ioctl_vol_args)
 
-#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \
-				  struct btrfs_ioctl_clone_range_args)
-
 #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \
 				   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
  2015-08-25 15:33   ` [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer Peng Tao
@ 2015-08-26  1:40     ` Peng Tao
  2015-08-26  1:50     ` Dave Chinner
  2015-08-26  4:09     ` Darrick J. Wong
  2 siblings, 0 replies; 11+ messages in thread
From: Peng Tao @ 2015-08-26  1:40 UTC (permalink / raw)
  To: linux-btrfs
  Cc: Trond Myklebust, Anna Schumaker, Christoph Hellwig, Zach Brown,
	Darren Hart, Bruce Fields, Jeff Layton, Peng Tao, Devel FS Linux,
	Linux NFS Mailing List

On Tue, Aug 25, 2015 at 11:33 PM, Peng Tao <tao.peng@primarydata.com> wrote:
> Now that a few file systems are adding clone functionality, namingly
> btrfs, NFS (later in the series) and XFS
> (ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
> to pull the ioctl to common code.
>
> Add vfs_file_clone_range() helper and .clone_range file operation interface
> to allow underlying filesystems to clone between regular files.
>
> The change in do_vfs_ioctl() is defered to next patch where btrfs
> .clone_range is added, just so that we don't break btrfs CLONE ioctl
> with this patch.
>
> Cc: linux-btrfs@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Peng Tao <tao.peng@primarydata.com>
> ---
>  fs/ioctl.c              | 24 ++++++++++++++++++++++++
>  fs/read_write.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h      |  4 ++++
>  include/uapi/linux/fs.h |  9 +++++++++
>  4 files changed, 82 insertions(+)
>
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 5d01d26..726c5d7 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -215,6 +215,30 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
>         return error;
>  }
>
> +static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
> +                            u64 off, u64 olen, u64 destoff)
> +{
> +       struct fd src_file = fdget(srcfd);
> +       int ret;
> +
> +       if (!src_file.file)
> +               return -EBADF;
> +       ret = vfs_file_clone_range(src_file.file, dst_file, off, olen, destoff);
> +
> +       fdput(src_file);
> +       return ret;
> +}
> +
> +static long ioctl_file_clone_range(struct file *file, void __user *argp)
> +{
> +       struct file_clone_range args;
> +
> +       if (copy_from_user(&args, argp, sizeof(args)))
> +               return -EFAULT;
> +       return ioctl_file_clone(file, args.src_fd, args.src_offset,
> +                               args.src_length, args.dest_offset);
> +}
> +
>  #ifdef CONFIG_BLOCK
>
>  static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
> diff --git a/fs/read_write.c b/fs/read_write.c
> index 819ef3f..beaad2c 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -16,6 +16,7 @@
>  #include <linux/pagemap.h>
>  #include <linux/splice.h>
>  #include <linux/compat.h>
> +#include <linux/mount.h>
>  #include "internal.h"
>
>  #include <asm/uaccess.h>
> @@ -1327,3 +1328,47 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
>         return do_sendfile(out_fd, in_fd, NULL, count, 0);
>  }
>  #endif
> +
> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
> +                        loff_t off, size_t len, loff_t dstoff)
> +{
> +       struct inode *src_ino;
> +       struct inode *dst_ino;
> +       ssize_t ret;
> +
> +       if (!(src_file->f_mode & FMODE_READ) ||
> +           !(dst_file->f_mode & FMODE_WRITE) ||
> +           (dst_file->f_flags & O_APPEND) ||
> +           !src_file->f_op || !src_file->f_op->clone_range)
> +               return -EINVAL;
> +
> +       src_ino = file_inode(src_file);
> +       dst_ino = file_inode(dst_file);
> +
> +        if (S_ISDIR(src_ino->i_mode) || S_ISDIR(dst_ino->i_mode))
> +                return -EISDIR;
> +
> +       /* sanity check on offsets and length */
> +       if (off + len < off || dstoff + len < dstoff ||
> +           off + len > i_size_read(src_ino))
> +               return -EINVAL;
> +
> +       if (src_ino->i_sb != dst_ino->i_sb ||
> +           src_file->f_path.mnt != dst_file->f_path.mnt)
> +               return -EXDEV;
> +
> +       ret = mnt_want_write_file(dst_file);
> +       if (ret)
> +               return ret;
> +
> +       ret = src_file->f_op->clone_range(src_file, dst_file, off, len, dstoff);
> +       if (!ret) {
> +               fsnotify_access(src_file);
> +               fsnotify_modify(dst_file);
> +       }
> +
> +       mnt_drop_write_file(dst_file);
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL(vfs_file_clone_range);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index cc008c3..612d7f4 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1628,6 +1628,8 @@ struct file_operations {
>         long (*fallocate)(struct file *file, int mode, loff_t offset,
>                           loff_t len);
>         void (*show_fdinfo)(struct seq_file *m, struct file *f);
> +       int (*clone_range)(struct file *src_file, struct file *dst_file,
> +                          loff_t off, size_t len, loff_t dstoff);
One question to btrfs guys... I wanted to add the .clone_range
operation explicit semantics such that it does not allow partial
success, and returns either 0 for success or a negative failure code,
because we don't not expect CLONE to succeed partially. Does btrfs
CLONE have the same semantics? It looks like so by going over
btrfs_clone() but it would be great if someone working on btrfs can
confirm it.

Thanks,
Tao

>  #ifndef CONFIG_MMU
>         unsigned (*mmap_capabilities)(struct file *);
>  #endif
> @@ -2678,6 +2680,8 @@ int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t,
>  int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *);
>  #define dax_mkwrite(vma, vmf, gb, iod)         dax_fault(vma, vmf, gb, iod)
>  #define __dax_mkwrite(vma, vmf, gb, iod)       __dax_fault(vma, vmf, gb, iod)
> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
> +                        loff_t off, size_t len, loff_t dstoff);
>
>  #ifdef CONFIG_BLOCK
>  typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index 9b964a5..ac7f1c5 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -39,6 +39,13 @@
>  #define RENAME_EXCHANGE                (1 << 1)        /* Exchange source and dest */
>  #define RENAME_WHITEOUT                (1 << 2)        /* Whiteout source */
>
> +struct file_clone_range {
> +       __s64 src_fd;
> +       __u64 src_offset;
> +       __u64 src_length;
> +       __u64 dest_offset;
> +};
> +
>  struct fstrim_range {
>         __u64 start;
>         __u64 len;
> @@ -159,6 +166,8 @@ struct inodes_stat_t {
>  #define FIFREEZE       _IOWR('X', 119, int)    /* Freeze */
>  #define FITHAW         _IOWR('X', 120, int)    /* Thaw */
>  #define FITRIM         _IOWR('X', 121, struct fstrim_range)    /* Trim */
> +#define FICLONE                _IOW(0x94, 9, int)      /* Clone */
> +#define FICLONERANGE   _IOW(0x94, 13, struct file_clone_range) /* Clone range */
>
>  #define        FS_IOC_GETFLAGS                 _IOR('f', 1, long)
>  #define        FS_IOC_SETFLAGS                 _IOW('f', 2, long)
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
  2015-08-25 15:33   ` [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer Peng Tao
  2015-08-26  1:40     ` Peng Tao
@ 2015-08-26  1:50     ` Dave Chinner
  2015-08-26  1:59       ` Dave Chinner
  2015-08-26  4:09     ` Darrick J. Wong
  2 siblings, 1 reply; 11+ messages in thread
From: Dave Chinner @ 2015-08-26  1:50 UTC (permalink / raw)
  To: Peng Tao
  Cc: linux-nfs, Trond Myklebust, Anna Schumaker, Christoph Hellwig,
	Zach Brown, Darren Hart, bfields, Jeff Layton, linux-btrfs,
	linux-fsdevel

On Tue, Aug 25, 2015 at 11:33:39PM +0800, Peng Tao wrote:
> Now that a few file systems are adding clone functionality, namingly
> btrfs, NFS (later in the series) and XFS
> (ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
> to pull the ioctl to common code.
> 
> Add vfs_file_clone_range() helper and .clone_range file operation interface
> to allow underlying filesystems to clone between regular files.
> 
> The change in do_vfs_ioctl() is defered to next patch where btrfs
> .clone_range is added, just so that we don't break btrfs CLONE ioctl
> with this patch.
> 
> Cc: linux-btrfs@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org

Can you please cc the entire patch series to linux-fsdevel?

Spraying random patches from a larger series to different lists is
not very nice - I can't really comment on this patch because I have
no idea what context it is being proposed in, what the problem being
solved is, how it is being used by existing filesystems, how it will
be used by your new changes, etc.

You may have explained all this in patch 0 for the series, but
that hasn't been cc'd to linux-fsdevel....

Cheers,

Dave.

PS: CC list spraying also plays badly with dup filters and per-list
procmail sorting that a lot of people use to manage incoming
feeds....
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
  2015-08-26  1:50     ` Dave Chinner
@ 2015-08-26  1:59       ` Dave Chinner
  0 siblings, 0 replies; 11+ messages in thread
From: Dave Chinner @ 2015-08-26  1:59 UTC (permalink / raw)
  To: Peng Tao
  Cc: linux-nfs, Trond Myklebust, Anna Schumaker, Christoph Hellwig,
	Zach Brown, Darren Hart, bfields, Jeff Layton, linux-btrfs,
	linux-fsdevel

On Wed, Aug 26, 2015 at 11:50:34AM +1000, Dave Chinner wrote:
> On Tue, Aug 25, 2015 at 11:33:39PM +0800, Peng Tao wrote:
> > Now that a few file systems are adding clone functionality, namingly
> > btrfs, NFS (later in the series) and XFS
> > (ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
> > to pull the ioctl to common code.
> > 
> > Add vfs_file_clone_range() helper and .clone_range file operation interface
> > to allow underlying filesystems to clone between regular files.
> > 
> > The change in do_vfs_ioctl() is defered to next patch where btrfs
> > .clone_range is added, just so that we don't break btrfs CLONE ioctl
> > with this patch.
> > 
> > Cc: linux-btrfs@vger.kernel.org
> > Cc: linux-fsdevel@vger.kernel.org
> 
> Can you please cc the entire patch series to linux-fsdevel?
> 
> Spraying random patches from a larger series to different lists is
> not very nice - I can't really comment on this patch because I have
> no idea what context it is being proposed in, what the problem being
> solved is, how it is being used by existing filesystems, how it will
> be used by your new changes, etc.
> 
> You may have explained all this in patch 0 for the series, but
> that hasn't been cc'd to linux-fsdevel....

Also, proposed test infrastructure for the clone_range functionality
that Darrick is working on for XFS (and to validate existing btrfs
functionality):

http://oss.sgi.com/archives/xfs/2015-06/msg00479.html

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
  2015-08-25 15:33   ` [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer Peng Tao
  2015-08-26  1:40     ` Peng Tao
  2015-08-26  1:50     ` Dave Chinner
@ 2015-08-26  4:09     ` Darrick J. Wong
       [not found]       ` <20150826040943.GC10038-PTl6brltDGh4DFYR7WNSRA@public.gmane.org>
  2 siblings, 1 reply; 11+ messages in thread
From: Darrick J. Wong @ 2015-08-26  4:09 UTC (permalink / raw)
  To: Peng Tao
  Cc: linux-nfs, Trond Myklebust, Anna Schumaker, Christoph Hellwig,
	Zach Brown, Darren Hart, bfields, Jeff Layton, linux-btrfs,
	linux-fsdevel

On Tue, Aug 25, 2015 at 11:33:39PM +0800, Peng Tao wrote:
> Now that a few file systems are adding clone functionality, namingly
> btrfs, NFS (later in the series) and XFS
> (ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
> to pull the ioctl to common code.

Please cc me on future postings of this entire patchset, seeing as you're
referencing an email I sent and am still actively working on. :)

I agree with what Dave said, please also cc the entire set to fsdevel.

--D

> 
> Add vfs_file_clone_range() helper and .clone_range file operation interface
> to allow underlying filesystems to clone between regular files.
> 
> The change in do_vfs_ioctl() is defered to next patch where btrfs
> .clone_range is added, just so that we don't break btrfs CLONE ioctl
> with this patch.
> 
> Cc: linux-btrfs@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Peng Tao <tao.peng@primarydata.com>
> ---
>  fs/ioctl.c              | 24 ++++++++++++++++++++++++
>  fs/read_write.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h      |  4 ++++
>  include/uapi/linux/fs.h |  9 +++++++++
>  4 files changed, 82 insertions(+)
> 
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 5d01d26..726c5d7 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -215,6 +215,30 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
>  	return error;
>  }
>  
> +static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
> +			     u64 off, u64 olen, u64 destoff)
> +{
> +	struct fd src_file = fdget(srcfd);
> +	int ret;
> +
> +	if (!src_file.file)
> +		return -EBADF;
> +	ret = vfs_file_clone_range(src_file.file, dst_file, off, olen, destoff);
> +
> +	fdput(src_file);
> +	return ret;
> +}
> +
> +static long ioctl_file_clone_range(struct file *file, void __user *argp)
> +{
> +	struct file_clone_range args;
> +
> +	if (copy_from_user(&args, argp, sizeof(args)))
> +		return -EFAULT;
> +	return ioctl_file_clone(file, args.src_fd, args.src_offset,
> +				args.src_length, args.dest_offset);
> +}
> +
>  #ifdef CONFIG_BLOCK
>  
>  static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
> diff --git a/fs/read_write.c b/fs/read_write.c
> index 819ef3f..beaad2c 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -16,6 +16,7 @@
>  #include <linux/pagemap.h>
>  #include <linux/splice.h>
>  #include <linux/compat.h>
> +#include <linux/mount.h>
>  #include "internal.h"
>  
>  #include <asm/uaccess.h>
> @@ -1327,3 +1328,47 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
>  	return do_sendfile(out_fd, in_fd, NULL, count, 0);
>  }
>  #endif
> +
> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
> +			 loff_t off, size_t len, loff_t dstoff)
> +{
> +	struct inode *src_ino;
> +	struct inode *dst_ino;
> +	ssize_t ret;
> +
> +	if (!(src_file->f_mode & FMODE_READ) ||
> +	    !(dst_file->f_mode & FMODE_WRITE) ||
> +	    (dst_file->f_flags & O_APPEND) ||
> +	    !src_file->f_op || !src_file->f_op->clone_range)
> +		return -EINVAL;
> +
> +	src_ino = file_inode(src_file);
> +	dst_ino = file_inode(dst_file);
> +
> +        if (S_ISDIR(src_ino->i_mode) || S_ISDIR(dst_ino->i_mode))
> +                return -EISDIR;
> +
> +	/* sanity check on offsets and length */
> +	if (off + len < off || dstoff + len < dstoff ||
> +	    off + len > i_size_read(src_ino))
> +		return -EINVAL;
> +
> +	if (src_ino->i_sb != dst_ino->i_sb ||
> +	    src_file->f_path.mnt != dst_file->f_path.mnt)
> +		return -EXDEV;
> +
> +	ret = mnt_want_write_file(dst_file);
> +	if (ret)
> +		return ret;
> +
> +	ret = src_file->f_op->clone_range(src_file, dst_file, off, len, dstoff);
> +	if (!ret) {
> +		fsnotify_access(src_file);
> +		fsnotify_modify(dst_file);
> +	}
> +
> +	mnt_drop_write_file(dst_file);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(vfs_file_clone_range);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index cc008c3..612d7f4 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1628,6 +1628,8 @@ struct file_operations {
>  	long (*fallocate)(struct file *file, int mode, loff_t offset,
>  			  loff_t len);
>  	void (*show_fdinfo)(struct seq_file *m, struct file *f);
> +	int (*clone_range)(struct file *src_file, struct file *dst_file,
> +			   loff_t off, size_t len, loff_t dstoff);
>  #ifndef CONFIG_MMU
>  	unsigned (*mmap_capabilities)(struct file *);
>  #endif
> @@ -2678,6 +2680,8 @@ int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t,
>  int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *);
>  #define dax_mkwrite(vma, vmf, gb, iod)		dax_fault(vma, vmf, gb, iod)
>  #define __dax_mkwrite(vma, vmf, gb, iod)	__dax_fault(vma, vmf, gb, iod)
> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
> +			 loff_t off, size_t len, loff_t dstoff);
>  
>  #ifdef CONFIG_BLOCK
>  typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index 9b964a5..ac7f1c5 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -39,6 +39,13 @@
>  #define RENAME_EXCHANGE		(1 << 1)	/* Exchange source and dest */
>  #define RENAME_WHITEOUT		(1 << 2)	/* Whiteout source */
>  
> +struct file_clone_range {
> +	__s64 src_fd;
> +	__u64 src_offset;
> +	__u64 src_length;
> +	__u64 dest_offset;
> +};
> +
>  struct fstrim_range {
>  	__u64 start;
>  	__u64 len;
> @@ -159,6 +166,8 @@ struct inodes_stat_t {
>  #define FIFREEZE	_IOWR('X', 119, int)	/* Freeze */
>  #define FITHAW		_IOWR('X', 120, int)	/* Thaw */
>  #define FITRIM		_IOWR('X', 121, struct fstrim_range)	/* Trim */
> +#define FICLONE		_IOW(0x94, 9, int)	/* Clone */
> +#define FICLONERANGE	_IOW(0x94, 13, struct file_clone_range)	/* Clone range */
>  
>  #define	FS_IOC_GETFLAGS			_IOR('f', 1, long)
>  #define	FS_IOC_SETFLAGS			_IOW('f', 2, long)
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation
       [not found]   ` <1440516829-116041-3-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
@ 2015-08-26  8:01     ` David Sterba
       [not found]       ` <20150826080111.GV10756-1ReQVI26iDCaZKY3DrU6dA@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: David Sterba @ 2015-08-26  8:01 UTC (permalink / raw)
  To: Peng Tao
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, Trond Myklebust, Anna Schumaker,
	Christoph Hellwig, Zach Brown, Darren Hart,
	bfields-uC3wQj2KruNg9hUCZPvPmw, Jeff Layton,
	linux-btrfs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA

On Tue, Aug 25, 2015 at 11:33:40PM +0800, Peng Tao wrote:
> --- a/include/uapi/linux/btrfs.h
> +++ b/include/uapi/linux/btrfs.h
> @@ -316,12 +316,6 @@ struct btrfs_ioctl_search_args_v2 {
>  	__u64 buf[0];                       /* out - found items */
>  };
>  
> -struct btrfs_ioctl_clone_range_args {
> -  __s64 src_fd;
> -  __u64 src_offset, src_length;
> -  __u64 dest_offset;
> -};

For backward compatibility and not-breaking-builds reasons, do not
remove anything from this file.

> -
>  /* flags for the defrag range ioctl */
>  #define BTRFS_DEFRAG_RANGE_COMPRESS 1
>  #define BTRFS_DEFRAG_RANGE_START_IO 2
> @@ -548,7 +542,6 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
>  #define BTRFS_IOC_TRANS_END    _IO(BTRFS_IOCTL_MAGIC, 7)
>  #define BTRFS_IOC_SYNC         _IO(BTRFS_IOCTL_MAGIC, 8)
>  
> -#define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)

The ioctl definition reuses the BTRFS_IOCTL_MAGIC (0x94), which is IMHO
wrong.

I'll comment more once the whole series is posted to fsdevel.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer
       [not found]       ` <20150826040943.GC10038-PTl6brltDGh4DFYR7WNSRA@public.gmane.org>
@ 2015-08-26  8:03         ` Peng Tao
  0 siblings, 0 replies; 11+ messages in thread
From: Peng Tao @ 2015-08-26  8:03 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: Linux NFS Mailing List, Trond Myklebust, Anna Schumaker,
	Christoph Hellwig, Zach Brown, Darren Hart, Bruce Fields,
	Jeff Layton, linux-btrfs-u79uwXL29TY76Z2rM5mHXA, Devel FS Linux

On Wed, Aug 26, 2015 at 12:09 PM, Darrick J. Wong
<darrick.wong-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org> wrote:
> On Tue, Aug 25, 2015 at 11:33:39PM +0800, Peng Tao wrote:
>> Now that a few file systems are adding clone functionality, namingly
>> btrfs, NFS (later in the series) and XFS
>> (ttp://oss.sgi.com/archives/xfs/2015-06/msg00407.html), it makes sense
>> to pull the ioctl to common code.
>
> Please cc me on future postings of this entire patchset, seeing as you're
> referencing an email I sent and am still actively working on. :)
>
> I agree with what Dave said, please also cc the entire set to fsdevel.
>
sorry for the inconvenience. I'll resend the series adding
linux-fsdevel and you to the cc list.

Cheers,
Tao

> --D
>
>>
>> Add vfs_file_clone_range() helper and .clone_range file operation interface
>> to allow underlying filesystems to clone between regular files.
>>
>> The change in do_vfs_ioctl() is defered to next patch where btrfs
>> .clone_range is added, just so that we don't break btrfs CLONE ioctl
>> with this patch.
>>
>> Cc: linux-btrfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Peng Tao <tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
>> ---
>>  fs/ioctl.c              | 24 ++++++++++++++++++++++++
>>  fs/read_write.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/fs.h      |  4 ++++
>>  include/uapi/linux/fs.h |  9 +++++++++
>>  4 files changed, 82 insertions(+)
>>
>> diff --git a/fs/ioctl.c b/fs/ioctl.c
>> index 5d01d26..726c5d7 100644
>> --- a/fs/ioctl.c
>> +++ b/fs/ioctl.c
>> @@ -215,6 +215,30 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
>>       return error;
>>  }
>>
>> +static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
>> +                          u64 off, u64 olen, u64 destoff)
>> +{
>> +     struct fd src_file = fdget(srcfd);
>> +     int ret;
>> +
>> +     if (!src_file.file)
>> +             return -EBADF;
>> +     ret = vfs_file_clone_range(src_file.file, dst_file, off, olen, destoff);
>> +
>> +     fdput(src_file);
>> +     return ret;
>> +}
>> +
>> +static long ioctl_file_clone_range(struct file *file, void __user *argp)
>> +{
>> +     struct file_clone_range args;
>> +
>> +     if (copy_from_user(&args, argp, sizeof(args)))
>> +             return -EFAULT;
>> +     return ioctl_file_clone(file, args.src_fd, args.src_offset,
>> +                             args.src_length, args.dest_offset);
>> +}
>> +
>>  #ifdef CONFIG_BLOCK
>>
>>  static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
>> diff --git a/fs/read_write.c b/fs/read_write.c
>> index 819ef3f..beaad2c 100644
>> --- a/fs/read_write.c
>> +++ b/fs/read_write.c
>> @@ -16,6 +16,7 @@
>>  #include <linux/pagemap.h>
>>  #include <linux/splice.h>
>>  #include <linux/compat.h>
>> +#include <linux/mount.h>
>>  #include "internal.h"
>>
>>  #include <asm/uaccess.h>
>> @@ -1327,3 +1328,47 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
>>       return do_sendfile(out_fd, in_fd, NULL, count, 0);
>>  }
>>  #endif
>> +
>> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
>> +                      loff_t off, size_t len, loff_t dstoff)
>> +{
>> +     struct inode *src_ino;
>> +     struct inode *dst_ino;
>> +     ssize_t ret;
>> +
>> +     if (!(src_file->f_mode & FMODE_READ) ||
>> +         !(dst_file->f_mode & FMODE_WRITE) ||
>> +         (dst_file->f_flags & O_APPEND) ||
>> +         !src_file->f_op || !src_file->f_op->clone_range)
>> +             return -EINVAL;
>> +
>> +     src_ino = file_inode(src_file);
>> +     dst_ino = file_inode(dst_file);
>> +
>> +        if (S_ISDIR(src_ino->i_mode) || S_ISDIR(dst_ino->i_mode))
>> +                return -EISDIR;
>> +
>> +     /* sanity check on offsets and length */
>> +     if (off + len < off || dstoff + len < dstoff ||
>> +         off + len > i_size_read(src_ino))
>> +             return -EINVAL;
>> +
>> +     if (src_ino->i_sb != dst_ino->i_sb ||
>> +         src_file->f_path.mnt != dst_file->f_path.mnt)
>> +             return -EXDEV;
>> +
>> +     ret = mnt_want_write_file(dst_file);
>> +     if (ret)
>> +             return ret;
>> +
>> +     ret = src_file->f_op->clone_range(src_file, dst_file, off, len, dstoff);
>> +     if (!ret) {
>> +             fsnotify_access(src_file);
>> +             fsnotify_modify(dst_file);
>> +     }
>> +
>> +     mnt_drop_write_file(dst_file);
>> +
>> +     return ret;
>> +}
>> +EXPORT_SYMBOL(vfs_file_clone_range);
>> diff --git a/include/linux/fs.h b/include/linux/fs.h
>> index cc008c3..612d7f4 100644
>> --- a/include/linux/fs.h
>> +++ b/include/linux/fs.h
>> @@ -1628,6 +1628,8 @@ struct file_operations {
>>       long (*fallocate)(struct file *file, int mode, loff_t offset,
>>                         loff_t len);
>>       void (*show_fdinfo)(struct seq_file *m, struct file *f);
>> +     int (*clone_range)(struct file *src_file, struct file *dst_file,
>> +                        loff_t off, size_t len, loff_t dstoff);
>>  #ifndef CONFIG_MMU
>>       unsigned (*mmap_capabilities)(struct file *);
>>  #endif
>> @@ -2678,6 +2680,8 @@ int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t,
>>  int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *);
>>  #define dax_mkwrite(vma, vmf, gb, iod)               dax_fault(vma, vmf, gb, iod)
>>  #define __dax_mkwrite(vma, vmf, gb, iod)     __dax_fault(vma, vmf, gb, iod)
>> +int vfs_file_clone_range(struct file *src_file, struct file *dst_file,
>> +                      loff_t off, size_t len, loff_t dstoff);
>>
>>  #ifdef CONFIG_BLOCK
>>  typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
>> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
>> index 9b964a5..ac7f1c5 100644
>> --- a/include/uapi/linux/fs.h
>> +++ b/include/uapi/linux/fs.h
>> @@ -39,6 +39,13 @@
>>  #define RENAME_EXCHANGE              (1 << 1)        /* Exchange source and dest */
>>  #define RENAME_WHITEOUT              (1 << 2)        /* Whiteout source */
>>
>> +struct file_clone_range {
>> +     __s64 src_fd;
>> +     __u64 src_offset;
>> +     __u64 src_length;
>> +     __u64 dest_offset;
>> +};
>> +
>>  struct fstrim_range {
>>       __u64 start;
>>       __u64 len;
>> @@ -159,6 +166,8 @@ struct inodes_stat_t {
>>  #define FIFREEZE     _IOWR('X', 119, int)    /* Freeze */
>>  #define FITHAW               _IOWR('X', 120, int)    /* Thaw */
>>  #define FITRIM               _IOWR('X', 121, struct fstrim_range)    /* Trim */
>> +#define FICLONE              _IOW(0x94, 9, int)      /* Clone */
>> +#define FICLONERANGE _IOW(0x94, 13, struct file_clone_range) /* Clone range */
>>
>>  #define      FS_IOC_GETFLAGS                 _IOR('f', 1, long)
>>  #define      FS_IOC_SETFLAGS                 _IOW('f', 2, long)
>> --
>> 1.8.3.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation
       [not found]       ` <20150826080111.GV10756-1ReQVI26iDCaZKY3DrU6dA@public.gmane.org>
@ 2015-08-26  8:31         ` Peng Tao
       [not found]           ` <CAKVebiWy6S4ri8_V+SuT+mnyTKjiubPS49k3LHF2Csh2TVf_SQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Peng Tao @ 2015-08-26  8:31 UTC (permalink / raw)
  To: dsterba-AlSwsSmVLrQ, Peng Tao, Linux NFS Mailing List,
	Trond Myklebust, Anna Schumaker, Christoph Hellwig, Zach Brown,
	Darren Hart, Bruce Fields, Jeff Layton,
	linux-btrfs-u79uwXL29TY76Z2rM5mHXA, Devel FS Linux

On Wed, Aug 26, 2015 at 4:01 PM, David Sterba <dsterba-AlSwsSmVLrQ@public.gmane.org> wrote:
> On Tue, Aug 25, 2015 at 11:33:40PM +0800, Peng Tao wrote:
>> --- a/include/uapi/linux/btrfs.h
>> +++ b/include/uapi/linux/btrfs.h
>> @@ -316,12 +316,6 @@ struct btrfs_ioctl_search_args_v2 {
>>       __u64 buf[0];                       /* out - found items */
>>  };
>>
>> -struct btrfs_ioctl_clone_range_args {
>> -  __s64 src_fd;
>> -  __u64 src_offset, src_length;
>> -  __u64 dest_offset;
>> -};
>
> For backward compatibility and not-breaking-builds reasons, do not
> remove anything from this file.
>
Got you. I'll keep it unchanged in the next version.

>> -
>>  /* flags for the defrag range ioctl */
>>  #define BTRFS_DEFRAG_RANGE_COMPRESS 1
>>  #define BTRFS_DEFRAG_RANGE_START_IO 2
>> @@ -548,7 +542,6 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
>>  #define BTRFS_IOC_TRANS_END    _IO(BTRFS_IOCTL_MAGIC, 7)
>>  #define BTRFS_IOC_SYNC         _IO(BTRFS_IOCTL_MAGIC, 8)
>>
>> -#define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)
>
> The ioctl definition reuses the BTRFS_IOCTL_MAGIC (0x94), which is IMHO
> wrong.
>
I thought it breaks ABI if we choose a different value for the type
field of the ioctl. Am I misunderstanding it?

Thanks,
Tao
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation
       [not found]           ` <CAKVebiWy6S4ri8_V+SuT+mnyTKjiubPS49k3LHF2Csh2TVf_SQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2015-08-26 13:00             ` David Sterba
  2015-08-26 13:07               ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: David Sterba @ 2015-08-26 13:00 UTC (permalink / raw)
  To: Peng Tao
  Cc: Linux NFS Mailing List, Trond Myklebust, Anna Schumaker,
	Christoph Hellwig, Zach Brown, Darren Hart, Bruce Fields,
	Jeff Layton, linux-btrfs-u79uwXL29TY76Z2rM5mHXA, Devel FS Linux

On Wed, Aug 26, 2015 at 04:31:09PM +0800, Peng Tao wrote:
> >> -#define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)
> >
> > The ioctl definition reuses the BTRFS_IOCTL_MAGIC (0x94), which is IMHO
> > wrong.
> >
> I thought it breaks ABI if we choose a different value for the type
> field of the ioctl. Am I misunderstanding it?

The ioctl is now private to btrfs, you're going to define the new ABI so
it IMHO should use the generic filesystem ioctl magic/namespace.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation
  2015-08-26 13:00             ` David Sterba
@ 2015-08-26 13:07               ` Christoph Hellwig
  0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2015-08-26 13:07 UTC (permalink / raw)
  To: dsterba, Peng Tao, Linux NFS Mailing List, Trond Myklebust,
	Anna Schumaker, Christoph Hellwig, Zach Brown, Darren Hart,
	Bruce Fields, Jeff Layton, linux-btrfs, Devel FS Linux

On Wed, Aug 26, 2015 at 03:00:57PM +0200, David Sterba wrote:
> > I thought it breaks ABI if we choose a different value for the type
> > field of the ioctl. Am I misunderstanding it?
> 
> The ioctl is now private to btrfs, you're going to define the new ABI so
> it IMHO should use the generic filesystem ioctl magic/namespace.

No, that's completly backwards.  We move up ioctls that have prooven
to be generally useful to common code, and we've done that with various
extN and XFS ones already.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-08-26 13:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1440516829-116041-1-git-send-email-tao.peng@primarydata.com>
     [not found] ` <1440516829-116041-1-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2015-08-25 15:33   ` [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer Peng Tao
2015-08-26  1:40     ` Peng Tao
2015-08-26  1:50     ` Dave Chinner
2015-08-26  1:59       ` Dave Chinner
2015-08-26  4:09     ` Darrick J. Wong
     [not found]       ` <20150826040943.GC10038-PTl6brltDGh4DFYR7WNSRA@public.gmane.org>
2015-08-26  8:03         ` Peng Tao
2015-08-25 15:33 ` [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation Peng Tao
     [not found]   ` <1440516829-116041-3-git-send-email-tao.peng-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2015-08-26  8:01     ` David Sterba
     [not found]       ` <20150826080111.GV10756-1ReQVI26iDCaZKY3DrU6dA@public.gmane.org>
2015-08-26  8:31         ` Peng Tao
     [not found]           ` <CAKVebiWy6S4ri8_V+SuT+mnyTKjiubPS49k3LHF2Csh2TVf_SQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-08-26 13:00             ` David Sterba
2015-08-26 13:07               ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).