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