From owner-p4-projects@FreeBSD.ORG Sat Jul 25 11:00:08 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6C4BC1065676; Sat, 25 Jul 2009 11:00:08 +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 28DA7106564A for ; Sat, 25 Jul 2009 11:00:08 +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 14CE28FC17 for ; Sat, 25 Jul 2009 11:00:08 +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 n6PB07cF082153 for ; Sat, 25 Jul 2009 11:00:07 GMT (envelope-from tatsianka@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n6PB076h082151 for perforce@freebsd.org; Sat, 25 Jul 2009 11:00:07 GMT (envelope-from tatsianka@FreeBSD.org) Date: Sat, 25 Jul 2009 11:00:07 GMT Message-Id: <200907251100.n6PB076h082151@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 166546 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, 25 Jul 2009 11:00:10 -0000 http://perforce.freebsd.org/chv.cgi?CH=166546 Change 166546 by tatsianka@tatsianka_zonder on 2009/07/25 10:59:42 Lock vfs and vnodes in puffsop_flush. Unconditionally use vop_stdgetpages/vop_stdputpages. Mark puffs mpsafe. Return EINVAL if vop_pathconf is not implemented. Do not wait for reply in vop_inactive to prevent deadlock. Fix long standing cc stack alignment bug in lubpuffs. Initialize fi.flags before calling fuse.create in librefuse. Reduce debug. Affected files ... .. //depot/projects/soc2009/tatsianka_puffs/libpuffs/callcontext.c#4 edit .. //depot/projects/soc2009/tatsianka_puffs/libpuffs/dispatcher.c#3 edit .. //depot/projects/soc2009/tatsianka_puffs/librefuse/Makefile#2 edit .. //depot/projects/soc2009/tatsianka_puffs/librefuse/refuse.c#2 edit .. //depot/projects/soc2009/tatsianka_puffs/librefuse/refuse_opt.c#2 edit .. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_msgif.c#6 edit .. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_node.c#8 edit .. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vfsops.c#7 edit .. //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vnops.c#8 edit Differences ... ==== //depot/projects/soc2009/tatsianka_puffs/libpuffs/callcontext.c#4 (text+ko) ==== @@ -180,16 +180,25 @@ struct puffs_cc *volatile pcc; void *sp; size_t stacksize = 1<pu_cc_stackshift; + size_t stackalign; long psize = sysconf(_SC_PAGESIZE); if (puffs_fakecc) return &fakecc; /* XXX_TS MAP_ALIGNED(pu->pu_cc_stackshift) */ - sp = mmap(NULL, stacksize, PROT_READ|PROT_WRITE, + sp = mmap(NULL, stacksize * 2, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); if (sp == MAP_FAILED) return NULL; + stackalign = ((uintptr_t)sp) & (stacksize-1); + if (stackalign != 0) { + munmap(sp, stacksize - stackalign); + sp = (uint8_t *)sp + stacksize - stackalign; + munmap((uint8_t *)sp + stacksize, stackalign); + } else { + munmap((uint8_t *)sp + stacksize, stacksize); + } pcc = sp; memset(pcc, 0, sizeof(struct puffs_cc)); @@ -247,7 +256,7 @@ * swapcontext(). However, it gets lost. So reinit it. */ st = &pcc->pcc_uc.uc_stack; - st->ss_sp = pcc; + st->ss_sp = (void *)pcc; st->ss_size = stacksize; st->ss_flags = 0; ==== //depot/projects/soc2009/tatsianka_puffs/libpuffs/dispatcher.c#3 (text+ko) ==== @@ -69,12 +69,6 @@ struct puffs_cc *pcc = puffs_cc_getcc(pu); struct puffs_req *preq; - /* XXX_TS */ - if (!pcc->pcc_pu) { - printf("XXX puffs__ml_dispatch: pcc->pcc_pu == NULL\n"); - pcc->pcc_pu = pu; - } - pcc->pcc_pb = pb; pcc->pcc_flags |= PCC_MLCONT; dispatch(pcc); @@ -798,7 +792,7 @@ { struct puffs_vnmsg_pathconf *auxt = auxbuf; if (pops->puffs_node_pathconf == NULL) { - error = 0; + error = EINVAL; break; } ==== //depot/projects/soc2009/tatsianka_puffs/librefuse/Makefile#2 (text+ko) ==== @@ -7,11 +7,12 @@ MOUNT= /usr/src/sbin/mount .PATH: ${MOUNT} +CFLAGS+= -DMULTITHREADED_REFUSE CFLAGS+= ${FUSE_OPT_DEBUG_FLAGS} CFLAGS+= -g -I${.CURDIR}/../libpuffs -I${.CURDIR}/../putter -I${.CURDIR}/../puffs -I${MOUNT} SRCS= refuse.c refuse_opt.c MAN= refuse.3 -#WARNS= 4 +WARNS= 2 #SHLIB_MAJOR= 1 .include ==== //depot/projects/soc2009/tatsianka_puffs/librefuse/refuse.c#2 (text+ko) ==== @@ -611,6 +611,9 @@ set_fuse_context_uid_gid(pcn->pcn_cred); + if (fuse->op.getattr == NULL) { + return ENOSYS; + } ret = fuse->op.getattr(path, &st); if (ret != 0) { @@ -770,6 +773,8 @@ created = 0; if (fuse->op.create) { + bzero(&fi, sizeof(fi)); + fi.flags = O_CREAT | O_EXCL | O_WRONLY; ret = fuse->op.create(path, mode | S_IFREG, &fi); if (ret == 0) created = 1; ==== //depot/projects/soc2009/tatsianka_puffs/librefuse/refuse_opt.c#2 (text+ko) ==== @@ -141,6 +141,8 @@ args->argv = a; args->allocated = na; } + + return 0; } void ==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_msgif.c#6 (text+ko) ==== @@ -788,16 +788,19 @@ puffsop_flush(struct puffs_mount *pmp, struct puffs_flush *pf) { struct vnode *vp; - int rv; + int rv, vfslocked; if (pf->pf_req.preq_pth.pth_framelen != sizeof(struct puffs_flush)) { rv = EINVAL; goto out; } + vfslocked = VFS_LOCK_GIANT(PMPTOMP(pmp)); + /* XXX: slurry */ if (pf->pf_op == PUFFS_INVAL_NAMECACHE_ALL) { cache_purgevfs(PMPTOMP(pmp)); + VFS_UNLOCK_GIANT(vfslocked); rv = 0; goto out; } @@ -810,9 +813,12 @@ * userspace waiting for us to complete ==> deadlock. Another * reason we need to eventually bump locking to userspace, as we * will need to lock the node if we wish to do flushes. + * + * XXX_TS: Lock vnode, there is no locks held while in userspace */ - rv = puffs_cookie2vnode(pmp, pf->pf_cookie, 0, 0, &vp); + rv = puffs_cookie2vnode(pmp, pf->pf_cookie, LK_EXCLUSIVE, 0, &vp); if (rv) { + VFS_UNLOCK_GIANT(vfslocked); if (rv == PUFFS_NOSUCHCOOKIE) rv = ENOENT; goto out; @@ -855,7 +861,9 @@ rv = EINVAL; } + VOP_UNLOCK(vp, 0); vrele(vp); + VFS_UNLOCK_GIANT(vfslocked); out: puffs_msg_sendresp(pmp, &pf->pf_req, rv); ==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_node.c#8 (text+ko) ==== @@ -465,7 +465,6 @@ mtx_assert(&pn->pn_mtx, MA_OWNED); pn->pn_refcount++; - DPRINTF(("puffs_referencenode: pn_refcount=%d pn_vp=%p\n", pn->pn_refcount, pn->pn_vp)); } /* @@ -487,7 +486,6 @@ knlist_destroy(&pn->pn_sel.si_note); uma_zfree(puffs_pnpool, pn); } else { - DPRINTF(("puffs_releasenode: pn_refcount=%d pn_vp=%p\n", pn->pn_refcount, pn->pn_vp)); mtx_unlock(&pn->pn_mtx); } } @@ -527,7 +525,6 @@ 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); ==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vfsops.c#7 (text+ko) ==== @@ -198,6 +198,7 @@ MNT_ILOCK(mp); mp->mnt_flag &= ~MNT_LOCAL; /* we don't really know, so ... */ + mp->mnt_kern_flag |= MNTK_MPSAFE; MNT_IUNLOCK(mp); pmp->pmp_status = PUFFSTAT_MOUNTING; ==== //depot/projects/soc2009/tatsianka_puffs/puffs/puffs_vnops.c#8 (text+ko) ==== @@ -199,29 +199,21 @@ isdot = cnp->cn_namelen == 1 && *cnp->cn_nameptr == '.'; - DPRINTF(("puffs_lookup: \"%s\", parent vnode %p, op: %jx\n", - cnp->cn_nameptr, dvp, (intmax_t) cnp->cn_nameiop)); - /* * Check if someone fed it into the cache */ if (PUFFS_USE_NAMECACHE(pmp)) { - DPRINTF(("puffs_lookup: use name cache\n")); error = cache_lookup(dvp, ap->a_vpp, cnp); if (error == -1) { - DPRINTF(("puffs_lookup: cache_lookup(%s): vp=%p\n", cnp->cn_nameptr, *ap->a_vpp)); return 0; } if (error == ENOENT) { - DPRINTF(("puffs_lookup: cache_lookup(%s): negative\n", cnp->cn_nameptr)); return error; } - DPRINTF(("puffs_lookup: cache_lookup(%s): failed\n", cnp->cn_nameptr)); } if (isdot) { - DPRINTF(("puffs_lookup: isdot: %.*s\n", (int) cnp->cn_namelen, cnp->cn_nameptr)); vp = ap->a_dvp; vref(vp); *ap->a_vpp = vp; @@ -232,10 +224,6 @@ puffs_makecn(&lookup_msg->pvnr_cn, &lookup_msg->pvnr_cn_cred, cnp, PUFFS_USE_FULLPNBUF(pmp)); - if (cnp->cn_flags & ISDOTDOT) { - DPRINTF(("puffs_lookup: ISDOTDOT\n")); - } - puffs_msg_setinfo(park_lookup, PUFFSOP_VN, PUFFS_VN_LOOKUP, VPTOPNC(dvp)); @@ -324,7 +312,6 @@ out: PUFFS_MSG_RELEASE(lookup); - DPRINTF(("puffs_lookup: returning %d %p\n", error, *ap->a_vpp)); return error; } @@ -340,9 +327,6 @@ int dltype; int error; - DPRINTF(("puffs_create: dvp %p, cnp: %s\n", - dvp, ap->a_cnp->cn_nameptr)); - PUFFS_MSG_ALLOC(vn, create); puffs_makecn(&create_msg->pvnr_cn, &create_msg->pvnr_cn_cred, cnp, PUFFS_USE_FULLPNBUF(pmp)); @@ -376,7 +360,6 @@ out: PUFFS_MSG_RELEASE(create); - DPRINTF(("puffs_create: return %d\n", error)); return error; } @@ -421,7 +404,6 @@ out: PUFFS_MSG_RELEASE(mknod); - DPRINTF(("puff_mknod: returning %d\n", error)); return error; } @@ -436,8 +418,6 @@ 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)) return EROFS; @@ -461,7 +441,6 @@ /* calls VOP_GETATTR */ vnode_create_vobject(vp, 0, ap->a_td); } - DPRINTF(("puffs_open: returning %d\n", error)); return error; } @@ -540,7 +519,6 @@ int ltype; int error = 0; - DPRINTF(("puffs_getattr: vp %p\n", vp)); vap = ap->a_vap; PUFFS_MSG_ALLOC(vn, getattr); @@ -703,20 +681,23 @@ struct vnode *vp = ap->a_vp; struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); struct puffs_node *pnode; - int error; pnode = vp->v_data; if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) { + /* + * do not wait for reply from userspace, otherwise it may + * deadlock. + */ PUFFS_MSG_ALLOC(vn, inactive); + puffs_msg_setfaf(park_inactive); puffs_msg_setinfo(park_inactive, PUFFSOP_VN, PUFFS_VN_INACTIVE, VPTOPNC(vp)); - PUFFS_MSG_ENQUEUEWAIT2(pmp, park_inactive, vp->v_data, - NULL, error); + puffs_msg_enqueue(pmp, park_inactive); PUFFS_MSG_RELEASE(inactive); } - DPRINTF(("puffs_vnop_inactive: vp=%p; lock_class=%p\n", vp, LOCK_CLASS(&vp->v_lock.lock_object))); + DPRINTF(("puffs_vnop_inactive: vp=%p\n", vp)); pnode->pn_stat &= ~PNODE_DOINACT; /* @@ -1038,8 +1019,6 @@ int dltype; int error; - DPRINTF(("puffs_vnop_mkdir: %.*s\n", (int) cnp->cn_namelen, cnp->cn_nameptr)); - PUFFS_MSG_ALLOC(vn, mkdir); puffs_makecn(&mkdir_msg->pvnr_cn, &mkdir_msg->pvnr_cn_cred, cnp, PUFFS_USE_FULLPNBUF(pmp)); @@ -1631,6 +1610,9 @@ int ltype; int error; + if (!EXISTSOP(pmp, PATHCONF)) + return EINVAL; + PUFFS_MSG_ALLOC(vn, pathconf); pathconf_msg->pvnr_name = ap->a_name; puffs_msg_setinfo(park_pathconf, PUFFSOP_VN, @@ -1869,28 +1851,6 @@ #endif static int -puffs_vnop_getpages(struct vop_getpages_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); - - if (!PUFFS_USE_PAGECACHE(pmp)) - return EOPNOTSUPP; - return vop_stdgetpages(ap); -} - -static int -puffs_vnop_putpages(struct vop_putpages_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); - - if (!PUFFS_USE_PAGECACHE(pmp)) - return EOPNOTSUPP; - return vop_stdputpages(ap); -} - -static int puffs_fifo_close(struct vop_close_args *ap) { puffs_updatenode(VPTOPP(ap->a_vp), PUFFS_UPDATEATIME | PUFFS_UPDATEMTIME, 0); @@ -1931,8 +1891,8 @@ .vop_vptofh = puffs_vnop_vptofh, .vop_strategy = VOP_PANIC, .vop_bmap = VOP_EOPNOTSUPP, - .vop_getpages = puffs_vnop_getpages, - .vop_putpages = puffs_vnop_putpages, + .vop_getpages = vop_stdgetpages, + .vop_putpages = vop_stdputpages, }; /*