diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c --- a/sys/fs/fuse/fuse_vnops.c +++ b/sys/fs/fuse/fuse_vnops.c @@ -877,6 +877,9 @@ pid_t pid; int err; + if ((ap->a_flags & COPY_FILE_RANGE_CLONE) != 0) + return (EXTERROR(ENOSYS, "Cannot clone")); + if (mp == NULL || mp != vnode_mount(outvp)) return (EXTERROR(ENOSYS, "Mount points do not match")); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -457,6 +457,7 @@ case _PC_NAMEDATTR_ENABLED: case _PC_HAS_NAMEDATTR: case _PC_HAS_HIDDENSYSTEM: + case _PC_CLONE_BLKSIZE: *ap->a_retval = 0; return (0); default: diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -5058,7 +5058,7 @@ error = 0; retlen = 0; - if (flags != 0) { + if ((flags & ~COPY_FILE_RANGE_USERFLAGS) != 0) { error = EINVAL; goto out; } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3443,6 +3443,11 @@ interrupted = 0; dat = NULL; + if ((flags & COPY_FILE_RANGE_CLONE) != 0) { + error = ENOSYS; + goto out; + } + error = vn_lock(invp, LK_SHARED); if (error != 0) goto out; diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -159,6 +159,7 @@ #define _PC_XATTR_ENABLED _PC_NAMEDATTR_ENABLED /* Solaris Compatible */ #define _PC_XATTR_EXISTS _PC_HAS_NAMEDATTR /* Solaris Compatible */ #define _PC_HAS_HIDDENSYSTEM 68 +#define _PC_CLONE_BLKSIZE 69 #endif /* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -397,8 +397,21 @@ */ #define VLKTIMEOUT (hz / 20 + 1) +/* copy_file_range flags */ +#define COPY_FILE_RANGE_KFLAGS 0xff000000 + +/* + * copy_file_range flags visible to user space. + * Allocate high bits first, to try and avoid conflicting with Linux. + */ +#define COPY_FILE_RANGE_CLONE 0x00800000 /* Require cloning. */ +#define COPY_FILE_RANGE_USERFLAGS (COPY_FILE_RANGE_CLONE) + #ifdef _KERNEL +/* copy_file_range flags only usable in the kernel */ +#define COPY_FILE_RANGE_TIMEO1SEC 0x01000000 /* Return after 1sec. */ + #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_VNODE); #endif @@ -621,10 +634,6 @@ #define VN_OPEN_INVFS 0x00000008 #define VN_OPEN_WANTIOCTLCAPS 0x00000010 -/* copy_file_range kernel flags */ -#define COPY_FILE_RANGE_KFLAGS 0xff000000 -#define COPY_FILE_RANGE_TIMEO1SEC 0x01000000 /* Return after 1sec. */ - /* * Public vnode manipulation functions. */