From ce302369fbc64b2aa6f88338e81f3b1b823e19c9 Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 8 Jul 2002 01:50:14 +0000 Subject: 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 --- sys/fs/pseudofs/pseudofs_vncache.c | 5 +++++ sys/fs/pseudofs/pseudofs_vnops.c | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'sys/fs/pseudofs') diff --git a/sys/fs/pseudofs/pseudofs_vncache.c b/sys/fs/pseudofs/pseudofs_vncache.c index 5f21d67..498de38 100644 --- a/sys/fs/pseudofs/pseudofs_vncache.c +++ b/sys/fs/pseudofs/pseudofs_vncache.c @@ -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); } diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c index 1c3c847..0eed8ea 100644 --- a/sys/fs/pseudofs/pseudofs_vnops.c +++ b/sys/fs/pseudofs/pseudofs_vnops.c @@ -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 } }; -- cgit v1.1