PERFORCE change 165328 for review
Tatsiana Severyna
tatsianka at FreeBSD.org
Sat Jun 27 20:34:03 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165328
Change 165328 by tatsianka at tatsianka_zonder on 2009/06/27 20:33:22
Unlock-lock vnodes while waiting for reply from userland
Bring back support for fifos
Disable VOP_STRATEGY
Work around bug of reusing same message without release in read/write
Affected files ...
.. //depot/projects/soc2009/tatsianka_puffs/libpuffs/null.c#2 edit
.. //depot/projects/soc2009/tatsianka_puffs/libpuffs/puffs.c#3 edit
.. //depot/projects/soc2009/tatsianka_puffs/puffs/Makefile#4 edit
.. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_node.c#5 edit
.. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_sys.h#4 edit
.. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vfsops.c#5 edit
.. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vnops.c#5 edit
Differences ...
==== //depot/projects/soc2009/tatsianka_puffs/libpuffs/null.c#2 (text+ko) ====
@@ -265,8 +265,19 @@
int rv;
mode = puffs_addvtype2mode(va->va_mode, va->va_type);
- if (mknod(PCNPATH(pcn), mode, va->va_rdev) == -1)
- return errno;
+ switch (va->va_type) {
+ case VFIFO:
+ if (mkfifo(PCNPATH(pcn), mode) == -1)
+ return errno;
+ break;
+ case VCHR:
+ case VBLK:
+ if (mknod(PCNPATH(pcn), mode, va->va_rdev) == -1)
+ return errno;
+ break;
+ default:
+ return EINVAL;
+ }
rv = makenode(pu, pni, pcn, va, 0);
if (rv)
==== //depot/projects/soc2009/tatsianka_puffs/libpuffs/puffs.c#3 (text+ko) ====
@@ -714,7 +714,6 @@
int ndone;
while (puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED) {
- printf("puffs__theloop: iteration\n");
/*
* Schedule existing requests.
*/
@@ -793,7 +792,6 @@
ndone = kevent(pu->pu_kq, pu->pu_evs, nchanges,
pu->pu_evs, 2*pu->pu_nfds, pu->pu_ml_timep);
- printf("puffs__theloop: kevent: %d; errno=%d\n", ndone, errno);
if (ndone == -1) {
if (errno != EINTR)
break;
@@ -821,7 +819,6 @@
fio = (void *)curev->udata;
pfctrl = fio->fctrl;
if (curev->flags & EV_ERROR) {
- printf("puffs__theloop: EV_ERROR\n");
assert(curev->filter == EVFILT_WRITE);
fio->stat &= ~FIO_WR;
@@ -834,13 +831,11 @@
what = 0;
if (curev->filter == EVFILT_READ) {
- printf("puffs__theloop: EVFILT_READ\n");
puffs__framev_input(pu, pfctrl, fio);
what |= PUFFS_FBIO_READ;
}
else if (curev->filter == EVFILT_WRITE) {
- printf("puffs__theloop: EVFILT_WRITE\n");
puffs__framev_output(pu, pfctrl, fio);
what |= PUFFS_FBIO_WRITE;
}
@@ -858,8 +853,6 @@
}
}
- printf("puffs__theloop: done\n");
-
if (puffs__cc_restoremain(pu) == -1)
warn("cannot restore main context. impending doom");
}
==== //depot/projects/soc2009/tatsianka_puffs/puffs/Makefile#4 (text+ko) ====
@@ -5,6 +5,7 @@
KMOD= puffs
SRCS= vnode_if.h puffs_msgif.c puffs_msgif.h puffs_node.c puffs_subr.c \
puffs_sys.h puffs_vfsops.c puffs_vnops.c
-DEBUG_FLAGS= -DPUFFSDEBUG -g -I${.CURDIR} -I${.CURDIR}/../putter
+DEBUG_FLAGS+= -g -I${.CURDIR} -I${.CURDIR}/../putter
+DEBUG_FLAGS+= -DPUFFSDEBUG
.include <bsd.kmod.mk>
==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_node.c#5 (text+ko) ====
@@ -89,6 +89,7 @@
int error;
DTRACE();
+ KASSERT(mp != NULL, ("mp == NULL"));
pmp = MPTOPUFFSMP(mp);
@@ -130,39 +131,22 @@
* care must be taken so that VOP_INACTIVE() isn't called.
*/
- /* default size */
- vnode_pager_setsize(vp, vsize);
-
-#ifdef XXX_TS /* mystirious stuff */
- /* dances based on vnode type. almost ufs_vinit(), but not quite */
switch (type) {
case VCHR:
case VBLK:
- /*
- * replace vnode operation vector with the specops vector.
- * our user server has very little control over the node
- * if it decides its a character or block special file
- */
- vp->v_op = puffs_specop_p;
- spec_node_init(vp, rdev);
+ case VDIR:
+ case VLNK:
+ case VSOCK:
break;
-
case VFIFO:
- vp->v_op = puffs_fifoop_p;
+ vp->v_op = &puffs_fifoops;
break;
-
case VREG:
- uvm_vnp_setsize(vp, vsize);
+ vnode_pager_setsize(vp, vsize);
break;
-
- case VDIR:
- case VLNK:
- case VSOCK:
- break;
default:
panic("puffs_getvnode: invalid vtype %d", type);
}
-#endif
pnode->pn_cookie = ck;
pnode->pn_refcount = 1;
@@ -225,13 +209,16 @@
puffs_cookie_t ck, struct componentname *cnp,
enum vtype type, dev_t rdev)
{
- struct puffs_mount *pmp = MPTOPUFFSMP(mp);
+ struct puffs_mount *pmp;
struct puffs_newcookie *pnc, *npnc;
struct vnode *vp;
int error;
DTRACE();
+ KASSERT(mp != NULL, ("mp == NULL"));
+ pmp = MPTOPUFFSMP(mp);
+
/* userspace probably has this as a NULL op */
if (ck == NULL) {
error = EOPNOTSUPP;
@@ -285,16 +272,12 @@
void
puffs_putvnode(struct vnode *vp)
{
- struct puffs_mount *pmp;
struct puffs_node *pnode;
- pmp = VPTOPUFFSMP(vp);
pnode = VPTOPP(vp);
LIST_REMOVE(pnode, pn_hashent);
-#ifdef XXX_TS
- genfs_node_destroy(vp);
-#endif
+ vnode_destroy_vobject(vp);
puffs_releasenode(pnode);
vp->v_data = NULL;
@@ -384,7 +367,6 @@
/* store cache */
vp->v_vflag |= VV_ROOT;
pmp->pmp_root = vp;
- vref(vp);
mtx_unlock(&pmp->pmp_lock);
ASSERT_VI_UNLOCKED(vp, "puffs_makeroot");
@@ -441,9 +423,7 @@
mtx_unlock(&pmp->pmp_lock);
DPRINTF(("puffs_cookie2vnode vget vp=%p lkflag=%x lock=%x\n", vp, lkflag, lkflag & LK_TYPE_MASK));
- vholdl(vp);
vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, curthread);
- vdrop(vp);
*vpp = vp;
@@ -462,6 +442,7 @@
nanotime(&ts);
+ mtx_lock(&pn->pn_mtx);
if (flags & PUFFS_UPDATEATIME) {
pn->pn_mc_atime = ts;
pn->pn_stat |= PNODE_METACACHE_ATIME;
@@ -478,6 +459,7 @@
pn->pn_mc_size = size;
pn->pn_stat |= PNODE_METACACHE_SIZE;
}
+ mtx_unlock(&pn->pn_mtx);
}
/*
@@ -516,3 +498,48 @@
mtx_unlock(&pn->pn_mtx);
}
}
+
+int
+puffs_lockvnode(struct puffs_node *pn, int ltype)
+{
+ struct vnode *vp;
+
+ KASSERT(pn != NULL, ("invalid node"));
+ vp = pn->pn_vp;
+ KASSERT(vp != NULL, ("invalid vnode"));
+ ASSERT_VOP_UNLOCKED(vp, "puffs_lockvnode");
+
+ vrele(vp);
+ vn_lock(vp, (ltype & LK_TYPE_MASK) | LK_RETRY);
+ ASSERT_VOP_LOCKED(vp, "puffs_lockvnode");
+ puffs_releasenode(pn);
+ if (vp->v_iflag & VI_DOOMED) {
+ DPRINTF(("puffs_lockvnode: vnode is dead %p\n", vp));
+ return EBADF;
+ }
+ return 0;
+}
+
+int
+puffs_unlockvnode(struct puffs_node *pn, int *ltype)
+{
+ struct vnode *vp;
+ int error;
+
+ KASSERT(pn != NULL, ("invalid node"));
+ vp = pn->pn_vp;
+ KASSERT(vp != NULL, ("invalid vnode"));
+ ASSERT_VOP_LOCKED(vp, "puffs_unlockvnode");
+
+ mtx_lock(&pn->pn_mtx);
+ puffs_referencenode(pn);
+ mtx_unlock(&pn->pn_mtx);
+ DPRINTF(("puffs_unlockvnode: unlocking vnode %p; vrefcnt=%d\n", vp, vrefcnt(vp)));
+ vref(vp);
+ if (ltype)
+ *ltype = VOP_ISLOCKED(vp);
+ error = VOP_UNLOCK(vp, 0);
+ ASSERT_VOP_UNLOCKED(vp, "puffs_unlockvnode");
+ return error;
+}
+
==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_sys.h#4 (text+ko) ====
@@ -46,6 +46,7 @@
MALLOC_DECLARE(M_PUFFS);
extern struct vop_vector puffs_vnodeops;
+extern struct vop_vector puffs_fifoops;
extern uma_zone_t puffs_pnpool;
@@ -70,7 +71,6 @@
#define PMPTOMP(pmp) (pmp->pmp_mp)
#define VPTOPP(vp) ((struct puffs_node *)(vp)->v_data)
#define VPTOPNC(vp) (((struct puffs_node *)(vp)->v_data)->pn_cookie)
-#define VPTOPUFFSMP(vp) ((struct puffs_mount*)((struct puffs_node*)vp->v_data))
/* we don't pass the kernel overlay to userspace */
#define PUFFS_TOFHSIZE(s) ((s)==0 ? (s) : (s)+4)
@@ -210,6 +210,8 @@
void puffs_releasenode(struct puffs_node *);
void puffs_referencenode(struct puffs_node *);
+int puffs_lockvnode(struct puffs_node *, int);
+int puffs_unlockvnode(struct puffs_node *, int *);
#define PUFFS_NOSUCHCOOKIE (-1)
int puffs_cookie2vnode(struct puffs_mount *, puffs_cookie_t, int, int,
==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vfsops.c#5 (text+ko) ====
@@ -54,14 +54,6 @@
#include <nfs/nfsproto.h> /* for fh sizes */
-/* XXX_TS */
-#ifndef INVARIANTS
-#error INVARIANTS are not enabled
-#endif
-#ifndef WITNESS
-#error WITNESS is not enabled
-#endif
-
#ifndef PUFFS_PNODEBUCKETS
#define PUFFS_PNODEBUCKETS 256
#endif
==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vnops.c#5 (text+ko) ====
@@ -73,6 +73,12 @@
#define PUFFS_ABORT_MKDIR 4
#define PUFFS_ABORT_SYMLINK 5
+#define PUFFS_LOCKVNODE(a, l, e) \
+do { \
+ if (puffs_lockvnode((a), (l)) != 0 && (e) != 0) \
+ e = EBADF; \
+} while(/*CONSTCOND*/0)
+
/*
* Press the pani^Wabort button! Kernel resource allocation failed.
*/
@@ -80,6 +86,7 @@
puffs_abortbutton(struct puffs_mount *pmp, int what,
puffs_cookie_t dck, puffs_cookie_t ck, struct componentname *cnp)
{
+ KASSERT(pmp != NULL, ("pmp == NULL"));
switch (what) {
case PUFFS_ABORT_CREATE:
@@ -170,12 +177,14 @@
struct componentname *cnp;
struct vnode *vp, *dvp;
struct puffs_node *dpn;
+ int dltype;
int isdot;
int error;
pmp = MPTOPUFFSMP(ap->a_dvp->v_mount);
cnp = ap->a_cnp;
dvp = ap->a_dvp;
+ dpn = dvp->v_data;
*ap->a_vpp = NULL;
/* r/o fs? we check create later to handle EEXIST */
@@ -223,18 +232,19 @@
DPRINTF(("puffs_lookup: ISDOTDOT\n"));
}
-#ifdef XXX_TS
- if (cnp->cn_flags & ISDOTDOT)
- VOP_UNLOCK(dvp, 0);
-#endif
-
puffs_msg_setinfo(park_lookup, PUFFSOP_VN,
PUFFS_VN_LOOKUP, VPTOPNC(dvp));
DPRINTF(("puffs_lookup: enqueue message: %.*s\n", (int) cnp->cn_namelen, cnp->cn_nameptr));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_lookup, dvp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_lookup);
+ puffs_unlockvnode(dpn, &dltype);
+ error = puffs_msg_wait2(pmp, park_lookup, dpn, NULL);
DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error));
+ if (puffs_lockvnode(dpn, dltype) && !error) {
+ error = ENOENT;
+ goto out;
+ }
/*
* In case of error, there is no new vnode to play with, so be
@@ -247,7 +257,7 @@
error = checkerr(pmp, error, __func__);
if (error == ENOENT) {
/* don't allow to create files on r/o fs */
- if ((dvp->v_mount->mnt_flag & MNT_RDONLY)
+ if (dvp->v_mount->mnt_flag & MNT_RDONLY
&& cnp->cn_nameiop == CREATE) {
error = EROFS;
@@ -272,7 +282,6 @@
* Check that we don't get our parent node back, that would cause
* a pretty obvious deadlock.
*/
- dpn = dvp->v_data;
if (lookup_msg->pvnr_newnode == dpn->pn_cookie) {
puffs_senderr(pmp, PUFFS_ERR_LOOKUP, EINVAL,
"lookup produced parent cookie", lookup_msg->pvnr_newnode);
@@ -286,13 +295,17 @@
lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, LK_EXCLUSIVE, &vp);
if (error) {
+ puffs_unlockvnode(dpn, &dltype);
puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),
lookup_msg->pvnr_newnode, ap->a_cnp);
+ puffs_lockvnode(dpn, dltype);
goto out;
}
} else if (error) {
+ puffs_unlockvnode(dpn, &dltype);
puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, VPTOPNC(dvp),
lookup_msg->pvnr_newnode, ap->a_cnp);
+ puffs_lockvnode(dpn, dltype);
goto out;
}
@@ -311,56 +324,11 @@
strlen(cnp->cn_nameptr) - cnp->cn_namelen);
out:
-#ifdef XXX_TS
- if (cnp->cn_flags & ISDOTDOT)
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
-#endif
-
+ PUFFS_MSG_RELEASE(lookup);
DPRINTF(("puffs_lookup: returning %d %p\n", error, *ap->a_vpp));
- PUFFS_MSG_RELEASE(lookup);
return error;
}
-#ifdef XXX_TS
-#define REFPN_AND_UNLOCKVP(a, b) \
-do { \
- mtx_lock(&b->pn_mtx); \
- puffs_referencenode(b); \
- mtx_unlock(&b->pn_mtx); \
- vhold(a); \
- VOP_UNLOCK(a, 0); \
-} while (/*CONSTCOND*/0)
-#else
-#define REFPN_AND_UNLOCKVP(a, b) \
-do { \
- mtx_lock(&b->pn_mtx); \
- puffs_referencenode(b); \
- mtx_unlock(&b->pn_mtx); \
-} while (/*CONSTCOND*/0)
-#endif
-
-#define REFPN(b) \
-do { \
- mtx_lock(&b->pn_mtx); \
- puffs_referencenode(b); \
- mtx_unlock(&b->pn_mtx); \
-} while (/*CONSTCOND*/0)
-
-#ifdef XXX_TS
-#define RELEPN_AND_VP(a, b) \
-do { \
- puffs_releasenode(b); \
- vrele(a); \
- vn_lock(a, LK_EXCLUSIVE | LK_RETRY); \
- vdrop(a); \
-} while (/*CONSTCOND*/0)
-#else
-#define RELEPN_AND_VP(a, b) \
-do { \
- puffs_releasenode(b); \
-} while (/*CONSTCOND*/0)
-#endif
-
static int
puffs_vnop_create(struct vop_create_args *ap)
{
@@ -370,6 +338,7 @@
struct componentname *cnp = ap->a_cnp;
struct mount *mp = dvp->v_mount;
struct puffs_mount *pmp = MPTOPUFFSMP(mp);
+ int dltype;
int error;
DPRINTF(("puffs_create: dvp %p, cnp: %s\n",
@@ -389,23 +358,71 @@
* + wait for response
*/
puffs_msg_enqueue(pmp, park_create);
- REFPN_AND_UNLOCKVP(dvp, dpn);
+ puffs_unlockvnode(dpn, &dltype);
error = puffs_msg_wait2(pmp, park_create, dpn, NULL);
+ error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
- error = checkerr(pmp, error, __func__);
if (error)
goto out;
error = puffs_newnode(mp, dvp, ap->a_vpp,
create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0);
- if (error)
+ if (error) {
+ puffs_unlockvnode(dpn, &dltype);
puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, dpn->pn_cookie,
create_msg->pvnr_newnode, cnp);
+ puffs_lockvnode(dpn, dltype);
+ }
out:
- RELEPN_AND_VP(dvp, dpn);
+ PUFFS_MSG_RELEASE(create);
DPRINTF(("puffs_create: return %d\n", error));
- PUFFS_MSG_RELEASE(create);
+ return error;
+}
+
+static int
+puffs_vnop_mknod(struct vop_mknod_args *ap)
+{
+ PUFFS_MSG_VARS(vn, mknod);
+ struct vnode *dvp = ap->a_dvp;
+ struct puffs_node *dpn = VPTOPP(dvp);
+ struct componentname *cnp = ap->a_cnp;
+ struct mount *mp = dvp->v_mount;
+ struct puffs_mount *pmp = MPTOPUFFSMP(mp);
+ int dltype;
+ int error;
+
+ DTRACE();
+ PUFFS_MSG_ALLOC(vn, mknod);
+ puffs_makecn(&mknod_msg->pvnr_cn, &mknod_msg->pvnr_cn_cred,
+ cnp, PUFFS_USE_FULLPNBUF(pmp));
+ mknod_msg->pvnr_va = *ap->a_vap;
+ puffs_msg_setinfo(park_mknod, PUFFSOP_VN,
+ PUFFS_VN_MKNOD, VPTOPNC(dvp));
+
+ puffs_msg_enqueue(pmp, park_mknod);
+ puffs_unlockvnode(dpn, &dltype);
+ error = puffs_msg_wait2(pmp, park_mknod, dpn, NULL);
+ error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
+
+ if (error)
+ goto out;
+
+ error = puffs_newnode(mp, dvp, ap->a_vpp,
+ mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type,
+ ap->a_vap->va_rdev);
+ if (error) {
+ puffs_unlockvnode(dpn, &dltype);
+ puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, dpn->pn_cookie,
+ mknod_msg->pvnr_newnode, cnp);
+ puffs_lockvnode(dpn, dltype);
+ }
+
+ out:
+ PUFFS_MSG_RELEASE(mknod);
+ DPRINTF(("puff_mknod: returning %d\n", error));
return error;
}
@@ -414,17 +431,19 @@
{
PUFFS_MSG_VARS(vn, open);
struct vnode *vp = ap->a_vp;
+ struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
int mode = ap->a_mode;
+ int ltype;
int error;
DPRINTF(("puffs_open: vp %p, mode 0x%x\n", vp, mode));
if (vp->v_type == VREG && mode & FWRITE && !EXISTSOP(pmp, WRITE))
- ERROUT(EROFS);
+ return EROFS;
if (!EXISTSOP(pmp, OPEN))
- ERROUT(0);
+ return 0;
PUFFS_MSG_ALLOC(vn, open);
open_msg->pvnr_mode = mode;
@@ -432,12 +451,18 @@
puffs_msg_setinfo(park_open, PUFFSOP_VN,
PUFFS_VN_OPEN, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_open);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_open, pn, NULL);
error = checkerr(pmp, error, __func__);
- out:
+ PUFFS_MSG_RELEASE(open);
+ PUFFS_LOCKVNODE(pn, ltype, error);
+ if (!error) {
+ /* calls VOP_GETATTR */
+ vnode_create_vobject(vp, 0, ap->a_td);
+ }
DPRINTF(("puffs_open: returning %d\n", error));
- PUFFS_MSG_RELEASE(open);
return error;
}
@@ -465,8 +490,10 @@
{
PUFFS_MSG_VARS(vn, access);
struct vnode *vp = ap->a_vp;
+ struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
accmode_t accmode = ap->a_accmode;
+ int ltype;
int error;
if (accmode & VWRITE) {
@@ -492,9 +519,12 @@
puffs_msg_setinfo(park_access, PUFFSOP_VN,
PUFFS_VN_ACCESS, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_access, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_access);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_access, pn, NULL);
error = checkerr(pmp, error, __func__);
PUFFS_MSG_RELEASE(access);
+ PUFFS_LOCKVNODE(pn, ltype, error);
return error;
}
@@ -505,9 +535,10 @@
PUFFS_MSG_VARS(vn, getattr);
struct vnode *vp = ap->a_vp;
struct mount *mp = vp->v_mount;
+ struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(mp);
struct vattr *vap, *rvap;
- struct puffs_node *pn;
+ int ltype;
int error = 0;
DPRINTF(("puffs_getattr: vp %p\n", vp));
@@ -519,8 +550,11 @@
puffs_msg_setinfo(park_getattr, PUFFSOP_VN,
PUFFS_VN_GETATTR, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_getattr, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_getattr);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_getattr, pn, NULL);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(pn, ltype, error);
if (error)
goto out;
@@ -543,7 +577,6 @@
(void) memcpy(vap, rvap, sizeof(struct vattr));
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
- pn = VPTOPP(vp);
if (pn->pn_stat & PNODE_METACACHE_ATIME)
vap->va_atime = pn->pn_mc_atime;
if (pn->pn_stat & PNODE_METACACHE_CTIME)
@@ -571,6 +604,7 @@
PUFFS_MSG_VARS(vn, setattr);
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
struct puffs_node *pn = vp->v_data;
+ int ltype;
int error;
if ((vp->v_mount->mnt_flag & MNT_RDONLY) &&
@@ -611,8 +645,11 @@
puffs_msg_setinfo(park_setattr, PUFFSOP_VN,
PUFFS_VN_SETATTR, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_setattr, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_setattr);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_setattr, pn, NULL);
PUFFS_MSG_RELEASE(setattr);
+ PUFFS_LOCKVNODE(pn, ltype, error);
error = checkerr(pmp, error, __func__);
if (error)
return error;
@@ -674,7 +711,6 @@
struct puffs_node *pnode;
int error;
- DPRINTF(("puffs_vnop_inactive: vp=%p; lock_class=%p\n", vp, LOCK_CLASS(&vp->v_lock.lock_object)));
pnode = vp->v_data;
if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) {
@@ -756,10 +792,12 @@
{
PUFFS_MSG_VARS(vn, readdir);
struct vnode *vp = ap->a_vp;
+ struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
size_t argsize, tomove, cookiemem, cookiesmax;
struct uio *uio = ap->a_uio;
size_t howmuch, resid;
+ int ltype;
int error;
const static struct dirent _dirent_minsize = {
@@ -813,8 +851,11 @@
PUFFS_VN_READDIR, VPTOPNC(vp));
puffs_msg_setdelta(park_readdir, tomove);
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_readdir, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_readdir);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_readdir, pn, NULL);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(pn, ltype, error);
if (error)
goto out;
@@ -873,6 +914,7 @@
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
struct puffs_node *pn;
struct vattr va;
+ int ltype;
int error, dofaf;
pn = VPTOPP(vp);
@@ -934,10 +976,13 @@
puffs_msg_setinfo(park_fsync, PUFFSOP_VN,
PUFFS_VN_FSYNC, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_fsync, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_fsync);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_fsync, pn, NULL);
+ error = checkerr(pmp, error, __func__);
+
PUFFS_MSG_RELEASE(fsync);
-
- error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(pn, ltype, error);
return error;
}
@@ -977,6 +1022,7 @@
struct mount *mp = dvp->v_mount;
struct puffs_mount *pmp = MPTOPUFFSMP(mp);
int error;
+ int ltype, dltype;
PUFFS_MSG_ALLOC(vn, remove);
remove_msg->pvnr_cookie_targ = VPTOPNC(vp);
@@ -986,17 +1032,22 @@
PUFFS_VN_REMOVE, VPTOPNC(dvp));
puffs_msg_enqueue(pmp, park_remove);
- REFPN_AND_UNLOCKVP(dvp, dpn);
- if (dvp == vp)
- REFPN(pn);
- else
- REFPN_AND_UNLOCKVP(vp, pn);
+ puffs_unlockvnode(dpn, &dltype);
+ if (dvp == vp) {
+ mtx_lock(&pn->pn_mtx);
+ puffs_referencenode(pn);
+ mtx_unlock(&pn->pn_mtx);
+ } else
+ puffs_unlockvnode(pn, <ype);
error = puffs_msg_wait2(pmp, park_remove, dpn, pn);
PUFFS_MSG_RELEASE(remove);
- RELEPN_AND_VP(dvp, dpn);
- RELEPN_AND_VP(vp, pn);
+ if (dvp == vp)
+ puffs_releasenode(pn);
+ else
+ PUFFS_LOCKVNODE(dpn, dltype, error);
+ PUFFS_LOCKVNODE(pn, dltype, error);
error = checkerr(pmp, error, __func__);
return error;
@@ -1011,6 +1062,7 @@
struct componentname *cnp = ap->a_cnp;
struct mount *mp = dvp->v_mount;
struct puffs_mount *pmp = MPTOPUFFSMP(mp);
+ int dltype;
int error;
DPRINTF(("puffs_vnop_mkdir: %.*s\n", (int) cnp->cn_namelen, cnp->cn_nameptr));
@@ -1023,22 +1075,25 @@
PUFFS_VN_MKDIR, VPTOPNC(dvp));
puffs_msg_enqueue(pmp, park_mkdir);
- REFPN_AND_UNLOCKVP(dvp, dpn);
+ puffs_unlockvnode(dpn, &dltype);
error = puffs_msg_wait2(pmp, park_mkdir, dpn, NULL);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
if (error)
goto out;
error = puffs_newnode(mp, dvp, ap->a_vpp,
mkdir_msg->pvnr_newnode, cnp, VDIR, 0);
- if (error)
+ if (error) {
+ puffs_unlockvnode(dpn, &dltype);
puffs_abortbutton(pmp, PUFFS_ABORT_MKDIR, dpn->pn_cookie,
mkdir_msg->pvnr_newnode, cnp);
+ puffs_lockvnode(dpn, dltype);
+ }
out:
PUFFS_MSG_RELEASE(mkdir);
- RELEPN_AND_VP(dvp, dpn);
return error;
}
@@ -1071,6 +1126,7 @@
struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount);
struct componentname *cnp = ap->a_cnp;
+ int dltype, ltype;
int error;
PUFFS_MSG_ALLOC(vn, rmdir);
@@ -1081,15 +1137,15 @@
PUFFS_VN_RMDIR, VPTOPNC(dvp));
puffs_msg_enqueue(pmp, park_rmdir);
- REFPN_AND_UNLOCKVP(dvp, dpn);
- REFPN_AND_UNLOCKVP(vp, pn);
+ puffs_unlockvnode(dpn, &dltype);
+ puffs_unlockvnode(pn, <ype);
error = puffs_msg_wait2(pmp, park_rmdir, dpn, pn);
PUFFS_MSG_RELEASE(rmdir);
/* XXX: some call cache_purge() *for both vnodes* here, investigate */
- RELEPN_AND_VP(dvp, dpn);
- RELEPN_AND_VP(vp, pn);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
+ PUFFS_LOCKVNODE(pn, ltype, error);
return error;
}
@@ -1104,6 +1160,7 @@
struct puffs_node *pn = VPTOPP(vp);
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount);
struct componentname *cnp = ap->a_cnp;
+ int dltype;
int error;
PUFFS_MSG_ALLOC(vn, link);
@@ -1114,13 +1171,16 @@
PUFFS_VN_LINK, VPTOPNC(dvp));
puffs_msg_enqueue(pmp, park_link);
- REFPN_AND_UNLOCKVP(dvp, dpn);
- REFPN(pn);
+ puffs_unlockvnode(dpn, &dltype);
+ mtx_lock(&pn->pn_mtx);
+ puffs_referencenode(pn);
+ mtx_unlock(&pn->pn_mtx);
error = puffs_msg_wait2(pmp, park_link, dpn, pn);
PUFFS_MSG_RELEASE(link);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
/*
* XXX: stay in touch with the cache. I don't like this, but
@@ -1129,7 +1189,6 @@
if (error == 0)
puffs_updatenode(pn, PUFFS_UPDATECTIME, 0);
- RELEPN_AND_VP(dvp, dpn);
puffs_releasenode(pn);
return error;
@@ -1144,6 +1203,7 @@
struct mount *mp = dvp->v_mount;
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount);
struct componentname *cnp = ap->a_cnp;
+ int dltype;
int error;
*ap->a_vpp = NULL;
@@ -1158,22 +1218,25 @@
PUFFS_VN_SYMLINK, VPTOPNC(dvp));
puffs_msg_enqueue(pmp, park_symlink);
- REFPN_AND_UNLOCKVP(dvp, dpn);
+ puffs_unlockvnode(dpn, &dltype);
error = puffs_msg_wait2(pmp, park_symlink, dpn, NULL);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(dpn, dltype, error);
if (error)
goto out;
error = puffs_newnode(mp, dvp, ap->a_vpp,
symlink_msg->pvnr_newnode, cnp, VLNK, 0);
- if (error)
+ if (error) {
+ puffs_unlockvnode(dpn, &dltype);
puffs_abortbutton(pmp, PUFFS_ABORT_SYMLINK, dpn->pn_cookie,
symlink_msg->pvnr_newnode, cnp);
+ puffs_lockvnode(dpn, dltype);
+ }
out:
PUFFS_MSG_RELEASE(symlink);
- RELEPN_AND_VP(dvp, dpn);
return error;
}
@@ -1184,7 +1247,9 @@
PUFFS_MSG_VARS(vn, readlink);
struct vnode *vp = ap->a_vp;
struct puffs_mount *pmp = MPTOPUFFSMP(ap->a_vp->v_mount);
+ struct puffs_node *pn = VPTOPP(vp);
size_t linklen;
+ int ltype;
int error;
PUFFS_MSG_ALLOC(vn, readlink);
@@ -1194,8 +1259,11 @@
puffs_msg_setinfo(park_readlink, PUFFSOP_VN,
PUFFS_VN_READLINK, VPTOPNC(vp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_readlink, vp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_readlink);
+ puffs_unlockvnode(pn, <ype);
+ error = puffs_msg_wait2(pmp, park_readlink, pn, NULL);
error = checkerr(pmp, error, __func__);
+ PUFFS_LOCKVNODE(pn, ltype, error);
if (error)
goto out;
@@ -1220,7 +1288,10 @@
PUFFS_MSG_VARS(vn, rename);
struct vnode *fdvp = ap->a_fdvp;
struct puffs_node *fpn = ap->a_fvp->v_data;
+ struct puffs_node *tdpn = VPTOPP(ap->a_tdvp);
+ struct puffs_node *tpn = NULL;
struct puffs_mount *pmp = MPTOPUFFSMP(fdvp->v_mount);
+ int tltype, tdltype;
int error;
if (ap->a_fvp->v_mount != ap->a_tdvp->v_mount)
@@ -1240,8 +1311,20 @@
puffs_msg_setinfo(park_rename, PUFFSOP_VN,
PUFFS_VN_RENAME, VPTOPNC(fdvp));
- PUFFS_MSG_ENQUEUEWAIT2(pmp, park_rename, fdvp->v_data, NULL, error);
+ puffs_msg_enqueue(pmp, park_rename);
+ if (ap->a_tvp) {
+ tpn = VPTOPP(ap->a_tvp);
+ puffs_unlockvnode(tpn, &tltype);
+ }
+ puffs_unlockvnode(tdpn, &tdltype);
+ error = puffs_msg_wait2(pmp, park_rename, fdvp->v_data, NULL);
error = checkerr(pmp, error, __func__);
+ if (ap->a_tvp) {
+ PUFFS_LOCKVNODE(tpn, tltype, error);
+ }
+ PUFFS_LOCKVNODE(tdpn, tdltype, error);
+ if (error)
+ goto out;
/*
* XXX: stay in touch with the cache. I don't like this, but
@@ -1277,6 +1360,7 @@
PUFFS_MSG_VARS(vn, read);
struct vnode *vp = ap->a_vp;
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+ struct puffs_node *pn = VPTOPP(vp);
struct uio *uio = ap->a_uio;
size_t tomove, argsize;
#ifdef XXX_TS
@@ -1284,6 +1368,7 @@
size_t bytelen;
int error, ubcflags;
#else
+ int ltype;
int error;
#endif
@@ -1329,14 +1414,22 @@
* i.e. explicit read operations
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list