1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2007-2009 Google Inc. and Amit Singh 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following disclaimer 15 * in the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Google Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Copyright (C) 2005 Csaba Henk. 34 * All rights reserved. 35 * 36 * Copyright (c) 2019 The FreeBSD Foundation 37 * 38 * Portions of this software were developed by BFF Storage Systems, LLC under 39 * sponsorship from the FreeBSD Foundation. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 50 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 */ 62 63 #include <sys/cdefs.h> 64 __FBSDID("$FreeBSD$"); 65 66 #include <sys/param.h> 67 #include <sys/module.h> 68 #include <sys/systm.h> 69 #include <sys/errno.h> 70 #include <sys/kernel.h> 71 #include <sys/conf.h> 72 #include <sys/uio.h> 73 #include <sys/malloc.h> 74 #include <sys/queue.h> 75 #include <sys/limits.h> 76 #include <sys/lock.h> 77 #include <sys/rwlock.h> 78 #include <sys/sx.h> 79 #include <sys/proc.h> 80 #include <sys/mount.h> 81 #include <sys/vnode.h> 82 #include <sys/namei.h> 83 #include <sys/extattr.h> 84 #include <sys/stat.h> 85 #include <sys/unistd.h> 86 #include <sys/filedesc.h> 87 #include <sys/file.h> 88 #include <sys/fcntl.h> 89 #include <sys/dirent.h> 90 #include <sys/bio.h> 91 #include <sys/buf.h> 92 #include <sys/sysctl.h> 93 #include <sys/vmmeter.h> 94 95 #include <vm/vm.h> 96 #include <vm/vm_extern.h> 97 #include <vm/pmap.h> 98 #include <vm/vm_map.h> 99 #include <vm/vm_page.h> 100 #include <vm/vm_param.h> 101 #include <vm/vm_object.h> 102 #include <vm/vm_pager.h> 103 #include <vm/vnode_pager.h> 104 #include <vm/vm_object.h> 105 106 #include "fuse.h" 107 #include "fuse_file.h" 108 #include "fuse_internal.h" 109 #include "fuse_ipc.h" 110 #include "fuse_node.h" 111 #include "fuse_io.h" 112 113 #include <sys/priv.h> 114 115 /* Maximum number of hardlinks to a single FUSE file */ 116 #define FUSE_LINK_MAX UINT32_MAX 117 118 SDT_PROVIDER_DECLARE(fusefs); 119 /* 120 * Fuse trace probe: 121 * arg0: verbosity. Higher numbers give more verbose messages 122 * arg1: Textual message 123 */ 124 SDT_PROBE_DEFINE2(fusefs, , vnops, trace, "int", "char*"); 125 126 /* vnode ops */ 127 static vop_access_t fuse_vnop_access; 128 static vop_advlock_t fuse_vnop_advlock; 129 static vop_bmap_t fuse_vnop_bmap; 130 static vop_close_t fuse_fifo_close; 131 static vop_close_t fuse_vnop_close; 132 static vop_create_t fuse_vnop_create; 133 static vop_deleteextattr_t fuse_vnop_deleteextattr; 134 static vop_fdatasync_t fuse_vnop_fdatasync; 135 static vop_fsync_t fuse_vnop_fsync; 136 static vop_getattr_t fuse_vnop_getattr; 137 static vop_getextattr_t fuse_vnop_getextattr; 138 static vop_inactive_t fuse_vnop_inactive; 139 static vop_link_t fuse_vnop_link; 140 static vop_listextattr_t fuse_vnop_listextattr; 141 static vop_lookup_t fuse_vnop_lookup; 142 static vop_mkdir_t fuse_vnop_mkdir; 143 static vop_mknod_t fuse_vnop_mknod; 144 static vop_open_t fuse_vnop_open; 145 static vop_pathconf_t fuse_vnop_pathconf; 146 static vop_read_t fuse_vnop_read; 147 static vop_readdir_t fuse_vnop_readdir; 148 static vop_readlink_t fuse_vnop_readlink; 149 static vop_reclaim_t fuse_vnop_reclaim; 150 static vop_remove_t fuse_vnop_remove; 151 static vop_rename_t fuse_vnop_rename; 152 static vop_rmdir_t fuse_vnop_rmdir; 153 static vop_setattr_t fuse_vnop_setattr; 154 static vop_setextattr_t fuse_vnop_setextattr; 155 static vop_strategy_t fuse_vnop_strategy; 156 static vop_symlink_t fuse_vnop_symlink; 157 static vop_write_t fuse_vnop_write; 158 static vop_getpages_t fuse_vnop_getpages; 159 static vop_print_t fuse_vnop_print; 160 static vop_vptofh_t fuse_vnop_vptofh; 161 162 struct vop_vector fuse_fifoops = { 163 .vop_default = &fifo_specops, 164 .vop_access = fuse_vnop_access, 165 .vop_close = fuse_fifo_close, 166 .vop_fsync = fuse_vnop_fsync, 167 .vop_getattr = fuse_vnop_getattr, 168 .vop_inactive = fuse_vnop_inactive, 169 .vop_pathconf = fuse_vnop_pathconf, 170 .vop_print = fuse_vnop_print, 171 .vop_read = VOP_PANIC, 172 .vop_reclaim = fuse_vnop_reclaim, 173 .vop_setattr = fuse_vnop_setattr, 174 .vop_write = VOP_PANIC, 175 .vop_vptofh = fuse_vnop_vptofh, 176 }; 177 VFS_VOP_VECTOR_REGISTER(fuse_fifoops); 178 179 struct vop_vector fuse_vnops = { 180 .vop_allocate = VOP_EINVAL, 181 .vop_default = &default_vnodeops, 182 .vop_access = fuse_vnop_access, 183 .vop_advlock = fuse_vnop_advlock, 184 .vop_bmap = fuse_vnop_bmap, 185 .vop_close = fuse_vnop_close, 186 .vop_create = fuse_vnop_create, 187 .vop_deleteextattr = fuse_vnop_deleteextattr, 188 .vop_fsync = fuse_vnop_fsync, 189 .vop_fdatasync = fuse_vnop_fdatasync, 190 .vop_getattr = fuse_vnop_getattr, 191 .vop_getextattr = fuse_vnop_getextattr, 192 .vop_inactive = fuse_vnop_inactive, 193 /* 194 * TODO: implement vop_ioctl after upgrading to protocol 7.16. 195 * FUSE_IOCTL was added in 7.11, but 32-bit compat is broken until 196 * 7.16. 197 */ 198 .vop_link = fuse_vnop_link, 199 .vop_listextattr = fuse_vnop_listextattr, 200 .vop_lookup = fuse_vnop_lookup, 201 .vop_mkdir = fuse_vnop_mkdir, 202 .vop_mknod = fuse_vnop_mknod, 203 .vop_open = fuse_vnop_open, 204 .vop_pathconf = fuse_vnop_pathconf, 205 /* 206 * TODO: implement vop_poll after upgrading to protocol 7.21. 207 * FUSE_POLL was added in protocol 7.11, but it's kind of broken until 208 * 7.21, which adds the ability for the client to choose which poll 209 * events it wants, and for a client to deregister a file handle 210 */ 211 .vop_read = fuse_vnop_read, 212 .vop_readdir = fuse_vnop_readdir, 213 .vop_readlink = fuse_vnop_readlink, 214 .vop_reclaim = fuse_vnop_reclaim, 215 .vop_remove = fuse_vnop_remove, 216 .vop_rename = fuse_vnop_rename, 217 .vop_rmdir = fuse_vnop_rmdir, 218 .vop_setattr = fuse_vnop_setattr, 219 .vop_setextattr = fuse_vnop_setextattr, 220 .vop_strategy = fuse_vnop_strategy, 221 .vop_symlink = fuse_vnop_symlink, 222 .vop_write = fuse_vnop_write, 223 .vop_getpages = fuse_vnop_getpages, 224 .vop_print = fuse_vnop_print, 225 .vop_vptofh = fuse_vnop_vptofh, 226 }; 227 VFS_VOP_VECTOR_REGISTER(fuse_vnops); 228 229 uma_zone_t fuse_pbuf_zone; 230 231 /* Check permission for extattr operations, much like extattr_check_cred */ 232 static int 233 fuse_extattr_check_cred(struct vnode *vp, int ns, struct ucred *cred, 234 struct thread *td, accmode_t accmode) 235 { 236 struct mount *mp = vnode_mount(vp); 237 struct fuse_data *data = fuse_get_mpdata(mp); 238 239 /* 240 * Kernel-invoked always succeeds. 241 */ 242 if (cred == NOCRED) 243 return (0); 244 245 /* 246 * Do not allow privileged processes in jail to directly manipulate 247 * system attributes. 248 */ 249 switch (ns) { 250 case EXTATTR_NAMESPACE_SYSTEM: 251 if (data->dataflags & FSESS_DEFAULT_PERMISSIONS) { 252 return (priv_check_cred(cred, PRIV_VFS_EXTATTR_SYSTEM)); 253 } 254 /* FALLTHROUGH */ 255 case EXTATTR_NAMESPACE_USER: 256 return (fuse_internal_access(vp, accmode, td, cred)); 257 default: 258 return (EPERM); 259 } 260 } 261 262 /* Get a filehandle for a directory */ 263 static int 264 fuse_filehandle_get_dir(struct vnode *vp, struct fuse_filehandle **fufhp, 265 struct ucred *cred, pid_t pid) 266 { 267 if (fuse_filehandle_get(vp, FREAD, fufhp, cred, pid) == 0) 268 return 0; 269 return fuse_filehandle_get(vp, FEXEC, fufhp, cred, pid); 270 } 271 272 /* Send FUSE_FLUSH for this vnode */ 273 static int 274 fuse_flush(struct vnode *vp, struct ucred *cred, pid_t pid, int fflag) 275 { 276 struct fuse_flush_in *ffi; 277 struct fuse_filehandle *fufh; 278 struct fuse_dispatcher fdi; 279 struct thread *td = curthread; 280 struct mount *mp = vnode_mount(vp); 281 int err; 282 283 if (!fsess_isimpl(vnode_mount(vp), FUSE_FLUSH)) 284 return 0; 285 286 err = fuse_filehandle_getrw(vp, fflag, &fufh, cred, pid); 287 if (err) 288 return err; 289 290 fdisp_init(&fdi, sizeof(*ffi)); 291 fdisp_make_vp(&fdi, FUSE_FLUSH, vp, td, cred); 292 ffi = fdi.indata; 293 ffi->fh = fufh->fh_id; 294 /* 295 * If the file has a POSIX lock then we're supposed to set lock_owner. 296 * If not, then lock_owner is undefined. So we may as well always set 297 * it. 298 */ 299 ffi->lock_owner = td->td_proc->p_pid; 300 301 err = fdisp_wait_answ(&fdi); 302 if (err == ENOSYS) { 303 fsess_set_notimpl(mp, FUSE_FLUSH); 304 err = 0; 305 } 306 fdisp_destroy(&fdi); 307 return err; 308 } 309 310 /* Close wrapper for fifos. */ 311 static int 312 fuse_fifo_close(struct vop_close_args *ap) 313 { 314 return (fifo_specops.vop_close(ap)); 315 } 316 317 /* 318 struct vnop_access_args { 319 struct vnode *a_vp; 320 #if VOP_ACCESS_TAKES_ACCMODE_T 321 accmode_t a_accmode; 322 #else 323 int a_mode; 324 #endif 325 struct ucred *a_cred; 326 struct thread *a_td; 327 }; 328 */ 329 static int 330 fuse_vnop_access(struct vop_access_args *ap) 331 { 332 struct vnode *vp = ap->a_vp; 333 int accmode = ap->a_accmode; 334 struct ucred *cred = ap->a_cred; 335 336 struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp)); 337 338 int err; 339 340 if (fuse_isdeadfs(vp)) { 341 if (vnode_isvroot(vp)) { 342 return 0; 343 } 344 return ENXIO; 345 } 346 if (!(data->dataflags & FSESS_INITED)) { 347 if (vnode_isvroot(vp)) { 348 if (priv_check_cred(cred, PRIV_VFS_ADMIN) || 349 (fuse_match_cred(data->daemoncred, cred) == 0)) { 350 return 0; 351 } 352 } 353 return EBADF; 354 } 355 if (vnode_islnk(vp)) { 356 return 0; 357 } 358 359 err = fuse_internal_access(vp, accmode, ap->a_td, ap->a_cred); 360 return err; 361 } 362 363 /* 364 * struct vop_advlock_args { 365 * struct vop_generic_args a_gen; 366 * struct vnode *a_vp; 367 * void *a_id; 368 * int a_op; 369 * struct flock *a_fl; 370 * int a_flags; 371 * } 372 */ 373 static int 374 fuse_vnop_advlock(struct vop_advlock_args *ap) 375 { 376 struct vnode *vp = ap->a_vp; 377 struct flock *fl = ap->a_fl; 378 struct thread *td = curthread; 379 struct ucred *cred = td->td_ucred; 380 pid_t pid = td->td_proc->p_pid; 381 struct fuse_filehandle *fufh; 382 struct fuse_dispatcher fdi; 383 struct fuse_lk_in *fli; 384 struct fuse_lk_out *flo; 385 enum fuse_opcode op; 386 int dataflags, err; 387 int flags = ap->a_flags; 388 389 dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; 390 391 if (fuse_isdeadfs(vp)) { 392 return ENXIO; 393 } 394 395 if (!(dataflags & FSESS_POSIX_LOCKS)) 396 return vop_stdadvlock(ap); 397 /* FUSE doesn't properly support flock until protocol 7.17 */ 398 if (flags & F_FLOCK) 399 return vop_stdadvlock(ap); 400 401 err = fuse_filehandle_get_anyflags(vp, &fufh, cred, pid); 402 if (err) 403 return err; 404 405 fdisp_init(&fdi, sizeof(*fli)); 406 407 switch(ap->a_op) { 408 case F_GETLK: 409 op = FUSE_GETLK; 410 break; 411 case F_SETLK: 412 op = FUSE_SETLK; 413 break; 414 case F_SETLKW: 415 op = FUSE_SETLKW; 416 break; 417 default: 418 return EINVAL; 419 } 420 421 fdisp_make_vp(&fdi, op, vp, td, cred); 422 fli = fdi.indata; 423 fli->fh = fufh->fh_id; 424 fli->owner = fl->l_pid; 425 fli->lk.start = fl->l_start; 426 if (fl->l_len != 0) 427 fli->lk.end = fl->l_start + fl->l_len - 1; 428 else 429 fli->lk.end = INT64_MAX; 430 fli->lk.type = fl->l_type; 431 fli->lk.pid = fl->l_pid; 432 433 err = fdisp_wait_answ(&fdi); 434 fdisp_destroy(&fdi); 435 436 if (err == 0 && op == FUSE_GETLK) { 437 flo = fdi.answ; 438 fl->l_type = flo->lk.type; 439 fl->l_pid = flo->lk.pid; 440 if (flo->lk.type != F_UNLCK) { 441 fl->l_start = flo->lk.start; 442 if (flo->lk.end == INT64_MAX) 443 fl->l_len = 0; 444 else 445 fl->l_len = flo->lk.end - flo->lk.start + 1; 446 fl->l_start = flo->lk.start; 447 } 448 } 449 450 return err; 451 } 452 453 /* { 454 struct vnode *a_vp; 455 daddr_t a_bn; 456 struct bufobj **a_bop; 457 daddr_t *a_bnp; 458 int *a_runp; 459 int *a_runb; 460 } */ 461 static int 462 fuse_vnop_bmap(struct vop_bmap_args *ap) 463 { 464 struct vnode *vp = ap->a_vp; 465 struct bufobj **bo = ap->a_bop; 466 struct thread *td = curthread; 467 struct mount *mp; 468 struct fuse_dispatcher fdi; 469 struct fuse_bmap_in *fbi; 470 struct fuse_bmap_out *fbo; 471 struct fuse_data *data; 472 uint64_t biosize; 473 off_t filesize; 474 daddr_t lbn = ap->a_bn; 475 daddr_t *pbn = ap->a_bnp; 476 int *runp = ap->a_runp; 477 int *runb = ap->a_runb; 478 int error = 0; 479 int maxrun; 480 481 if (fuse_isdeadfs(vp)) { 482 return ENXIO; 483 } 484 485 mp = vnode_mount(vp); 486 data = fuse_get_mpdata(mp); 487 biosize = fuse_iosize(vp); 488 maxrun = MIN(vp->v_mount->mnt_iosize_max / biosize - 1, 489 data->max_readahead_blocks); 490 491 if (bo != NULL) 492 *bo = &vp->v_bufobj; 493 494 /* 495 * The FUSE_BMAP operation does not include the runp and runb 496 * variables, so we must guess. Report nonzero contiguous runs so 497 * cluster_read will combine adjacent reads. It's worthwhile to reduce 498 * upcalls even if we don't know the true physical layout of the file. 499 * 500 * FUSE file systems may opt out of read clustering in two ways: 501 * * mounting with -onoclusterr 502 * * Setting max_readahead <= maxbcachebuf during FUSE_INIT 503 */ 504 if (runb != NULL) 505 *runb = MIN(lbn, maxrun); 506 if (runp != NULL) { 507 error = fuse_vnode_size(vp, &filesize, td->td_ucred, td); 508 if (error == 0) 509 *runp = MIN(MAX(0, filesize / (off_t)biosize - lbn - 1), 510 maxrun); 511 else 512 *runp = 0; 513 } 514 515 if (fsess_isimpl(mp, FUSE_BMAP)) { 516 fdisp_init(&fdi, sizeof(*fbi)); 517 fdisp_make_vp(&fdi, FUSE_BMAP, vp, td, td->td_ucred); 518 fbi = fdi.indata; 519 fbi->block = lbn; 520 fbi->blocksize = biosize; 521 error = fdisp_wait_answ(&fdi); 522 if (error == ENOSYS) { 523 fdisp_destroy(&fdi); 524 fsess_set_notimpl(mp, FUSE_BMAP); 525 error = 0; 526 } else { 527 fbo = fdi.answ; 528 if (error == 0 && pbn != NULL) 529 *pbn = fbo->block; 530 fdisp_destroy(&fdi); 531 return error; 532 } 533 } 534 535 /* If the daemon doesn't support BMAP, make up a sensible default */ 536 if (pbn != NULL) 537 *pbn = lbn * btodb(biosize); 538 return (error); 539 } 540 541 /* 542 struct vop_close_args { 543 struct vnode *a_vp; 544 int a_fflag; 545 struct ucred *a_cred; 546 struct thread *a_td; 547 }; 548 */ 549 static int 550 fuse_vnop_close(struct vop_close_args *ap) 551 { 552 struct vnode *vp = ap->a_vp; 553 struct ucred *cred = ap->a_cred; 554 int fflag = ap->a_fflag; 555 struct thread *td = ap->a_td; 556 pid_t pid = td->td_proc->p_pid; 557 int err = 0; 558 559 if (fuse_isdeadfs(vp)) 560 return 0; 561 if (vnode_isdir(vp)) 562 return 0; 563 if (fflag & IO_NDELAY) 564 return 0; 565 566 err = fuse_flush(vp, cred, pid, fflag); 567 /* TODO: close the file handle, if we're sure it's no longer used */ 568 if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) { 569 fuse_vnode_savesize(vp, cred, td->td_proc->p_pid); 570 } 571 return err; 572 } 573 574 static void 575 fdisp_make_mknod_for_fallback( 576 struct fuse_dispatcher *fdip, 577 struct componentname *cnp, 578 struct vnode *dvp, 579 uint64_t parentnid, 580 struct thread *td, 581 struct ucred *cred, 582 mode_t mode, 583 enum fuse_opcode *op) 584 { 585 struct fuse_mknod_in *fmni; 586 587 fdisp_init(fdip, sizeof(*fmni) + cnp->cn_namelen + 1); 588 *op = FUSE_MKNOD; 589 fdisp_make(fdip, *op, vnode_mount(dvp), parentnid, td, cred); 590 fmni = fdip->indata; 591 fmni->mode = mode; 592 fmni->rdev = 0; 593 memcpy((char *)fdip->indata + sizeof(*fmni), cnp->cn_nameptr, 594 cnp->cn_namelen); 595 ((char *)fdip->indata)[sizeof(*fmni) + cnp->cn_namelen] = '\0'; 596 } 597 /* 598 struct vnop_create_args { 599 struct vnode *a_dvp; 600 struct vnode **a_vpp; 601 struct componentname *a_cnp; 602 struct vattr *a_vap; 603 }; 604 */ 605 static int 606 fuse_vnop_create(struct vop_create_args *ap) 607 { 608 struct vnode *dvp = ap->a_dvp; 609 struct vnode **vpp = ap->a_vpp; 610 struct componentname *cnp = ap->a_cnp; 611 struct vattr *vap = ap->a_vap; 612 struct thread *td = cnp->cn_thread; 613 struct ucred *cred = cnp->cn_cred; 614 615 struct fuse_data *data; 616 struct fuse_create_in *fci; 617 struct fuse_entry_out *feo; 618 struct fuse_open_out *foo; 619 struct fuse_dispatcher fdi, fdi2; 620 struct fuse_dispatcher *fdip = &fdi; 621 struct fuse_dispatcher *fdip2 = NULL; 622 623 int err; 624 625 struct mount *mp = vnode_mount(dvp); 626 data = fuse_get_mpdata(mp); 627 uint64_t parentnid = VTOFUD(dvp)->nid; 628 mode_t mode = MAKEIMODE(vap->va_type, vap->va_mode); 629 enum fuse_opcode op; 630 int flags; 631 632 if (fuse_isdeadfs(dvp)) 633 return ENXIO; 634 635 /* FUSE expects sockets to be created with FUSE_MKNOD */ 636 if (vap->va_type == VSOCK) 637 return fuse_internal_mknod(dvp, vpp, cnp, vap); 638 639 /* 640 * VOP_CREATE doesn't tell us the open(2) flags, so we guess. Only a 641 * writable mode makes sense, and we might as well include readability 642 * too. 643 */ 644 flags = O_RDWR; 645 646 bzero(&fdi, sizeof(fdi)); 647 648 if (vap->va_type != VREG) 649 return (EINVAL); 650 651 if (!fsess_isimpl(mp, FUSE_CREATE) || vap->va_type == VSOCK) { 652 /* Fallback to FUSE_MKNOD/FUSE_OPEN */ 653 fdisp_make_mknod_for_fallback(fdip, cnp, dvp, parentnid, td, 654 cred, mode, &op); 655 } else { 656 /* Use FUSE_CREATE */ 657 size_t insize; 658 659 op = FUSE_CREATE; 660 fdisp_init(fdip, sizeof(*fci) + cnp->cn_namelen + 1); 661 fdisp_make(fdip, op, vnode_mount(dvp), parentnid, td, cred); 662 fci = fdip->indata; 663 fci->mode = mode; 664 fci->flags = O_CREAT | flags; 665 if (fuse_libabi_geq(data, 7, 12)) { 666 insize = sizeof(*fci); 667 fci->umask = td->td_proc->p_fd->fd_cmask; 668 } else { 669 insize = sizeof(struct fuse_open_in); 670 } 671 672 memcpy((char *)fdip->indata + insize, cnp->cn_nameptr, 673 cnp->cn_namelen); 674 ((char *)fdip->indata)[insize + cnp->cn_namelen] = '\0'; 675 } 676 677 err = fdisp_wait_answ(fdip); 678 679 if (err) { 680 if (err == ENOSYS && op == FUSE_CREATE) { 681 fsess_set_notimpl(mp, FUSE_CREATE); 682 fdisp_destroy(fdip); 683 fdisp_make_mknod_for_fallback(fdip, cnp, dvp, 684 parentnid, td, cred, mode, &op); 685 err = fdisp_wait_answ(fdip); 686 } 687 if (err) 688 goto out; 689 } 690 691 feo = fdip->answ; 692 693 if ((err = fuse_internal_checkentry(feo, vap->va_type))) { 694 goto out; 695 } 696 697 if (op == FUSE_CREATE) { 698 foo = (struct fuse_open_out*)(feo + 1); 699 } else { 700 /* Issue a separate FUSE_OPEN */ 701 struct fuse_open_in *foi; 702 703 fdip2 = &fdi2; 704 fdisp_init(fdip2, sizeof(*foi)); 705 fdisp_make(fdip2, FUSE_OPEN, vnode_mount(dvp), feo->nodeid, td, 706 cred); 707 foi = fdip2->indata; 708 foi->flags = flags; 709 err = fdisp_wait_answ(fdip2); 710 if (err) 711 goto out; 712 foo = fdip2->answ; 713 } 714 err = fuse_vnode_get(mp, feo, feo->nodeid, dvp, vpp, cnp, vap->va_type); 715 if (err) { 716 struct fuse_release_in *fri; 717 uint64_t nodeid = feo->nodeid; 718 uint64_t fh_id = foo->fh; 719 720 fdisp_init(fdip, sizeof(*fri)); 721 fdisp_make(fdip, FUSE_RELEASE, mp, nodeid, td, cred); 722 fri = fdip->indata; 723 fri->fh = fh_id; 724 fri->flags = flags; 725 fuse_insert_callback(fdip->tick, fuse_internal_forget_callback); 726 fuse_insert_message(fdip->tick, false); 727 goto out; 728 } 729 ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create"); 730 fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, 731 feo->attr_valid_nsec, NULL); 732 733 fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, td, cred, foo); 734 fuse_vnode_open(*vpp, foo->open_flags, td); 735 /* 736 * Purge the parent's attribute cache because the daemon should've 737 * updated its mtime and ctime 738 */ 739 fuse_vnode_clear_attr_cache(dvp); 740 cache_purge_negative(dvp); 741 742 out: 743 if (fdip2) 744 fdisp_destroy(fdip2); 745 fdisp_destroy(fdip); 746 return err; 747 } 748 749 /* 750 struct vnop_fdatasync_args { 751 struct vop_generic_args a_gen; 752 struct vnode * a_vp; 753 struct thread * a_td; 754 }; 755 */ 756 static int 757 fuse_vnop_fdatasync(struct vop_fdatasync_args *ap) 758 { 759 struct vnode *vp = ap->a_vp; 760 struct thread *td = ap->a_td; 761 int waitfor = MNT_WAIT; 762 763 int err = 0; 764 765 if (fuse_isdeadfs(vp)) { 766 return 0; 767 } 768 if ((err = vop_stdfdatasync_buf(ap))) 769 return err; 770 771 return fuse_internal_fsync(vp, td, waitfor, true); 772 } 773 774 /* 775 struct vnop_fsync_args { 776 struct vop_generic_args a_gen; 777 struct vnode * a_vp; 778 int a_waitfor; 779 struct thread * a_td; 780 }; 781 */ 782 static int 783 fuse_vnop_fsync(struct vop_fsync_args *ap) 784 { 785 struct vnode *vp = ap->a_vp; 786 struct thread *td = ap->a_td; 787 int waitfor = ap->a_waitfor; 788 int err = 0; 789 790 if (fuse_isdeadfs(vp)) { 791 return 0; 792 } 793 if ((err = vop_stdfsync(ap))) 794 return err; 795 796 return fuse_internal_fsync(vp, td, waitfor, false); 797 } 798 799 /* 800 struct vnop_getattr_args { 801 struct vnode *a_vp; 802 struct vattr *a_vap; 803 struct ucred *a_cred; 804 struct thread *a_td; 805 }; 806 */ 807 static int 808 fuse_vnop_getattr(struct vop_getattr_args *ap) 809 { 810 struct vnode *vp = ap->a_vp; 811 struct vattr *vap = ap->a_vap; 812 struct ucred *cred = ap->a_cred; 813 struct thread *td = curthread; 814 815 int err = 0; 816 int dataflags; 817 818 dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; 819 820 /* Note that we are not bailing out on a dead file system just yet. */ 821 822 if (!(dataflags & FSESS_INITED)) { 823 if (!vnode_isvroot(vp)) { 824 fdata_set_dead(fuse_get_mpdata(vnode_mount(vp))); 825 err = ENOTCONN; 826 return err; 827 } else { 828 goto fake; 829 } 830 } 831 err = fuse_internal_getattr(vp, vap, cred, td); 832 if (err == ENOTCONN && vnode_isvroot(vp)) { 833 /* see comment in fuse_vfsop_statfs() */ 834 goto fake; 835 } else { 836 return err; 837 } 838 839 fake: 840 bzero(vap, sizeof(*vap)); 841 vap->va_type = vnode_vtype(vp); 842 843 return 0; 844 } 845 846 /* 847 struct vnop_inactive_args { 848 struct vnode *a_vp; 849 struct thread *a_td; 850 }; 851 */ 852 static int 853 fuse_vnop_inactive(struct vop_inactive_args *ap) 854 { 855 struct vnode *vp = ap->a_vp; 856 struct thread *td = ap->a_td; 857 858 struct fuse_vnode_data *fvdat = VTOFUD(vp); 859 struct fuse_filehandle *fufh, *fufh_tmp; 860 861 int need_flush = 1; 862 863 LIST_FOREACH_SAFE(fufh, &fvdat->handles, next, fufh_tmp) { 864 if (need_flush && vp->v_type == VREG) { 865 if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) { 866 fuse_vnode_savesize(vp, NULL, 0); 867 } 868 if ((fvdat->flag & FN_REVOKED) != 0) 869 fuse_io_invalbuf(vp, td); 870 else 871 fuse_io_flushbuf(vp, MNT_WAIT, td); 872 need_flush = 0; 873 } 874 fuse_filehandle_close(vp, fufh, td, NULL); 875 } 876 877 if ((fvdat->flag & FN_REVOKED) != 0) 878 vrecycle(vp); 879 880 return 0; 881 } 882 883 /* 884 struct vnop_link_args { 885 struct vnode *a_tdvp; 886 struct vnode *a_vp; 887 struct componentname *a_cnp; 888 }; 889 */ 890 static int 891 fuse_vnop_link(struct vop_link_args *ap) 892 { 893 struct vnode *vp = ap->a_vp; 894 struct vnode *tdvp = ap->a_tdvp; 895 struct componentname *cnp = ap->a_cnp; 896 897 struct vattr *vap = VTOVA(vp); 898 899 struct fuse_dispatcher fdi; 900 struct fuse_entry_out *feo; 901 struct fuse_link_in fli; 902 903 int err; 904 905 if (fuse_isdeadfs(vp)) { 906 return ENXIO; 907 } 908 if (vnode_mount(tdvp) != vnode_mount(vp)) { 909 return EXDEV; 910 } 911 912 /* 913 * This is a seatbelt check to protect naive userspace filesystems from 914 * themselves and the limitations of the FUSE IPC protocol. If a 915 * filesystem does not allow attribute caching, assume it is capable of 916 * validating that nlink does not overflow. 917 */ 918 if (vap != NULL && vap->va_nlink >= FUSE_LINK_MAX) 919 return EMLINK; 920 fli.oldnodeid = VTOI(vp); 921 922 fdisp_init(&fdi, 0); 923 fuse_internal_newentry_makerequest(vnode_mount(tdvp), VTOI(tdvp), cnp, 924 FUSE_LINK, &fli, sizeof(fli), &fdi); 925 if ((err = fdisp_wait_answ(&fdi))) { 926 goto out; 927 } 928 feo = fdi.answ; 929 930 err = fuse_internal_checkentry(feo, vnode_vtype(vp)); 931 if (!err) { 932 /* 933 * Purge the parent's attribute cache because the daemon 934 * should've updated its mtime and ctime 935 */ 936 fuse_vnode_clear_attr_cache(tdvp); 937 fuse_internal_cache_attrs(vp, &feo->attr, feo->attr_valid, 938 feo->attr_valid_nsec, NULL); 939 } 940 out: 941 fdisp_destroy(&fdi); 942 return err; 943 } 944 945 struct fuse_lookup_alloc_arg { 946 struct fuse_entry_out *feo; 947 struct componentname *cnp; 948 uint64_t nid; 949 enum vtype vtyp; 950 }; 951 952 /* Callback for vn_get_ino */ 953 static int 954 fuse_lookup_alloc(struct mount *mp, void *arg, int lkflags, struct vnode **vpp) 955 { 956 struct fuse_lookup_alloc_arg *flaa = arg; 957 958 return fuse_vnode_get(mp, flaa->feo, flaa->nid, NULL, vpp, flaa->cnp, 959 flaa->vtyp); 960 } 961 962 SDT_PROBE_DEFINE3(fusefs, , vnops, cache_lookup, 963 "int", "struct timespec*", "struct timespec*"); 964 SDT_PROBE_DEFINE2(fusefs, , vnops, lookup_cache_incoherent, 965 "struct vnode*", "struct fuse_entry_out*"); 966 /* 967 struct vnop_lookup_args { 968 struct vnodeop_desc *a_desc; 969 struct vnode *a_dvp; 970 struct vnode **a_vpp; 971 struct componentname *a_cnp; 972 }; 973 */ 974 int 975 fuse_vnop_lookup(struct vop_lookup_args *ap) 976 { 977 struct vnode *dvp = ap->a_dvp; 978 struct vnode **vpp = ap->a_vpp; 979 struct componentname *cnp = ap->a_cnp; 980 struct thread *td = cnp->cn_thread; 981 struct ucred *cred = cnp->cn_cred; 982 983 int nameiop = cnp->cn_nameiop; 984 int flags = cnp->cn_flags; 985 int wantparent = flags & (LOCKPARENT | WANTPARENT); 986 int islastcn = flags & ISLASTCN; 987 struct mount *mp = vnode_mount(dvp); 988 989 int err = 0; 990 int lookup_err = 0; 991 struct vnode *vp = NULL; 992 993 struct fuse_dispatcher fdi; 994 bool did_lookup = false; 995 struct fuse_entry_out *feo = NULL; 996 enum vtype vtyp; /* vnode type of target */ 997 off_t filesize; /* filesize of target */ 998 999 uint64_t nid; 1000 1001 if (fuse_isdeadfs(dvp)) { 1002 *vpp = NULL; 1003 return ENXIO; 1004 } 1005 if (!vnode_isdir(dvp)) 1006 return ENOTDIR; 1007 1008 if (islastcn && vfs_isrdonly(mp) && (nameiop != LOOKUP)) 1009 return EROFS; 1010 1011 if ((cnp->cn_flags & NOEXECCHECK) != 0) 1012 cnp->cn_flags &= ~NOEXECCHECK; 1013 else if ((err = fuse_internal_access(dvp, VEXEC, td, cred))) 1014 return err; 1015 1016 if (flags & ISDOTDOT) { 1017 KASSERT(VTOFUD(dvp)->flag & FN_PARENT_NID, 1018 ("Looking up .. is TODO")); 1019 nid = VTOFUD(dvp)->parent_nid; 1020 if (nid == 0) 1021 return ENOENT; 1022 /* .. is obviously a directory */ 1023 vtyp = VDIR; 1024 filesize = 0; 1025 } else if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') { 1026 nid = VTOI(dvp); 1027 /* . is obviously a directory */ 1028 vtyp = VDIR; 1029 filesize = 0; 1030 } else { 1031 struct timespec now, timeout; 1032 1033 err = cache_lookup(dvp, vpp, cnp, &timeout, NULL); 1034 getnanouptime(&now); 1035 SDT_PROBE3(fusefs, , vnops, cache_lookup, err, &timeout, &now); 1036 switch (err) { 1037 case -1: /* positive match */ 1038 if (timespeccmp(&timeout, &now, >)) { 1039 counter_u64_add(fuse_lookup_cache_hits, 1); 1040 } else { 1041 /* Cache timeout */ 1042 counter_u64_add(fuse_lookup_cache_misses, 1); 1043 bintime_clear( 1044 &VTOFUD(*vpp)->entry_cache_timeout); 1045 cache_purge(*vpp); 1046 if (dvp != *vpp) 1047 vput(*vpp); 1048 else 1049 vrele(*vpp); 1050 *vpp = NULL; 1051 break; 1052 } 1053 return 0; 1054 1055 case 0: /* no match in cache */ 1056 counter_u64_add(fuse_lookup_cache_misses, 1); 1057 break; 1058 1059 case ENOENT: /* negative match */ 1060 getnanouptime(&now); 1061 if (timespeccmp(&timeout, &now, <=)) { 1062 /* Cache timeout */ 1063 cache_purge_negative(dvp); 1064 break; 1065 } 1066 /* fall through */ 1067 default: 1068 return err; 1069 } 1070 1071 nid = VTOI(dvp); 1072 fdisp_init(&fdi, cnp->cn_namelen + 1); 1073 fdisp_make(&fdi, FUSE_LOOKUP, mp, nid, td, cred); 1074 1075 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 1076 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 1077 lookup_err = fdisp_wait_answ(&fdi); 1078 did_lookup = true; 1079 1080 if (!lookup_err) { 1081 /* lookup call succeeded */ 1082 feo = (struct fuse_entry_out *)fdi.answ; 1083 nid = feo->nodeid; 1084 if (nid == 0) { 1085 /* zero nodeid means ENOENT and cache it */ 1086 struct timespec timeout; 1087 1088 fdi.answ_stat = ENOENT; 1089 lookup_err = ENOENT; 1090 if (cnp->cn_flags & MAKEENTRY) { 1091 fuse_validity_2_timespec(feo, &timeout); 1092 cache_enter_time(dvp, *vpp, cnp, 1093 &timeout, NULL); 1094 } 1095 } else if (nid == FUSE_ROOT_ID) { 1096 lookup_err = EINVAL; 1097 } 1098 vtyp = IFTOVT(feo->attr.mode); 1099 filesize = feo->attr.size; 1100 } 1101 if (lookup_err && (!fdi.answ_stat || lookup_err != ENOENT)) { 1102 fdisp_destroy(&fdi); 1103 return lookup_err; 1104 } 1105 } 1106 /* lookup_err, if non-zero, must be ENOENT at this point */ 1107 1108 if (lookup_err) { 1109 /* Entry not found */ 1110 if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { 1111 err = fuse_internal_access(dvp, VWRITE, td, cred); 1112 if (!err) { 1113 /* 1114 * Set the SAVENAME flag to hold onto the 1115 * pathname for use later in VOP_CREATE or 1116 * VOP_RENAME. 1117 */ 1118 cnp->cn_flags |= SAVENAME; 1119 1120 err = EJUSTRETURN; 1121 } 1122 } else { 1123 err = ENOENT; 1124 } 1125 } else { 1126 /* Entry was found */ 1127 if (flags & ISDOTDOT) { 1128 struct fuse_lookup_alloc_arg flaa; 1129 1130 flaa.nid = nid; 1131 flaa.feo = feo; 1132 flaa.cnp = cnp; 1133 flaa.vtyp = vtyp; 1134 err = vn_vget_ino_gen(dvp, fuse_lookup_alloc, &flaa, 0, 1135 &vp); 1136 *vpp = vp; 1137 } else if (nid == VTOI(dvp)) { 1138 vref(dvp); 1139 *vpp = dvp; 1140 } else { 1141 struct fuse_vnode_data *fvdat; 1142 struct vattr *vap; 1143 1144 err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp, 1145 &vp, cnp, vtyp); 1146 if (err) 1147 goto out; 1148 *vpp = vp; 1149 1150 /* 1151 * In the case where we are looking up a FUSE node 1152 * represented by an existing cached vnode, and the 1153 * true size reported by FUSE_LOOKUP doesn't match 1154 * the vnode's cached size, then any cached writes 1155 * beyond the file's current size are lost. 1156 * 1157 * We can get here: 1158 * * following attribute cache expiration, or 1159 * * due a bug in the daemon, or 1160 */ 1161 fvdat = VTOFUD(vp); 1162 if (vnode_isreg(vp) && 1163 ((filesize != fvdat->cached_attrs.va_size && 1164 fvdat->flag & FN_SIZECHANGE) || 1165 ((vap = VTOVA(vp)) && 1166 filesize != vap->va_size))) 1167 { 1168 SDT_PROBE2(fusefs, , vnops, lookup_cache_incoherent, vp, feo); 1169 fvdat->flag &= ~FN_SIZECHANGE; 1170 /* 1171 * The server changed the file's size even 1172 * though we had it cached, or had dirty writes 1173 * in the WB cache! 1174 */ 1175 printf("%s: cache incoherent on %s! " 1176 "Buggy FUSE server detected. To prevent " 1177 "data corruption, disable the data cache " 1178 "by mounting with -o direct_io, or as " 1179 "directed otherwise by your FUSE server's " 1180 "documentation\n", __func__, 1181 vnode_mount(vp)->mnt_stat.f_mntonname); 1182 int iosize = fuse_iosize(vp); 1183 v_inval_buf_range(vp, 0, INT64_MAX, iosize); 1184 } 1185 1186 MPASS(feo != NULL); 1187 fuse_internal_cache_attrs(*vpp, &feo->attr, 1188 feo->attr_valid, feo->attr_valid_nsec, NULL); 1189 fuse_validity_2_bintime(feo->entry_valid, 1190 feo->entry_valid_nsec, 1191 &fvdat->entry_cache_timeout); 1192 1193 if ((nameiop == DELETE || nameiop == RENAME) && 1194 islastcn) 1195 { 1196 struct vattr dvattr; 1197 1198 err = fuse_internal_access(dvp, VWRITE, td, 1199 cred); 1200 if (err != 0) 1201 goto out; 1202 /* 1203 * if the parent's sticky bit is set, check 1204 * whether we're allowed to remove the file. 1205 * Need to figure out the vnode locking to make 1206 * this work. 1207 */ 1208 fuse_internal_getattr(dvp, &dvattr, cred, td); 1209 if ((dvattr.va_mode & S_ISTXT) && 1210 fuse_internal_access(dvp, VADMIN, td, 1211 cred) && 1212 fuse_internal_access(*vpp, VADMIN, td, 1213 cred)) { 1214 err = EPERM; 1215 goto out; 1216 } 1217 } 1218 1219 if (islastcn && ( 1220 (nameiop == DELETE) || 1221 (nameiop == RENAME && wantparent))) { 1222 cnp->cn_flags |= SAVENAME; 1223 } 1224 1225 } 1226 } 1227 out: 1228 if (err) { 1229 if (vp != NULL && dvp != vp) 1230 vput(vp); 1231 else if (vp != NULL) 1232 vrele(vp); 1233 *vpp = NULL; 1234 } 1235 if (did_lookup) 1236 fdisp_destroy(&fdi); 1237 1238 return err; 1239 } 1240 1241 /* 1242 struct vnop_mkdir_args { 1243 struct vnode *a_dvp; 1244 struct vnode **a_vpp; 1245 struct componentname *a_cnp; 1246 struct vattr *a_vap; 1247 }; 1248 */ 1249 static int 1250 fuse_vnop_mkdir(struct vop_mkdir_args *ap) 1251 { 1252 struct vnode *dvp = ap->a_dvp; 1253 struct vnode **vpp = ap->a_vpp; 1254 struct componentname *cnp = ap->a_cnp; 1255 struct vattr *vap = ap->a_vap; 1256 1257 struct fuse_mkdir_in fmdi; 1258 1259 if (fuse_isdeadfs(dvp)) { 1260 return ENXIO; 1261 } 1262 fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode); 1263 fmdi.umask = curthread->td_proc->p_fd->fd_cmask; 1264 1265 return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi, 1266 sizeof(fmdi), VDIR)); 1267 } 1268 1269 /* 1270 struct vnop_mknod_args { 1271 struct vnode *a_dvp; 1272 struct vnode **a_vpp; 1273 struct componentname *a_cnp; 1274 struct vattr *a_vap; 1275 }; 1276 */ 1277 static int 1278 fuse_vnop_mknod(struct vop_mknod_args *ap) 1279 { 1280 1281 struct vnode *dvp = ap->a_dvp; 1282 struct vnode **vpp = ap->a_vpp; 1283 struct componentname *cnp = ap->a_cnp; 1284 struct vattr *vap = ap->a_vap; 1285 1286 if (fuse_isdeadfs(dvp)) 1287 return ENXIO; 1288 1289 return fuse_internal_mknod(dvp, vpp, cnp, vap); 1290 } 1291 1292 /* 1293 struct vop_open_args { 1294 struct vnode *a_vp; 1295 int a_mode; 1296 struct ucred *a_cred; 1297 struct thread *a_td; 1298 int a_fdidx; / struct file *a_fp; 1299 }; 1300 */ 1301 static int 1302 fuse_vnop_open(struct vop_open_args *ap) 1303 { 1304 struct vnode *vp = ap->a_vp; 1305 int a_mode = ap->a_mode; 1306 struct thread *td = ap->a_td; 1307 struct ucred *cred = ap->a_cred; 1308 pid_t pid = td->td_proc->p_pid; 1309 struct fuse_vnode_data *fvdat; 1310 1311 if (fuse_isdeadfs(vp)) 1312 return ENXIO; 1313 if (vp->v_type == VCHR || vp->v_type == VBLK || vp->v_type == VFIFO) 1314 return (EOPNOTSUPP); 1315 if ((a_mode & (FREAD | FWRITE | FEXEC)) == 0) 1316 return EINVAL; 1317 1318 fvdat = VTOFUD(vp); 1319 1320 if (fuse_filehandle_validrw(vp, a_mode, cred, pid)) { 1321 fuse_vnode_open(vp, 0, td); 1322 return 0; 1323 } 1324 1325 return fuse_filehandle_open(vp, a_mode, NULL, td, cred); 1326 } 1327 1328 static int 1329 fuse_vnop_pathconf(struct vop_pathconf_args *ap) 1330 { 1331 1332 switch (ap->a_name) { 1333 case _PC_FILESIZEBITS: 1334 *ap->a_retval = 64; 1335 return (0); 1336 case _PC_NAME_MAX: 1337 *ap->a_retval = NAME_MAX; 1338 return (0); 1339 case _PC_LINK_MAX: 1340 *ap->a_retval = MIN(LONG_MAX, FUSE_LINK_MAX); 1341 return (0); 1342 case _PC_SYMLINK_MAX: 1343 *ap->a_retval = MAXPATHLEN; 1344 return (0); 1345 case _PC_NO_TRUNC: 1346 *ap->a_retval = 1; 1347 return (0); 1348 default: 1349 return (vop_stdpathconf(ap)); 1350 } 1351 } 1352 1353 /* 1354 struct vnop_read_args { 1355 struct vnode *a_vp; 1356 struct uio *a_uio; 1357 int a_ioflag; 1358 struct ucred *a_cred; 1359 }; 1360 */ 1361 static int 1362 fuse_vnop_read(struct vop_read_args *ap) 1363 { 1364 struct vnode *vp = ap->a_vp; 1365 struct uio *uio = ap->a_uio; 1366 int ioflag = ap->a_ioflag; 1367 struct ucred *cred = ap->a_cred; 1368 pid_t pid = curthread->td_proc->p_pid; 1369 1370 if (fuse_isdeadfs(vp)) { 1371 return ENXIO; 1372 } 1373 1374 if (VTOFUD(vp)->flag & FN_DIRECTIO) { 1375 ioflag |= IO_DIRECT; 1376 } 1377 1378 return fuse_io_dispatch(vp, uio, ioflag, cred, pid); 1379 } 1380 1381 /* 1382 struct vnop_readdir_args { 1383 struct vnode *a_vp; 1384 struct uio *a_uio; 1385 struct ucred *a_cred; 1386 int *a_eofflag; 1387 int *a_ncookies; 1388 u_long **a_cookies; 1389 }; 1390 */ 1391 static int 1392 fuse_vnop_readdir(struct vop_readdir_args *ap) 1393 { 1394 struct vnode *vp = ap->a_vp; 1395 struct uio *uio = ap->a_uio; 1396 struct ucred *cred = ap->a_cred; 1397 struct fuse_filehandle *fufh = NULL; 1398 struct fuse_iov cookediov; 1399 int err = 0; 1400 u_long *cookies; 1401 off_t startoff; 1402 ssize_t tresid; 1403 int ncookies; 1404 bool closefufh = false; 1405 pid_t pid = curthread->td_proc->p_pid; 1406 1407 if (ap->a_eofflag) 1408 *ap->a_eofflag = 0; 1409 if (fuse_isdeadfs(vp)) { 1410 return ENXIO; 1411 } 1412 if ( /* XXXIP ((uio_iovcnt(uio) > 1)) || */ 1413 (uio_resid(uio) < sizeof(struct dirent))) { 1414 return EINVAL; 1415 } 1416 1417 tresid = uio->uio_resid; 1418 startoff = uio->uio_offset; 1419 err = fuse_filehandle_get_dir(vp, &fufh, cred, pid); 1420 if (err == EBADF && vnode_mount(vp)->mnt_flag & MNT_EXPORTED) { 1421 /* 1422 * nfsd will do VOP_READDIR without first doing VOP_OPEN. We 1423 * must implicitly open the directory here 1424 */ 1425 err = fuse_filehandle_open(vp, FREAD, &fufh, curthread, cred); 1426 if (err == 0) { 1427 /* 1428 * When a directory is opened, it must be read from 1429 * the beginning. Hopefully, the "startoff" still 1430 * exists as an offset cookie for the directory. 1431 * If not, it will read the entire directory without 1432 * returning any entries and just return eof. 1433 */ 1434 uio->uio_offset = 0; 1435 } 1436 closefufh = true; 1437 } 1438 if (err) 1439 return (err); 1440 if (ap->a_ncookies != NULL) { 1441 ncookies = uio->uio_resid / 1442 (offsetof(struct dirent, d_name) + 4) + 1; 1443 cookies = malloc(ncookies * sizeof(*cookies), M_TEMP, M_WAITOK); 1444 *ap->a_ncookies = ncookies; 1445 *ap->a_cookies = cookies; 1446 } else { 1447 ncookies = 0; 1448 cookies = NULL; 1449 } 1450 #define DIRCOOKEDSIZE FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + MAXNAMLEN + 1) 1451 fiov_init(&cookediov, DIRCOOKEDSIZE); 1452 1453 err = fuse_internal_readdir(vp, uio, startoff, fufh, &cookediov, 1454 &ncookies, cookies); 1455 1456 fiov_teardown(&cookediov); 1457 if (closefufh) 1458 fuse_filehandle_close(vp, fufh, curthread, cred); 1459 1460 if (ap->a_ncookies != NULL) { 1461 if (err == 0) { 1462 *ap->a_ncookies -= ncookies; 1463 } else { 1464 free(*ap->a_cookies, M_TEMP); 1465 *ap->a_ncookies = 0; 1466 *ap->a_cookies = NULL; 1467 } 1468 } 1469 if (err == 0 && tresid == uio->uio_resid) 1470 *ap->a_eofflag = 1; 1471 1472 return err; 1473 } 1474 1475 /* 1476 struct vnop_readlink_args { 1477 struct vnode *a_vp; 1478 struct uio *a_uio; 1479 struct ucred *a_cred; 1480 }; 1481 */ 1482 static int 1483 fuse_vnop_readlink(struct vop_readlink_args *ap) 1484 { 1485 struct vnode *vp = ap->a_vp; 1486 struct uio *uio = ap->a_uio; 1487 struct ucred *cred = ap->a_cred; 1488 1489 struct fuse_dispatcher fdi; 1490 int err; 1491 1492 if (fuse_isdeadfs(vp)) { 1493 return ENXIO; 1494 } 1495 if (!vnode_islnk(vp)) { 1496 return EINVAL; 1497 } 1498 fdisp_init(&fdi, 0); 1499 err = fdisp_simple_putget_vp(&fdi, FUSE_READLINK, vp, curthread, cred); 1500 if (err) { 1501 goto out; 1502 } 1503 if (((char *)fdi.answ)[0] == '/' && 1504 fuse_get_mpdata(vnode_mount(vp))->dataflags & FSESS_PUSH_SYMLINKS_IN) { 1505 char *mpth = vnode_mount(vp)->mnt_stat.f_mntonname; 1506 1507 err = uiomove(mpth, strlen(mpth), uio); 1508 } 1509 if (!err) { 1510 err = uiomove(fdi.answ, fdi.iosize, uio); 1511 } 1512 out: 1513 fdisp_destroy(&fdi); 1514 return err; 1515 } 1516 1517 /* 1518 struct vnop_reclaim_args { 1519 struct vnode *a_vp; 1520 struct thread *a_td; 1521 }; 1522 */ 1523 static int 1524 fuse_vnop_reclaim(struct vop_reclaim_args *ap) 1525 { 1526 struct vnode *vp = ap->a_vp; 1527 struct thread *td = ap->a_td; 1528 struct fuse_vnode_data *fvdat = VTOFUD(vp); 1529 struct fuse_filehandle *fufh, *fufh_tmp; 1530 1531 if (!fvdat) { 1532 panic("FUSE: no vnode data during recycling"); 1533 } 1534 LIST_FOREACH_SAFE(fufh, &fvdat->handles, next, fufh_tmp) { 1535 printf("FUSE: vnode being reclaimed with open fufh " 1536 "(type=%#x)", fufh->fufh_type); 1537 fuse_filehandle_close(vp, fufh, td, NULL); 1538 } 1539 1540 if (!fuse_isdeadfs(vp) && fvdat->nlookup > 0) { 1541 fuse_internal_forget_send(vnode_mount(vp), td, NULL, VTOI(vp), 1542 fvdat->nlookup); 1543 } 1544 cache_purge(vp); 1545 vfs_hash_remove(vp); 1546 fuse_vnode_destroy(vp); 1547 1548 return 0; 1549 } 1550 1551 /* 1552 struct vnop_remove_args { 1553 struct vnode *a_dvp; 1554 struct vnode *a_vp; 1555 struct componentname *a_cnp; 1556 }; 1557 */ 1558 static int 1559 fuse_vnop_remove(struct vop_remove_args *ap) 1560 { 1561 struct vnode *dvp = ap->a_dvp; 1562 struct vnode *vp = ap->a_vp; 1563 struct componentname *cnp = ap->a_cnp; 1564 1565 int err; 1566 1567 if (fuse_isdeadfs(vp)) { 1568 return ENXIO; 1569 } 1570 if (vnode_isdir(vp)) { 1571 return EPERM; 1572 } 1573 1574 err = fuse_internal_remove(dvp, vp, cnp, FUSE_UNLINK); 1575 1576 return err; 1577 } 1578 1579 /* 1580 struct vnop_rename_args { 1581 struct vnode *a_fdvp; 1582 struct vnode *a_fvp; 1583 struct componentname *a_fcnp; 1584 struct vnode *a_tdvp; 1585 struct vnode *a_tvp; 1586 struct componentname *a_tcnp; 1587 }; 1588 */ 1589 static int 1590 fuse_vnop_rename(struct vop_rename_args *ap) 1591 { 1592 struct vnode *fdvp = ap->a_fdvp; 1593 struct vnode *fvp = ap->a_fvp; 1594 struct componentname *fcnp = ap->a_fcnp; 1595 struct vnode *tdvp = ap->a_tdvp; 1596 struct vnode *tvp = ap->a_tvp; 1597 struct componentname *tcnp = ap->a_tcnp; 1598 struct fuse_data *data; 1599 bool newparent = fdvp != tdvp; 1600 bool isdir = fvp->v_type == VDIR; 1601 int err = 0; 1602 1603 if (fuse_isdeadfs(fdvp)) { 1604 return ENXIO; 1605 } 1606 if (fvp->v_mount != tdvp->v_mount || 1607 (tvp && fvp->v_mount != tvp->v_mount)) { 1608 SDT_PROBE2(fusefs, , vnops, trace, 1, "cross-device rename"); 1609 err = EXDEV; 1610 goto out; 1611 } 1612 cache_purge(fvp); 1613 1614 /* 1615 * FUSE library is expected to check if target directory is not 1616 * under the source directory in the file system tree. 1617 * Linux performs this check at VFS level. 1618 */ 1619 /* 1620 * If source is a directory, and it will get a new parent, user must 1621 * have write permission to it, so ".." can be modified. 1622 */ 1623 data = fuse_get_mpdata(vnode_mount(tdvp)); 1624 if (data->dataflags & FSESS_DEFAULT_PERMISSIONS && isdir && newparent) { 1625 err = fuse_internal_access(fvp, VWRITE, 1626 tcnp->cn_thread, tcnp->cn_cred); 1627 if (err) 1628 goto out; 1629 } 1630 sx_xlock(&data->rename_lock); 1631 err = fuse_internal_rename(fdvp, fcnp, tdvp, tcnp); 1632 if (err == 0) { 1633 if (tdvp != fdvp) 1634 fuse_vnode_setparent(fvp, tdvp); 1635 if (tvp != NULL) 1636 fuse_vnode_setparent(tvp, NULL); 1637 } 1638 sx_unlock(&data->rename_lock); 1639 1640 if (tvp != NULL && tvp != fvp) { 1641 cache_purge(tvp); 1642 } 1643 if (vnode_isdir(fvp)) { 1644 if ((tvp != NULL) && vnode_isdir(tvp)) { 1645 cache_purge(tdvp); 1646 } 1647 cache_purge(fdvp); 1648 } 1649 out: 1650 if (tdvp == tvp) { 1651 vrele(tdvp); 1652 } else { 1653 vput(tdvp); 1654 } 1655 if (tvp != NULL) { 1656 vput(tvp); 1657 } 1658 vrele(fdvp); 1659 vrele(fvp); 1660 1661 return err; 1662 } 1663 1664 /* 1665 struct vnop_rmdir_args { 1666 struct vnode *a_dvp; 1667 struct vnode *a_vp; 1668 struct componentname *a_cnp; 1669 } *ap; 1670 */ 1671 static int 1672 fuse_vnop_rmdir(struct vop_rmdir_args *ap) 1673 { 1674 struct vnode *dvp = ap->a_dvp; 1675 struct vnode *vp = ap->a_vp; 1676 1677 int err; 1678 1679 if (fuse_isdeadfs(vp)) { 1680 return ENXIO; 1681 } 1682 if (VTOFUD(vp) == VTOFUD(dvp)) { 1683 return EINVAL; 1684 } 1685 err = fuse_internal_remove(dvp, vp, ap->a_cnp, FUSE_RMDIR); 1686 1687 return err; 1688 } 1689 1690 /* 1691 struct vnop_setattr_args { 1692 struct vnode *a_vp; 1693 struct vattr *a_vap; 1694 struct ucred *a_cred; 1695 struct thread *a_td; 1696 }; 1697 */ 1698 static int 1699 fuse_vnop_setattr(struct vop_setattr_args *ap) 1700 { 1701 struct vnode *vp = ap->a_vp; 1702 struct vattr *vap = ap->a_vap; 1703 struct ucred *cred = ap->a_cred; 1704 struct thread *td = curthread; 1705 struct mount *mp; 1706 struct fuse_data *data; 1707 struct vattr old_va; 1708 int dataflags; 1709 int err = 0, err2; 1710 accmode_t accmode = 0; 1711 bool checkperm; 1712 bool drop_suid = false; 1713 gid_t cr_gid; 1714 1715 mp = vnode_mount(vp); 1716 data = fuse_get_mpdata(mp); 1717 dataflags = data->dataflags; 1718 checkperm = dataflags & FSESS_DEFAULT_PERMISSIONS; 1719 if (cred->cr_ngroups > 0) 1720 cr_gid = cred->cr_groups[0]; 1721 else 1722 cr_gid = 0; 1723 1724 if (fuse_isdeadfs(vp)) { 1725 return ENXIO; 1726 } 1727 1728 if (vap->va_uid != (uid_t)VNOVAL) { 1729 if (checkperm) { 1730 /* Only root may change a file's owner */ 1731 err = priv_check_cred(cred, PRIV_VFS_CHOWN); 1732 if (err) { 1733 /* As a special case, allow the null chown */ 1734 err2 = fuse_internal_getattr(vp, &old_va, cred, 1735 td); 1736 if (err2) 1737 return (err2); 1738 if (vap->va_uid != old_va.va_uid) 1739 return err; 1740 else 1741 accmode |= VADMIN; 1742 drop_suid = true; 1743 } else 1744 accmode |= VADMIN; 1745 } else 1746 accmode |= VADMIN; 1747 } 1748 if (vap->va_gid != (gid_t)VNOVAL) { 1749 if (checkperm && priv_check_cred(cred, PRIV_VFS_CHOWN)) 1750 drop_suid = true; 1751 if (checkperm && !groupmember(vap->va_gid, cred)) 1752 { 1753 /* 1754 * Non-root users may only chgrp to one of their own 1755 * groups 1756 */ 1757 err = priv_check_cred(cred, PRIV_VFS_CHOWN); 1758 if (err) { 1759 /* As a special case, allow the null chgrp */ 1760 err2 = fuse_internal_getattr(vp, &old_va, cred, 1761 td); 1762 if (err2) 1763 return (err2); 1764 if (vap->va_gid != old_va.va_gid) 1765 return err; 1766 accmode |= VADMIN; 1767 } else 1768 accmode |= VADMIN; 1769 } else 1770 accmode |= VADMIN; 1771 } 1772 if (vap->va_size != VNOVAL) { 1773 switch (vp->v_type) { 1774 case VDIR: 1775 return (EISDIR); 1776 case VLNK: 1777 case VREG: 1778 if (vfs_isrdonly(mp)) 1779 return (EROFS); 1780 break; 1781 default: 1782 /* 1783 * According to POSIX, the result is unspecified 1784 * for file types other than regular files, 1785 * directories and shared memory objects. We 1786 * don't support shared memory objects in the file 1787 * system, and have dubious support for truncating 1788 * symlinks. Just ignore the request in other cases. 1789 */ 1790 return (0); 1791 } 1792 /* Don't set accmode. Permission to trunc is checked upstack */ 1793 } 1794 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 1795 if (vap->va_vaflags & VA_UTIMES_NULL) 1796 accmode |= VWRITE; 1797 else 1798 accmode |= VADMIN; 1799 } 1800 if (drop_suid) { 1801 if (vap->va_mode != (mode_t)VNOVAL) 1802 vap->va_mode &= ~(S_ISUID | S_ISGID); 1803 else { 1804 err = fuse_internal_getattr(vp, &old_va, cred, td); 1805 if (err) 1806 return (err); 1807 vap->va_mode = old_va.va_mode & ~(S_ISUID | S_ISGID); 1808 } 1809 } 1810 if (vap->va_mode != (mode_t)VNOVAL) { 1811 /* Only root may set the sticky bit on non-directories */ 1812 if (checkperm && vp->v_type != VDIR && (vap->va_mode & S_ISTXT) 1813 && priv_check_cred(cred, PRIV_VFS_STICKYFILE)) 1814 return EFTYPE; 1815 if (checkperm && (vap->va_mode & S_ISGID)) { 1816 err = fuse_internal_getattr(vp, &old_va, cred, td); 1817 if (err) 1818 return (err); 1819 if (!groupmember(old_va.va_gid, cred)) { 1820 err = priv_check_cred(cred, PRIV_VFS_SETGID); 1821 if (err) 1822 return (err); 1823 } 1824 } 1825 accmode |= VADMIN; 1826 } 1827 1828 if (vfs_isrdonly(mp)) 1829 return EROFS; 1830 1831 err = fuse_internal_access(vp, accmode, td, cred); 1832 if (err) 1833 return err; 1834 else 1835 return fuse_internal_setattr(vp, vap, td, cred); 1836 } 1837 1838 /* 1839 struct vnop_strategy_args { 1840 struct vnode *a_vp; 1841 struct buf *a_bp; 1842 }; 1843 */ 1844 static int 1845 fuse_vnop_strategy(struct vop_strategy_args *ap) 1846 { 1847 struct vnode *vp = ap->a_vp; 1848 struct buf *bp = ap->a_bp; 1849 1850 if (!vp || fuse_isdeadfs(vp)) { 1851 bp->b_ioflags |= BIO_ERROR; 1852 bp->b_error = ENXIO; 1853 bufdone(bp); 1854 return 0; 1855 } 1856 1857 /* 1858 * VOP_STRATEGY always returns zero and signals error via bp->b_ioflags. 1859 * fuse_io_strategy sets bp's error fields 1860 */ 1861 (void)fuse_io_strategy(vp, bp); 1862 1863 return 0; 1864 } 1865 1866 1867 /* 1868 struct vnop_symlink_args { 1869 struct vnode *a_dvp; 1870 struct vnode **a_vpp; 1871 struct componentname *a_cnp; 1872 struct vattr *a_vap; 1873 char *a_target; 1874 }; 1875 */ 1876 static int 1877 fuse_vnop_symlink(struct vop_symlink_args *ap) 1878 { 1879 struct vnode *dvp = ap->a_dvp; 1880 struct vnode **vpp = ap->a_vpp; 1881 struct componentname *cnp = ap->a_cnp; 1882 const char *target = ap->a_target; 1883 1884 struct fuse_dispatcher fdi; 1885 1886 int err; 1887 size_t len; 1888 1889 if (fuse_isdeadfs(dvp)) { 1890 return ENXIO; 1891 } 1892 /* 1893 * Unlike the other creator type calls, here we have to create a message 1894 * where the name of the new entry comes first, and the data describing 1895 * the entry comes second. 1896 * Hence we can't rely on our handy fuse_internal_newentry() routine, 1897 * but put together the message manually and just call the core part. 1898 */ 1899 1900 len = strlen(target) + 1; 1901 fdisp_init(&fdi, len + cnp->cn_namelen + 1); 1902 fdisp_make_vp(&fdi, FUSE_SYMLINK, dvp, curthread, NULL); 1903 1904 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 1905 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 1906 memcpy((char *)fdi.indata + cnp->cn_namelen + 1, target, len); 1907 1908 err = fuse_internal_newentry_core(dvp, vpp, cnp, VLNK, &fdi); 1909 fdisp_destroy(&fdi); 1910 return err; 1911 } 1912 1913 /* 1914 struct vnop_write_args { 1915 struct vnode *a_vp; 1916 struct uio *a_uio; 1917 int a_ioflag; 1918 struct ucred *a_cred; 1919 }; 1920 */ 1921 static int 1922 fuse_vnop_write(struct vop_write_args *ap) 1923 { 1924 struct vnode *vp = ap->a_vp; 1925 struct uio *uio = ap->a_uio; 1926 int ioflag = ap->a_ioflag; 1927 struct ucred *cred = ap->a_cred; 1928 pid_t pid = curthread->td_proc->p_pid; 1929 1930 if (fuse_isdeadfs(vp)) { 1931 return ENXIO; 1932 } 1933 1934 if (VTOFUD(vp)->flag & FN_DIRECTIO) { 1935 ioflag |= IO_DIRECT; 1936 } 1937 1938 return fuse_io_dispatch(vp, uio, ioflag, cred, pid); 1939 } 1940 1941 static daddr_t 1942 fuse_gbp_getblkno(struct vnode *vp, vm_ooffset_t off) 1943 { 1944 const int biosize = fuse_iosize(vp); 1945 1946 return (off / biosize); 1947 } 1948 1949 static int 1950 fuse_gbp_getblksz(struct vnode *vp, daddr_t lbn) 1951 { 1952 off_t filesize; 1953 int blksz, err; 1954 const int biosize = fuse_iosize(vp); 1955 1956 err = fuse_vnode_size(vp, &filesize, NULL, NULL); 1957 KASSERT(err == 0, ("vfs_bio_getpages can't handle errors here")); 1958 if (err) 1959 return biosize; 1960 1961 if ((off_t)lbn * biosize >= filesize) { 1962 blksz = 0; 1963 } else if ((off_t)(lbn + 1) * biosize > filesize) { 1964 blksz = filesize - (off_t)lbn *biosize; 1965 } else { 1966 blksz = biosize; 1967 } 1968 return (blksz); 1969 } 1970 1971 /* 1972 struct vnop_getpages_args { 1973 struct vnode *a_vp; 1974 vm_page_t *a_m; 1975 int a_count; 1976 int a_reqpage; 1977 }; 1978 */ 1979 static int 1980 fuse_vnop_getpages(struct vop_getpages_args *ap) 1981 { 1982 struct vnode *vp = ap->a_vp; 1983 1984 if (!fsess_opt_mmap(vnode_mount(vp))) { 1985 SDT_PROBE2(fusefs, , vnops, trace, 1, 1986 "called on non-cacheable vnode??\n"); 1987 return (VM_PAGER_ERROR); 1988 } 1989 1990 return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind, 1991 ap->a_rahead, fuse_gbp_getblkno, fuse_gbp_getblksz)); 1992 } 1993 1994 static const char extattr_namespace_separator = '.'; 1995 1996 /* 1997 struct vop_getextattr_args { 1998 struct vop_generic_args a_gen; 1999 struct vnode *a_vp; 2000 int a_attrnamespace; 2001 const char *a_name; 2002 struct uio *a_uio; 2003 size_t *a_size; 2004 struct ucred *a_cred; 2005 struct thread *a_td; 2006 }; 2007 */ 2008 static int 2009 fuse_vnop_getextattr(struct vop_getextattr_args *ap) 2010 { 2011 struct vnode *vp = ap->a_vp; 2012 struct uio *uio = ap->a_uio; 2013 struct fuse_dispatcher fdi; 2014 struct fuse_getxattr_in *get_xattr_in; 2015 struct fuse_getxattr_out *get_xattr_out; 2016 struct mount *mp = vnode_mount(vp); 2017 struct thread *td = ap->a_td; 2018 struct ucred *cred = ap->a_cred; 2019 char *prefix; 2020 char *attr_str; 2021 size_t len; 2022 int err; 2023 2024 if (fuse_isdeadfs(vp)) 2025 return (ENXIO); 2026 2027 if (!fsess_isimpl(mp, FUSE_GETXATTR)) 2028 return EOPNOTSUPP; 2029 2030 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD); 2031 if (err) 2032 return err; 2033 2034 /* Default to looking for user attributes. */ 2035 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2036 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2037 else 2038 prefix = EXTATTR_NAMESPACE_USER_STRING; 2039 2040 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2041 strlen(ap->a_name) + 1; 2042 2043 fdisp_init(&fdi, len + sizeof(*get_xattr_in)); 2044 fdisp_make_vp(&fdi, FUSE_GETXATTR, vp, td, cred); 2045 2046 get_xattr_in = fdi.indata; 2047 /* 2048 * Check to see whether we're querying the available size or 2049 * issuing the actual request. If we pass in 0, we get back struct 2050 * fuse_getxattr_out. If we pass in a non-zero size, we get back 2051 * that much data, without the struct fuse_getxattr_out header. 2052 */ 2053 if (uio == NULL) 2054 get_xattr_in->size = 0; 2055 else 2056 get_xattr_in->size = uio->uio_resid; 2057 2058 attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); 2059 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2060 ap->a_name); 2061 2062 err = fdisp_wait_answ(&fdi); 2063 if (err != 0) { 2064 if (err == ENOSYS) { 2065 fsess_set_notimpl(mp, FUSE_GETXATTR); 2066 err = EOPNOTSUPP; 2067 } 2068 goto out; 2069 } 2070 2071 get_xattr_out = fdi.answ; 2072 2073 if (ap->a_size != NULL) 2074 *ap->a_size = get_xattr_out->size; 2075 2076 if (uio != NULL) 2077 err = uiomove(fdi.answ, fdi.iosize, uio); 2078 2079 out: 2080 fdisp_destroy(&fdi); 2081 return (err); 2082 } 2083 2084 /* 2085 struct vop_setextattr_args { 2086 struct vop_generic_args a_gen; 2087 struct vnode *a_vp; 2088 int a_attrnamespace; 2089 const char *a_name; 2090 struct uio *a_uio; 2091 struct ucred *a_cred; 2092 struct thread *a_td; 2093 }; 2094 */ 2095 static int 2096 fuse_vnop_setextattr(struct vop_setextattr_args *ap) 2097 { 2098 struct vnode *vp = ap->a_vp; 2099 struct uio *uio = ap->a_uio; 2100 struct fuse_dispatcher fdi; 2101 struct fuse_setxattr_in *set_xattr_in; 2102 struct mount *mp = vnode_mount(vp); 2103 struct thread *td = ap->a_td; 2104 struct ucred *cred = ap->a_cred; 2105 char *prefix; 2106 size_t len; 2107 char *attr_str; 2108 int err; 2109 2110 if (fuse_isdeadfs(vp)) 2111 return (ENXIO); 2112 2113 if (!fsess_isimpl(mp, FUSE_SETXATTR)) 2114 return EOPNOTSUPP; 2115 2116 if (vfs_isrdonly(mp)) 2117 return EROFS; 2118 2119 /* Deleting xattrs must use VOP_DELETEEXTATTR instead */ 2120 if (ap->a_uio == NULL) { 2121 /* 2122 * If we got here as fallback from VOP_DELETEEXTATTR, then 2123 * return EOPNOTSUPP. 2124 */ 2125 if (!fsess_isimpl(mp, FUSE_REMOVEXATTR)) 2126 return (EOPNOTSUPP); 2127 else 2128 return (EINVAL); 2129 } 2130 2131 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, 2132 VWRITE); 2133 if (err) 2134 return err; 2135 2136 /* Default to looking for user attributes. */ 2137 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2138 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2139 else 2140 prefix = EXTATTR_NAMESPACE_USER_STRING; 2141 2142 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2143 strlen(ap->a_name) + 1; 2144 2145 fdisp_init(&fdi, len + sizeof(*set_xattr_in) + uio->uio_resid); 2146 fdisp_make_vp(&fdi, FUSE_SETXATTR, vp, td, cred); 2147 2148 set_xattr_in = fdi.indata; 2149 set_xattr_in->size = uio->uio_resid; 2150 2151 attr_str = (char *)fdi.indata + sizeof(*set_xattr_in); 2152 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2153 ap->a_name); 2154 2155 err = uiomove((char *)fdi.indata + sizeof(*set_xattr_in) + len, 2156 uio->uio_resid, uio); 2157 if (err != 0) { 2158 goto out; 2159 } 2160 2161 err = fdisp_wait_answ(&fdi); 2162 2163 if (err == ENOSYS) { 2164 fsess_set_notimpl(mp, FUSE_SETXATTR); 2165 err = EOPNOTSUPP; 2166 } 2167 if (err == ERESTART) { 2168 /* Can't restart after calling uiomove */ 2169 err = EINTR; 2170 } 2171 2172 out: 2173 fdisp_destroy(&fdi); 2174 return (err); 2175 } 2176 2177 /* 2178 * The Linux / FUSE extended attribute list is simply a collection of 2179 * NUL-terminated strings. The FreeBSD extended attribute list is a single 2180 * byte length followed by a non-NUL terminated string. So, this allows 2181 * conversion of the Linux / FUSE format to the FreeBSD format in place. 2182 * Linux attribute names are reported with the namespace as a prefix (e.g. 2183 * "user.attribute_name"), but in FreeBSD they are reported without the 2184 * namespace prefix (e.g. "attribute_name"). So, we're going from: 2185 * 2186 * user.attr_name1\0user.attr_name2\0 2187 * 2188 * to: 2189 * 2190 * <num>attr_name1<num>attr_name2 2191 * 2192 * Where "<num>" is a single byte number of characters in the attribute name. 2193 * 2194 * Args: 2195 * prefix - exattr namespace prefix string 2196 * list, list_len - input list with namespace prefixes 2197 * bsd_list, bsd_list_len - output list compatible with bsd vfs 2198 */ 2199 static int 2200 fuse_xattrlist_convert(char *prefix, const char *list, int list_len, 2201 char *bsd_list, int *bsd_list_len) 2202 { 2203 int len, pos, dist_to_next, prefix_len; 2204 2205 pos = 0; 2206 *bsd_list_len = 0; 2207 prefix_len = strlen(prefix); 2208 2209 while (pos < list_len && list[pos] != '\0') { 2210 dist_to_next = strlen(&list[pos]) + 1; 2211 if (bcmp(&list[pos], prefix, prefix_len) == 0 && 2212 list[pos + prefix_len] == extattr_namespace_separator) { 2213 len = dist_to_next - 2214 (prefix_len + sizeof(extattr_namespace_separator)) - 1; 2215 if (len >= EXTATTR_MAXNAMELEN) 2216 return (ENAMETOOLONG); 2217 2218 bsd_list[*bsd_list_len] = len; 2219 memcpy(&bsd_list[*bsd_list_len + 1], 2220 &list[pos + prefix_len + 2221 sizeof(extattr_namespace_separator)], len); 2222 2223 *bsd_list_len += len + 1; 2224 } 2225 2226 pos += dist_to_next; 2227 } 2228 2229 return (0); 2230 } 2231 2232 /* 2233 * List extended attributes 2234 * 2235 * The FUSE_LISTXATTR operation is based on Linux's listxattr(2) syscall, which 2236 * has a number of differences compared to its FreeBSD equivalent, 2237 * extattr_list_file: 2238 * 2239 * - FUSE_LISTXATTR returns all extended attributes across all namespaces, 2240 * whereas listxattr(2) only returns attributes for a single namespace 2241 * - FUSE_LISTXATTR prepends each attribute name with "namespace." 2242 * - If the provided buffer is not large enough to hold the result, 2243 * FUSE_LISTXATTR should return ERANGE, whereas listxattr is expected to 2244 * return as many results as will fit. 2245 */ 2246 /* 2247 struct vop_listextattr_args { 2248 struct vop_generic_args a_gen; 2249 struct vnode *a_vp; 2250 int a_attrnamespace; 2251 struct uio *a_uio; 2252 size_t *a_size; 2253 struct ucred *a_cred; 2254 struct thread *a_td; 2255 }; 2256 */ 2257 static int 2258 fuse_vnop_listextattr(struct vop_listextattr_args *ap) 2259 { 2260 struct vnode *vp = ap->a_vp; 2261 struct uio *uio = ap->a_uio; 2262 struct fuse_dispatcher fdi; 2263 struct fuse_listxattr_in *list_xattr_in; 2264 struct fuse_listxattr_out *list_xattr_out; 2265 struct mount *mp = vnode_mount(vp); 2266 struct thread *td = ap->a_td; 2267 struct ucred *cred = ap->a_cred; 2268 char *prefix; 2269 char *bsd_list = NULL; 2270 char *linux_list; 2271 int bsd_list_len; 2272 int linux_list_len; 2273 int err; 2274 2275 if (fuse_isdeadfs(vp)) 2276 return (ENXIO); 2277 2278 if (!fsess_isimpl(mp, FUSE_LISTXATTR)) 2279 return EOPNOTSUPP; 2280 2281 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD); 2282 if (err) 2283 return err; 2284 2285 /* 2286 * Add space for a NUL and the period separator if enabled. 2287 * Default to looking for user attributes. 2288 */ 2289 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2290 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2291 else 2292 prefix = EXTATTR_NAMESPACE_USER_STRING; 2293 2294 fdisp_init(&fdi, sizeof(*list_xattr_in)); 2295 fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); 2296 2297 /* 2298 * Retrieve Linux / FUSE compatible list size. 2299 */ 2300 list_xattr_in = fdi.indata; 2301 list_xattr_in->size = 0; 2302 2303 err = fdisp_wait_answ(&fdi); 2304 if (err != 0) { 2305 if (err == ENOSYS) { 2306 fsess_set_notimpl(mp, FUSE_LISTXATTR); 2307 err = EOPNOTSUPP; 2308 } 2309 goto out; 2310 } 2311 2312 list_xattr_out = fdi.answ; 2313 linux_list_len = list_xattr_out->size; 2314 if (linux_list_len == 0) { 2315 if (ap->a_size != NULL) 2316 *ap->a_size = linux_list_len; 2317 goto out; 2318 } 2319 2320 /* 2321 * Retrieve Linux / FUSE compatible list values. 2322 */ 2323 fdisp_refresh_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); 2324 list_xattr_in = fdi.indata; 2325 list_xattr_in->size = linux_list_len; 2326 2327 err = fdisp_wait_answ(&fdi); 2328 if (err == ERANGE) { 2329 /* 2330 * Race detected. The attribute list must've grown since the 2331 * first FUSE_LISTXATTR call. Start over. Go all the way back 2332 * to userland so we can process signals, if necessary, before 2333 * restarting. 2334 */ 2335 err = ERESTART; 2336 goto out; 2337 } else if (err != 0) 2338 goto out; 2339 2340 linux_list = fdi.answ; 2341 /* FUSE doesn't allow the server to return more data than requested */ 2342 if (fdi.iosize > linux_list_len) { 2343 printf("WARNING: FUSE protocol violation. Server returned " 2344 "more extended attribute data than requested; " 2345 "should've returned ERANGE instead"); 2346 } else { 2347 /* But returning less data is fine */ 2348 linux_list_len = fdi.iosize; 2349 } 2350 2351 /* 2352 * Retrieve the BSD compatible list values. 2353 * The Linux / FUSE attribute list format isn't the same 2354 * as FreeBSD's format. So we need to transform it into 2355 * FreeBSD's format before giving it to the user. 2356 */ 2357 bsd_list = malloc(linux_list_len, M_TEMP, M_WAITOK); 2358 err = fuse_xattrlist_convert(prefix, linux_list, linux_list_len, 2359 bsd_list, &bsd_list_len); 2360 if (err != 0) 2361 goto out; 2362 2363 if (ap->a_size != NULL) 2364 *ap->a_size = bsd_list_len; 2365 2366 if (uio != NULL) 2367 err = uiomove(bsd_list, bsd_list_len, uio); 2368 2369 out: 2370 free(bsd_list, M_TEMP); 2371 fdisp_destroy(&fdi); 2372 return (err); 2373 } 2374 2375 /* 2376 struct vop_deleteextattr_args { 2377 struct vop_generic_args a_gen; 2378 struct vnode *a_vp; 2379 int a_attrnamespace; 2380 const char *a_name; 2381 struct ucred *a_cred; 2382 struct thread *a_td; 2383 }; 2384 */ 2385 static int 2386 fuse_vnop_deleteextattr(struct vop_deleteextattr_args *ap) 2387 { 2388 struct vnode *vp = ap->a_vp; 2389 struct fuse_dispatcher fdi; 2390 struct mount *mp = vnode_mount(vp); 2391 struct thread *td = ap->a_td; 2392 struct ucred *cred = ap->a_cred; 2393 char *prefix; 2394 size_t len; 2395 char *attr_str; 2396 int err; 2397 2398 if (fuse_isdeadfs(vp)) 2399 return (ENXIO); 2400 2401 if (!fsess_isimpl(mp, FUSE_REMOVEXATTR)) 2402 return EOPNOTSUPP; 2403 2404 if (vfs_isrdonly(mp)) 2405 return EROFS; 2406 2407 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, 2408 VWRITE); 2409 if (err) 2410 return err; 2411 2412 /* Default to looking for user attributes. */ 2413 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2414 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2415 else 2416 prefix = EXTATTR_NAMESPACE_USER_STRING; 2417 2418 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2419 strlen(ap->a_name) + 1; 2420 2421 fdisp_init(&fdi, len); 2422 fdisp_make_vp(&fdi, FUSE_REMOVEXATTR, vp, td, cred); 2423 2424 attr_str = fdi.indata; 2425 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2426 ap->a_name); 2427 2428 err = fdisp_wait_answ(&fdi); 2429 if (err == ENOSYS) { 2430 fsess_set_notimpl(mp, FUSE_REMOVEXATTR); 2431 err = EOPNOTSUPP; 2432 } 2433 2434 fdisp_destroy(&fdi); 2435 return (err); 2436 } 2437 2438 /* 2439 struct vnop_print_args { 2440 struct vnode *a_vp; 2441 }; 2442 */ 2443 static int 2444 fuse_vnop_print(struct vop_print_args *ap) 2445 { 2446 struct fuse_vnode_data *fvdat = VTOFUD(ap->a_vp); 2447 2448 printf("nodeid: %ju, parent nodeid: %ju, nlookup: %ju, flag: %#x\n", 2449 (uintmax_t)VTOILLU(ap->a_vp), (uintmax_t)fvdat->parent_nid, 2450 (uintmax_t)fvdat->nlookup, 2451 fvdat->flag); 2452 2453 return 0; 2454 } 2455 2456 /* 2457 * Get an NFS filehandle for a FUSE file. 2458 * 2459 * This will only work for FUSE file systems that guarantee the uniqueness of 2460 * nodeid:generation, which most don't. 2461 */ 2462 /* 2463 vop_vptofh { 2464 IN struct vnode *a_vp; 2465 IN struct fid *a_fhp; 2466 }; 2467 */ 2468 static int 2469 fuse_vnop_vptofh(struct vop_vptofh_args *ap) 2470 { 2471 struct vnode *vp = ap->a_vp; 2472 struct fuse_vnode_data *fvdat = VTOFUD(vp); 2473 struct fuse_fid *fhp = (struct fuse_fid *)(ap->a_fhp); 2474 _Static_assert(sizeof(struct fuse_fid) <= sizeof(struct fid), 2475 "FUSE fid type is too big"); 2476 struct mount *mp = vnode_mount(vp); 2477 struct fuse_data *data = fuse_get_mpdata(mp); 2478 struct vattr va; 2479 int err; 2480 2481 if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) 2482 return EOPNOTSUPP; 2483 2484 err = fuse_internal_getattr(vp, &va, curthread->td_ucred, curthread); 2485 if (err) 2486 return err; 2487 2488 /*ip = VTOI(ap->a_vp);*/ 2489 /*ufhp = (struct ufid *)ap->a_fhp;*/ 2490 fhp->len = sizeof(struct fuse_fid); 2491 fhp->nid = fvdat->nid; 2492 if (fvdat->generation <= UINT32_MAX) 2493 fhp->gen = fvdat->generation; 2494 else 2495 return EOVERFLOW; 2496 return (0); 2497 } 2498 2499 2500