git: 23210f538a00 - main - vn_copy_file_range(): busy both in and out mp around call to VOP_COPY_FILE_RANGE()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 13 Nov 2023 22:28:02 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=23210f538a008788b2e16b9eddafa4f598a21663
commit 23210f538a008788b2e16b9eddafa4f598a21663
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-11-12 18:37:29 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-11-13 22:26:34 +0000
vn_copy_file_range(): busy both in and out mp around call to VOP_COPY_FILE_RANGE()
This is required e.g. for nullfs to ensure liveness of the lower mount
points.
Reviewed by: jah, rmacklem, Olivier Certner <olce.freebsd@certner.fr>
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D42554
---
sys/kern/vfs_vnops.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index e2227537dde1..27ce5401f15f 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3078,6 +3078,29 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp,
inmp = invp->v_mount;
outmp = outvp->v_mount;
+ if (inmp == NULL || outmp == NULL) {
+ error = EBADF;
+ goto out;
+ }
+
+ for (;;) {
+ error = vfs_busy(inmp, 0);
+ if (error != 0)
+ goto out;
+ if (inmp == outmp)
+ break;
+ error = vfs_busy(outmp, MBF_NOWAIT);
+ if (error != 0) {
+ vfs_unbusy(inmp);
+ error = vfs_busy(outmp, 0);
+ if (error == 0) {
+ vfs_unbusy(outmp);
+ continue;
+ }
+ goto out;
+ }
+ break;
+ }
/*
* If the two vnodes are for the same file system type, call
@@ -3092,6 +3115,9 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp,
else
error = vn_generic_copy_file_range(invp, inoffp, outvp,
outoffp, lenp, flags, incred, outcred, fsize_td);
+ vfs_unbusy(outmp);
+ if (inmp != outmp)
+ vfs_unbusy(inmp);
out:
return (error);
}