Page MenuHomeFreeBSD

D38803.id.diff
No OneTemporary

D38803.id.diff

diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3
--- a/lib/libc/gen/getvfsbyname.3
+++ b/lib/libc/gen/getvfsbyname.3
@@ -28,7 +28,7 @@
.\" @(#)kvm_getvfsbyname.3 8.3 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd August 16, 2018
+.Dd February 26, 2023
.Dt GETVFSBYNAME 3
.Os
.Sh NAME
@@ -92,6 +92,10 @@
.Va vfs.usermount
sysctl is set to
.Dv 1
+.It Dv VFCF_CROSS_COPY_FILE_RANGE
+supports file system specific
+.Xr copy_file_range 2
+across mount points.
.El
.Sh RETURN VALUES
.Rv -std getvfsbyname
@@ -105,6 +109,7 @@
specifies a file system that is unknown or not configured in the kernel.
.El
.Sh SEE ALSO
+.Xr copy_file_range 2 ,
.Xr jail 2 ,
.Xr mount 2 ,
.Xr sysctl 3 ,
diff --git a/share/man/man9/VFS_SET.9 b/share/man/man9/VFS_SET.9
--- a/share/man/man9/VFS_SET.9
+++ b/share/man/man9/VFS_SET.9
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 16, 2018
+.Dd February 26, 2023
.Dt VFS_SET 9
.Os
.Sh NAME
@@ -57,7 +57,7 @@
Possible values for the
.Fa flags
argument are:
-.Bl -hang -width ".Dv VFCF_DELEGADMIN"
+.Bl -tag -width ".Dv VFCF_DELEGADMIN"
.It Dv VFCF_STATIC
File system should be statically available in the kernel.
.It Dv VFCF_NETWORK
@@ -84,6 +84,11 @@
.It Dv VFCF_SBDRY
When in VFS method, the thread suspension is deferred to the user
boundary upon arrival of stop action.
+.It Dv VFCF_CROSS_COPY_FILE_RANGE
+Allow
+.Xr copy_file_range 2
+to call file system specific VOP even for different mount points,
+but the same file system type.
.El
.Sh PSEUDOCODE
.Bd -literal
@@ -102,6 +107,7 @@
VFS_SET(myfs_vfsops, myfs, 0);
.Ed
.Sh SEE ALSO
+.Xr copy_file_range 2 ,
.Xr jail 2 ,
.Xr jail 8 ,
.Xr DECLARE_MODULE 9 ,
diff --git a/share/man/man9/VOP_COPY_FILE_RANGE.9 b/share/man/man9/VOP_COPY_FILE_RANGE.9
--- a/share/man/man9/VOP_COPY_FILE_RANGE.9
+++ b/share/man/man9/VOP_COPY_FILE_RANGE.9
@@ -25,13 +25,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd February 26, 2023
.Dt VOP_COPY_FILE_RANGE 9
.Os
.Sh NAME
.Nm VOP_COPY_FILE_RANGE
.Nd copy a byte range from one file to another or within one file
-in a single file system
.Sh SYNOPSIS
.In sys/param.h
.In sys/vnode.h
@@ -50,6 +49,15 @@
.Sh DESCRIPTION
This entry point copies a byte range from one regular file to another
or within one file in a single file system.
+If the file system type is declared with the
+.Dv VFCF_CROSS_COPY_FILE_RANGE
+flag,
+.Nm VOP_COPY_FILE_RANGE
+will also be called if both
+.Fa invp
+and
+.Fa outvp
+reside under different mount points of the same file system type.
.Fa invp
and
.Fa outvp
@@ -138,7 +146,12 @@
Corrupted data was detected while reading/writing the files.
.It Bq Er ENOSPC
The file system is full.
+.It Bq Er EXDEV
+The file system was not able to perform the operation, but it should be still
+possible to perform generic copy.
.El
.Sh SEE ALSO
+.Xr copy_file_range 2 ,
+.Xr VFS_SET 9 ,
.Xr vn_rdwr 9 ,
.Xr vnode 9
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
@@ -3039,7 +3039,8 @@
off_t *outoffp, size_t *lenp, unsigned int flags, struct ucred *incred,
struct ucred *outcred, struct thread *fsize_td)
{
- int error;
+ struct vfsconf *invfc, *outvfc;
+ int error, crosscopy;
size_t len;
uint64_t uval;
@@ -3068,18 +3069,29 @@
if (len == 0)
goto out;
+ *lenp = len;
+
/*
- * If the two vnode are for the same file system, call
- * VOP_COPY_FILE_RANGE(), otherwise call vn_generic_copy_file_range()
- * which can handle copies across multiple file systems.
+ * If the two vnode are for the same file system or this is the same
+ * file system type and it supports cross-mount-point copy_file_range()
+ * (like ZFS), call VOP_COPY_FILE_RANGE(), otherwise call
+ * vn_generic_copy_file_range() which can handle copies across multiple
+ * file systems.
*/
- *lenp = len;
- if (invp->v_mount == outvp->v_mount)
+ invfc = invp->v_mount->mnt_vfc;
+ outvfc = outvp->v_mount->mnt_vfc;
+ crosscopy = (invfc == outvfc &&
+ (outvfc->vfc_flags & VFCF_CROSS_COPY_FILE_RANGE) != 0);
+
+ if (invp->v_mount == outvp->v_mount || crosscopy) {
error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp,
lenp, flags, incred, outcred, fsize_td);
- else
- error = vn_generic_copy_file_range(invp, inoffp, outvp,
- outoffp, lenp, flags, incred, outcred, fsize_td);
+ /* EXDEV means that we should try generic copy. */
+ if (error != EXDEV)
+ goto out;
+ }
+ error = vn_generic_copy_file_range(invp, inoffp, outvp, outoffp, lenp,
+ flags, incred, outcred, fsize_td);
out:
return (error);
}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -681,6 +681,10 @@
#define VFCF_SBDRY 0x01000000 /* Stop at Boundary: defer stop requests
to kernel->user (AST) transition */
#define VFCF_FILEMOUNT 0x02000000 /* allow mounting files */
+#define VFCF_CROSS_COPY_FILE_RANGE \
+ 0x04000000 /* allow copy_file_range(2) between
+ different mount points of the same
+ file system type */
typedef uint32_t fsctlop_t;
diff --git a/usr.bin/lsvfs/lsvfs.c b/usr.bin/lsvfs/lsvfs.c
--- a/usr.bin/lsvfs/lsvfs.c
+++ b/usr.bin/lsvfs/lsvfs.c
@@ -34,6 +34,7 @@
{ .flag = VFCF_UNICODE, .str = "unicode", },
{ .flag = VFCF_JAIL, .str = "jail", },
{ .flag = VFCF_DELEGADMIN, .str = "delegated-administration", },
+ { .flag = VFCF_CROSS_COPY_FILE_RANGE, .str = "cross-copy_file_range", },
};
static const char *fmt_flags(int);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 28, 10:17 PM (17 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32308600
Default Alt Text
D38803.id.diff (5 KB)

Event Timeline