pseudofs: make readdir work without a pid again

Specifically, the following was broken:

$ mount -t procfs procfs /proc
$ ls -l /proc

r351741 reworked readdir slightly to avoid pfs_node/pidhash LOR, but
inadvertently regressed pid == NO_PID; new pfs_lookup_proc() fails for the
obvious reasons, and later pfs_visible_proc doesn't capture the
pid == NO_PID -> return 1 aspect of pfs_visible. We can infact skip this
whole block if we're operating on a directory w/ NO_PID, as it's always
visible.

Reported by:	trasz
Reviewed by:	mjg
Differential Revision:	https://reviews.freebsd.org/D21518
This commit is contained in:
Kyle Evans 2019-09-04 14:20:39 +00:00
parent f0298be018
commit f99c5e8d28

View File

@ -809,24 +809,29 @@ pfs_readdir(struct vop_readdir_args *va)
if (resid == 0) if (resid == 0)
PFS_RETURN (0); PFS_RETURN (0);
if (!pfs_lookup_proc(pid, &proc)) proc = NULL;
if (pid != NO_PID && !pfs_lookup_proc(pid, &proc))
PFS_RETURN (ENOENT); PFS_RETURN (ENOENT);
sx_slock(&allproc_lock); sx_slock(&allproc_lock);
pfs_lock(pd); pfs_lock(pd);
PROC_LOCK(proc);
/* check if the directory is visible to the caller */
if (!pfs_visible_proc(curthread, pd, proc)) {
_PRELE(proc);
PROC_UNLOCK(proc);
sx_sunlock(&allproc_lock);
pfs_unlock(pd);
PFS_RETURN (ENOENT);
}
KASSERT(pid == NO_PID || proc != NULL, KASSERT(pid == NO_PID || proc != NULL,
("%s(): no process for pid %lu", __func__, (unsigned long)pid)); ("%s(): no process for pid %lu", __func__, (unsigned long)pid));
if (pid != NO_PID) {
PROC_LOCK(proc);
/* check if the directory is visible to the caller */
if (!pfs_visible_proc(curthread, pd, proc)) {
_PRELE(proc);
PROC_UNLOCK(proc);
sx_sunlock(&allproc_lock);
pfs_unlock(pd);
PFS_RETURN (ENOENT);
}
}
/* skip unwanted entries */ /* skip unwanted entries */
for (pn = NULL, p = NULL; offset > 0; offset -= PFS_DELEN) { for (pn = NULL, p = NULL; offset > 0; offset -= PFS_DELEN) {
if (pfs_iterate(curthread, proc, pd, &pn, &p) == -1) { if (pfs_iterate(curthread, proc, pd, &pn, &p) == -1) {