From 4ff291ebe80a226295351936d99fc6e3e7fce48a Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 19 Nov 2024 21:03:14 +0000 Subject: [PATCH] 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 --- 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 #include +#include #include #include #include #include +#include #include #include @@ -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 f5722851d729..4067ab4ba446 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1158,7 +1158,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