1 1.50 mlelstv /* $NetBSD: dispatcher.c,v 1.50 2023/12/11 12:42:18 mlelstv Exp $ */ 2 1.1 pooka 3 1.1 pooka /* 4 1.30 pooka * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. 5 1.1 pooka * 6 1.1 pooka * Development of this software was supported by the 7 1.30 pooka * Ulla Tuominen Foundation, the Finnish Cultural Foundation and 8 1.30 pooka * Research Foundation of Helsinki University of Technology. 9 1.1 pooka * 10 1.1 pooka * Redistribution and use in source and binary forms, with or without 11 1.1 pooka * modification, are permitted provided that the following conditions 12 1.1 pooka * are met: 13 1.1 pooka * 1. Redistributions of source code must retain the above copyright 14 1.1 pooka * notice, this list of conditions and the following disclaimer. 15 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 pooka * notice, this list of conditions and the following disclaimer in the 17 1.1 pooka * documentation and/or other materials provided with the distribution. 18 1.1 pooka * 19 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 20 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 pooka * SUCH DAMAGE. 30 1.1 pooka */ 31 1.1 pooka 32 1.1 pooka #include <sys/cdefs.h> 33 1.1 pooka #if !defined(lint) 34 1.50 mlelstv __RCSID("$NetBSD: dispatcher.c,v 1.50 2023/12/11 12:42:18 mlelstv Exp $"); 35 1.1 pooka #endif /* !lint */ 36 1.1 pooka 37 1.1 pooka #include <sys/types.h> 38 1.4 pooka #include <sys/poll.h> 39 1.1 pooka 40 1.1 pooka #include <assert.h> 41 1.1 pooka #include <errno.h> 42 1.17 pooka #include <pthread.h> 43 1.1 pooka #include <puffs.h> 44 1.1 pooka #include <puffsdump.h> 45 1.1 pooka #include <stdio.h> 46 1.1 pooka #include <stdlib.h> 47 1.1 pooka #include <unistd.h> 48 1.1 pooka 49 1.1 pooka #include "puffs_priv.h" 50 1.1 pooka 51 1.39 manu #define PUFFS_USE_FS_TTL(pu) (pu->pu_flags & PUFFS_KFLAG_CACHE_FS_TTL) 52 1.39 manu 53 1.30 pooka static void dispatch(struct puffs_cc *); 54 1.17 pooka 55 1.30 pooka /* for our eyes only */ 56 1.30 pooka void 57 1.30 pooka puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb) 58 1.30 pooka { 59 1.30 pooka struct puffs_cc *pcc = puffs_cc_getcc(pu); 60 1.30 pooka struct puffs_req *preq; 61 1.17 pooka 62 1.30 pooka pcc->pcc_pb = pb; 63 1.30 pooka pcc->pcc_flags |= PCC_MLCONT; 64 1.30 pooka dispatch(pcc); 65 1.17 pooka 66 1.30 pooka /* Put result to kernel sendqueue if necessary */ 67 1.30 pooka preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 68 1.30 pooka if (PUFFSOP_WANTREPLY(preq->preq_opclass)) { 69 1.30 pooka if (pu->pu_flags & PUFFS_FLAG_OPDUMP) 70 1.30 pooka puffsdump_rv(preq); 71 1.17 pooka 72 1.30 pooka puffs_framev_enqueue_justsend(pu, pu->pu_fd, 73 1.30 pooka pcc->pcc_pb, 0, 0); 74 1.30 pooka } else { 75 1.30 pooka puffs_framebuf_destroy(pcc->pcc_pb); 76 1.30 pooka } 77 1.17 pooka 78 1.30 pooka /* who needs information when you're living on borrowed time? */ 79 1.30 pooka if (pcc->pcc_flags & PCC_BORROWED) { 80 1.30 pooka puffs_cc_yield(pcc); /* back to borrow source */ 81 1.17 pooka } 82 1.30 pooka pcc->pcc_flags = 0; 83 1.17 pooka } 84 1.17 pooka 85 1.30 pooka /* public, but not really tested and only semi-supported */ 86 1.1 pooka int 87 1.30 pooka puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb, 88 1.30 pooka struct puffs_cc **pccp) 89 1.1 pooka { 90 1.30 pooka struct puffs_cc *pcc; 91 1.1 pooka 92 1.30 pooka if (puffs__cc_create(pu, dispatch, &pcc) == -1) 93 1.30 pooka return -1; 94 1.1 pooka 95 1.30 pooka pcc->pcc_pb = pb; 96 1.30 pooka *pccp = pcc; 97 1.1 pooka 98 1.30 pooka return 0; 99 1.1 pooka } 100 1.1 pooka 101 1.30 pooka int 102 1.30 pooka puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp) 103 1.1 pooka { 104 1.30 pooka int rv; 105 1.1 pooka 106 1.30 pooka puffs_cc_continue(pcc); 107 1.25 pooka 108 1.30 pooka if (pcc->pcc_flags & PCC_DONE) { 109 1.30 pooka rv = 1; 110 1.30 pooka *pbp = pcc->pcc_pb; 111 1.30 pooka pcc->pcc_flags = 0; 112 1.30 pooka puffs__cc_destroy(pcc, 0); 113 1.30 pooka } else { 114 1.30 pooka rv = 0; 115 1.1 pooka } 116 1.25 pooka 117 1.30 pooka return rv; 118 1.1 pooka } 119 1.1 pooka 120 1.30 pooka static void 121 1.30 pooka dispatch(struct puffs_cc *pcc) 122 1.1 pooka { 123 1.1 pooka struct puffs_usermount *pu = pcc->pcc_pu; 124 1.1 pooka struct puffs_ops *pops = &pu->pu_ops; 125 1.25 pooka struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 126 1.31 pooka void *auxbuf; /* help with typecasting */ 127 1.32 pooka puffs_cookie_t opcookie; 128 1.44 manu int error = 0, buildpath, pncookie; 129 1.31 pooka 130 1.31 pooka /* XXX: smaller hammer, please */ 131 1.31 pooka if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS && 132 1.31 pooka preq->preq_optype == PUFFS_VFS_VPTOFH)) || 133 1.31 pooka (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN && 134 1.31 pooka (preq->preq_optype == PUFFS_VN_READDIR 135 1.31 pooka || preq->preq_optype == PUFFS_VN_READ))) { 136 1.31 pooka if (puffs_framebuf_reserve_space(pcc->pcc_pb, 137 1.31 pooka PUFFS_MSG_MAXSIZE) == -1) 138 1.31 pooka error = errno; 139 1.31 pooka preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 140 1.31 pooka } 141 1.31 pooka 142 1.31 pooka auxbuf = preq; 143 1.31 pooka opcookie = preq->preq_cookie; 144 1.1 pooka 145 1.30 pooka assert((pcc->pcc_flags & PCC_DONE) == 0); 146 1.1 pooka 147 1.1 pooka buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; 148 1.44 manu pncookie = pu->pu_flags & PUFFS_FLAG_PNCOOKIE; 149 1.44 manu assert(!buildpath || pncookie); 150 1.44 manu 151 1.1 pooka preq->preq_setbacks = 0; 152 1.1 pooka 153 1.30 pooka if (pu->pu_flags & PUFFS_FLAG_OPDUMP) 154 1.30 pooka puffsdump_req(preq); 155 1.30 pooka 156 1.30 pooka puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid); 157 1.30 pooka 158 1.30 pooka /* pre-operation */ 159 1.18 pooka if (pu->pu_oppre) 160 1.24 pooka pu->pu_oppre(pu); 161 1.18 pooka 162 1.31 pooka if (error) 163 1.31 pooka goto out; 164 1.31 pooka 165 1.30 pooka /* Execute actual operation */ 166 1.1 pooka if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) { 167 1.49 christos switch ((enum puffs_vfs)preq->preq_optype) { 168 1.1 pooka case PUFFS_VFS_UNMOUNT: 169 1.1 pooka { 170 1.15 pooka struct puffs_vfsmsg_unmount *auxt = auxbuf; 171 1.1 pooka 172 1.1 pooka PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING); 173 1.24 pooka error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags); 174 1.1 pooka if (!error) 175 1.1 pooka PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED); 176 1.1 pooka else 177 1.1 pooka PU_SETSTATE(pu, PUFFS_STATE_RUNNING); 178 1.1 pooka break; 179 1.1 pooka } 180 1.1 pooka 181 1.1 pooka case PUFFS_VFS_STATVFS: 182 1.1 pooka { 183 1.15 pooka struct puffs_vfsmsg_statvfs *auxt = auxbuf; 184 1.1 pooka 185 1.24 pooka error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb); 186 1.1 pooka break; 187 1.1 pooka } 188 1.1 pooka 189 1.1 pooka case PUFFS_VFS_SYNC: 190 1.1 pooka { 191 1.15 pooka struct puffs_vfsmsg_sync *auxt = auxbuf; 192 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred); 193 1.1 pooka 194 1.24 pooka error = pops->puffs_fs_sync(pu, 195 1.22 pooka auxt->pvfsr_waitfor, pcr); 196 1.1 pooka break; 197 1.1 pooka } 198 1.1 pooka 199 1.1 pooka case PUFFS_VFS_FHTOVP: 200 1.1 pooka { 201 1.15 pooka struct puffs_vfsmsg_fhtonode *auxt = auxbuf; 202 1.9 pooka struct puffs_newinfo pni; 203 1.9 pooka 204 1.9 pooka pni.pni_cookie = &auxt->pvfsr_fhcookie; 205 1.9 pooka pni.pni_vtype = &auxt->pvfsr_vtype; 206 1.9 pooka pni.pni_size = &auxt->pvfsr_size; 207 1.9 pooka pni.pni_rdev = &auxt->pvfsr_rdev; 208 1.40 manu pni.pni_va = NULL; 209 1.40 manu pni.pni_va_ttl = NULL; 210 1.40 manu pni.pni_cn_ttl = NULL; 211 1.1 pooka 212 1.24 pooka error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data, 213 1.9 pooka auxt->pvfsr_dsize, &pni); 214 1.1 pooka 215 1.1 pooka break; 216 1.1 pooka } 217 1.1 pooka 218 1.1 pooka case PUFFS_VFS_VPTOFH: 219 1.1 pooka { 220 1.15 pooka struct puffs_vfsmsg_nodetofh *auxt = auxbuf; 221 1.1 pooka 222 1.24 pooka error = pops->puffs_fs_nodetofh(pu, 223 1.1 pooka auxt->pvfsr_fhcookie, auxt->pvfsr_data, 224 1.1 pooka &auxt->pvfsr_dsize); 225 1.1 pooka 226 1.1 pooka break; 227 1.1 pooka } 228 1.1 pooka 229 1.34 pooka case PUFFS_VFS_EXTATTRCTL: 230 1.1 pooka { 231 1.34 pooka struct puffs_vfsmsg_extattrctl *auxt = auxbuf; 232 1.34 pooka const char *attrname; 233 1.34 pooka int flags; 234 1.1 pooka 235 1.34 pooka if (pops->puffs_fs_extattrctl == NULL) { 236 1.34 pooka error = EOPNOTSUPP; 237 1.1 pooka break; 238 1.34 pooka } 239 1.34 pooka 240 1.34 pooka if (auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASATTRNAME) 241 1.34 pooka attrname = auxt->pvfsr_attrname; 242 1.34 pooka else 243 1.34 pooka attrname = NULL; 244 1.1 pooka 245 1.34 pooka flags = auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASNODE; 246 1.34 pooka error = pops->puffs_fs_extattrctl(pu, auxt->pvfsr_cmd, 247 1.34 pooka opcookie, flags, 248 1.34 pooka auxt->pvfsr_attrnamespace, attrname); 249 1.1 pooka break; 250 1.1 pooka } 251 1.1 pooka 252 1.1 pooka default: 253 1.1 pooka /* 254 1.1 pooka * I guess the kernel sees this one coming 255 1.1 pooka */ 256 1.1 pooka error = EINVAL; 257 1.1 pooka break; 258 1.1 pooka } 259 1.1 pooka 260 1.1 pooka /* XXX: audit return values */ 261 1.1 pooka /* XXX: sync with kernel */ 262 1.1 pooka } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { 263 1.49 christos switch ((enum puffs_vn)preq->preq_optype) { 264 1.1 pooka case PUFFS_VN_LOOKUP: 265 1.1 pooka { 266 1.15 pooka struct puffs_vnmsg_lookup *auxt = auxbuf; 267 1.9 pooka struct puffs_newinfo pni; 268 1.1 pooka struct puffs_cn pcn; 269 1.39 manu struct puffs_node *pn = NULL; 270 1.1 pooka 271 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 272 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 273 1.9 pooka pni.pni_cookie = &auxt->pvnr_newnode; 274 1.9 pooka pni.pni_vtype = &auxt->pvnr_vtype; 275 1.9 pooka pni.pni_size = &auxt->pvnr_size; 276 1.9 pooka pni.pni_rdev = &auxt->pvnr_rdev; 277 1.40 manu pni.pni_va = &auxt->pvnr_va; 278 1.40 manu pni.pni_va_ttl = &auxt->pvnr_va_ttl; 279 1.40 manu pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 280 1.7 pooka 281 1.1 pooka if (buildpath) { 282 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 283 1.1 pooka if (error) 284 1.1 pooka break; 285 1.1 pooka } 286 1.1 pooka 287 1.1 pooka /* lookup *must* be present */ 288 1.24 pooka error = pops->puffs_node_lookup(pu, opcookie, 289 1.9 pooka &pni, &pcn); 290 1.1 pooka 291 1.1 pooka if (buildpath) { 292 1.1 pooka if (error) { 293 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 294 1.1 pooka } else { 295 1.1 pooka /* 296 1.1 pooka * did we get a new node or a 297 1.1 pooka * recycled node? 298 1.1 pooka */ 299 1.1 pooka pn = PU_CMAP(pu, auxt->pvnr_newnode); 300 1.1 pooka if (pn->pn_po.po_path == NULL) 301 1.1 pooka pn->pn_po = pcn.pcn_po_full; 302 1.1 pooka else 303 1.1 pooka pu->pu_pathfree(pu, 304 1.1 pooka &pcn.pcn_po_full); 305 1.1 pooka } 306 1.1 pooka } 307 1.42 manu 308 1.44 manu if (pncookie && !error) { 309 1.42 manu if (pn == NULL) 310 1.42 manu pn = PU_CMAP(pu, auxt->pvnr_newnode); 311 1.42 manu pn->pn_nlookup++; 312 1.42 manu } 313 1.1 pooka break; 314 1.1 pooka } 315 1.1 pooka 316 1.1 pooka case PUFFS_VN_CREATE: 317 1.1 pooka { 318 1.15 pooka struct puffs_vnmsg_create *auxt = auxbuf; 319 1.9 pooka struct puffs_newinfo pni; 320 1.1 pooka struct puffs_cn pcn; 321 1.43 manu struct puffs_node *pn = NULL; 322 1.9 pooka 323 1.1 pooka if (pops->puffs_node_create == NULL) { 324 1.1 pooka error = 0; 325 1.1 pooka break; 326 1.1 pooka } 327 1.1 pooka 328 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 329 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 330 1.7 pooka 331 1.9 pooka memset(&pni, 0, sizeof(pni)); 332 1.9 pooka pni.pni_cookie = &auxt->pvnr_newnode; 333 1.40 manu pni.pni_va = &auxt->pvnr_va; 334 1.40 manu pni.pni_va_ttl = &auxt->pvnr_va_ttl; 335 1.40 manu pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 336 1.9 pooka 337 1.1 pooka if (buildpath) { 338 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 339 1.1 pooka if (error) 340 1.1 pooka break; 341 1.1 pooka } 342 1.1 pooka 343 1.24 pooka error = pops->puffs_node_create(pu, 344 1.9 pooka opcookie, &pni, &pcn, &auxt->pvnr_va); 345 1.1 pooka 346 1.1 pooka if (buildpath) { 347 1.1 pooka if (error) { 348 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 349 1.1 pooka } else { 350 1.1 pooka pn = PU_CMAP(pu, auxt->pvnr_newnode); 351 1.1 pooka pn->pn_po = pcn.pcn_po_full; 352 1.1 pooka } 353 1.1 pooka } 354 1.1 pooka 355 1.44 manu if (pncookie && !error) { 356 1.43 manu if (pn == NULL) 357 1.43 manu pn = PU_CMAP(pu, auxt->pvnr_newnode); 358 1.43 manu pn->pn_nlookup++; 359 1.43 manu } 360 1.1 pooka break; 361 1.1 pooka } 362 1.1 pooka 363 1.1 pooka case PUFFS_VN_MKNOD: 364 1.1 pooka { 365 1.15 pooka struct puffs_vnmsg_mknod *auxt = auxbuf; 366 1.9 pooka struct puffs_newinfo pni; 367 1.1 pooka struct puffs_cn pcn; 368 1.43 manu struct puffs_node *pn = NULL; 369 1.9 pooka 370 1.1 pooka if (pops->puffs_node_mknod == NULL) { 371 1.1 pooka error = 0; 372 1.1 pooka break; 373 1.1 pooka } 374 1.1 pooka 375 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 376 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 377 1.7 pooka 378 1.9 pooka memset(&pni, 0, sizeof(pni)); 379 1.9 pooka pni.pni_cookie = &auxt->pvnr_newnode; 380 1.40 manu pni.pni_va = &auxt->pvnr_va; 381 1.40 manu pni.pni_va_ttl = &auxt->pvnr_va_ttl; 382 1.40 manu pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 383 1.9 pooka 384 1.1 pooka if (buildpath) { 385 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 386 1.1 pooka if (error) 387 1.1 pooka break; 388 1.1 pooka } 389 1.1 pooka 390 1.24 pooka error = pops->puffs_node_mknod(pu, 391 1.9 pooka opcookie, &pni, &pcn, &auxt->pvnr_va); 392 1.1 pooka 393 1.1 pooka if (buildpath) { 394 1.1 pooka if (error) { 395 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 396 1.1 pooka } else { 397 1.1 pooka pn = PU_CMAP(pu, auxt->pvnr_newnode); 398 1.1 pooka pn->pn_po = pcn.pcn_po_full; 399 1.1 pooka } 400 1.1 pooka } 401 1.1 pooka 402 1.44 manu if (pncookie && !error) { 403 1.43 manu if (pn == NULL) 404 1.43 manu pn = PU_CMAP(pu, auxt->pvnr_newnode); 405 1.43 manu pn->pn_nlookup++; 406 1.43 manu } 407 1.1 pooka break; 408 1.1 pooka } 409 1.1 pooka 410 1.1 pooka case PUFFS_VN_OPEN: 411 1.1 pooka { 412 1.15 pooka struct puffs_vnmsg_open *auxt = auxbuf; 413 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 414 1.7 pooka 415 1.47 manu if (pops->puffs_node_open2 != NULL) { 416 1.47 manu error = pops->puffs_node_open2(pu, 417 1.47 manu opcookie, auxt->pvnr_mode, pcr, 418 1.47 manu &auxt->pvnr_oflags); 419 1.47 manu 420 1.47 manu break; 421 1.47 manu } 422 1.47 manu 423 1.1 pooka if (pops->puffs_node_open == NULL) { 424 1.1 pooka error = 0; 425 1.1 pooka break; 426 1.1 pooka } 427 1.1 pooka 428 1.24 pooka error = pops->puffs_node_open(pu, 429 1.22 pooka opcookie, auxt->pvnr_mode, pcr); 430 1.1 pooka break; 431 1.1 pooka } 432 1.1 pooka 433 1.1 pooka case PUFFS_VN_CLOSE: 434 1.1 pooka { 435 1.15 pooka struct puffs_vnmsg_close *auxt = auxbuf; 436 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 437 1.7 pooka 438 1.1 pooka if (pops->puffs_node_close == NULL) { 439 1.1 pooka error = 0; 440 1.1 pooka break; 441 1.1 pooka } 442 1.1 pooka 443 1.24 pooka error = pops->puffs_node_close(pu, 444 1.22 pooka opcookie, auxt->pvnr_fflag, pcr); 445 1.1 pooka break; 446 1.1 pooka } 447 1.1 pooka 448 1.1 pooka case PUFFS_VN_ACCESS: 449 1.1 pooka { 450 1.15 pooka struct puffs_vnmsg_access *auxt = auxbuf; 451 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 452 1.7 pooka 453 1.1 pooka if (pops->puffs_node_access == NULL) { 454 1.1 pooka error = 0; 455 1.1 pooka break; 456 1.1 pooka } 457 1.1 pooka 458 1.24 pooka error = pops->puffs_node_access(pu, 459 1.22 pooka opcookie, auxt->pvnr_mode, pcr); 460 1.1 pooka break; 461 1.1 pooka } 462 1.1 pooka 463 1.1 pooka case PUFFS_VN_GETATTR: 464 1.1 pooka { 465 1.15 pooka struct puffs_vnmsg_getattr *auxt = auxbuf; 466 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 467 1.7 pooka 468 1.40 manu if (PUFFS_USE_FS_TTL(pu)) { 469 1.40 manu if (pops->puffs_node_getattr_ttl == NULL) { 470 1.40 manu error = EOPNOTSUPP; 471 1.40 manu break; 472 1.40 manu } 473 1.1 pooka 474 1.40 manu error = pops->puffs_node_getattr_ttl(pu, 475 1.40 manu opcookie, &auxt->pvnr_va, pcr, 476 1.40 manu &auxt->pvnr_va_ttl); 477 1.40 manu } else { 478 1.40 manu if (pops->puffs_node_getattr == NULL) { 479 1.40 manu error = EOPNOTSUPP; 480 1.40 manu break; 481 1.40 manu } 482 1.39 manu 483 1.40 manu error = pops->puffs_node_getattr(pu, 484 1.40 manu opcookie, &auxt->pvnr_va, pcr); 485 1.39 manu } 486 1.1 pooka break; 487 1.1 pooka } 488 1.1 pooka 489 1.1 pooka case PUFFS_VN_SETATTR: 490 1.1 pooka { 491 1.15 pooka struct puffs_vnmsg_setattr *auxt = auxbuf; 492 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 493 1.7 pooka 494 1.40 manu if (PUFFS_USE_FS_TTL(pu)) { 495 1.41 manu int xflag = 0; 496 1.41 manu 497 1.40 manu if (pops->puffs_node_setattr_ttl == NULL) { 498 1.40 manu error = EOPNOTSUPP; 499 1.40 manu break; 500 1.40 manu } 501 1.1 pooka 502 1.41 manu if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) 503 1.41 manu xflag |= PUFFS_SETATTR_FAF; 504 1.41 manu 505 1.40 manu error = pops->puffs_node_setattr_ttl(pu, 506 1.40 manu opcookie, &auxt->pvnr_va, pcr, 507 1.41 manu &auxt->pvnr_va_ttl, xflag); 508 1.40 manu } else { 509 1.40 manu if (pops->puffs_node_setattr == NULL) { 510 1.40 manu error = EOPNOTSUPP; 511 1.40 manu break; 512 1.40 manu } 513 1.39 manu 514 1.40 manu error = pops->puffs_node_setattr(pu, 515 1.40 manu opcookie, &auxt->pvnr_va, pcr); 516 1.40 manu } 517 1.1 pooka break; 518 1.1 pooka } 519 1.1 pooka 520 1.1 pooka case PUFFS_VN_MMAP: 521 1.1 pooka { 522 1.15 pooka struct puffs_vnmsg_mmap *auxt = auxbuf; 523 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 524 1.7 pooka 525 1.1 pooka if (pops->puffs_node_mmap == NULL) { 526 1.1 pooka error = 0; 527 1.1 pooka break; 528 1.1 pooka } 529 1.1 pooka 530 1.24 pooka error = pops->puffs_node_mmap(pu, 531 1.22 pooka opcookie, auxt->pvnr_prot, pcr); 532 1.1 pooka break; 533 1.1 pooka } 534 1.1 pooka 535 1.1 pooka case PUFFS_VN_FSYNC: 536 1.1 pooka { 537 1.15 pooka struct puffs_vnmsg_fsync *auxt = auxbuf; 538 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 539 1.7 pooka 540 1.1 pooka if (pops->puffs_node_fsync == NULL) { 541 1.1 pooka error = 0; 542 1.1 pooka break; 543 1.1 pooka } 544 1.1 pooka 545 1.24 pooka error = pops->puffs_node_fsync(pu, opcookie, pcr, 546 1.1 pooka auxt->pvnr_flags, auxt->pvnr_offlo, 547 1.22 pooka auxt->pvnr_offhi); 548 1.1 pooka break; 549 1.1 pooka } 550 1.1 pooka 551 1.1 pooka case PUFFS_VN_SEEK: 552 1.1 pooka { 553 1.15 pooka struct puffs_vnmsg_seek *auxt = auxbuf; 554 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 555 1.7 pooka 556 1.1 pooka if (pops->puffs_node_seek == NULL) { 557 1.1 pooka error = 0; 558 1.1 pooka break; 559 1.1 pooka } 560 1.1 pooka 561 1.24 pooka error = pops->puffs_node_seek(pu, 562 1.1 pooka opcookie, auxt->pvnr_oldoff, 563 1.7 pooka auxt->pvnr_newoff, pcr); 564 1.1 pooka break; 565 1.1 pooka } 566 1.1 pooka 567 1.1 pooka case PUFFS_VN_REMOVE: 568 1.1 pooka { 569 1.15 pooka struct puffs_vnmsg_remove *auxt = auxbuf; 570 1.1 pooka struct puffs_cn pcn; 571 1.1 pooka if (pops->puffs_node_remove == NULL) { 572 1.1 pooka error = 0; 573 1.1 pooka break; 574 1.1 pooka } 575 1.1 pooka 576 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 577 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 578 1.1 pooka 579 1.24 pooka error = pops->puffs_node_remove(pu, 580 1.1 pooka opcookie, auxt->pvnr_cookie_targ, &pcn); 581 1.1 pooka break; 582 1.1 pooka } 583 1.1 pooka 584 1.1 pooka case PUFFS_VN_LINK: 585 1.1 pooka { 586 1.15 pooka struct puffs_vnmsg_link *auxt = auxbuf; 587 1.1 pooka struct puffs_cn pcn; 588 1.1 pooka if (pops->puffs_node_link == NULL) { 589 1.1 pooka error = 0; 590 1.1 pooka break; 591 1.1 pooka } 592 1.1 pooka 593 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 594 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 595 1.7 pooka 596 1.1 pooka if (buildpath) { 597 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 598 1.1 pooka if (error) 599 1.1 pooka break; 600 1.1 pooka } 601 1.1 pooka 602 1.24 pooka error = pops->puffs_node_link(pu, 603 1.1 pooka opcookie, auxt->pvnr_cookie_targ, &pcn); 604 1.1 pooka if (buildpath) 605 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 606 1.1 pooka 607 1.1 pooka break; 608 1.1 pooka } 609 1.1 pooka 610 1.1 pooka case PUFFS_VN_RENAME: 611 1.1 pooka { 612 1.15 pooka struct puffs_vnmsg_rename *auxt = auxbuf; 613 1.1 pooka struct puffs_cn pcn_src, pcn_targ; 614 1.1 pooka struct puffs_node *pn_src; 615 1.1 pooka 616 1.1 pooka if (pops->puffs_node_rename == NULL) { 617 1.1 pooka error = 0; 618 1.1 pooka break; 619 1.1 pooka } 620 1.1 pooka 621 1.1 pooka pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src; 622 1.7 pooka PUFFS_KCREDTOCRED(pcn_src.pcn_cred, 623 1.7 pooka &auxt->pvnr_cn_src_cred); 624 1.8 pooka 625 1.1 pooka pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ; 626 1.7 pooka PUFFS_KCREDTOCRED(pcn_targ.pcn_cred, 627 1.7 pooka &auxt->pvnr_cn_targ_cred); 628 1.7 pooka 629 1.1 pooka if (buildpath) { 630 1.1 pooka pn_src = auxt->pvnr_cookie_src; 631 1.1 pooka pcn_src.pcn_po_full = pn_src->pn_po; 632 1.1 pooka 633 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn_targ, 634 1.1 pooka auxt->pvnr_cookie_targdir); 635 1.1 pooka if (error) 636 1.1 pooka break; 637 1.46 christos } 638 1.1 pooka 639 1.24 pooka error = pops->puffs_node_rename(pu, 640 1.1 pooka opcookie, auxt->pvnr_cookie_src, 641 1.1 pooka &pcn_src, auxt->pvnr_cookie_targdir, 642 1.1 pooka auxt->pvnr_cookie_targ, &pcn_targ); 643 1.1 pooka 644 1.1 pooka if (buildpath) { 645 1.1 pooka if (error) { 646 1.1 pooka pu->pu_pathfree(pu, 647 1.1 pooka &pcn_targ.pcn_po_full); 648 1.1 pooka } else { 649 1.1 pooka struct puffs_pathinfo pi; 650 1.1 pooka struct puffs_pathobj po_old; 651 1.1 pooka 652 1.1 pooka /* handle this node */ 653 1.1 pooka po_old = pn_src->pn_po; 654 1.1 pooka pn_src->pn_po = pcn_targ.pcn_po_full; 655 1.1 pooka 656 1.1 pooka if (pn_src->pn_va.va_type != VDIR) { 657 1.1 pooka pu->pu_pathfree(pu, &po_old); 658 1.1 pooka break; 659 1.1 pooka } 660 1.1 pooka 661 1.1 pooka /* handle all child nodes for DIRs */ 662 1.1 pooka pi.pi_old = &pcn_src.pcn_po_full; 663 1.1 pooka pi.pi_new = &pcn_targ.pcn_po_full; 664 1.1 pooka 665 1.19 pooka PU_LOCK(); 666 1.1 pooka if (puffs_pn_nodewalk(pu, 667 1.1 pooka puffs_path_prefixadj, &pi) != NULL) 668 1.1 pooka error = ENOMEM; 669 1.19 pooka PU_UNLOCK(); 670 1.1 pooka pu->pu_pathfree(pu, &po_old); 671 1.1 pooka } 672 1.1 pooka } 673 1.1 pooka break; 674 1.1 pooka } 675 1.1 pooka 676 1.1 pooka case PUFFS_VN_MKDIR: 677 1.1 pooka { 678 1.15 pooka struct puffs_vnmsg_mkdir *auxt = auxbuf; 679 1.9 pooka struct puffs_newinfo pni; 680 1.1 pooka struct puffs_cn pcn; 681 1.43 manu struct puffs_node *pn = NULL; 682 1.9 pooka 683 1.1 pooka if (pops->puffs_node_mkdir == NULL) { 684 1.1 pooka error = 0; 685 1.1 pooka break; 686 1.1 pooka } 687 1.1 pooka 688 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 689 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 690 1.7 pooka 691 1.9 pooka memset(&pni, 0, sizeof(pni)); 692 1.9 pooka pni.pni_cookie = &auxt->pvnr_newnode; 693 1.40 manu pni.pni_va = &auxt->pvnr_va; 694 1.40 manu pni.pni_va_ttl = &auxt->pvnr_va_ttl; 695 1.40 manu pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 696 1.9 pooka 697 1.1 pooka if (buildpath) { 698 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 699 1.1 pooka if (error) 700 1.1 pooka break; 701 1.1 pooka } 702 1.1 pooka 703 1.24 pooka error = pops->puffs_node_mkdir(pu, 704 1.9 pooka opcookie, &pni, &pcn, &auxt->pvnr_va); 705 1.1 pooka 706 1.1 pooka if (buildpath) { 707 1.1 pooka if (error) { 708 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 709 1.1 pooka } else { 710 1.1 pooka pn = PU_CMAP(pu, auxt->pvnr_newnode); 711 1.1 pooka pn->pn_po = pcn.pcn_po_full; 712 1.1 pooka } 713 1.1 pooka } 714 1.1 pooka 715 1.44 manu if (pncookie && !error) { 716 1.43 manu if (pn == NULL) 717 1.43 manu pn = PU_CMAP(pu, auxt->pvnr_newnode); 718 1.43 manu pn->pn_nlookup++; 719 1.43 manu } 720 1.1 pooka break; 721 1.1 pooka } 722 1.1 pooka 723 1.1 pooka case PUFFS_VN_RMDIR: 724 1.1 pooka { 725 1.15 pooka struct puffs_vnmsg_rmdir *auxt = auxbuf; 726 1.1 pooka struct puffs_cn pcn; 727 1.1 pooka if (pops->puffs_node_rmdir == NULL) { 728 1.1 pooka error = 0; 729 1.1 pooka break; 730 1.1 pooka } 731 1.1 pooka 732 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 733 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 734 1.1 pooka 735 1.24 pooka error = pops->puffs_node_rmdir(pu, 736 1.1 pooka opcookie, auxt->pvnr_cookie_targ, &pcn); 737 1.1 pooka break; 738 1.1 pooka } 739 1.1 pooka 740 1.1 pooka case PUFFS_VN_SYMLINK: 741 1.1 pooka { 742 1.15 pooka struct puffs_vnmsg_symlink *auxt = auxbuf; 743 1.9 pooka struct puffs_newinfo pni; 744 1.1 pooka struct puffs_cn pcn; 745 1.43 manu struct puffs_node *pn = NULL; 746 1.9 pooka 747 1.1 pooka if (pops->puffs_node_symlink == NULL) { 748 1.1 pooka error = 0; 749 1.1 pooka break; 750 1.1 pooka } 751 1.1 pooka 752 1.1 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 753 1.7 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 754 1.7 pooka 755 1.9 pooka memset(&pni, 0, sizeof(pni)); 756 1.9 pooka pni.pni_cookie = &auxt->pvnr_newnode; 757 1.40 manu pni.pni_va = &auxt->pvnr_va; 758 1.40 manu pni.pni_va_ttl = &auxt->pvnr_va_ttl; 759 1.40 manu pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 760 1.9 pooka 761 1.1 pooka if (buildpath) { 762 1.1 pooka error = puffs_path_pcnbuild(pu, &pcn, opcookie); 763 1.1 pooka if (error) 764 1.1 pooka break; 765 1.1 pooka } 766 1.1 pooka 767 1.24 pooka error = pops->puffs_node_symlink(pu, 768 1.9 pooka opcookie, &pni, &pcn, 769 1.9 pooka &auxt->pvnr_va, auxt->pvnr_link); 770 1.1 pooka 771 1.1 pooka if (buildpath) { 772 1.1 pooka if (error) { 773 1.1 pooka pu->pu_pathfree(pu, &pcn.pcn_po_full); 774 1.1 pooka } else { 775 1.1 pooka pn = PU_CMAP(pu, auxt->pvnr_newnode); 776 1.1 pooka pn->pn_po = pcn.pcn_po_full; 777 1.1 pooka } 778 1.1 pooka } 779 1.1 pooka 780 1.44 manu if (pncookie && !error) { 781 1.43 manu if (pn == NULL) 782 1.43 manu pn = PU_CMAP(pu, auxt->pvnr_newnode); 783 1.43 manu pn->pn_nlookup++; 784 1.43 manu } 785 1.1 pooka break; 786 1.1 pooka } 787 1.1 pooka 788 1.1 pooka case PUFFS_VN_READDIR: 789 1.1 pooka { 790 1.15 pooka struct puffs_vnmsg_readdir *auxt = auxbuf; 791 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 792 1.1 pooka struct dirent *dent; 793 1.1 pooka off_t *cookies; 794 1.1 pooka size_t res, origcookies; 795 1.1 pooka 796 1.1 pooka if (pops->puffs_node_readdir == NULL) { 797 1.1 pooka error = 0; 798 1.1 pooka break; 799 1.1 pooka } 800 1.1 pooka 801 1.1 pooka if (auxt->pvnr_ncookies) { 802 1.1 pooka /* LINTED: pvnr_data is __aligned() */ 803 1.1 pooka cookies = (off_t *)auxt->pvnr_data; 804 1.1 pooka origcookies = auxt->pvnr_ncookies; 805 1.1 pooka } else { 806 1.1 pooka cookies = NULL; 807 1.1 pooka origcookies = 0; 808 1.1 pooka } 809 1.1 pooka /* LINTED: dentoff is aligned in the kernel */ 810 1.1 pooka dent = (struct dirent *) 811 1.1 pooka (auxt->pvnr_data + auxt->pvnr_dentoff); 812 1.1 pooka 813 1.1 pooka res = auxt->pvnr_resid; 814 1.24 pooka error = pops->puffs_node_readdir(pu, 815 1.1 pooka opcookie, dent, &auxt->pvnr_offset, 816 1.7 pooka &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag, 817 1.7 pooka cookies, &auxt->pvnr_ncookies); 818 1.1 pooka 819 1.1 pooka /* much easier to track non-working NFS */ 820 1.1 pooka assert(auxt->pvnr_ncookies <= origcookies); 821 1.1 pooka 822 1.1 pooka /* need to move a bit more */ 823 1.15 pooka preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir) 824 1.1 pooka + auxt->pvnr_dentoff + (res - auxt->pvnr_resid); 825 1.1 pooka break; 826 1.1 pooka } 827 1.1 pooka 828 1.1 pooka case PUFFS_VN_READLINK: 829 1.1 pooka { 830 1.15 pooka struct puffs_vnmsg_readlink *auxt = auxbuf; 831 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 832 1.7 pooka 833 1.1 pooka if (pops->puffs_node_readlink == NULL) { 834 1.1 pooka error = EOPNOTSUPP; 835 1.1 pooka break; 836 1.1 pooka } 837 1.1 pooka 838 1.7 pooka /*LINTED*/ 839 1.24 pooka error = pops->puffs_node_readlink(pu, opcookie, pcr, 840 1.1 pooka auxt->pvnr_link, &auxt->pvnr_linklen); 841 1.1 pooka break; 842 1.1 pooka } 843 1.1 pooka 844 1.1 pooka case PUFFS_VN_RECLAIM: 845 1.1 pooka { 846 1.42 manu struct puffs_vnmsg_reclaim *auxt = auxbuf; 847 1.42 manu struct puffs_node *pn; 848 1.42 manu 849 1.44 manu if (pops->puffs_node_reclaim2 != NULL) { 850 1.44 manu error = pops->puffs_node_reclaim2(pu, opcookie, 851 1.44 manu auxt->pvnr_nlookup); 852 1.44 manu break; 853 1.44 manu } 854 1.44 manu 855 1.42 manu if (pops->puffs_node_reclaim == NULL) { 856 1.42 manu error = 0; 857 1.42 manu break; 858 1.42 manu } 859 1.8 pooka 860 1.42 manu /* 861 1.42 manu * This fixes a race condition, 862 1.42 manu * where a node in reclaimed by kernel 863 1.42 manu * after a lookup request is sent, 864 1.42 manu * but before the reply, leaving the kernel 865 1.42 manu * with a invalid vnode/cookie reference. 866 1.42 manu */ 867 1.44 manu if (pncookie) { 868 1.44 manu pn = PU_CMAP(pu, opcookie); 869 1.44 manu pn->pn_nlookup -= auxt->pvnr_nlookup; 870 1.44 manu if (pn->pn_nlookup >= 1) { 871 1.44 manu error = 0; 872 1.44 manu break; 873 1.44 manu } 874 1.1 pooka } 875 1.1 pooka 876 1.24 pooka error = pops->puffs_node_reclaim(pu, opcookie); 877 1.1 pooka break; 878 1.1 pooka } 879 1.1 pooka 880 1.1 pooka case PUFFS_VN_INACTIVE: 881 1.1 pooka { 882 1.8 pooka 883 1.1 pooka if (pops->puffs_node_inactive == NULL) { 884 1.1 pooka error = EOPNOTSUPP; 885 1.1 pooka break; 886 1.1 pooka } 887 1.1 pooka 888 1.24 pooka error = pops->puffs_node_inactive(pu, opcookie); 889 1.1 pooka break; 890 1.1 pooka } 891 1.1 pooka 892 1.1 pooka case PUFFS_VN_PATHCONF: 893 1.1 pooka { 894 1.15 pooka struct puffs_vnmsg_pathconf *auxt = auxbuf; 895 1.1 pooka if (pops->puffs_node_pathconf == NULL) { 896 1.50 mlelstv error = EINVAL; 897 1.1 pooka break; 898 1.1 pooka } 899 1.1 pooka 900 1.24 pooka error = pops->puffs_node_pathconf(pu, 901 1.1 pooka opcookie, auxt->pvnr_name, 902 1.1 pooka &auxt->pvnr_retval); 903 1.1 pooka break; 904 1.1 pooka } 905 1.1 pooka 906 1.1 pooka case PUFFS_VN_ADVLOCK: 907 1.1 pooka { 908 1.15 pooka struct puffs_vnmsg_advlock *auxt = auxbuf; 909 1.1 pooka if (pops->puffs_node_advlock == NULL) { 910 1.1 pooka error = 0; 911 1.1 pooka break; 912 1.1 pooka } 913 1.1 pooka 914 1.24 pooka error = pops->puffs_node_advlock(pu, 915 1.1 pooka opcookie, auxt->pvnr_id, auxt->pvnr_op, 916 1.1 pooka &auxt->pvnr_fl, auxt->pvnr_flags); 917 1.1 pooka break; 918 1.1 pooka } 919 1.1 pooka 920 1.1 pooka case PUFFS_VN_PRINT: 921 1.1 pooka { 922 1.1 pooka if (pops->puffs_node_print == NULL) { 923 1.1 pooka error = 0; 924 1.1 pooka break; 925 1.1 pooka } 926 1.1 pooka 927 1.24 pooka error = pops->puffs_node_print(pu, 928 1.1 pooka opcookie); 929 1.1 pooka break; 930 1.1 pooka } 931 1.1 pooka 932 1.33 pooka case PUFFS_VN_ABORTOP: 933 1.33 pooka { 934 1.33 pooka struct puffs_vnmsg_abortop *auxt = auxbuf; 935 1.33 pooka struct puffs_cn pcn; 936 1.33 pooka 937 1.33 pooka if (pops->puffs_node_abortop == NULL) { 938 1.33 pooka error = 0; 939 1.33 pooka break; 940 1.33 pooka } 941 1.33 pooka 942 1.33 pooka pcn.pcn_pkcnp = &auxt->pvnr_cn; 943 1.33 pooka PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 944 1.33 pooka 945 1.33 pooka error = pops->puffs_node_abortop(pu, opcookie, &pcn); 946 1.33 pooka 947 1.33 pooka break; 948 1.33 pooka } 949 1.33 pooka 950 1.1 pooka case PUFFS_VN_READ: 951 1.1 pooka { 952 1.15 pooka struct puffs_vnmsg_read *auxt = auxbuf; 953 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 954 1.1 pooka size_t res; 955 1.1 pooka 956 1.1 pooka if (pops->puffs_node_read == NULL) { 957 1.1 pooka error = EIO; 958 1.1 pooka break; 959 1.1 pooka } 960 1.1 pooka 961 1.1 pooka res = auxt->pvnr_resid; 962 1.24 pooka error = pops->puffs_node_read(pu, 963 1.1 pooka opcookie, auxt->pvnr_data, 964 1.1 pooka auxt->pvnr_offset, &auxt->pvnr_resid, 965 1.7 pooka pcr, auxt->pvnr_ioflag); 966 1.1 pooka 967 1.1 pooka /* need to move a bit more */ 968 1.15 pooka preq->preq_buflen = sizeof(struct puffs_vnmsg_read) 969 1.1 pooka + (res - auxt->pvnr_resid); 970 1.1 pooka break; 971 1.1 pooka } 972 1.1 pooka 973 1.1 pooka case PUFFS_VN_WRITE: 974 1.1 pooka { 975 1.15 pooka struct puffs_vnmsg_write *auxt = auxbuf; 976 1.7 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 977 1.1 pooka 978 1.41 manu if (pops->puffs_node_write2 != NULL) { 979 1.41 manu int xflag = 0; 980 1.41 manu 981 1.41 manu if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) 982 1.41 manu xflag |= PUFFS_SETATTR_FAF; 983 1.41 manu 984 1.41 manu error = pops->puffs_node_write2(pu, 985 1.41 manu opcookie, auxt->pvnr_data, 986 1.41 manu auxt->pvnr_offset, &auxt->pvnr_resid, 987 1.41 manu pcr, auxt->pvnr_ioflag, xflag); 988 1.41 manu 989 1.41 manu } else if (pops->puffs_node_write != NULL) { 990 1.41 manu error = pops->puffs_node_write(pu, 991 1.41 manu opcookie, auxt->pvnr_data, 992 1.41 manu auxt->pvnr_offset, &auxt->pvnr_resid, 993 1.41 manu pcr, auxt->pvnr_ioflag); 994 1.41 manu } else { 995 1.1 pooka error = EIO; 996 1.1 pooka break; 997 1.1 pooka } 998 1.1 pooka 999 1.1 pooka 1000 1.1 pooka /* don't need to move data back to the kernel */ 1001 1.15 pooka preq->preq_buflen = sizeof(struct puffs_vnmsg_write); 1002 1.1 pooka break; 1003 1.1 pooka } 1004 1.1 pooka 1005 1.4 pooka case PUFFS_VN_POLL: 1006 1.4 pooka { 1007 1.15 pooka struct puffs_vnmsg_poll *auxt = auxbuf; 1008 1.8 pooka 1009 1.4 pooka if (pops->puffs_node_poll == NULL) { 1010 1.4 pooka error = 0; 1011 1.4 pooka 1012 1.4 pooka /* emulate genfs_poll() */ 1013 1.4 pooka auxt->pvnr_events &= (POLLIN | POLLOUT 1014 1.4 pooka | POLLRDNORM | POLLWRNORM); 1015 1.4 pooka 1016 1.4 pooka break; 1017 1.4 pooka } 1018 1.4 pooka 1019 1.24 pooka error = pops->puffs_node_poll(pu, 1020 1.22 pooka opcookie, &auxt->pvnr_events); 1021 1.4 pooka break; 1022 1.4 pooka } 1023 1.4 pooka 1024 1.34 pooka case PUFFS_VN_GETEXTATTR: 1025 1.34 pooka { 1026 1.34 pooka struct puffs_vnmsg_getextattr *auxt = auxbuf; 1027 1.34 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1028 1.34 pooka size_t res, *resp, *sizep; 1029 1.34 pooka uint8_t *data; 1030 1.34 pooka 1031 1.34 pooka if (pops->puffs_node_getextattr == NULL) { 1032 1.34 pooka error = EOPNOTSUPP; 1033 1.34 pooka break; 1034 1.34 pooka } 1035 1.34 pooka 1036 1.34 pooka if (auxt->pvnr_datasize) 1037 1.34 pooka sizep = &auxt->pvnr_datasize; 1038 1.34 pooka else 1039 1.34 pooka sizep = NULL; 1040 1.34 pooka 1041 1.34 pooka res = auxt->pvnr_resid; 1042 1.34 pooka if (res > 0) { 1043 1.34 pooka data = auxt->pvnr_data; 1044 1.34 pooka resp = &auxt->pvnr_resid; 1045 1.34 pooka } else { 1046 1.34 pooka data = NULL; 1047 1.34 pooka resp = NULL; 1048 1.34 pooka } 1049 1.34 pooka 1050 1.34 pooka error = pops->puffs_node_getextattr(pu, 1051 1.34 pooka opcookie, auxt->pvnr_attrnamespace, 1052 1.34 pooka auxt->pvnr_attrname, sizep, data, resp, pcr); 1053 1.34 pooka 1054 1.34 pooka /* need to move a bit more? */ 1055 1.34 pooka preq->preq_buflen = 1056 1.34 pooka sizeof(struct puffs_vnmsg_getextattr) 1057 1.34 pooka + (res - auxt->pvnr_resid); 1058 1.34 pooka break; 1059 1.34 pooka } 1060 1.34 pooka 1061 1.34 pooka case PUFFS_VN_SETEXTATTR: 1062 1.34 pooka { 1063 1.34 pooka struct puffs_vnmsg_setextattr *auxt = auxbuf; 1064 1.34 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1065 1.34 pooka size_t *resp; 1066 1.34 pooka uint8_t *data; 1067 1.34 pooka 1068 1.34 pooka if (pops->puffs_node_setextattr == NULL) { 1069 1.34 pooka error = EOPNOTSUPP; 1070 1.34 pooka break; 1071 1.34 pooka } 1072 1.34 pooka 1073 1.34 pooka if (auxt->pvnr_resid > 0) { 1074 1.34 pooka data = auxt->pvnr_data; 1075 1.34 pooka resp = &auxt->pvnr_resid; 1076 1.34 pooka } else { 1077 1.34 pooka data = NULL; 1078 1.34 pooka resp = NULL; 1079 1.34 pooka } 1080 1.34 pooka 1081 1.34 pooka error = pops->puffs_node_setextattr(pu, 1082 1.34 pooka opcookie, auxt->pvnr_attrnamespace, 1083 1.34 pooka auxt->pvnr_attrname, data, resp, pcr); 1084 1.34 pooka break; 1085 1.34 pooka } 1086 1.34 pooka 1087 1.34 pooka case PUFFS_VN_LISTEXTATTR: 1088 1.34 pooka { 1089 1.34 pooka struct puffs_vnmsg_listextattr *auxt = auxbuf; 1090 1.34 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1091 1.34 pooka size_t res, *resp, *sizep; 1092 1.36 manu int flag; 1093 1.34 pooka uint8_t *data; 1094 1.34 pooka 1095 1.34 pooka if (pops->puffs_node_listextattr == NULL) { 1096 1.34 pooka error = EOPNOTSUPP; 1097 1.34 pooka break; 1098 1.34 pooka } 1099 1.34 pooka 1100 1.34 pooka if (auxt->pvnr_datasize) 1101 1.34 pooka sizep = &auxt->pvnr_datasize; 1102 1.34 pooka else 1103 1.34 pooka sizep = NULL; 1104 1.34 pooka 1105 1.34 pooka res = auxt->pvnr_resid; 1106 1.34 pooka if (res > 0) { 1107 1.34 pooka data = auxt->pvnr_data; 1108 1.34 pooka resp = &auxt->pvnr_resid; 1109 1.34 pooka } else { 1110 1.34 pooka data = NULL; 1111 1.34 pooka resp = NULL; 1112 1.34 pooka } 1113 1.34 pooka 1114 1.34 pooka res = auxt->pvnr_resid; 1115 1.36 manu flag = auxt->pvnr_flag; 1116 1.34 pooka error = pops->puffs_node_listextattr(pu, 1117 1.34 pooka opcookie, auxt->pvnr_attrnamespace, 1118 1.36 manu sizep, data, resp, flag, pcr); 1119 1.34 pooka 1120 1.34 pooka /* need to move a bit more? */ 1121 1.34 pooka preq->preq_buflen = 1122 1.34 pooka sizeof(struct puffs_vnmsg_listextattr) 1123 1.34 pooka + (res - auxt->pvnr_resid); 1124 1.34 pooka break; 1125 1.34 pooka } 1126 1.34 pooka 1127 1.34 pooka case PUFFS_VN_DELETEEXTATTR: 1128 1.34 pooka { 1129 1.34 pooka struct puffs_vnmsg_deleteextattr *auxt = auxbuf; 1130 1.34 pooka PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1131 1.34 pooka 1132 1.34 pooka if (pops->puffs_node_deleteextattr == NULL) { 1133 1.34 pooka error = EOPNOTSUPP; 1134 1.34 pooka break; 1135 1.34 pooka } 1136 1.34 pooka 1137 1.34 pooka error = pops->puffs_node_deleteextattr(pu, 1138 1.34 pooka opcookie, auxt->pvnr_attrnamespace, 1139 1.34 pooka auxt->pvnr_attrname, pcr); 1140 1.34 pooka break; 1141 1.34 pooka } 1142 1.34 pooka 1143 1.48 manu case PUFFS_VN_FALLOCATE: 1144 1.48 manu { 1145 1.48 manu struct puffs_vnmsg_fallocate *auxt = auxbuf; 1146 1.48 manu 1147 1.48 manu if (pops->puffs_node_fallocate == NULL) { 1148 1.48 manu error = EOPNOTSUPP; 1149 1.48 manu break; 1150 1.48 manu } 1151 1.48 manu 1152 1.48 manu error = pops->puffs_node_fallocate(pu, 1153 1.48 manu opcookie, auxt->pvnr_off, auxt->pvnr_len); 1154 1.48 manu break; 1155 1.48 manu } 1156 1.48 manu 1157 1.48 manu case PUFFS_VN_FDISCARD: 1158 1.48 manu { 1159 1.48 manu struct puffs_vnmsg_fdiscard *auxt = auxbuf; 1160 1.48 manu 1161 1.48 manu if (pops->puffs_node_fdiscard == NULL) { 1162 1.48 manu error = EOPNOTSUPP; 1163 1.48 manu break; 1164 1.48 manu } 1165 1.48 manu 1166 1.48 manu error = pops->puffs_node_fdiscard(pu, 1167 1.48 manu opcookie, auxt->pvnr_off, auxt->pvnr_len); 1168 1.48 manu break; 1169 1.48 manu } 1170 1.48 manu 1171 1.1 pooka default: 1172 1.1 pooka printf("inval op %d\n", preq->preq_optype); 1173 1.1 pooka error = EINVAL; 1174 1.1 pooka break; 1175 1.1 pooka } 1176 1.30 pooka 1177 1.33 pooka #if 0 1178 1.33 pooka /* not issued by kernel currently */ 1179 1.30 pooka } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) { 1180 1.30 pooka struct puffs_cacheinfo *pci = (void *)preq; 1181 1.30 pooka 1182 1.30 pooka if (pu->pu_ops.puffs_cache_write) { 1183 1.30 pooka pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie, 1184 1.30 pooka pci->pcache_nruns, pci->pcache_runs); 1185 1.30 pooka } 1186 1.30 pooka error = 0; 1187 1.33 pooka #endif 1188 1.30 pooka 1189 1.30 pooka } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) { 1190 1.30 pooka struct puffs_error *perr = (void *)preq; 1191 1.30 pooka 1192 1.30 pooka pu->pu_errnotify(pu, preq->preq_optype, 1193 1.30 pooka perr->perr_error, perr->perr_str, preq->preq_cookie); 1194 1.30 pooka error = 0; 1195 1.1 pooka } else { 1196 1.1 pooka /* 1197 1.30 pooka * I guess the kernel sees this one coming also 1198 1.1 pooka */ 1199 1.1 pooka error = EINVAL; 1200 1.1 pooka } 1201 1.31 pooka 1202 1.31 pooka out: 1203 1.1 pooka preq->preq_rv = error; 1204 1.1 pooka 1205 1.18 pooka if (pu->pu_oppost) 1206 1.24 pooka pu->pu_oppost(pu); 1207 1.18 pooka 1208 1.30 pooka pcc->pcc_flags |= PCC_DONE; 1209 1.1 pooka } 1210