git: 4e1f29b92dc5 - main - kern_copy_file_range(): handle rangelock recursion

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 28 Aug 2024 14:49:59 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=4e1f29b92dc5fdc84d646eb3c16a4155b6ec688d

commit 4e1f29b92dc5fdc84d646eb3c16a4155b6ec688d
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-08-27 21:34:16 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-08-28 14:34:40 +0000

    kern_copy_file_range(): handle rangelock recursion
    
    PR:     281073
    Reviewed by:    markj
    Tested by:      lwhsu
    Sponsored by:   The FreeBSD Foundation
    Differential revision:  https://reviews.freebsd.org/D46465
---
 sys/kern/vfs_syscalls.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 28ab3080c075..ab0e562e73aa 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4978,11 +4978,13 @@ kern_copy_file_range(struct thread *td, int infd, off_t *inoffp, int outfd,
 	 * If infp and outfp refer to the same file, the byte ranges cannot
 	 * overlap.
 	 */
-	if (invp == outvp && ((savinoff <= savoutoff && savinoff + len >
-	    savoutoff) || (savinoff > savoutoff && savoutoff + len >
-	    savinoff))) {
-		error = EINVAL;
-		goto out;
+	if (invp == outvp) {
+		if ((savinoff <= savoutoff && savinoff + len > savoutoff) ||
+		    (savinoff > savoutoff && savoutoff + len > savinoff)) {
+			error = EINVAL;
+			goto out;
+		}
+		rangelock_may_recurse(&invp->v_rl);
 	}
 
 	/* Range lock the byte ranges for both invp and outvp. */