From owner-p4-projects@FreeBSD.ORG Sat Jun 27 20:34:02 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A7E671065674; Sat, 27 Jun 2009 20:34:01 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6772A106564A for ; Sat, 27 Jun 2009 20:34:01 +0000 (UTC) (envelope-from tatsianka@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 53BC38FC0A for ; Sat, 27 Jun 2009 20:34:01 +0000 (UTC) (envelope-from tatsianka@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5RKY1vQ081024 for ; Sat, 27 Jun 2009 20:34:01 GMT (envelope-from tatsianka@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5RKY1bH081022 for perforce@freebsd.org; Sat, 27 Jun 2009 20:34:01 GMT (envelope-from tatsianka@FreeBSD.org) Date: Sat, 27 Jun 2009 20:34:01 GMT Message-Id: <200906272034.n5RKY1bH081022@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to tatsianka@FreeBSD.org using -f From: Tatsiana Severyna To: Perforce Change Reviews Cc: Subject: PERFORCE change 165328 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jun 2009 20:34:03 -0000 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 ==== //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 /* 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) <<<