Add a PFS_DISABLED flag; pfs_visible() automatically returns 0 if it is set
on the node in question. Also add two API functions for setting and clearing this flag; setting it also reclaims all vnodes associated with the node.
This commit is contained in:
parent
1c3903d23f
commit
b84ce33438
@ -57,6 +57,7 @@ typedef enum {
|
||||
#define PFS_RAWRD 0x0004 /* raw reader */
|
||||
#define PFS_RAWWR 0x0008 /* raw writer */
|
||||
#define PFS_RAW (PFS_RAWRD|PFS_RAWWR)
|
||||
#define PFS_DISABLED 0x8000 /* node is disabled */
|
||||
|
||||
/*
|
||||
* Data structures
|
||||
@ -164,6 +165,12 @@ int pfs_statfs (struct mount *mp, struct statfs *sbp,
|
||||
int pfs_init (struct pfs_info *pi, struct vfsconf *vfc);
|
||||
int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc);
|
||||
|
||||
/*
|
||||
* Other utility functions
|
||||
*/
|
||||
int pfs_disable (struct pfs_node *pn);
|
||||
int pfs_enable (struct pfs_node *pn);
|
||||
|
||||
/*
|
||||
* Now for some initialization magic...
|
||||
*/
|
||||
|
@ -92,6 +92,9 @@ void
|
||||
pfs_vncache_unload(void)
|
||||
{
|
||||
rm_at_exit(pfs_exit);
|
||||
if (pfs_vncache_entries != 0)
|
||||
printf("pfs_vncache_unload(): %d entries remaining\n",
|
||||
pfs_vncache_entries);
|
||||
mtx_destroy(&pfs_vncache_mutex);
|
||||
}
|
||||
|
||||
@ -217,3 +220,38 @@ pfs_exit(struct proc *p)
|
||||
}
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable a pseudofs node, and free all vnodes associated with it
|
||||
*/
|
||||
int
|
||||
pfs_disable(struct pfs_node *pn)
|
||||
{
|
||||
struct pfs_vdata *pvd, *prev;
|
||||
|
||||
if (pn->pn_flags & PFS_DISABLED)
|
||||
return (0);
|
||||
mtx_lock(&pfs_vncache_mutex);
|
||||
pn->pn_flags |= PFS_DISABLED;
|
||||
/* see the comment about the double loop in pfs_exit() */
|
||||
/* XXX linear search... not very efficient */
|
||||
for (pvd = pfs_vncache; pvd != NULL; pvd = pvd->pvd_next) {
|
||||
while (pvd != NULL && pvd->pvd_pn == pn) {
|
||||
prev = pvd->pvd_prev;
|
||||
vgone(pvd->pvd_vnode);
|
||||
pvd = prev ? prev->pvd_next : pfs_vncache;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-enable a disabled pseudofs node
|
||||
*/
|
||||
int
|
||||
pfs_enable(struct pfs_node *pn)
|
||||
{
|
||||
pn->pn_flags &= ~PFS_DISABLED;
|
||||
return (0);
|
||||
}
|
||||
|
@ -77,17 +77,20 @@ pfs_visible(struct thread *td, struct pfs_node *pn, pid_t pid)
|
||||
|
||||
PFS_TRACE(("%s (pid: %d, req: %d)",
|
||||
pn->pn_name, pid, td->td_proc->p_pid));
|
||||
if (pid == NO_PID)
|
||||
PFS_RETURN (1);
|
||||
|
||||
if (pn->pn_flags & PFS_DISABLED)
|
||||
PFS_RETURN (0);
|
||||
|
||||
r = 1;
|
||||
if ((proc = pfind(pid)) == NULL)
|
||||
PFS_RETURN (0);
|
||||
/* XXX should lock td->td_proc? */
|
||||
if (p_cansee(td->td_proc, proc) != 0 ||
|
||||
(pn->pn_vis != NULL && !(pn->pn_vis)(td, proc, pn)))
|
||||
r = 0;
|
||||
PROC_UNLOCK(proc);
|
||||
if (pid != NO_PID) {
|
||||
if ((proc = pfind(pid)) == NULL)
|
||||
PFS_RETURN (0);
|
||||
/* XXX should lock td->td_proc? */
|
||||
if (p_cansee(td->td_proc, proc) != 0 ||
|
||||
(pn->pn_vis != NULL && !(pn->pn_vis)(td, proc, pn)))
|
||||
r = 0;
|
||||
PROC_UNLOCK(proc);
|
||||
}
|
||||
PFS_RETURN (r);
|
||||
}
|
||||
|
||||
@ -150,7 +153,6 @@ pfs_getattr(struct vop_getattr_args *va)
|
||||
|
||||
switch (pn->pn_type) {
|
||||
case pfstype_procdir:
|
||||
/* XXX needs p_cansee */
|
||||
case pfstype_root:
|
||||
case pfstype_dir:
|
||||
vap->va_mode = 0555;
|
||||
|
Loading…
x
Reference in New Issue
Block a user