git: e9b713513a78 - main - pseudofs: Simplify pfs_readdir() and set eofflag
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Jul 2025 16:22:59 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=e9b713513a78ccb01dbfa1a3f087f94b33531787
commit e9b713513a78ccb01dbfa1a3f087f94b33531787
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-07-23 01:52:38 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-23 16:20:31 +0000
pseudofs: Simplify pfs_readdir() and set eofflag
There were two loops, one to skip entries before the requested offset,
and one to populate entries. Merge them and use the return value of
pfs_iterate() to decide whether to set eofflag.
As a side effect, this fixes a small bug: the first loop would decrement
`offset` to zero, and the second loop would increment it again.
However, `offset` was used to set `d_off`, and we should include the
starting offset there.
Add a comment explaining the use of the allproc lock.
Reviewed by: des, kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D51462
---
sys/fs/pseudofs/pseudofs_vnops.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 0bdfedffafcb..8cd092118d0e 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -850,7 +850,7 @@ pfs_readdir(struct vop_readdir_args *va)
struct uio *uio;
struct pfsentry *pfsent, *pfsent2;
struct pfsdirentlist lst;
- off_t offset;
+ off_t coffset, offset;
int error, i, resid;
STAILQ_INIT(&lst);
@@ -860,6 +860,9 @@ pfs_readdir(struct vop_readdir_args *va)
PFS_TRACE(("%s pid %lu", pd->pn_name, (unsigned long)pid));
pfs_assert_not_owned(pd);
+ if (va->a_eofflag != NULL)
+ *va->a_eofflag = 0;
+
if (vn->v_type != VDIR)
PFS_RETURN (ENOTDIR);
KASSERT_PN_IS_DIR(pd);
@@ -878,6 +881,10 @@ pfs_readdir(struct vop_readdir_args *va)
if (pid != NO_PID && !pfs_lookup_proc(pid, &proc))
PFS_RETURN (ENOENT);
+ /*
+ * The allproc lock is required in pfs_iterate() for procdir
+ * directories.
+ */
sx_slock(&allproc_lock);
pfs_lock(pd);
@@ -897,23 +904,15 @@ pfs_readdir(struct vop_readdir_args *va)
}
}
- /* skip unwanted entries */
- for (pn = NULL, p = NULL; offset > 0; offset -= PFS_DELEN) {
+ for (pn = NULL, p = NULL, coffset = 0; resid >= PFS_DELEN;
+ coffset += PFS_DELEN) {
if (pfs_iterate(curthread, proc, pd, &pn, &p) == -1) {
- /* nothing left... */
- if (proc != NULL) {
- _PRELE(proc);
- PROC_UNLOCK(proc);
- }
- pfs_unlock(pd);
- sx_sunlock(&allproc_lock);
- PFS_RETURN (0);
+ if (va->a_eofflag != NULL)
+ *va->a_eofflag = 1;
+ break;
}
- }
-
- /* fill in entries */
- while (pfs_iterate(curthread, proc, pd, &pn, &p) != -1 &&
- resid >= PFS_DELEN) {
+ if (coffset < offset)
+ continue;
if ((pfsent = malloc(sizeof(struct pfsentry), M_IOV,
M_NOWAIT | M_ZERO)) == NULL) {
error = ENOMEM;