git: e59a3bb02863 - stable/14 - vfs: Fix vop_stdis_text()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 28 Nov 2024 14:38:56 UTC
The branch stable/14 has been updated by markj:

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

commit e59a3bb02863a5a24523bf826682a1de8b27d74e
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-11-19 21:03:14 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-11-28 14:38:17 +0000

    vfs: Fix vop_stdis_text()
    
    atomic(9) primitives are documented as operating on unsigned types.
    Here, we need a cast to avoid a tautological comparison.
    
    Add a regression test for access(2), which was affected by the bug.
    
    Reported by:    NetApp
    Reviewed by:    kib
    Fixes:          e511bd1406fa ("vfs: fully lockless v_writecount adjustment")
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Sponsored by:   NetApp, Inc.
    Differential Revision:  https://reviews.freebsd.org/D47672
    
    (cherry picked from commit 4ff291ebe80a226295351936d99fc6e3e7fce48a)
---
 contrib/netbsd-tests/lib/libc/sys/t_access.c | 35 ++++++++++++++++++++++++++++
 sys/kern/vfs_default.c                       |  2 +-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c
index b37643c57d7d..f973aba3fb4a 100644
--- a/contrib/netbsd-tests/lib/libc/sys/t_access.c
+++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c
@@ -38,11 +38,13 @@ __RCSID("$NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $");
 #include <atf-c.h>
 
 #include <sys/stat.h>
+#include <sys/sysctl.h>
 
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -176,6 +178,38 @@ ATF_TC_BODY(access_notexist, tc)
 	}
 }
 
+ATF_TC(access_text);
+ATF_TC_HEAD(access_text, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test access(2) for ETXTBSY");
+}
+
+ATF_TC_BODY(access_text, tc)
+{
+	char path[PATH_MAX];
+	size_t sz;
+	int fd, name[4];
+
+	name[0] = CTL_KERN;
+	name[1] = KERN_PROC;
+	name[2] = KERN_PROC_PATHNAME;
+	name[3] = -1;
+
+	sz = sizeof(path);
+	ATF_REQUIRE(sysctl(name, 4, path, &sz, NULL, 0) == 0);
+
+	fd = open(path, O_RDONLY);
+	ATF_REQUIRE(fd >= 0);
+
+	ATF_REQUIRE(access(path, W_OK) != 0);
+	ATF_REQUIRE(errno == ETXTBSY);
+
+	ATF_REQUIRE(faccessat(AT_FDCWD, path, W_OK, 0) != 0);
+	ATF_REQUIRE(errno == ETXTBSY);
+
+	ATF_REQUIRE(close(fd) == 0);
+}
+
 ATF_TC(access_toolong);
 ATF_TC_HEAD(access_toolong, tc)
 {
@@ -214,6 +248,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, access_inval);
 	ATF_TP_ADD_TC(tp, access_notdir);
 	ATF_TP_ADD_TC(tp, access_notexist);
+	ATF_TP_ADD_TC(tp, access_text);
 	ATF_TP_ADD_TC(tp, access_toolong);
 
 	return atf_no_error();
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index c2bded76f6dc..69a7a2cb472c 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1161,7 +1161,7 @@ static int
 vop_stdis_text(struct vop_is_text_args *ap)
 {
 
-	return (atomic_load_int(&ap->a_vp->v_writecount) < 0);
+	return ((int)atomic_load_int(&ap->a_vp->v_writecount) < 0);
 }
 
 int