From da96d2410a9b9a69efa0c6f3ed1087c224061089 Mon Sep 17 00:00:00 2001 From: des Date: Sun, 10 Jun 2001 18:39:21 +0000 Subject: Add support for process-dependent directories. This means that save for the lack of a man page, pseudofs is mostly complete now. --- sys/fs/pseudofs/pseudofs.c | 2 +- sys/fs/pseudofs/pseudofs.h | 22 ++-- sys/fs/pseudofs/pseudofs_fileno.c | 26 ++--- sys/fs/pseudofs/pseudofs_internal.h | 16 +-- sys/fs/pseudofs/pseudofs_vncache.c | 57 ++++++---- sys/fs/pseudofs/pseudofs_vnops.c | 219 +++++++++++++++++++++--------------- 6 files changed, 195 insertions(+), 147 deletions(-) (limited to 'sys/fs') diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index 24379aa..e74c683 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -101,7 +101,7 @@ pfs_root(struct mount *mp, struct vnode **vpp) struct pfs_info *pi; pi = (struct pfs_info *)mp->mnt_data; - return pfs_vncache_alloc(mp, vpp, pi->pi_root); + return pfs_vncache_alloc(mp, vpp, pi->pi_root, NO_PID); } /* diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index 928d2db..539a04d 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -45,12 +45,9 @@ typedef enum { pfstype_parent, pfstype_file, pfstype_symlink, - pfstype_procdep + pfstype_procdir } pfs_type_t; -/* Flags */ -#define PFS_DYNAMIC 1 - /* * Data structures */ @@ -58,7 +55,11 @@ struct pfs_info; struct pfs_node; struct pfs_bitmap; -typedef int (*pfs_fill_t)(struct pfs_node *, struct proc *, struct sbuf *); +#define PFS_FILL_ARGS \ + struct proc *curp, struct proc *p, struct pfs_node *pn, struct sbuf *sb +#define PFS_FILL_PROTO(name) \ + int name(PFS_FILL_ARGS); +typedef int (*pfs_fill_t)(PFS_FILL_ARGS); struct pfs_bitmap; /* opaque */ @@ -75,7 +76,7 @@ struct pfs_info { }; /* - * pfs_node: describes a node (file or directory) within a pseudofs + * pfs_node: describes a node (file or directory) within a pseudofs */ struct pfs_node { char pn_name[PFS_NAMELEN]; @@ -94,12 +95,7 @@ struct pfs_node { #define pn_nodes u1._pn_nodes /* members below this line aren't initialized */ struct pfs_node *pn_parent; - union { - u_int32_t _pn_fileno; - struct pfs_node *_pn_shadow; - } u2; -#define pn_fileno u2._pn_fileno -#define pn_shadow u2._pn_shadow + u_int32_t pn_fileno; }; #define PFS_NODE(name, type, flags, uid, gid, mode, data) \ @@ -116,6 +112,8 @@ struct pfs_node { PFS_NODE(name, pfstype_file, flags, uid, gid, mode, func) #define PFS_SYMLINK(name, flags, uid, gid, mode, func) \ PFS_NODE(name, pfstype_symlink, flags, uid, gid, mode, func) +#define PFS_PROCDIR(uid, gid, mode, nodes) \ + PFS_NODE("", pfstype_procdir, 0, uid, gid, mode, nodes) #define PFS_LASTNODE \ PFS_NODE("", pfstype_none, 0, 0, 0, 0, NULL) diff --git a/sys/fs/pseudofs/pseudofs_fileno.c b/sys/fs/pseudofs/pseudofs_fileno.c index f27b885..fa23edf 100644 --- a/sys/fs/pseudofs/pseudofs_fileno.c +++ b/sys/fs/pseudofs/pseudofs_fileno.c @@ -43,12 +43,12 @@ #include #include -static MALLOC_DEFINE(M_PFSFILENO, "pseudofs_fileno", "pseudofs fileno bitmap"); +static MALLOC_DEFINE(M_PFSFILENO, "pfs_fileno", "pseudofs fileno bitmap"); static struct mtx pfs_fileno_mutex; #define PFS_BITMAP_SIZE 4096 -#define PFS_SLOT_BITS (sizeof(unsigned int) * CHAR_BIT) +#define PFS_SLOT_BITS (int)(sizeof(unsigned int) * CHAR_BIT) #define PFS_BITMAP_BITS (PFS_BITMAP_SIZE * PFS_SLOT_BITS) struct pfs_bitmap { u_int32_t pb_offset; @@ -117,8 +117,11 @@ pfs_fileno_uninit(struct pfs_info *pi) used += pb->pb_used; FREE(pb, M_PFSFILENO); } +#if 0 + /* we currently don't reclaim filenos */ if (used > 2) printf("WARNING: %d file numbers still in use\n", used); +#endif } /* @@ -202,6 +205,7 @@ pfs_free_fileno(struct pfs_info *pi, u_int32_t fileno) --pb->pb_used; mtx_unlock(&pi->pi_mutex); + printf("pfs_free_fileno(): reclaimed %d\n", fileno); } /* @@ -219,6 +223,7 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn) case pfstype_dir: case pfstype_file: case pfstype_symlink: + case pfstype_procdir: pn->pn_fileno = pfs_get_fileno(pi); break; case pfstype_this: @@ -237,16 +242,13 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn) ("pfstype_parent node has no grandparent")); pn->pn_fileno = pn->pn_parent->pn_parent->pn_fileno; break; - case pfstype_procdep: - KASSERT(1, - ("pfs_fileno_alloc() called for pfstype_procdep node")); - break; case pfstype_none: - KASSERT(1, + KASSERT(0, ("pfs_fileno_alloc() called for pfstype_none node")); break; } - + +#if 0 printf("pfs_fileno_alloc(): %s: ", pi->pi_name); if (pn->pn_parent) { if (pn->pn_parent->pn_parent) { @@ -255,6 +257,7 @@ pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn) printf("%s/", pn->pn_parent->pn_name); } printf("%s -> %d\n", pn->pn_name, pn->pn_fileno); +#endif } /* @@ -268,18 +271,15 @@ pfs_fileno_free(struct pfs_info *pi, struct pfs_node *pn) case pfstype_dir: case pfstype_file: case pfstype_symlink: + case pfstype_procdir: pfs_free_fileno(pi, pn->pn_fileno); break; case pfstype_this: case pfstype_parent: /* ignore these, as they don't "own" their file number */ break; - case pfstype_procdep: - KASSERT(1, - ("pfs_fileno_free() called for pfstype_procdep node")); - break; case pfstype_none: - KASSERT(1, + KASSERT(0, ("pfs_fileno_free() called for pfstype_none node")); break; } diff --git a/sys/fs/pseudofs/pseudofs_internal.h b/sys/fs/pseudofs/pseudofs_internal.h index 0e25c47..9307466 100644 --- a/sys/fs/pseudofs/pseudofs_internal.h +++ b/sys/fs/pseudofs/pseudofs_internal.h @@ -37,12 +37,20 @@ SYSCTL_DECL(_vfs_pfs); /* + * Vnode data + */ +struct pfs_vdata { + struct pfs_node *pvd_pn; + pid_t pvd_pid; +}; + +/* * Vnode cache */ void pfs_vncache_load (void); void pfs_vncache_unload (void); int pfs_vncache_alloc (struct mount *, struct vnode **, - struct pfs_node *); + struct pfs_node *, pid_t pid); int pfs_vncache_free (struct vnode *); /* @@ -55,10 +63,4 @@ void pfs_fileno_uninit (struct pfs_info *); void pfs_fileno_alloc (struct pfs_info *, struct pfs_node *); void pfs_fileno_free (struct pfs_info *, struct pfs_node *); -/* - * Shadow manager - */ -void pfs_create_shadow (struct pfs_info *, struct pfs_node *, pid_t); -void pfs_reap_shadows (pid_t); - #endif diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c index 8c822f2..f222f64 100644 --- a/sys/fs/pseudofs/pseudofs_vncache.c +++ b/sys/fs/pseudofs/pseudofs_vncache.c @@ -41,7 +41,7 @@ #include #include -static MALLOC_DEFINE(M_PFSVNCACHE, "pseudofs_vncache", "pseudofs vnode cache"); +static MALLOC_DEFINE(M_PFSVNCACHE, "pfs_vncache", "pseudofs vnode cache"); static struct mtx pfs_vncache_mutex; @@ -85,32 +85,40 @@ pfs_vncache_unload(void) * Allocate a vnode */ int -pfs_vncache_alloc(struct mount *mp, struct vnode **vpp, struct pfs_node *pn) +pfs_vncache_alloc(struct mount *mp, struct vnode **vpp, + struct pfs_node *pn, pid_t pid) { struct pfs_vnode *pv; + struct pfs_vdata *pvd; int error; - mtx_lock(&pfs_vncache_mutex); - /* see if the vnode is in the cache */ - for (pv = pfs_vncache; pv; pv = pv->pv_next) - if (pv->pv_vnode->v_data == pn) + mtx_lock(&pfs_vncache_mutex); + for (pv = pfs_vncache; pv; pv = pv->pv_next) { + pvd = (struct pfs_vdata *)pv->pv_vnode->v_data; + if (pvd->pvd_pn == pn && pvd->pvd_pid == pid) { if (vget(pv->pv_vnode, 0, curproc) == 0) { ++pfs_vncache_hits; *vpp = pv->pv_vnode; mtx_unlock(&pfs_vncache_mutex); return (0); } + /* XXX if this can happen, we're in trouble */ + break; + } + } + mtx_unlock(&pfs_vncache_mutex); ++pfs_vncache_misses; /* nope, get a new one */ MALLOC(pv, struct pfs_vnode *, sizeof *pv, M_PFSVNCACHE, M_WAITOK); + MALLOC(pvd, struct pfs_vdata *, sizeof *pvd, M_PFSVNCACHE, M_WAITOK); error = getnewvnode(VT_PSEUDOFS, mp, pfs_vnodeop_p, vpp); - if (error) { - mtx_unlock(&pfs_vncache_mutex); + if (error) return (error); - } - (*vpp)->v_data = pn; + pvd->pvd_pn = pn; + pvd->pvd_pid = pid; + (*vpp)->v_data = pvd; switch (pn->pn_type) { case pfstype_root: (*vpp)->v_flag = VROOT; @@ -120,6 +128,7 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp, struct pfs_node *pn) case pfstype_dir: case pfstype_this: case pfstype_parent: + case pfstype_procdir: (*vpp)->v_type = VDIR; break; case pfstype_file: @@ -128,10 +137,13 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp, struct pfs_node *pn) case pfstype_symlink: (*vpp)->v_type = VLNK; break; + case pfstype_none: + KASSERT(0, ("pfs_vncache_alloc called for null node\n")); default: panic("%s has unexpected type: %d", pn->pn_name, pn->pn_type); } pv->pv_vnode = *vpp; + mtx_lock(&pfs_vncache_mutex); pv->pv_next = pfs_vncache; pfs_vncache = pv; mtx_unlock(&pfs_vncache_mutex); @@ -145,25 +157,22 @@ int pfs_vncache_free(struct vnode *vp) { struct pfs_vnode *prev, *pv; + struct pfs_vdata *pvd; mtx_lock(&pfs_vncache_mutex); for (prev = NULL, pv = pfs_vncache; pv; prev = pv, pv = pv->pv_next) if (pv->pv_vnode == vp) break; - if (!pv) - printf("pfs_vncache_free(): not in cache\n"); /* it should be! */ -#if 0 - if (vp->v_data == ((struct pfs_info *)vp->v_mount->mnt_data)->pi_root) - printf("root vnode reclaimed\n"); -#endif - vp->v_data = NULL; - if (pv) { - if (prev) - prev->pv_next = pv->pv_next; - else - pfs_vncache = pv->pv_next; - FREE(pv, M_PFSVNCACHE); - } + KASSERT(pv != NULL, ("pfs_vncache_free(): not in cache\n")); + if (prev) + prev->pv_next = pv->pv_next; + else + pfs_vncache = pv->pv_next; mtx_unlock(&pfs_vncache_mutex); + + pvd = (struct pfs_vdata *)vp->v_data; + FREE(pvd, M_PFSVNCACHE); + vp->v_data = NULL; + FREE(pv, M_PFSVNCACHE); return (0); } diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c index ae6cbe1..473b414 100644 --- a/sys/fs/pseudofs/pseudofs_vnops.c +++ b/sys/fs/pseudofs/pseudofs_vnops.c @@ -79,7 +79,8 @@ static int pfs_getattr(struct vop_getattr_args *va) { struct vnode *vn = va->a_vp; - struct pfs_node *pn = (struct pfs_node *)vn->v_data; + struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data; + struct pfs_node *pn = pvd->pvd_pn; struct vattr *vap = va->a_vap; VATTR_NULL(vap); @@ -105,19 +106,17 @@ pfs_getattr(struct vop_getattr_args *va) static int pfs_lookup(struct vop_lookup_args *va) { - struct vnode *dvp = va->a_dvp; + struct vnode *vn = va->a_dvp; struct vnode **vpp = va->a_vpp; struct componentname *cnp = va->a_cnp; -#if 0 - struct pfs_info *pi = (struct pfs_info *)dvp->v_mount->mnt_data; -#endif - struct pfs_node *pd = (struct pfs_node *)dvp->v_data, *pn; - struct proc *p; + struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data; + struct pfs_node *pd = pvd->pvd_pn; + struct pfs_node *pn, *pdn = NULL; + pid_t pid = pvd->pvd_pid; char *pname; - int error, i; - pid_t pid; + int error, i, namelen; - if (dvp->v_type != VDIR) + if (vn->v_type != VDIR) return (ENOTDIR); /* don't support CREATE, RENAME or DELETE */ @@ -129,11 +128,12 @@ pfs_lookup(struct vop_lookup_args *va) return (ENOENT); /* self */ + namelen = cnp->cn_namelen; pname = cnp->cn_nameptr; - if (cnp->cn_namelen == 1 && *pname == '.') { + if (namelen == 1 && *pname == '.') { pn = pd; - *vpp = dvp; - VREF(dvp); + *vpp = vn; + VREF(vn); goto got_vnode; } @@ -142,61 +142,48 @@ pfs_lookup(struct vop_lookup_args *va) if (pd->pn_type == pfstype_root) return (EIO); KASSERT(pd->pn_parent, ("non-root directory has no parent")); - return pfs_vncache_alloc(dvp->v_mount, vpp, pd->pn_parent); + /* + * This one is tricky. Descendents of procdir nodes + * inherit their parent's process affinity, but + * there's no easy reverse mapping. For simplicity, + * we assume that if this node is a procdir, its + * parent isn't (which is correct as long as + * descendents of procdir nodes are never procdir + * nodes themselves) + */ + if (pd->pn_type == pfstype_procdir) + pid = NO_PID; + return pfs_vncache_alloc(vn->v_mount, vpp, pd->pn_parent, pid); } - /* process dependent */ - for (i = 0, pid = 0; i < cnp->cn_namelen && isdigit(pname[i]); ++i) - pid = pid * 10 + pname[i] - '0'; - /* XXX assume that 8 digits is the maximum safe length for a pid */ - if (i == cnp->cn_namelen && i < 8) { - /* see if this directory has process-dependent children */ - for (pn = pd->pn_nodes; pn->pn_type; ++pn) - if (pn->pn_type == pfstype_procdep) - break; - if (pn->pn_type) { - /* XXX pfind(0) should DTRT here */ - p = pid ? pfind(pid) : &proc0; - if (p == NULL) - return (ENOENT); - if (p_can(cnp->cn_proc, p, P_CAN_SEE, NULL)) { - /* pretend it doesn't exist */ - PROC_UNLOCK(p); - return (ENOENT); - } -#if 0 - if (!pn->pn_shadow) - pfs_create_shadow(pn, p); - pn = pn->pn_shadow; - PROC_UNLOCK(p); + /* named node */ + for (pn = pd->pn_nodes; pn->pn_type; ++pn) + if (pn->pn_type == pfstype_procdir) + pdn = pn; + else if (pn->pn_name[namelen] == '\0' + && bcmp(pname, pn->pn_name, namelen) == 0) goto got_pnode; -#else - /* not yet implemented */ - PROC_UNLOCK(p); - return (EIO); -#endif - } - } - - /* something else */ - for (pn = pd->pn_nodes; pn->pn_type; ++pn) { - for (i = 0; i < cnp->cn_namelen && pn->pn_name[i]; ++i) - if (pname[i] != pn->pn_name[i]) + + /* process dependent node */ + if ((pn = pdn) != NULL) { + pid = 0; + for (pid = 0, i = 0; i < namelen && isdigit(pname[i]); ++i) + if ((pid = pid * 10 + pname[i] - '0') > PID_MAX) break; if (i == cnp->cn_namelen) goto got_pnode; } - + return (ENOENT); got_pnode: if (!pn->pn_parent) pn->pn_parent = pd; - error = pfs_vncache_alloc(dvp->v_mount, vpp, pn); + error = pfs_vncache_alloc(vn->v_mount, vpp, pn, pid); if (error) return error; got_vnode: if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, *vpp, cnp); + cache_enter(vn, *vpp, cnp); return (0); } @@ -217,8 +204,10 @@ static int pfs_read(struct vop_read_args *va) { struct vnode *vn = va->a_vp; - struct pfs_node *pn = vn->v_data; + struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data; + struct pfs_node *pn = pvd->pvd_pn; struct uio *uio = va->a_uio; + struct proc *proc = NULL; struct sbuf *sb = NULL; char *ps; int error, xlen; @@ -226,11 +215,24 @@ pfs_read(struct vop_read_args *va) if (vn->v_type != VREG) return (EINVAL); + if (pvd->pvd_pid != NO_PID) { + if ((proc = pfind(pvd->pvd_pid)) == NULL) + return (EIO); + _PHOLD(proc); + PROC_UNLOCK(proc); + } + sb = sbuf_new(sb, NULL, uio->uio_offset + uio->uio_resid, 0); - if (sb == NULL) + if (sb == NULL) { + if (proc != NULL) + PRELE(proc); return (EIO); + } - error = (pn->pn_func)(pn, curproc, sb); + error = (pn->pn_func)(curproc, proc, pn, sb); + + if (proc != NULL) + PRELE(proc); /* XXX we should possibly detect and handle overflows */ sbuf_finish(sb); @@ -243,27 +245,52 @@ pfs_read(struct vop_read_args *va) } /* + * Iterate through directory entries + */ +static int +pfs_iterate(struct pfs_info *pi, struct pfs_node **pn, struct proc **p) +{ + if ((*pn)->pn_type == pfstype_none) + return (-1); + + if ((*pn)->pn_type != pfstype_procdir) + ++*pn; + + while ((*pn)->pn_type == pfstype_procdir) { + if (*p == NULL) + *p = LIST_FIRST(&allproc); + else + *p = LIST_NEXT(*p, p_list); + if (*p != NULL) + return (0); + ++*pn; + } + + if ((*pn)->pn_type == pfstype_none) + return (-1); + + return (0); +} + +/* * Return directory entries. */ static int pfs_readdir(struct vop_readdir_args *va) { struct vnode *vn = va->a_vp; - struct pfs_info *pi; - struct pfs_node *pd, *pn; + struct pfs_info *pi = (struct pfs_info *)vn->v_mount->mnt_data; + struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data; + struct pfs_node *pd = pvd->pvd_pn; + struct pfs_node *pn; struct dirent entry; struct uio *uio; -#if 0 struct proc *p; -#endif off_t offset; int error, i, resid; if (vn->v_type != VDIR) return (ENOTDIR); - pi = (struct pfs_info *)vn->v_mount->mnt_data; - pd = (struct pfs_node *)vn->v_data; - pn = pd->pn_nodes; uio = va->a_uio; /* only allow reading entire entries */ @@ -273,23 +300,35 @@ pfs_readdir(struct vop_readdir_args *va) return (EINVAL); /* skip unwanted entries */ - for (; pn->pn_type && offset > 0; ++pn, offset -= PFS_DELEN) - /* nothing */ ; - + sx_slock(&allproc_lock); + for (pn = pd->pn_nodes, p = NULL; offset > 0; offset -= PFS_DELEN) + if (pfs_iterate(pi, &pn, &p) == -1) + break; + /* fill in entries */ entry.d_reclen = PFS_DELEN; - for (; pn->pn_type && resid > 0; ++pn) { + while (pfs_iterate(pi, &pn, &p) != -1 && resid > 0) { if (!pn->pn_parent) pn->pn_parent = pd; if (!pn->pn_fileno) pfs_fileno_alloc(pi, pn); - entry.d_fileno = pn->pn_fileno; + if (pvd->pvd_pid != NO_PID) + entry.d_fileno = pn->pn_fileno * NO_PID + pvd->pvd_pid; + else + entry.d_fileno = pn->pn_fileno; /* PFS_DELEN was picked to fit PFS_NAMLEN */ for (i = 0; i < PFS_NAMELEN - 1 && pn->pn_name[i] != '\0'; ++i) entry.d_name[i] = pn->pn_name[i]; entry.d_name[i] = 0; entry.d_namlen = i; switch (pn->pn_type) { + case pfstype_procdir: + KASSERT(p != NULL, + ("reached procdir node with p == NULL")); + entry.d_fileno = pn->pn_fileno * NO_PID + p->p_pid; + entry.d_namlen = snprintf(entry.d_name, + PFS_NAMELEN, "%d", p->p_pid); + /* fall through */ case pfstype_root: case pfstype_dir: case pfstype_this: @@ -302,32 +341,19 @@ pfs_readdir(struct vop_readdir_args *va) case pfstype_symlink: entry.d_type = DT_LNK; break; - case pfstype_procdep: - /* don't handle process-dependent nodes here */ - continue; default: + sx_sunlock(&allproc_lock); panic("%s has unexpected node type: %d", pn->pn_name, pn->pn_type); } - if ((error = uiomove((caddr_t)&entry, PFS_DELEN, uio))) + if ((error = uiomove((caddr_t)&entry, PFS_DELEN, uio))) { + sx_sunlock(&allproc_lock); return (error); + } offset += PFS_DELEN; resid -= PFS_DELEN; } -#if 0 - for (pn = pd->pn_nodes; pn->pn_type && resid > 0; ++pn) { - if (pn->pn_type != pfstype_procdep) - continue; - - sx_slock(&allproc_lock); - p = LIST_FIRST(&allproc); - - sx_sunlock(&allproc_lock); - offset += PFS_DELEN; - resid -= PFS_DELEN; - break; - } -#endif - + + sx_sunlock(&allproc_lock); uio->uio_offset += offset; return (0); } @@ -339,8 +365,10 @@ static int pfs_readlink(struct vop_readlink_args *va) { struct vnode *vn = va->a_vp; - struct pfs_node *pn = vn->v_data; + struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data; + struct pfs_node *pn = pvd->pvd_pn; struct uio *uio = va->a_uio; + struct proc *proc = NULL; char buf[MAXPATHLEN], *ps; struct sbuf sb; int error, xlen; @@ -348,10 +376,20 @@ pfs_readlink(struct vop_readlink_args *va) if (vn->v_type != VLNK) return (EINVAL); + if (pvd->pvd_pid != NO_PID) { + if ((proc = pfind(pvd->pvd_pid)) == NULL) + return (EIO); + _PHOLD(proc); + PROC_UNLOCK(proc); + } + /* sbuf_new() can't fail with a static buffer */ sbuf_new(&sb, buf, sizeof buf, 0); - error = (pn->pn_func)(pn, curproc, &sb); + error = (pn->pn_func)(curproc, proc, pn, &sb); + + if (proc != NULL) + PRELE(proc); /* XXX we should detect and handle overflows */ sbuf_finish(&sb); @@ -378,8 +416,9 @@ pfs_reclaim(struct vop_reclaim_args *va) static int pfs_setattr(struct vop_setattr_args *va) { - if (va->a_vap->va_flags != VNOVAL) + if (va->a_vap->va_flags != (u_long)VNOVAL) return (EOPNOTSUPP); + /* XXX it's a bit more complex than that, really... */ return (0); } -- cgit v1.1