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); }