git: 77b273d8f5f4 - main - vfs: Assert that VOP_READDIR sets *eofflag properly
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Jul 2025 16:23:01 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=77b273d8f5f40939841952cf8daf6e934922d264
commit 77b273d8f5f40939841952cf8daf6e934922d264
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-07-23 01:52:13 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-23 16:20:31 +0000
vfs: Assert that VOP_READDIR sets *eofflag properly
Suggested by: kib
Reviewed by: olce, kib
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D51300
---
sys/kern/vfs_subr.c | 11 -----------
sys/kern/vnode_if.src | 1 +
sys/sys/vnode.h | 29 ++++++++++++++++++++++++++++-
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 918b256e6c59..29774cf87393 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -6533,17 +6533,6 @@ vop_read_pgcache_post(void *ap, int rc)
VFS_KNOTE_UNLOCKED(a->a_vp, NOTE_READ);
}
-void
-vop_readdir_post(void *ap, int rc)
-{
- struct vop_readdir_args *a = ap;
-
- if (!rc) {
- VFS_KNOTE_LOCKED(a->a_vp, NOTE_READ);
- INOTIFY(a->a_vp, IN_ACCESS);
- }
-}
-
static struct knlist fs_knlist;
static void
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 38138a4af921..4684eb8a7d77 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -380,6 +380,7 @@ vop_symlink {
%% readdir vp L L L
+%! readdir pre vop_readdir_pre
%! readdir post vop_readdir_post
vop_readdir {
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 2c6947103c94..201e260c41f5 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -939,7 +939,6 @@ void vop_mknod_post(void *a, int rc);
void vop_open_post(void *a, int rc);
void vop_read_post(void *a, int rc);
void vop_read_pgcache_post(void *ap, int rc);
-void vop_readdir_post(void *a, int rc);
void vop_reclaim_post(void *a, int rc);
void vop_remove_pre(void *a);
void vop_remove_post(void *a, int rc);
@@ -1015,6 +1014,34 @@ void vop_rename_fail(struct vop_rename_args *ap);
_error; \
})
+#ifdef INVARIANTS
+#define vop_readdir_pre_assert(ap) \
+ ssize_t nresid, oresid; \
+ \
+ oresid = (ap)->a_uio->uio_resid;
+
+#define vop_readdir_post_assert(ap, ret) \
+ nresid = (ap)->a_uio->uio_resid; \
+ if ((ret) == 0 && (ap)->a_eofflag != NULL) { \
+ VNASSERT(nresid != oresid || *(ap)->a_eofflag == 1, \
+ (ap)->a_vp, ("VOP_READDIR: eofflag not set")); \
+ }
+#else
+#define vop_readdir_pre_assert(ap)
+#define vop_readdir_post_assert(ap, ret)
+#endif
+
+#define vop_readdir_pre(ap) do { \
+ vop_readdir_pre_assert(ap)
+
+#define vop_readdir_post(ap, ret) \
+ vop_readdir_post_assert(ap, ret); \
+ if ((ret) == 0) { \
+ VFS_KNOTE_LOCKED((ap)->a_vp, NOTE_READ); \
+ INOTIFY((ap)->a_vp, IN_ACCESS); \
+ } \
+} while (0)
+
#define VOP_WRITE_PRE(ap) \
struct vattr va; \
int error; \