1*0a6a1f1dSLionel Sambuc /* $NetBSD: dispatcher.c,v 1.48 2014/10/31 13:56:04 manu Exp $ */
284d9c625SLionel Sambuc
384d9c625SLionel Sambuc /*
484d9c625SLionel Sambuc * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved.
584d9c625SLionel Sambuc *
684d9c625SLionel Sambuc * Development of this software was supported by the
784d9c625SLionel Sambuc * Ulla Tuominen Foundation, the Finnish Cultural Foundation and
884d9c625SLionel Sambuc * Research Foundation of Helsinki University of Technology.
984d9c625SLionel Sambuc *
1084d9c625SLionel Sambuc * Redistribution and use in source and binary forms, with or without
1184d9c625SLionel Sambuc * modification, are permitted provided that the following conditions
1284d9c625SLionel Sambuc * are met:
1384d9c625SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
1484d9c625SLionel Sambuc * notice, this list of conditions and the following disclaimer.
1584d9c625SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
1684d9c625SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
1784d9c625SLionel Sambuc * documentation and/or other materials provided with the distribution.
1884d9c625SLionel Sambuc *
1984d9c625SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
2084d9c625SLionel Sambuc * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2184d9c625SLionel Sambuc * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2284d9c625SLionel Sambuc * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2384d9c625SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2484d9c625SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2584d9c625SLionel Sambuc * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2684d9c625SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2784d9c625SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2884d9c625SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2984d9c625SLionel Sambuc * SUCH DAMAGE.
3084d9c625SLionel Sambuc */
3184d9c625SLionel Sambuc
3284d9c625SLionel Sambuc #include <sys/cdefs.h>
3384d9c625SLionel Sambuc #if !defined(lint)
34*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: dispatcher.c,v 1.48 2014/10/31 13:56:04 manu Exp $");
3584d9c625SLionel Sambuc #endif /* !lint */
3684d9c625SLionel Sambuc
3784d9c625SLionel Sambuc #include <sys/types.h>
3884d9c625SLionel Sambuc #include <sys/poll.h>
3984d9c625SLionel Sambuc
4084d9c625SLionel Sambuc #include <assert.h>
4184d9c625SLionel Sambuc #include <errno.h>
4284d9c625SLionel Sambuc #include <pthread.h>
4384d9c625SLionel Sambuc #include <puffs.h>
4484d9c625SLionel Sambuc #include <puffsdump.h>
4584d9c625SLionel Sambuc #include <stdio.h>
4684d9c625SLionel Sambuc #include <stdlib.h>
4784d9c625SLionel Sambuc #include <unistd.h>
4884d9c625SLionel Sambuc
4984d9c625SLionel Sambuc #include "puffs_priv.h"
5084d9c625SLionel Sambuc
5184d9c625SLionel Sambuc #define PUFFS_USE_FS_TTL(pu) (pu->pu_flags & PUFFS_KFLAG_CACHE_FS_TTL)
5284d9c625SLionel Sambuc
5384d9c625SLionel Sambuc static void dispatch(struct puffs_cc *);
5484d9c625SLionel Sambuc
5584d9c625SLionel Sambuc /* for our eyes only */
5684d9c625SLionel Sambuc void
puffs__ml_dispatch(struct puffs_usermount * pu,struct puffs_framebuf * pb)5784d9c625SLionel Sambuc puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb)
5884d9c625SLionel Sambuc {
5984d9c625SLionel Sambuc struct puffs_cc *pcc = puffs_cc_getcc(pu);
6084d9c625SLionel Sambuc struct puffs_req *preq;
6184d9c625SLionel Sambuc
6284d9c625SLionel Sambuc pcc->pcc_pb = pb;
6384d9c625SLionel Sambuc pcc->pcc_flags |= PCC_MLCONT;
6484d9c625SLionel Sambuc dispatch(pcc);
6584d9c625SLionel Sambuc
6684d9c625SLionel Sambuc /* Put result to kernel sendqueue if necessary */
6784d9c625SLionel Sambuc preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
6884d9c625SLionel Sambuc if (PUFFSOP_WANTREPLY(preq->preq_opclass)) {
6984d9c625SLionel Sambuc if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
7084d9c625SLionel Sambuc puffsdump_rv(preq);
7184d9c625SLionel Sambuc
7284d9c625SLionel Sambuc puffs_framev_enqueue_justsend(pu, pu->pu_fd,
7384d9c625SLionel Sambuc pcc->pcc_pb, 0, 0);
7484d9c625SLionel Sambuc } else {
7584d9c625SLionel Sambuc puffs_framebuf_destroy(pcc->pcc_pb);
7684d9c625SLionel Sambuc }
7784d9c625SLionel Sambuc
7884d9c625SLionel Sambuc /* who needs information when you're living on borrowed time? */
7984d9c625SLionel Sambuc if (pcc->pcc_flags & PCC_BORROWED) {
8084d9c625SLionel Sambuc puffs_cc_yield(pcc); /* back to borrow source */
8184d9c625SLionel Sambuc }
8284d9c625SLionel Sambuc pcc->pcc_flags = 0;
8384d9c625SLionel Sambuc }
8484d9c625SLionel Sambuc
8584d9c625SLionel Sambuc /* public, but not really tested and only semi-supported */
8684d9c625SLionel Sambuc int
puffs_dispatch_create(struct puffs_usermount * pu,struct puffs_framebuf * pb,struct puffs_cc ** pccp)8784d9c625SLionel Sambuc puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb,
8884d9c625SLionel Sambuc struct puffs_cc **pccp)
8984d9c625SLionel Sambuc {
9084d9c625SLionel Sambuc struct puffs_cc *pcc;
9184d9c625SLionel Sambuc
9284d9c625SLionel Sambuc if (puffs__cc_create(pu, dispatch, &pcc) == -1)
9384d9c625SLionel Sambuc return -1;
9484d9c625SLionel Sambuc
9584d9c625SLionel Sambuc pcc->pcc_pb = pb;
9684d9c625SLionel Sambuc *pccp = pcc;
9784d9c625SLionel Sambuc
9884d9c625SLionel Sambuc return 0;
9984d9c625SLionel Sambuc }
10084d9c625SLionel Sambuc
10184d9c625SLionel Sambuc int
puffs_dispatch_exec(struct puffs_cc * pcc,struct puffs_framebuf ** pbp)10284d9c625SLionel Sambuc puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp)
10384d9c625SLionel Sambuc {
10484d9c625SLionel Sambuc int rv;
10584d9c625SLionel Sambuc
10684d9c625SLionel Sambuc puffs_cc_continue(pcc);
10784d9c625SLionel Sambuc
10884d9c625SLionel Sambuc if (pcc->pcc_flags & PCC_DONE) {
10984d9c625SLionel Sambuc rv = 1;
11084d9c625SLionel Sambuc *pbp = pcc->pcc_pb;
11184d9c625SLionel Sambuc pcc->pcc_flags = 0;
11284d9c625SLionel Sambuc puffs__cc_destroy(pcc, 0);
11384d9c625SLionel Sambuc } else {
11484d9c625SLionel Sambuc rv = 0;
11584d9c625SLionel Sambuc }
11684d9c625SLionel Sambuc
11784d9c625SLionel Sambuc return rv;
11884d9c625SLionel Sambuc }
11984d9c625SLionel Sambuc
12084d9c625SLionel Sambuc static void
dispatch(struct puffs_cc * pcc)12184d9c625SLionel Sambuc dispatch(struct puffs_cc *pcc)
12284d9c625SLionel Sambuc {
12384d9c625SLionel Sambuc struct puffs_usermount *pu = pcc->pcc_pu;
12484d9c625SLionel Sambuc struct puffs_ops *pops = &pu->pu_ops;
12584d9c625SLionel Sambuc struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
12684d9c625SLionel Sambuc void *auxbuf; /* help with typecasting */
12784d9c625SLionel Sambuc puffs_cookie_t opcookie;
12884d9c625SLionel Sambuc int error = 0, buildpath, pncookie;
12984d9c625SLionel Sambuc
13084d9c625SLionel Sambuc /* XXX: smaller hammer, please */
13184d9c625SLionel Sambuc if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS &&
13284d9c625SLionel Sambuc preq->preq_optype == PUFFS_VFS_VPTOFH)) ||
13384d9c625SLionel Sambuc (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN &&
13484d9c625SLionel Sambuc (preq->preq_optype == PUFFS_VN_READDIR
13584d9c625SLionel Sambuc || preq->preq_optype == PUFFS_VN_READ))) {
13684d9c625SLionel Sambuc if (puffs_framebuf_reserve_space(pcc->pcc_pb,
13784d9c625SLionel Sambuc PUFFS_MSG_MAXSIZE) == -1)
13884d9c625SLionel Sambuc error = errno;
13984d9c625SLionel Sambuc preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
14084d9c625SLionel Sambuc }
14184d9c625SLionel Sambuc
14284d9c625SLionel Sambuc auxbuf = preq;
14384d9c625SLionel Sambuc opcookie = preq->preq_cookie;
14484d9c625SLionel Sambuc
14584d9c625SLionel Sambuc assert((pcc->pcc_flags & PCC_DONE) == 0);
14684d9c625SLionel Sambuc
14784d9c625SLionel Sambuc buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH;
14884d9c625SLionel Sambuc pncookie = pu->pu_flags & PUFFS_FLAG_PNCOOKIE;
14984d9c625SLionel Sambuc assert(!buildpath || pncookie);
15084d9c625SLionel Sambuc
15184d9c625SLionel Sambuc preq->preq_setbacks = 0;
15284d9c625SLionel Sambuc
15384d9c625SLionel Sambuc if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
15484d9c625SLionel Sambuc puffsdump_req(preq);
15584d9c625SLionel Sambuc
15684d9c625SLionel Sambuc puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid);
15784d9c625SLionel Sambuc
15884d9c625SLionel Sambuc /* pre-operation */
15984d9c625SLionel Sambuc if (pu->pu_oppre)
16084d9c625SLionel Sambuc pu->pu_oppre(pu);
16184d9c625SLionel Sambuc
16284d9c625SLionel Sambuc if (error)
16384d9c625SLionel Sambuc goto out;
16484d9c625SLionel Sambuc
16584d9c625SLionel Sambuc /* Execute actual operation */
16684d9c625SLionel Sambuc if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) {
16784d9c625SLionel Sambuc switch (preq->preq_optype) {
16884d9c625SLionel Sambuc case PUFFS_VFS_UNMOUNT:
16984d9c625SLionel Sambuc {
17084d9c625SLionel Sambuc struct puffs_vfsmsg_unmount *auxt = auxbuf;
17184d9c625SLionel Sambuc
17284d9c625SLionel Sambuc PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING);
17384d9c625SLionel Sambuc error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags);
17484d9c625SLionel Sambuc if (!error)
17584d9c625SLionel Sambuc PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED);
17684d9c625SLionel Sambuc else
17784d9c625SLionel Sambuc PU_SETSTATE(pu, PUFFS_STATE_RUNNING);
17884d9c625SLionel Sambuc break;
17984d9c625SLionel Sambuc }
18084d9c625SLionel Sambuc
18184d9c625SLionel Sambuc case PUFFS_VFS_STATVFS:
18284d9c625SLionel Sambuc {
18384d9c625SLionel Sambuc struct puffs_vfsmsg_statvfs *auxt = auxbuf;
18484d9c625SLionel Sambuc
18584d9c625SLionel Sambuc error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb);
18684d9c625SLionel Sambuc break;
18784d9c625SLionel Sambuc }
18884d9c625SLionel Sambuc
18984d9c625SLionel Sambuc case PUFFS_VFS_SYNC:
19084d9c625SLionel Sambuc {
19184d9c625SLionel Sambuc struct puffs_vfsmsg_sync *auxt = auxbuf;
19284d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred);
19384d9c625SLionel Sambuc
19484d9c625SLionel Sambuc error = pops->puffs_fs_sync(pu,
19584d9c625SLionel Sambuc auxt->pvfsr_waitfor, pcr);
19684d9c625SLionel Sambuc break;
19784d9c625SLionel Sambuc }
19884d9c625SLionel Sambuc
19984d9c625SLionel Sambuc case PUFFS_VFS_FHTOVP:
20084d9c625SLionel Sambuc {
20184d9c625SLionel Sambuc struct puffs_vfsmsg_fhtonode *auxt = auxbuf;
20284d9c625SLionel Sambuc struct puffs_newinfo pni;
20384d9c625SLionel Sambuc
20484d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvfsr_fhcookie;
20584d9c625SLionel Sambuc pni.pni_vtype = &auxt->pvfsr_vtype;
20684d9c625SLionel Sambuc pni.pni_size = &auxt->pvfsr_size;
20784d9c625SLionel Sambuc pni.pni_rdev = &auxt->pvfsr_rdev;
20884d9c625SLionel Sambuc pni.pni_va = NULL;
20984d9c625SLionel Sambuc pni.pni_va_ttl = NULL;
21084d9c625SLionel Sambuc pni.pni_cn_ttl = NULL;
21184d9c625SLionel Sambuc
21284d9c625SLionel Sambuc error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data,
21384d9c625SLionel Sambuc auxt->pvfsr_dsize, &pni);
21484d9c625SLionel Sambuc
21584d9c625SLionel Sambuc break;
21684d9c625SLionel Sambuc }
21784d9c625SLionel Sambuc
21884d9c625SLionel Sambuc case PUFFS_VFS_VPTOFH:
21984d9c625SLionel Sambuc {
22084d9c625SLionel Sambuc struct puffs_vfsmsg_nodetofh *auxt = auxbuf;
22184d9c625SLionel Sambuc
22284d9c625SLionel Sambuc error = pops->puffs_fs_nodetofh(pu,
22384d9c625SLionel Sambuc auxt->pvfsr_fhcookie, auxt->pvfsr_data,
22484d9c625SLionel Sambuc &auxt->pvfsr_dsize);
22584d9c625SLionel Sambuc
22684d9c625SLionel Sambuc break;
22784d9c625SLionel Sambuc }
22884d9c625SLionel Sambuc
22984d9c625SLionel Sambuc case PUFFS_VFS_EXTATTRCTL:
23084d9c625SLionel Sambuc {
23184d9c625SLionel Sambuc struct puffs_vfsmsg_extattrctl *auxt = auxbuf;
23284d9c625SLionel Sambuc const char *attrname;
23384d9c625SLionel Sambuc int flags;
23484d9c625SLionel Sambuc
23584d9c625SLionel Sambuc if (pops->puffs_fs_extattrctl == NULL) {
23684d9c625SLionel Sambuc error = EOPNOTSUPP;
23784d9c625SLionel Sambuc break;
23884d9c625SLionel Sambuc }
23984d9c625SLionel Sambuc
24084d9c625SLionel Sambuc if (auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASATTRNAME)
24184d9c625SLionel Sambuc attrname = auxt->pvfsr_attrname;
24284d9c625SLionel Sambuc else
24384d9c625SLionel Sambuc attrname = NULL;
24484d9c625SLionel Sambuc
24584d9c625SLionel Sambuc flags = auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASNODE;
24684d9c625SLionel Sambuc error = pops->puffs_fs_extattrctl(pu, auxt->pvfsr_cmd,
24784d9c625SLionel Sambuc opcookie, flags,
24884d9c625SLionel Sambuc auxt->pvfsr_attrnamespace, attrname);
24984d9c625SLionel Sambuc break;
25084d9c625SLionel Sambuc }
25184d9c625SLionel Sambuc
25284d9c625SLionel Sambuc default:
25384d9c625SLionel Sambuc /*
25484d9c625SLionel Sambuc * I guess the kernel sees this one coming
25584d9c625SLionel Sambuc */
25684d9c625SLionel Sambuc error = EINVAL;
25784d9c625SLionel Sambuc break;
25884d9c625SLionel Sambuc }
25984d9c625SLionel Sambuc
26084d9c625SLionel Sambuc /* XXX: audit return values */
26184d9c625SLionel Sambuc /* XXX: sync with kernel */
26284d9c625SLionel Sambuc } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
26384d9c625SLionel Sambuc switch (preq->preq_optype) {
26484d9c625SLionel Sambuc case PUFFS_VN_LOOKUP:
26584d9c625SLionel Sambuc {
26684d9c625SLionel Sambuc struct puffs_vnmsg_lookup *auxt = auxbuf;
26784d9c625SLionel Sambuc struct puffs_newinfo pni;
26884d9c625SLionel Sambuc struct puffs_cn pcn;
26984d9c625SLionel Sambuc struct puffs_node *pn = NULL;
27084d9c625SLionel Sambuc
27184d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
27284d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
27384d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvnr_newnode;
27484d9c625SLionel Sambuc pni.pni_vtype = &auxt->pvnr_vtype;
27584d9c625SLionel Sambuc pni.pni_size = &auxt->pvnr_size;
27684d9c625SLionel Sambuc pni.pni_rdev = &auxt->pvnr_rdev;
27784d9c625SLionel Sambuc pni.pni_va = &auxt->pvnr_va;
27884d9c625SLionel Sambuc pni.pni_va_ttl = &auxt->pvnr_va_ttl;
27984d9c625SLionel Sambuc pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
28084d9c625SLionel Sambuc
28184d9c625SLionel Sambuc if (buildpath) {
28284d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
28384d9c625SLionel Sambuc if (error)
28484d9c625SLionel Sambuc break;
28584d9c625SLionel Sambuc }
28684d9c625SLionel Sambuc
28784d9c625SLionel Sambuc /* lookup *must* be present */
28884d9c625SLionel Sambuc error = pops->puffs_node_lookup(pu, opcookie,
28984d9c625SLionel Sambuc &pni, &pcn);
29084d9c625SLionel Sambuc
29184d9c625SLionel Sambuc if (buildpath) {
29284d9c625SLionel Sambuc if (error) {
29384d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
29484d9c625SLionel Sambuc } else {
29584d9c625SLionel Sambuc /*
29684d9c625SLionel Sambuc * did we get a new node or a
29784d9c625SLionel Sambuc * recycled node?
29884d9c625SLionel Sambuc */
29984d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
30084d9c625SLionel Sambuc if (pn->pn_po.po_path == NULL)
30184d9c625SLionel Sambuc pn->pn_po = pcn.pcn_po_full;
30284d9c625SLionel Sambuc else
30384d9c625SLionel Sambuc pu->pu_pathfree(pu,
30484d9c625SLionel Sambuc &pcn.pcn_po_full);
30584d9c625SLionel Sambuc }
30684d9c625SLionel Sambuc }
30784d9c625SLionel Sambuc
30884d9c625SLionel Sambuc if (pncookie && !error) {
30984d9c625SLionel Sambuc if (pn == NULL)
31084d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
31184d9c625SLionel Sambuc pn->pn_nlookup++;
31284d9c625SLionel Sambuc }
31384d9c625SLionel Sambuc break;
31484d9c625SLionel Sambuc }
31584d9c625SLionel Sambuc
31684d9c625SLionel Sambuc case PUFFS_VN_CREATE:
31784d9c625SLionel Sambuc {
31884d9c625SLionel Sambuc struct puffs_vnmsg_create *auxt = auxbuf;
31984d9c625SLionel Sambuc struct puffs_newinfo pni;
32084d9c625SLionel Sambuc struct puffs_cn pcn;
32184d9c625SLionel Sambuc struct puffs_node *pn = NULL;
32284d9c625SLionel Sambuc
32384d9c625SLionel Sambuc if (pops->puffs_node_create == NULL) {
32484d9c625SLionel Sambuc error = 0;
32584d9c625SLionel Sambuc break;
32684d9c625SLionel Sambuc }
32784d9c625SLionel Sambuc
32884d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
32984d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
33084d9c625SLionel Sambuc
33184d9c625SLionel Sambuc memset(&pni, 0, sizeof(pni));
33284d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvnr_newnode;
33384d9c625SLionel Sambuc pni.pni_va = &auxt->pvnr_va;
33484d9c625SLionel Sambuc pni.pni_va_ttl = &auxt->pvnr_va_ttl;
33584d9c625SLionel Sambuc pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
33684d9c625SLionel Sambuc
33784d9c625SLionel Sambuc if (buildpath) {
33884d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
33984d9c625SLionel Sambuc if (error)
34084d9c625SLionel Sambuc break;
34184d9c625SLionel Sambuc }
34284d9c625SLionel Sambuc
34384d9c625SLionel Sambuc error = pops->puffs_node_create(pu,
34484d9c625SLionel Sambuc opcookie, &pni, &pcn, &auxt->pvnr_va);
34584d9c625SLionel Sambuc
34684d9c625SLionel Sambuc if (buildpath) {
34784d9c625SLionel Sambuc if (error) {
34884d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
34984d9c625SLionel Sambuc } else {
35084d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
35184d9c625SLionel Sambuc pn->pn_po = pcn.pcn_po_full;
35284d9c625SLionel Sambuc }
35384d9c625SLionel Sambuc }
35484d9c625SLionel Sambuc
35584d9c625SLionel Sambuc if (pncookie && !error) {
35684d9c625SLionel Sambuc if (pn == NULL)
35784d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
35884d9c625SLionel Sambuc pn->pn_nlookup++;
35984d9c625SLionel Sambuc }
36084d9c625SLionel Sambuc break;
36184d9c625SLionel Sambuc }
36284d9c625SLionel Sambuc
36384d9c625SLionel Sambuc case PUFFS_VN_MKNOD:
36484d9c625SLionel Sambuc {
36584d9c625SLionel Sambuc struct puffs_vnmsg_mknod *auxt = auxbuf;
36684d9c625SLionel Sambuc struct puffs_newinfo pni;
36784d9c625SLionel Sambuc struct puffs_cn pcn;
36884d9c625SLionel Sambuc struct puffs_node *pn = NULL;
36984d9c625SLionel Sambuc
37084d9c625SLionel Sambuc if (pops->puffs_node_mknod == NULL) {
37184d9c625SLionel Sambuc error = 0;
37284d9c625SLionel Sambuc break;
37384d9c625SLionel Sambuc }
37484d9c625SLionel Sambuc
37584d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
37684d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
37784d9c625SLionel Sambuc
37884d9c625SLionel Sambuc memset(&pni, 0, sizeof(pni));
37984d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvnr_newnode;
38084d9c625SLionel Sambuc pni.pni_va = &auxt->pvnr_va;
38184d9c625SLionel Sambuc pni.pni_va_ttl = &auxt->pvnr_va_ttl;
38284d9c625SLionel Sambuc pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
38384d9c625SLionel Sambuc
38484d9c625SLionel Sambuc if (buildpath) {
38584d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
38684d9c625SLionel Sambuc if (error)
38784d9c625SLionel Sambuc break;
38884d9c625SLionel Sambuc }
38984d9c625SLionel Sambuc
39084d9c625SLionel Sambuc error = pops->puffs_node_mknod(pu,
39184d9c625SLionel Sambuc opcookie, &pni, &pcn, &auxt->pvnr_va);
39284d9c625SLionel Sambuc
39384d9c625SLionel Sambuc if (buildpath) {
39484d9c625SLionel Sambuc if (error) {
39584d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
39684d9c625SLionel Sambuc } else {
39784d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
39884d9c625SLionel Sambuc pn->pn_po = pcn.pcn_po_full;
39984d9c625SLionel Sambuc }
40084d9c625SLionel Sambuc }
40184d9c625SLionel Sambuc
40284d9c625SLionel Sambuc if (pncookie && !error) {
40384d9c625SLionel Sambuc if (pn == NULL)
40484d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
40584d9c625SLionel Sambuc pn->pn_nlookup++;
40684d9c625SLionel Sambuc }
40784d9c625SLionel Sambuc break;
40884d9c625SLionel Sambuc }
40984d9c625SLionel Sambuc
41084d9c625SLionel Sambuc case PUFFS_VN_OPEN:
41184d9c625SLionel Sambuc {
41284d9c625SLionel Sambuc struct puffs_vnmsg_open *auxt = auxbuf;
41384d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
41484d9c625SLionel Sambuc
415*0a6a1f1dSLionel Sambuc if (pops->puffs_node_open2 != NULL) {
416*0a6a1f1dSLionel Sambuc error = pops->puffs_node_open2(pu,
417*0a6a1f1dSLionel Sambuc opcookie, auxt->pvnr_mode, pcr,
418*0a6a1f1dSLionel Sambuc &auxt->pvnr_oflags);
419*0a6a1f1dSLionel Sambuc
420*0a6a1f1dSLionel Sambuc break;
421*0a6a1f1dSLionel Sambuc }
422*0a6a1f1dSLionel Sambuc
42384d9c625SLionel Sambuc if (pops->puffs_node_open == NULL) {
42484d9c625SLionel Sambuc error = 0;
42584d9c625SLionel Sambuc break;
42684d9c625SLionel Sambuc }
42784d9c625SLionel Sambuc
42884d9c625SLionel Sambuc error = pops->puffs_node_open(pu,
42984d9c625SLionel Sambuc opcookie, auxt->pvnr_mode, pcr);
43084d9c625SLionel Sambuc break;
43184d9c625SLionel Sambuc }
43284d9c625SLionel Sambuc
43384d9c625SLionel Sambuc case PUFFS_VN_CLOSE:
43484d9c625SLionel Sambuc {
43584d9c625SLionel Sambuc struct puffs_vnmsg_close *auxt = auxbuf;
43684d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
43784d9c625SLionel Sambuc
43884d9c625SLionel Sambuc if (pops->puffs_node_close == NULL) {
43984d9c625SLionel Sambuc error = 0;
44084d9c625SLionel Sambuc break;
44184d9c625SLionel Sambuc }
44284d9c625SLionel Sambuc
44384d9c625SLionel Sambuc error = pops->puffs_node_close(pu,
44484d9c625SLionel Sambuc opcookie, auxt->pvnr_fflag, pcr);
44584d9c625SLionel Sambuc break;
44684d9c625SLionel Sambuc }
44784d9c625SLionel Sambuc
44884d9c625SLionel Sambuc case PUFFS_VN_ACCESS:
44984d9c625SLionel Sambuc {
45084d9c625SLionel Sambuc struct puffs_vnmsg_access *auxt = auxbuf;
45184d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
45284d9c625SLionel Sambuc
45384d9c625SLionel Sambuc if (pops->puffs_node_access == NULL) {
45484d9c625SLionel Sambuc error = 0;
45584d9c625SLionel Sambuc break;
45684d9c625SLionel Sambuc }
45784d9c625SLionel Sambuc
45884d9c625SLionel Sambuc error = pops->puffs_node_access(pu,
45984d9c625SLionel Sambuc opcookie, auxt->pvnr_mode, pcr);
46084d9c625SLionel Sambuc break;
46184d9c625SLionel Sambuc }
46284d9c625SLionel Sambuc
46384d9c625SLionel Sambuc case PUFFS_VN_GETATTR:
46484d9c625SLionel Sambuc {
46584d9c625SLionel Sambuc struct puffs_vnmsg_getattr *auxt = auxbuf;
46684d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
46784d9c625SLionel Sambuc
46884d9c625SLionel Sambuc if (PUFFS_USE_FS_TTL(pu)) {
46984d9c625SLionel Sambuc if (pops->puffs_node_getattr_ttl == NULL) {
47084d9c625SLionel Sambuc error = EOPNOTSUPP;
47184d9c625SLionel Sambuc break;
47284d9c625SLionel Sambuc }
47384d9c625SLionel Sambuc
47484d9c625SLionel Sambuc error = pops->puffs_node_getattr_ttl(pu,
47584d9c625SLionel Sambuc opcookie, &auxt->pvnr_va, pcr,
47684d9c625SLionel Sambuc &auxt->pvnr_va_ttl);
47784d9c625SLionel Sambuc } else {
47884d9c625SLionel Sambuc if (pops->puffs_node_getattr == NULL) {
47984d9c625SLionel Sambuc error = EOPNOTSUPP;
48084d9c625SLionel Sambuc break;
48184d9c625SLionel Sambuc }
48284d9c625SLionel Sambuc
48384d9c625SLionel Sambuc error = pops->puffs_node_getattr(pu,
48484d9c625SLionel Sambuc opcookie, &auxt->pvnr_va, pcr);
48584d9c625SLionel Sambuc }
48684d9c625SLionel Sambuc break;
48784d9c625SLionel Sambuc }
48884d9c625SLionel Sambuc
48984d9c625SLionel Sambuc case PUFFS_VN_SETATTR:
49084d9c625SLionel Sambuc {
49184d9c625SLionel Sambuc struct puffs_vnmsg_setattr *auxt = auxbuf;
49284d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
49384d9c625SLionel Sambuc
49484d9c625SLionel Sambuc if (PUFFS_USE_FS_TTL(pu)) {
49584d9c625SLionel Sambuc int xflag = 0;
49684d9c625SLionel Sambuc
49784d9c625SLionel Sambuc if (pops->puffs_node_setattr_ttl == NULL) {
49884d9c625SLionel Sambuc error = EOPNOTSUPP;
49984d9c625SLionel Sambuc break;
50084d9c625SLionel Sambuc }
50184d9c625SLionel Sambuc
50284d9c625SLionel Sambuc if (!PUFFSOP_WANTREPLY(preq->preq_opclass))
50384d9c625SLionel Sambuc xflag |= PUFFS_SETATTR_FAF;
50484d9c625SLionel Sambuc
50584d9c625SLionel Sambuc error = pops->puffs_node_setattr_ttl(pu,
50684d9c625SLionel Sambuc opcookie, &auxt->pvnr_va, pcr,
50784d9c625SLionel Sambuc &auxt->pvnr_va_ttl, xflag);
50884d9c625SLionel Sambuc } else {
50984d9c625SLionel Sambuc if (pops->puffs_node_setattr == NULL) {
51084d9c625SLionel Sambuc error = EOPNOTSUPP;
51184d9c625SLionel Sambuc break;
51284d9c625SLionel Sambuc }
51384d9c625SLionel Sambuc
51484d9c625SLionel Sambuc error = pops->puffs_node_setattr(pu,
51584d9c625SLionel Sambuc opcookie, &auxt->pvnr_va, pcr);
51684d9c625SLionel Sambuc }
51784d9c625SLionel Sambuc break;
51884d9c625SLionel Sambuc }
51984d9c625SLionel Sambuc
52084d9c625SLionel Sambuc case PUFFS_VN_MMAP:
52184d9c625SLionel Sambuc {
52284d9c625SLionel Sambuc struct puffs_vnmsg_mmap *auxt = auxbuf;
52384d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
52484d9c625SLionel Sambuc
52584d9c625SLionel Sambuc if (pops->puffs_node_mmap == NULL) {
52684d9c625SLionel Sambuc error = 0;
52784d9c625SLionel Sambuc break;
52884d9c625SLionel Sambuc }
52984d9c625SLionel Sambuc
53084d9c625SLionel Sambuc error = pops->puffs_node_mmap(pu,
53184d9c625SLionel Sambuc opcookie, auxt->pvnr_prot, pcr);
53284d9c625SLionel Sambuc break;
53384d9c625SLionel Sambuc }
53484d9c625SLionel Sambuc
53584d9c625SLionel Sambuc case PUFFS_VN_FSYNC:
53684d9c625SLionel Sambuc {
53784d9c625SLionel Sambuc struct puffs_vnmsg_fsync *auxt = auxbuf;
53884d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
53984d9c625SLionel Sambuc
54084d9c625SLionel Sambuc if (pops->puffs_node_fsync == NULL) {
54184d9c625SLionel Sambuc error = 0;
54284d9c625SLionel Sambuc break;
54384d9c625SLionel Sambuc }
54484d9c625SLionel Sambuc
54584d9c625SLionel Sambuc error = pops->puffs_node_fsync(pu, opcookie, pcr,
54684d9c625SLionel Sambuc auxt->pvnr_flags, auxt->pvnr_offlo,
54784d9c625SLionel Sambuc auxt->pvnr_offhi);
54884d9c625SLionel Sambuc break;
54984d9c625SLionel Sambuc }
55084d9c625SLionel Sambuc
55184d9c625SLionel Sambuc case PUFFS_VN_SEEK:
55284d9c625SLionel Sambuc {
55384d9c625SLionel Sambuc struct puffs_vnmsg_seek *auxt = auxbuf;
55484d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
55584d9c625SLionel Sambuc
55684d9c625SLionel Sambuc if (pops->puffs_node_seek == NULL) {
55784d9c625SLionel Sambuc error = 0;
55884d9c625SLionel Sambuc break;
55984d9c625SLionel Sambuc }
56084d9c625SLionel Sambuc
56184d9c625SLionel Sambuc error = pops->puffs_node_seek(pu,
56284d9c625SLionel Sambuc opcookie, auxt->pvnr_oldoff,
56384d9c625SLionel Sambuc auxt->pvnr_newoff, pcr);
56484d9c625SLionel Sambuc break;
56584d9c625SLionel Sambuc }
56684d9c625SLionel Sambuc
56784d9c625SLionel Sambuc case PUFFS_VN_REMOVE:
56884d9c625SLionel Sambuc {
56984d9c625SLionel Sambuc struct puffs_vnmsg_remove *auxt = auxbuf;
57084d9c625SLionel Sambuc struct puffs_cn pcn;
57184d9c625SLionel Sambuc if (pops->puffs_node_remove == NULL) {
57284d9c625SLionel Sambuc error = 0;
57384d9c625SLionel Sambuc break;
57484d9c625SLionel Sambuc }
57584d9c625SLionel Sambuc
57684d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
57784d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
57884d9c625SLionel Sambuc
57984d9c625SLionel Sambuc error = pops->puffs_node_remove(pu,
58084d9c625SLionel Sambuc opcookie, auxt->pvnr_cookie_targ, &pcn);
58184d9c625SLionel Sambuc break;
58284d9c625SLionel Sambuc }
58384d9c625SLionel Sambuc
58484d9c625SLionel Sambuc case PUFFS_VN_LINK:
58584d9c625SLionel Sambuc {
58684d9c625SLionel Sambuc struct puffs_vnmsg_link *auxt = auxbuf;
58784d9c625SLionel Sambuc struct puffs_cn pcn;
58884d9c625SLionel Sambuc if (pops->puffs_node_link == NULL) {
58984d9c625SLionel Sambuc error = 0;
59084d9c625SLionel Sambuc break;
59184d9c625SLionel Sambuc }
59284d9c625SLionel Sambuc
59384d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
59484d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
59584d9c625SLionel Sambuc
59684d9c625SLionel Sambuc if (buildpath) {
59784d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
59884d9c625SLionel Sambuc if (error)
59984d9c625SLionel Sambuc break;
60084d9c625SLionel Sambuc }
60184d9c625SLionel Sambuc
60284d9c625SLionel Sambuc error = pops->puffs_node_link(pu,
60384d9c625SLionel Sambuc opcookie, auxt->pvnr_cookie_targ, &pcn);
60484d9c625SLionel Sambuc if (buildpath)
60584d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
60684d9c625SLionel Sambuc
60784d9c625SLionel Sambuc break;
60884d9c625SLionel Sambuc }
60984d9c625SLionel Sambuc
61084d9c625SLionel Sambuc case PUFFS_VN_RENAME:
61184d9c625SLionel Sambuc {
61284d9c625SLionel Sambuc struct puffs_vnmsg_rename *auxt = auxbuf;
61384d9c625SLionel Sambuc struct puffs_cn pcn_src, pcn_targ;
61484d9c625SLionel Sambuc struct puffs_node *pn_src;
61584d9c625SLionel Sambuc
61684d9c625SLionel Sambuc if (pops->puffs_node_rename == NULL) {
61784d9c625SLionel Sambuc error = 0;
61884d9c625SLionel Sambuc break;
61984d9c625SLionel Sambuc }
62084d9c625SLionel Sambuc
62184d9c625SLionel Sambuc pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src;
62284d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn_src.pcn_cred,
62384d9c625SLionel Sambuc &auxt->pvnr_cn_src_cred);
62484d9c625SLionel Sambuc
62584d9c625SLionel Sambuc pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ;
62684d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn_targ.pcn_cred,
62784d9c625SLionel Sambuc &auxt->pvnr_cn_targ_cred);
62884d9c625SLionel Sambuc
62984d9c625SLionel Sambuc if (buildpath) {
63084d9c625SLionel Sambuc pn_src = auxt->pvnr_cookie_src;
63184d9c625SLionel Sambuc pcn_src.pcn_po_full = pn_src->pn_po;
63284d9c625SLionel Sambuc
63384d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn_targ,
63484d9c625SLionel Sambuc auxt->pvnr_cookie_targdir);
63584d9c625SLionel Sambuc if (error)
63684d9c625SLionel Sambuc break;
63784d9c625SLionel Sambuc }
63884d9c625SLionel Sambuc
63984d9c625SLionel Sambuc error = pops->puffs_node_rename(pu,
64084d9c625SLionel Sambuc opcookie, auxt->pvnr_cookie_src,
64184d9c625SLionel Sambuc &pcn_src, auxt->pvnr_cookie_targdir,
64284d9c625SLionel Sambuc auxt->pvnr_cookie_targ, &pcn_targ);
64384d9c625SLionel Sambuc
64484d9c625SLionel Sambuc if (buildpath) {
64584d9c625SLionel Sambuc if (error) {
64684d9c625SLionel Sambuc pu->pu_pathfree(pu,
64784d9c625SLionel Sambuc &pcn_targ.pcn_po_full);
64884d9c625SLionel Sambuc } else {
64984d9c625SLionel Sambuc struct puffs_pathinfo pi;
65084d9c625SLionel Sambuc struct puffs_pathobj po_old;
65184d9c625SLionel Sambuc
65284d9c625SLionel Sambuc /* handle this node */
65384d9c625SLionel Sambuc po_old = pn_src->pn_po;
65484d9c625SLionel Sambuc pn_src->pn_po = pcn_targ.pcn_po_full;
65584d9c625SLionel Sambuc
65684d9c625SLionel Sambuc if (pn_src->pn_va.va_type != VDIR) {
65784d9c625SLionel Sambuc pu->pu_pathfree(pu, &po_old);
65884d9c625SLionel Sambuc break;
65984d9c625SLionel Sambuc }
66084d9c625SLionel Sambuc
66184d9c625SLionel Sambuc /* handle all child nodes for DIRs */
66284d9c625SLionel Sambuc pi.pi_old = &pcn_src.pcn_po_full;
66384d9c625SLionel Sambuc pi.pi_new = &pcn_targ.pcn_po_full;
66484d9c625SLionel Sambuc
66584d9c625SLionel Sambuc PU_LOCK();
66684d9c625SLionel Sambuc if (puffs_pn_nodewalk(pu,
66784d9c625SLionel Sambuc puffs_path_prefixadj, &pi) != NULL)
66884d9c625SLionel Sambuc error = ENOMEM;
66984d9c625SLionel Sambuc PU_UNLOCK();
67084d9c625SLionel Sambuc pu->pu_pathfree(pu, &po_old);
67184d9c625SLionel Sambuc }
67284d9c625SLionel Sambuc }
67384d9c625SLionel Sambuc break;
67484d9c625SLionel Sambuc }
67584d9c625SLionel Sambuc
67684d9c625SLionel Sambuc case PUFFS_VN_MKDIR:
67784d9c625SLionel Sambuc {
67884d9c625SLionel Sambuc struct puffs_vnmsg_mkdir *auxt = auxbuf;
67984d9c625SLionel Sambuc struct puffs_newinfo pni;
68084d9c625SLionel Sambuc struct puffs_cn pcn;
68184d9c625SLionel Sambuc struct puffs_node *pn = NULL;
68284d9c625SLionel Sambuc
68384d9c625SLionel Sambuc if (pops->puffs_node_mkdir == NULL) {
68484d9c625SLionel Sambuc error = 0;
68584d9c625SLionel Sambuc break;
68684d9c625SLionel Sambuc }
68784d9c625SLionel Sambuc
68884d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
68984d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
69084d9c625SLionel Sambuc
69184d9c625SLionel Sambuc memset(&pni, 0, sizeof(pni));
69284d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvnr_newnode;
69384d9c625SLionel Sambuc pni.pni_va = &auxt->pvnr_va;
69484d9c625SLionel Sambuc pni.pni_va_ttl = &auxt->pvnr_va_ttl;
69584d9c625SLionel Sambuc pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
69684d9c625SLionel Sambuc
69784d9c625SLionel Sambuc if (buildpath) {
69884d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
69984d9c625SLionel Sambuc if (error)
70084d9c625SLionel Sambuc break;
70184d9c625SLionel Sambuc }
70284d9c625SLionel Sambuc
70384d9c625SLionel Sambuc error = pops->puffs_node_mkdir(pu,
70484d9c625SLionel Sambuc opcookie, &pni, &pcn, &auxt->pvnr_va);
70584d9c625SLionel Sambuc
70684d9c625SLionel Sambuc if (buildpath) {
70784d9c625SLionel Sambuc if (error) {
70884d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
70984d9c625SLionel Sambuc } else {
71084d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
71184d9c625SLionel Sambuc pn->pn_po = pcn.pcn_po_full;
71284d9c625SLionel Sambuc }
71384d9c625SLionel Sambuc }
71484d9c625SLionel Sambuc
71584d9c625SLionel Sambuc if (pncookie && !error) {
71684d9c625SLionel Sambuc if (pn == NULL)
71784d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
71884d9c625SLionel Sambuc pn->pn_nlookup++;
71984d9c625SLionel Sambuc }
72084d9c625SLionel Sambuc break;
72184d9c625SLionel Sambuc }
72284d9c625SLionel Sambuc
72384d9c625SLionel Sambuc case PUFFS_VN_RMDIR:
72484d9c625SLionel Sambuc {
72584d9c625SLionel Sambuc struct puffs_vnmsg_rmdir *auxt = auxbuf;
72684d9c625SLionel Sambuc struct puffs_cn pcn;
72784d9c625SLionel Sambuc if (pops->puffs_node_rmdir == NULL) {
72884d9c625SLionel Sambuc error = 0;
72984d9c625SLionel Sambuc break;
73084d9c625SLionel Sambuc }
73184d9c625SLionel Sambuc
73284d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
73384d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
73484d9c625SLionel Sambuc
73584d9c625SLionel Sambuc error = pops->puffs_node_rmdir(pu,
73684d9c625SLionel Sambuc opcookie, auxt->pvnr_cookie_targ, &pcn);
73784d9c625SLionel Sambuc break;
73884d9c625SLionel Sambuc }
73984d9c625SLionel Sambuc
74084d9c625SLionel Sambuc case PUFFS_VN_SYMLINK:
74184d9c625SLionel Sambuc {
74284d9c625SLionel Sambuc struct puffs_vnmsg_symlink *auxt = auxbuf;
74384d9c625SLionel Sambuc struct puffs_newinfo pni;
74484d9c625SLionel Sambuc struct puffs_cn pcn;
74584d9c625SLionel Sambuc struct puffs_node *pn = NULL;
74684d9c625SLionel Sambuc
74784d9c625SLionel Sambuc if (pops->puffs_node_symlink == NULL) {
74884d9c625SLionel Sambuc error = 0;
74984d9c625SLionel Sambuc break;
75084d9c625SLionel Sambuc }
75184d9c625SLionel Sambuc
75284d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
75384d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
75484d9c625SLionel Sambuc
75584d9c625SLionel Sambuc memset(&pni, 0, sizeof(pni));
75684d9c625SLionel Sambuc pni.pni_cookie = &auxt->pvnr_newnode;
75784d9c625SLionel Sambuc pni.pni_va = &auxt->pvnr_va;
75884d9c625SLionel Sambuc pni.pni_va_ttl = &auxt->pvnr_va_ttl;
75984d9c625SLionel Sambuc pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
76084d9c625SLionel Sambuc
76184d9c625SLionel Sambuc if (buildpath) {
76284d9c625SLionel Sambuc error = puffs_path_pcnbuild(pu, &pcn, opcookie);
76384d9c625SLionel Sambuc if (error)
76484d9c625SLionel Sambuc break;
76584d9c625SLionel Sambuc }
76684d9c625SLionel Sambuc
76784d9c625SLionel Sambuc error = pops->puffs_node_symlink(pu,
76884d9c625SLionel Sambuc opcookie, &pni, &pcn,
76984d9c625SLionel Sambuc &auxt->pvnr_va, auxt->pvnr_link);
77084d9c625SLionel Sambuc
77184d9c625SLionel Sambuc if (buildpath) {
77284d9c625SLionel Sambuc if (error) {
77384d9c625SLionel Sambuc pu->pu_pathfree(pu, &pcn.pcn_po_full);
77484d9c625SLionel Sambuc } else {
77584d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
77684d9c625SLionel Sambuc pn->pn_po = pcn.pcn_po_full;
77784d9c625SLionel Sambuc }
77884d9c625SLionel Sambuc }
77984d9c625SLionel Sambuc
78084d9c625SLionel Sambuc if (pncookie && !error) {
78184d9c625SLionel Sambuc if (pn == NULL)
78284d9c625SLionel Sambuc pn = PU_CMAP(pu, auxt->pvnr_newnode);
78384d9c625SLionel Sambuc pn->pn_nlookup++;
78484d9c625SLionel Sambuc }
78584d9c625SLionel Sambuc break;
78684d9c625SLionel Sambuc }
78784d9c625SLionel Sambuc
78884d9c625SLionel Sambuc case PUFFS_VN_READDIR:
78984d9c625SLionel Sambuc {
79084d9c625SLionel Sambuc struct puffs_vnmsg_readdir *auxt = auxbuf;
79184d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
79284d9c625SLionel Sambuc struct dirent *dent;
79384d9c625SLionel Sambuc off_t *cookies;
79484d9c625SLionel Sambuc size_t res, origcookies;
79584d9c625SLionel Sambuc
79684d9c625SLionel Sambuc if (pops->puffs_node_readdir == NULL) {
79784d9c625SLionel Sambuc error = 0;
79884d9c625SLionel Sambuc break;
79984d9c625SLionel Sambuc }
80084d9c625SLionel Sambuc
80184d9c625SLionel Sambuc if (auxt->pvnr_ncookies) {
80284d9c625SLionel Sambuc /* LINTED: pvnr_data is __aligned() */
80384d9c625SLionel Sambuc cookies = (off_t *)auxt->pvnr_data;
80484d9c625SLionel Sambuc origcookies = auxt->pvnr_ncookies;
80584d9c625SLionel Sambuc } else {
80684d9c625SLionel Sambuc cookies = NULL;
80784d9c625SLionel Sambuc origcookies = 0;
80884d9c625SLionel Sambuc }
80984d9c625SLionel Sambuc /* LINTED: dentoff is aligned in the kernel */
81084d9c625SLionel Sambuc dent = (struct dirent *)
81184d9c625SLionel Sambuc (auxt->pvnr_data + auxt->pvnr_dentoff);
81284d9c625SLionel Sambuc
81384d9c625SLionel Sambuc res = auxt->pvnr_resid;
81484d9c625SLionel Sambuc error = pops->puffs_node_readdir(pu,
81584d9c625SLionel Sambuc opcookie, dent, &auxt->pvnr_offset,
81684d9c625SLionel Sambuc &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag,
81784d9c625SLionel Sambuc cookies, &auxt->pvnr_ncookies);
81884d9c625SLionel Sambuc
81984d9c625SLionel Sambuc /* much easier to track non-working NFS */
82084d9c625SLionel Sambuc assert(auxt->pvnr_ncookies <= origcookies);
82184d9c625SLionel Sambuc
82284d9c625SLionel Sambuc /* need to move a bit more */
82384d9c625SLionel Sambuc preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir)
82484d9c625SLionel Sambuc + auxt->pvnr_dentoff + (res - auxt->pvnr_resid);
82584d9c625SLionel Sambuc break;
82684d9c625SLionel Sambuc }
82784d9c625SLionel Sambuc
82884d9c625SLionel Sambuc case PUFFS_VN_READLINK:
82984d9c625SLionel Sambuc {
83084d9c625SLionel Sambuc struct puffs_vnmsg_readlink *auxt = auxbuf;
83184d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
83284d9c625SLionel Sambuc
83384d9c625SLionel Sambuc if (pops->puffs_node_readlink == NULL) {
83484d9c625SLionel Sambuc error = EOPNOTSUPP;
83584d9c625SLionel Sambuc break;
83684d9c625SLionel Sambuc }
83784d9c625SLionel Sambuc
83884d9c625SLionel Sambuc /*LINTED*/
83984d9c625SLionel Sambuc error = pops->puffs_node_readlink(pu, opcookie, pcr,
84084d9c625SLionel Sambuc auxt->pvnr_link, &auxt->pvnr_linklen);
84184d9c625SLionel Sambuc break;
84284d9c625SLionel Sambuc }
84384d9c625SLionel Sambuc
84484d9c625SLionel Sambuc case PUFFS_VN_RECLAIM:
84584d9c625SLionel Sambuc {
84684d9c625SLionel Sambuc struct puffs_vnmsg_reclaim *auxt = auxbuf;
84784d9c625SLionel Sambuc struct puffs_node *pn;
84884d9c625SLionel Sambuc
84984d9c625SLionel Sambuc if (pops->puffs_node_reclaim2 != NULL) {
85084d9c625SLionel Sambuc error = pops->puffs_node_reclaim2(pu, opcookie,
85184d9c625SLionel Sambuc auxt->pvnr_nlookup);
85284d9c625SLionel Sambuc break;
85384d9c625SLionel Sambuc }
85484d9c625SLionel Sambuc
85584d9c625SLionel Sambuc if (pops->puffs_node_reclaim == NULL) {
85684d9c625SLionel Sambuc error = 0;
85784d9c625SLionel Sambuc break;
85884d9c625SLionel Sambuc }
85984d9c625SLionel Sambuc
86084d9c625SLionel Sambuc /*
86184d9c625SLionel Sambuc * This fixes a race condition,
86284d9c625SLionel Sambuc * where a node in reclaimed by kernel
86384d9c625SLionel Sambuc * after a lookup request is sent,
86484d9c625SLionel Sambuc * but before the reply, leaving the kernel
86584d9c625SLionel Sambuc * with a invalid vnode/cookie reference.
86684d9c625SLionel Sambuc */
86784d9c625SLionel Sambuc if (pncookie) {
86884d9c625SLionel Sambuc pn = PU_CMAP(pu, opcookie);
86984d9c625SLionel Sambuc pn->pn_nlookup -= auxt->pvnr_nlookup;
87084d9c625SLionel Sambuc if (pn->pn_nlookup >= 1) {
87184d9c625SLionel Sambuc error = 0;
87284d9c625SLionel Sambuc break;
87384d9c625SLionel Sambuc }
87484d9c625SLionel Sambuc }
87584d9c625SLionel Sambuc
87684d9c625SLionel Sambuc error = pops->puffs_node_reclaim(pu, opcookie);
87784d9c625SLionel Sambuc break;
87884d9c625SLionel Sambuc }
87984d9c625SLionel Sambuc
88084d9c625SLionel Sambuc case PUFFS_VN_INACTIVE:
88184d9c625SLionel Sambuc {
88284d9c625SLionel Sambuc
88384d9c625SLionel Sambuc if (pops->puffs_node_inactive == NULL) {
88484d9c625SLionel Sambuc error = EOPNOTSUPP;
88584d9c625SLionel Sambuc break;
88684d9c625SLionel Sambuc }
88784d9c625SLionel Sambuc
88884d9c625SLionel Sambuc error = pops->puffs_node_inactive(pu, opcookie);
88984d9c625SLionel Sambuc break;
89084d9c625SLionel Sambuc }
89184d9c625SLionel Sambuc
89284d9c625SLionel Sambuc case PUFFS_VN_PATHCONF:
89384d9c625SLionel Sambuc {
89484d9c625SLionel Sambuc struct puffs_vnmsg_pathconf *auxt = auxbuf;
89584d9c625SLionel Sambuc if (pops->puffs_node_pathconf == NULL) {
89684d9c625SLionel Sambuc error = 0;
89784d9c625SLionel Sambuc break;
89884d9c625SLionel Sambuc }
89984d9c625SLionel Sambuc
90084d9c625SLionel Sambuc error = pops->puffs_node_pathconf(pu,
90184d9c625SLionel Sambuc opcookie, auxt->pvnr_name,
90284d9c625SLionel Sambuc &auxt->pvnr_retval);
90384d9c625SLionel Sambuc break;
90484d9c625SLionel Sambuc }
90584d9c625SLionel Sambuc
90684d9c625SLionel Sambuc case PUFFS_VN_ADVLOCK:
90784d9c625SLionel Sambuc {
90884d9c625SLionel Sambuc struct puffs_vnmsg_advlock *auxt = auxbuf;
90984d9c625SLionel Sambuc if (pops->puffs_node_advlock == NULL) {
91084d9c625SLionel Sambuc error = 0;
91184d9c625SLionel Sambuc break;
91284d9c625SLionel Sambuc }
91384d9c625SLionel Sambuc
91484d9c625SLionel Sambuc error = pops->puffs_node_advlock(pu,
91584d9c625SLionel Sambuc opcookie, auxt->pvnr_id, auxt->pvnr_op,
91684d9c625SLionel Sambuc &auxt->pvnr_fl, auxt->pvnr_flags);
91784d9c625SLionel Sambuc break;
91884d9c625SLionel Sambuc }
91984d9c625SLionel Sambuc
92084d9c625SLionel Sambuc case PUFFS_VN_PRINT:
92184d9c625SLionel Sambuc {
92284d9c625SLionel Sambuc if (pops->puffs_node_print == NULL) {
92384d9c625SLionel Sambuc error = 0;
92484d9c625SLionel Sambuc break;
92584d9c625SLionel Sambuc }
92684d9c625SLionel Sambuc
92784d9c625SLionel Sambuc error = pops->puffs_node_print(pu,
92884d9c625SLionel Sambuc opcookie);
92984d9c625SLionel Sambuc break;
93084d9c625SLionel Sambuc }
93184d9c625SLionel Sambuc
93284d9c625SLionel Sambuc case PUFFS_VN_ABORTOP:
93384d9c625SLionel Sambuc {
93484d9c625SLionel Sambuc struct puffs_vnmsg_abortop *auxt = auxbuf;
93584d9c625SLionel Sambuc struct puffs_cn pcn;
93684d9c625SLionel Sambuc
93784d9c625SLionel Sambuc if (pops->puffs_node_abortop == NULL) {
93884d9c625SLionel Sambuc error = 0;
93984d9c625SLionel Sambuc break;
94084d9c625SLionel Sambuc }
94184d9c625SLionel Sambuc
94284d9c625SLionel Sambuc pcn.pcn_pkcnp = &auxt->pvnr_cn;
94384d9c625SLionel Sambuc PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
94484d9c625SLionel Sambuc
94584d9c625SLionel Sambuc error = pops->puffs_node_abortop(pu, opcookie, &pcn);
94684d9c625SLionel Sambuc
94784d9c625SLionel Sambuc break;
94884d9c625SLionel Sambuc }
94984d9c625SLionel Sambuc
95084d9c625SLionel Sambuc case PUFFS_VN_READ:
95184d9c625SLionel Sambuc {
95284d9c625SLionel Sambuc struct puffs_vnmsg_read *auxt = auxbuf;
95384d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
95484d9c625SLionel Sambuc size_t res;
95584d9c625SLionel Sambuc
95684d9c625SLionel Sambuc if (pops->puffs_node_read == NULL) {
95784d9c625SLionel Sambuc error = EIO;
95884d9c625SLionel Sambuc break;
95984d9c625SLionel Sambuc }
96084d9c625SLionel Sambuc
96184d9c625SLionel Sambuc res = auxt->pvnr_resid;
96284d9c625SLionel Sambuc error = pops->puffs_node_read(pu,
96384d9c625SLionel Sambuc opcookie, auxt->pvnr_data,
96484d9c625SLionel Sambuc auxt->pvnr_offset, &auxt->pvnr_resid,
96584d9c625SLionel Sambuc pcr, auxt->pvnr_ioflag);
96684d9c625SLionel Sambuc
96784d9c625SLionel Sambuc /* need to move a bit more */
96884d9c625SLionel Sambuc preq->preq_buflen = sizeof(struct puffs_vnmsg_read)
96984d9c625SLionel Sambuc + (res - auxt->pvnr_resid);
97084d9c625SLionel Sambuc break;
97184d9c625SLionel Sambuc }
97284d9c625SLionel Sambuc
97384d9c625SLionel Sambuc case PUFFS_VN_WRITE:
97484d9c625SLionel Sambuc {
97584d9c625SLionel Sambuc struct puffs_vnmsg_write *auxt = auxbuf;
97684d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
97784d9c625SLionel Sambuc
97884d9c625SLionel Sambuc if (pops->puffs_node_write2 != NULL) {
97984d9c625SLionel Sambuc int xflag = 0;
98084d9c625SLionel Sambuc
98184d9c625SLionel Sambuc if (!PUFFSOP_WANTREPLY(preq->preq_opclass))
98284d9c625SLionel Sambuc xflag |= PUFFS_SETATTR_FAF;
98384d9c625SLionel Sambuc
98484d9c625SLionel Sambuc error = pops->puffs_node_write2(pu,
98584d9c625SLionel Sambuc opcookie, auxt->pvnr_data,
98684d9c625SLionel Sambuc auxt->pvnr_offset, &auxt->pvnr_resid,
98784d9c625SLionel Sambuc pcr, auxt->pvnr_ioflag, xflag);
98884d9c625SLionel Sambuc
98984d9c625SLionel Sambuc } else if (pops->puffs_node_write != NULL) {
99084d9c625SLionel Sambuc error = pops->puffs_node_write(pu,
99184d9c625SLionel Sambuc opcookie, auxt->pvnr_data,
99284d9c625SLionel Sambuc auxt->pvnr_offset, &auxt->pvnr_resid,
99384d9c625SLionel Sambuc pcr, auxt->pvnr_ioflag);
99484d9c625SLionel Sambuc } else {
99584d9c625SLionel Sambuc error = EIO;
99684d9c625SLionel Sambuc break;
99784d9c625SLionel Sambuc }
99884d9c625SLionel Sambuc
99984d9c625SLionel Sambuc
100084d9c625SLionel Sambuc /* don't need to move data back to the kernel */
100184d9c625SLionel Sambuc preq->preq_buflen = sizeof(struct puffs_vnmsg_write);
100284d9c625SLionel Sambuc break;
100384d9c625SLionel Sambuc }
100484d9c625SLionel Sambuc
100584d9c625SLionel Sambuc case PUFFS_VN_POLL:
100684d9c625SLionel Sambuc {
100784d9c625SLionel Sambuc struct puffs_vnmsg_poll *auxt = auxbuf;
100884d9c625SLionel Sambuc
100984d9c625SLionel Sambuc if (pops->puffs_node_poll == NULL) {
101084d9c625SLionel Sambuc error = 0;
101184d9c625SLionel Sambuc
101284d9c625SLionel Sambuc /* emulate genfs_poll() */
101384d9c625SLionel Sambuc auxt->pvnr_events &= (POLLIN | POLLOUT
101484d9c625SLionel Sambuc | POLLRDNORM | POLLWRNORM);
101584d9c625SLionel Sambuc
101684d9c625SLionel Sambuc break;
101784d9c625SLionel Sambuc }
101884d9c625SLionel Sambuc
101984d9c625SLionel Sambuc error = pops->puffs_node_poll(pu,
102084d9c625SLionel Sambuc opcookie, &auxt->pvnr_events);
102184d9c625SLionel Sambuc break;
102284d9c625SLionel Sambuc }
102384d9c625SLionel Sambuc
102484d9c625SLionel Sambuc case PUFFS_VN_GETEXTATTR:
102584d9c625SLionel Sambuc {
102684d9c625SLionel Sambuc struct puffs_vnmsg_getextattr *auxt = auxbuf;
102784d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
102884d9c625SLionel Sambuc size_t res, *resp, *sizep;
102984d9c625SLionel Sambuc uint8_t *data;
103084d9c625SLionel Sambuc
103184d9c625SLionel Sambuc if (pops->puffs_node_getextattr == NULL) {
103284d9c625SLionel Sambuc error = EOPNOTSUPP;
103384d9c625SLionel Sambuc break;
103484d9c625SLionel Sambuc }
103584d9c625SLionel Sambuc
103684d9c625SLionel Sambuc if (auxt->pvnr_datasize)
103784d9c625SLionel Sambuc sizep = &auxt->pvnr_datasize;
103884d9c625SLionel Sambuc else
103984d9c625SLionel Sambuc sizep = NULL;
104084d9c625SLionel Sambuc
104184d9c625SLionel Sambuc res = auxt->pvnr_resid;
104284d9c625SLionel Sambuc if (res > 0) {
104384d9c625SLionel Sambuc data = auxt->pvnr_data;
104484d9c625SLionel Sambuc resp = &auxt->pvnr_resid;
104584d9c625SLionel Sambuc } else {
104684d9c625SLionel Sambuc data = NULL;
104784d9c625SLionel Sambuc resp = NULL;
104884d9c625SLionel Sambuc }
104984d9c625SLionel Sambuc
105084d9c625SLionel Sambuc error = pops->puffs_node_getextattr(pu,
105184d9c625SLionel Sambuc opcookie, auxt->pvnr_attrnamespace,
105284d9c625SLionel Sambuc auxt->pvnr_attrname, sizep, data, resp, pcr);
105384d9c625SLionel Sambuc
105484d9c625SLionel Sambuc /* need to move a bit more? */
105584d9c625SLionel Sambuc preq->preq_buflen =
105684d9c625SLionel Sambuc sizeof(struct puffs_vnmsg_getextattr)
105784d9c625SLionel Sambuc + (res - auxt->pvnr_resid);
105884d9c625SLionel Sambuc break;
105984d9c625SLionel Sambuc }
106084d9c625SLionel Sambuc
106184d9c625SLionel Sambuc case PUFFS_VN_SETEXTATTR:
106284d9c625SLionel Sambuc {
106384d9c625SLionel Sambuc struct puffs_vnmsg_setextattr *auxt = auxbuf;
106484d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
106584d9c625SLionel Sambuc size_t *resp;
106684d9c625SLionel Sambuc uint8_t *data;
106784d9c625SLionel Sambuc
106884d9c625SLionel Sambuc if (pops->puffs_node_setextattr == NULL) {
106984d9c625SLionel Sambuc error = EOPNOTSUPP;
107084d9c625SLionel Sambuc break;
107184d9c625SLionel Sambuc }
107284d9c625SLionel Sambuc
107384d9c625SLionel Sambuc if (auxt->pvnr_resid > 0) {
107484d9c625SLionel Sambuc data = auxt->pvnr_data;
107584d9c625SLionel Sambuc resp = &auxt->pvnr_resid;
107684d9c625SLionel Sambuc } else {
107784d9c625SLionel Sambuc data = NULL;
107884d9c625SLionel Sambuc resp = NULL;
107984d9c625SLionel Sambuc }
108084d9c625SLionel Sambuc
108184d9c625SLionel Sambuc error = pops->puffs_node_setextattr(pu,
108284d9c625SLionel Sambuc opcookie, auxt->pvnr_attrnamespace,
108384d9c625SLionel Sambuc auxt->pvnr_attrname, data, resp, pcr);
108484d9c625SLionel Sambuc break;
108584d9c625SLionel Sambuc }
108684d9c625SLionel Sambuc
108784d9c625SLionel Sambuc case PUFFS_VN_LISTEXTATTR:
108884d9c625SLionel Sambuc {
108984d9c625SLionel Sambuc struct puffs_vnmsg_listextattr *auxt = auxbuf;
109084d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
109184d9c625SLionel Sambuc size_t res, *resp, *sizep;
109284d9c625SLionel Sambuc int flag;
109384d9c625SLionel Sambuc uint8_t *data;
109484d9c625SLionel Sambuc
109584d9c625SLionel Sambuc if (pops->puffs_node_listextattr == NULL) {
109684d9c625SLionel Sambuc error = EOPNOTSUPP;
109784d9c625SLionel Sambuc break;
109884d9c625SLionel Sambuc }
109984d9c625SLionel Sambuc
110084d9c625SLionel Sambuc if (auxt->pvnr_datasize)
110184d9c625SLionel Sambuc sizep = &auxt->pvnr_datasize;
110284d9c625SLionel Sambuc else
110384d9c625SLionel Sambuc sizep = NULL;
110484d9c625SLionel Sambuc
110584d9c625SLionel Sambuc res = auxt->pvnr_resid;
110684d9c625SLionel Sambuc if (res > 0) {
110784d9c625SLionel Sambuc data = auxt->pvnr_data;
110884d9c625SLionel Sambuc resp = &auxt->pvnr_resid;
110984d9c625SLionel Sambuc } else {
111084d9c625SLionel Sambuc data = NULL;
111184d9c625SLionel Sambuc resp = NULL;
111284d9c625SLionel Sambuc }
111384d9c625SLionel Sambuc
111484d9c625SLionel Sambuc res = auxt->pvnr_resid;
111584d9c625SLionel Sambuc flag = auxt->pvnr_flag;
111684d9c625SLionel Sambuc error = pops->puffs_node_listextattr(pu,
111784d9c625SLionel Sambuc opcookie, auxt->pvnr_attrnamespace,
111884d9c625SLionel Sambuc sizep, data, resp, flag, pcr);
111984d9c625SLionel Sambuc
112084d9c625SLionel Sambuc /* need to move a bit more? */
112184d9c625SLionel Sambuc preq->preq_buflen =
112284d9c625SLionel Sambuc sizeof(struct puffs_vnmsg_listextattr)
112384d9c625SLionel Sambuc + (res - auxt->pvnr_resid);
112484d9c625SLionel Sambuc break;
112584d9c625SLionel Sambuc }
112684d9c625SLionel Sambuc
112784d9c625SLionel Sambuc case PUFFS_VN_DELETEEXTATTR:
112884d9c625SLionel Sambuc {
112984d9c625SLionel Sambuc struct puffs_vnmsg_deleteextattr *auxt = auxbuf;
113084d9c625SLionel Sambuc PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
113184d9c625SLionel Sambuc
113284d9c625SLionel Sambuc if (pops->puffs_node_deleteextattr == NULL) {
113384d9c625SLionel Sambuc error = EOPNOTSUPP;
113484d9c625SLionel Sambuc break;
113584d9c625SLionel Sambuc }
113684d9c625SLionel Sambuc
113784d9c625SLionel Sambuc error = pops->puffs_node_deleteextattr(pu,
113884d9c625SLionel Sambuc opcookie, auxt->pvnr_attrnamespace,
113984d9c625SLionel Sambuc auxt->pvnr_attrname, pcr);
114084d9c625SLionel Sambuc break;
114184d9c625SLionel Sambuc }
114284d9c625SLionel Sambuc
1143*0a6a1f1dSLionel Sambuc case PUFFS_VN_FALLOCATE:
1144*0a6a1f1dSLionel Sambuc {
1145*0a6a1f1dSLionel Sambuc struct puffs_vnmsg_fallocate *auxt = auxbuf;
1146*0a6a1f1dSLionel Sambuc
1147*0a6a1f1dSLionel Sambuc if (pops->puffs_node_fallocate == NULL) {
1148*0a6a1f1dSLionel Sambuc error = EOPNOTSUPP;
1149*0a6a1f1dSLionel Sambuc break;
1150*0a6a1f1dSLionel Sambuc }
1151*0a6a1f1dSLionel Sambuc
1152*0a6a1f1dSLionel Sambuc error = pops->puffs_node_fallocate(pu,
1153*0a6a1f1dSLionel Sambuc opcookie, auxt->pvnr_off, auxt->pvnr_len);
1154*0a6a1f1dSLionel Sambuc break;
1155*0a6a1f1dSLionel Sambuc }
1156*0a6a1f1dSLionel Sambuc
1157*0a6a1f1dSLionel Sambuc case PUFFS_VN_FDISCARD:
1158*0a6a1f1dSLionel Sambuc {
1159*0a6a1f1dSLionel Sambuc struct puffs_vnmsg_fdiscard *auxt = auxbuf;
1160*0a6a1f1dSLionel Sambuc
1161*0a6a1f1dSLionel Sambuc if (pops->puffs_node_fdiscard == NULL) {
1162*0a6a1f1dSLionel Sambuc error = EOPNOTSUPP;
1163*0a6a1f1dSLionel Sambuc break;
1164*0a6a1f1dSLionel Sambuc }
1165*0a6a1f1dSLionel Sambuc
1166*0a6a1f1dSLionel Sambuc error = pops->puffs_node_fdiscard(pu,
1167*0a6a1f1dSLionel Sambuc opcookie, auxt->pvnr_off, auxt->pvnr_len);
1168*0a6a1f1dSLionel Sambuc break;
1169*0a6a1f1dSLionel Sambuc }
1170*0a6a1f1dSLionel Sambuc
117184d9c625SLionel Sambuc default:
117284d9c625SLionel Sambuc printf("inval op %d\n", preq->preq_optype);
117384d9c625SLionel Sambuc error = EINVAL;
117484d9c625SLionel Sambuc break;
117584d9c625SLionel Sambuc }
117684d9c625SLionel Sambuc
117784d9c625SLionel Sambuc #if 0
117884d9c625SLionel Sambuc /* not issued by kernel currently */
117984d9c625SLionel Sambuc } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) {
118084d9c625SLionel Sambuc struct puffs_cacheinfo *pci = (void *)preq;
118184d9c625SLionel Sambuc
118284d9c625SLionel Sambuc if (pu->pu_ops.puffs_cache_write) {
118384d9c625SLionel Sambuc pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie,
118484d9c625SLionel Sambuc pci->pcache_nruns, pci->pcache_runs);
118584d9c625SLionel Sambuc }
118684d9c625SLionel Sambuc error = 0;
118784d9c625SLionel Sambuc #endif
118884d9c625SLionel Sambuc
118984d9c625SLionel Sambuc } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) {
119084d9c625SLionel Sambuc struct puffs_error *perr = (void *)preq;
119184d9c625SLionel Sambuc
119284d9c625SLionel Sambuc pu->pu_errnotify(pu, preq->preq_optype,
119384d9c625SLionel Sambuc perr->perr_error, perr->perr_str, preq->preq_cookie);
119484d9c625SLionel Sambuc error = 0;
119584d9c625SLionel Sambuc } else {
119684d9c625SLionel Sambuc /*
119784d9c625SLionel Sambuc * I guess the kernel sees this one coming also
119884d9c625SLionel Sambuc */
119984d9c625SLionel Sambuc error = EINVAL;
120084d9c625SLionel Sambuc }
120184d9c625SLionel Sambuc
120284d9c625SLionel Sambuc out:
120384d9c625SLionel Sambuc preq->preq_rv = error;
120484d9c625SLionel Sambuc
120584d9c625SLionel Sambuc if (pu->pu_oppost)
120684d9c625SLionel Sambuc pu->pu_oppost(pu);
120784d9c625SLionel Sambuc
120884d9c625SLionel Sambuc pcc->pcc_flags |= PCC_DONE;
120984d9c625SLionel Sambuc }
1210