Lock down pseudofs:
- Initialize lock structure in vncache_alloc - Return locked vnodes from vncache_alloc - Setup vnode op vectors to use default lock, unlock, and islocked - Implement simple locking scheme required for lookup
This commit is contained in:
parent
15c3d6e567
commit
922b974a44
@ -120,6 +120,8 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp,
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
/* XXX see comment at top of pfs_lookup() */
|
||||
cache_purge(*vpp);
|
||||
vn_lock(*vpp, LK_RETRY | LK_EXCLUSIVE,
|
||||
curthread);
|
||||
return (0);
|
||||
}
|
||||
/* XXX if this can happen, we're in trouble */
|
||||
@ -171,6 +173,9 @@ pfs_vncache_alloc(struct mount *mp, struct vnode **vpp,
|
||||
pvd->pvd_next->pvd_prev = pvd;
|
||||
pfs_vncache = pvd;
|
||||
mtx_unlock(&pfs_vncache_mutex);
|
||||
(*vpp)->v_vnlock = &(*vpp)->v_lock;
|
||||
lockinit((*vpp)->v_vnlock, PINOD, "pfsnod", VLKTIMEOUT, LK_CANRECURSE);
|
||||
vn_lock(*vpp, LK_RETRY | LK_EXCLUSIVE, curthread);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -312,11 +312,15 @@ pfs_lookup(struct vop_lookup_args *va)
|
||||
struct pfs_node *pd = pvd->pvd_pn;
|
||||
struct pfs_node *pn, *pdn = NULL;
|
||||
pid_t pid = pvd->pvd_pid;
|
||||
int lockparent;
|
||||
int wantparent;
|
||||
char *pname;
|
||||
int error, i, namelen;
|
||||
|
||||
PFS_TRACE(("%.*s", (int)cnp->cn_namelen, cnp->cn_nameptr));
|
||||
|
||||
cnp->cn_flags &= ~PDIRUNLOCK;
|
||||
|
||||
if (vn->v_type != VDIR)
|
||||
PFS_RETURN (ENOTDIR);
|
||||
|
||||
@ -336,6 +340,10 @@ pfs_lookup(struct vop_lookup_args *va)
|
||||
if (!pfs_visible(curthread, pd, pvd->pvd_pid))
|
||||
PFS_RETURN (ENOENT);
|
||||
|
||||
lockparent = cnp->cn_flags & LOCKPARENT;
|
||||
wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
|
||||
|
||||
|
||||
/* self */
|
||||
namelen = cnp->cn_namelen;
|
||||
pname = cnp->cn_nameptr;
|
||||
@ -350,6 +358,9 @@ pfs_lookup(struct vop_lookup_args *va)
|
||||
if (cnp->cn_flags & ISDOTDOT) {
|
||||
if (pd->pn_type == pfstype_root)
|
||||
PFS_RETURN (EIO);
|
||||
VOP_UNLOCK(vn, 0, cnp->cn_thread);
|
||||
cnp->cn_flags |= PDIRUNLOCK;
|
||||
|
||||
KASSERT(pd->pn_parent, ("non-root directory has no parent"));
|
||||
/*
|
||||
* This one is tricky. Descendents of procdir nodes
|
||||
@ -390,9 +401,19 @@ pfs_lookup(struct vop_lookup_args *va)
|
||||
pn->pn_parent = pd;
|
||||
if (!pfs_visible(curthread, pn, pvd->pvd_pid))
|
||||
PFS_RETURN (ENOENT);
|
||||
|
||||
error = pfs_vncache_alloc(vn->v_mount, vpp, pn, pid);
|
||||
if (error)
|
||||
PFS_RETURN (error);
|
||||
|
||||
if ((cnp->cn_flags & ISDOTDOT) && (cnp->cn_flags & ISLASTCN)
|
||||
&& lockparent) {
|
||||
vn_lock(vn, LK_EXCLUSIVE|LK_RETRY, cnp->cn_thread);
|
||||
cnp->cn_flags &= ~PDIRUNLOCK;
|
||||
}
|
||||
if (!lockparent || !(cnp->cn_flags & ISLASTCN))
|
||||
VOP_UNLOCK(vn, 0, cnp->cn_thread);
|
||||
|
||||
/*
|
||||
* XXX See comment at top of the routine.
|
||||
*/
|
||||
@ -806,6 +827,9 @@ static struct vnodeopv_entry_desc pfs_vnodeop_entries[] = {
|
||||
{ &vop_setattr_desc, (vop_t *)pfs_setattr },
|
||||
{ &vop_symlink_desc, (vop_t *)vop_eopnotsupp },
|
||||
{ &vop_write_desc, (vop_t *)pfs_write },
|
||||
{ &vop_lock_desc, (vop_t *)vop_stdlock },
|
||||
{ &vop_unlock_desc, (vop_t *)vop_stdunlock },
|
||||
{ &vop_islocked_desc, (vop_t *)vop_stdislocked},
|
||||
/* XXX I've probably forgotten a few that need vop_eopnotsupp */
|
||||
{ NULL, (vop_t *)NULL }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user