Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Jun 2009 20:34:01 GMT
From:      Tatsiana Severyna <tatsianka@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 165328 for review
Message-ID:  <200906272034.n5RKY1bH081022@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165328

Change 165328 by tatsianka@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, &ltype);
+	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, &ltype);
+	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, &ltype);
+	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, &ltype);
+	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, &ltype);
+	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, &ltype);
+	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, &ltype);
 	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, &ltype);
 	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, &ltype);
+	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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906272034.n5RKY1bH081022>