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 1039 err = cache_lookup(dvp, vpp, cnp, &timeout, NULL); 1040 getnanouptime(&now); 1041 SDT_PROBE3(fusefs, , vnops, cache_lookup, err, &timeout, &now); 1042 switch (err) { 1043 case -1: /* positive match */ 1044 if (timespeccmp(&timeout, &now, >)) { 1045 counter_u64_add(fuse_lookup_cache_hits, 1); 1046 } else { 1047 /* Cache timeout */ 1048 counter_u64_add(fuse_lookup_cache_misses, 1); 1049 bintime_clear( 1050 &VTOFUD(*vpp)->entry_cache_timeout); 1051 cache_purge(*vpp); 1052 if (dvp != *vpp) 1053 vput(*vpp); 1054 else 1055 vrele(*vpp); 1056 *vpp = NULL; 1057 break; 1058 } 1059 return 0; 1060 1061 case 0: /* no match in cache */ 1062 counter_u64_add(fuse_lookup_cache_misses, 1); 1063 break; 1064 1065 case ENOENT: /* negative match */ 1066 getnanouptime(&now); 1067 if (timespeccmp(&timeout, &now, <=)) { 1068 /* Cache timeout */ 1069 cache_purge_negative(dvp); 1070 break; 1071 } 1072 /* fall through */ 1073 default: 1074 return err; 1075 } 1076 1077 nid = VTOI(dvp); 1078 fdisp_init(&fdi, cnp->cn_namelen + 1); 1079 fdisp_make(&fdi, FUSE_LOOKUP, mp, nid, td, cred); 1080 1081 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 1082 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 1083 lookup_err = fdisp_wait_answ(&fdi); 1084 did_lookup = true; 1085 1086 if (!lookup_err) { 1087 /* lookup call succeeded */ 1088 feo = (struct fuse_entry_out *)fdi.answ; 1089 nid = feo->nodeid; 1090 if (nid == 0) { 1091 /* zero nodeid means ENOENT and cache it */ 1092 struct timespec timeout; 1093 1094 fdi.answ_stat = ENOENT; 1095 lookup_err = ENOENT; 1096 if (cnp->cn_flags & MAKEENTRY) { 1097 fuse_validity_2_timespec(feo, &timeout); 1098 cache_enter_time(dvp, *vpp, cnp, 1099 &timeout, NULL); 1100 } 1101 } else if (nid == FUSE_ROOT_ID) { 1102 lookup_err = EINVAL; 1103 } 1104 vtyp = IFTOVT(feo->attr.mode); 1105 filesize = feo->attr.size; 1106 } 1107 if (lookup_err && (!fdi.answ_stat || lookup_err != ENOENT)) { 1108 fdisp_destroy(&fdi); 1109 return lookup_err; 1110 } 1111 } 1112 /* lookup_err, if non-zero, must be ENOENT at this point */ 1113 1114 if (lookup_err) { 1115 /* Entry not found */ 1116 if ((nameiop == CREATE || nameiop == RENAME) && islastcn) { 1117 if (default_permissions) 1118 err = fuse_internal_access(dvp, VWRITE, td, 1119 cred); 1120 else 1121 err = 0; 1122 if (!err) { 1123 /* 1124 * Set the SAVENAME flag to hold onto the 1125 * pathname for use later in VOP_CREATE or 1126 * VOP_RENAME. 1127 */ 1128 cnp->cn_flags |= SAVENAME; 1129 1130 err = EJUSTRETURN; 1131 } 1132 } else { 1133 err = ENOENT; 1134 } 1135 } else { 1136 /* Entry was found */ 1137 if (flags & ISDOTDOT) { 1138 struct fuse_lookup_alloc_arg flaa; 1139 1140 flaa.nid = nid; 1141 flaa.feo = feo; 1142 flaa.cnp = cnp; 1143 flaa.vtyp = vtyp; 1144 err = vn_vget_ino_gen(dvp, fuse_lookup_alloc, &flaa, 0, 1145 &vp); 1146 *vpp = vp; 1147 } else if (nid == VTOI(dvp)) { 1148 vref(dvp); 1149 *vpp = dvp; 1150 } else { 1151 struct fuse_vnode_data *fvdat; 1152 struct vattr *vap; 1153 1154 err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp, 1155 &vp, cnp, vtyp); 1156 if (err) 1157 goto out; 1158 *vpp = vp; 1159 1160 /* 1161 * In the case where we are looking up a FUSE node 1162 * represented by an existing cached vnode, and the 1163 * true size reported by FUSE_LOOKUP doesn't match 1164 * the vnode's cached size, then any cached writes 1165 * beyond the file's current size are lost. 1166 * 1167 * We can get here: 1168 * * following attribute cache expiration, or 1169 * * due a bug in the daemon, or 1170 */ 1171 fvdat = VTOFUD(vp); 1172 if (vnode_isreg(vp) && 1173 ((filesize != fvdat->cached_attrs.va_size && 1174 fvdat->flag & FN_SIZECHANGE) || 1175 ((vap = VTOVA(vp)) && 1176 filesize != vap->va_size))) 1177 { 1178 SDT_PROBE2(fusefs, , vnops, lookup_cache_incoherent, vp, feo); 1179 fvdat->flag &= ~FN_SIZECHANGE; 1180 /* 1181 * The server changed the file's size even 1182 * though we had it cached, or had dirty writes 1183 * in the WB cache! 1184 */ 1185 printf("%s: cache incoherent on %s! " 1186 "Buggy FUSE server detected. To prevent " 1187 "data corruption, disable the data cache " 1188 "by mounting with -o direct_io, or as " 1189 "directed otherwise by your FUSE server's " 1190 "documentation\n", __func__, 1191 vnode_mount(vp)->mnt_stat.f_mntonname); 1192 int iosize = fuse_iosize(vp); 1193 v_inval_buf_range(vp, 0, INT64_MAX, iosize); 1194 } 1195 1196 MPASS(feo != NULL); 1197 fuse_internal_cache_attrs(*vpp, &feo->attr, 1198 feo->attr_valid, feo->attr_valid_nsec, NULL); 1199 fuse_validity_2_bintime(feo->entry_valid, 1200 feo->entry_valid_nsec, 1201 &fvdat->entry_cache_timeout); 1202 1203 if ((nameiop == DELETE || nameiop == RENAME) && 1204 islastcn && default_permissions) 1205 { 1206 struct vattr dvattr; 1207 1208 err = fuse_internal_access(dvp, VWRITE, td, 1209 cred); 1210 if (err != 0) 1211 goto out; 1212 /* 1213 * if the parent's sticky bit is set, check 1214 * whether we're allowed to remove the file. 1215 * Need to figure out the vnode locking to make 1216 * this work. 1217 */ 1218 fuse_internal_getattr(dvp, &dvattr, cred, td); 1219 if ((dvattr.va_mode & S_ISTXT) && 1220 fuse_internal_access(dvp, VADMIN, td, 1221 cred) && 1222 fuse_internal_access(*vpp, VADMIN, td, 1223 cred)) { 1224 err = EPERM; 1225 goto out; 1226 } 1227 } 1228 1229 if (islastcn && ( 1230 (nameiop == DELETE) || 1231 (nameiop == RENAME && wantparent))) { 1232 cnp->cn_flags |= SAVENAME; 1233 } 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 struct thread *a_td; 1531 }; 1532 */ 1533 static int 1534 fuse_vnop_reclaim(struct vop_reclaim_args *ap) 1535 { 1536 struct vnode *vp = ap->a_vp; 1537 struct thread *td = ap->a_td; 1538 struct fuse_vnode_data *fvdat = VTOFUD(vp); 1539 struct fuse_filehandle *fufh, *fufh_tmp; 1540 1541 if (!fvdat) { 1542 panic("FUSE: no vnode data during recycling"); 1543 } 1544 LIST_FOREACH_SAFE(fufh, &fvdat->handles, next, fufh_tmp) { 1545 printf("FUSE: vnode being reclaimed with open fufh " 1546 "(type=%#x)", fufh->fufh_type); 1547 fuse_filehandle_close(vp, fufh, td, NULL); 1548 } 1549 1550 if (!fuse_isdeadfs(vp) && fvdat->nlookup > 0) { 1551 fuse_internal_forget_send(vnode_mount(vp), td, NULL, VTOI(vp), 1552 fvdat->nlookup); 1553 } 1554 cache_purge(vp); 1555 vfs_hash_remove(vp); 1556 fuse_vnode_destroy(vp); 1557 1558 return 0; 1559 } 1560 1561 /* 1562 struct vnop_remove_args { 1563 struct vnode *a_dvp; 1564 struct vnode *a_vp; 1565 struct componentname *a_cnp; 1566 }; 1567 */ 1568 static int 1569 fuse_vnop_remove(struct vop_remove_args *ap) 1570 { 1571 struct vnode *dvp = ap->a_dvp; 1572 struct vnode *vp = ap->a_vp; 1573 struct componentname *cnp = ap->a_cnp; 1574 1575 int err; 1576 1577 if (fuse_isdeadfs(vp)) { 1578 return ENXIO; 1579 } 1580 if (vnode_isdir(vp)) { 1581 return EPERM; 1582 } 1583 1584 err = fuse_internal_remove(dvp, vp, cnp, FUSE_UNLINK); 1585 1586 return err; 1587 } 1588 1589 /* 1590 struct vnop_rename_args { 1591 struct vnode *a_fdvp; 1592 struct vnode *a_fvp; 1593 struct componentname *a_fcnp; 1594 struct vnode *a_tdvp; 1595 struct vnode *a_tvp; 1596 struct componentname *a_tcnp; 1597 }; 1598 */ 1599 static int 1600 fuse_vnop_rename(struct vop_rename_args *ap) 1601 { 1602 struct vnode *fdvp = ap->a_fdvp; 1603 struct vnode *fvp = ap->a_fvp; 1604 struct componentname *fcnp = ap->a_fcnp; 1605 struct vnode *tdvp = ap->a_tdvp; 1606 struct vnode *tvp = ap->a_tvp; 1607 struct componentname *tcnp = ap->a_tcnp; 1608 struct fuse_data *data; 1609 bool newparent = fdvp != tdvp; 1610 bool isdir = fvp->v_type == VDIR; 1611 int err = 0; 1612 1613 if (fuse_isdeadfs(fdvp)) { 1614 return ENXIO; 1615 } 1616 if (fvp->v_mount != tdvp->v_mount || 1617 (tvp && fvp->v_mount != tvp->v_mount)) { 1618 SDT_PROBE2(fusefs, , vnops, trace, 1, "cross-device rename"); 1619 err = EXDEV; 1620 goto out; 1621 } 1622 cache_purge(fvp); 1623 1624 /* 1625 * FUSE library is expected to check if target directory is not 1626 * under the source directory in the file system tree. 1627 * Linux performs this check at VFS level. 1628 */ 1629 /* 1630 * If source is a directory, and it will get a new parent, user must 1631 * have write permission to it, so ".." can be modified. 1632 */ 1633 data = fuse_get_mpdata(vnode_mount(tdvp)); 1634 if (data->dataflags & FSESS_DEFAULT_PERMISSIONS && isdir && newparent) { 1635 err = fuse_internal_access(fvp, VWRITE, 1636 tcnp->cn_thread, tcnp->cn_cred); 1637 if (err) 1638 goto out; 1639 } 1640 sx_xlock(&data->rename_lock); 1641 err = fuse_internal_rename(fdvp, fcnp, tdvp, tcnp); 1642 if (err == 0) { 1643 if (tdvp != fdvp) 1644 fuse_vnode_setparent(fvp, tdvp); 1645 if (tvp != NULL) 1646 fuse_vnode_setparent(tvp, NULL); 1647 } 1648 sx_unlock(&data->rename_lock); 1649 1650 if (tvp != NULL && tvp != fvp) { 1651 cache_purge(tvp); 1652 } 1653 if (vnode_isdir(fvp)) { 1654 if ((tvp != NULL) && vnode_isdir(tvp)) { 1655 cache_purge(tdvp); 1656 } 1657 cache_purge(fdvp); 1658 } 1659 out: 1660 if (tdvp == tvp) { 1661 vrele(tdvp); 1662 } else { 1663 vput(tdvp); 1664 } 1665 if (tvp != NULL) { 1666 vput(tvp); 1667 } 1668 vrele(fdvp); 1669 vrele(fvp); 1670 1671 return err; 1672 } 1673 1674 /* 1675 struct vnop_rmdir_args { 1676 struct vnode *a_dvp; 1677 struct vnode *a_vp; 1678 struct componentname *a_cnp; 1679 } *ap; 1680 */ 1681 static int 1682 fuse_vnop_rmdir(struct vop_rmdir_args *ap) 1683 { 1684 struct vnode *dvp = ap->a_dvp; 1685 struct vnode *vp = ap->a_vp; 1686 1687 int err; 1688 1689 if (fuse_isdeadfs(vp)) { 1690 return ENXIO; 1691 } 1692 if (VTOFUD(vp) == VTOFUD(dvp)) { 1693 return EINVAL; 1694 } 1695 err = fuse_internal_remove(dvp, vp, ap->a_cnp, FUSE_RMDIR); 1696 1697 return err; 1698 } 1699 1700 /* 1701 struct vnop_setattr_args { 1702 struct vnode *a_vp; 1703 struct vattr *a_vap; 1704 struct ucred *a_cred; 1705 struct thread *a_td; 1706 }; 1707 */ 1708 static int 1709 fuse_vnop_setattr(struct vop_setattr_args *ap) 1710 { 1711 struct vnode *vp = ap->a_vp; 1712 struct vattr *vap = ap->a_vap; 1713 struct ucred *cred = ap->a_cred; 1714 struct thread *td = curthread; 1715 struct mount *mp; 1716 struct fuse_data *data; 1717 struct vattr old_va; 1718 int dataflags; 1719 int err = 0, err2; 1720 accmode_t accmode = 0; 1721 bool checkperm; 1722 bool drop_suid = false; 1723 gid_t cr_gid; 1724 1725 mp = vnode_mount(vp); 1726 data = fuse_get_mpdata(mp); 1727 dataflags = data->dataflags; 1728 checkperm = dataflags & FSESS_DEFAULT_PERMISSIONS; 1729 if (cred->cr_ngroups > 0) 1730 cr_gid = cred->cr_groups[0]; 1731 else 1732 cr_gid = 0; 1733 1734 if (fuse_isdeadfs(vp)) { 1735 return ENXIO; 1736 } 1737 1738 if (vap->va_uid != (uid_t)VNOVAL) { 1739 if (checkperm) { 1740 /* Only root may change a file's owner */ 1741 err = priv_check_cred(cred, PRIV_VFS_CHOWN); 1742 if (err) { 1743 /* As a special case, allow the null chown */ 1744 err2 = fuse_internal_getattr(vp, &old_va, cred, 1745 td); 1746 if (err2) 1747 return (err2); 1748 if (vap->va_uid != old_va.va_uid) 1749 return err; 1750 else 1751 accmode |= VADMIN; 1752 drop_suid = true; 1753 } else 1754 accmode |= VADMIN; 1755 } else 1756 accmode |= VADMIN; 1757 } 1758 if (vap->va_gid != (gid_t)VNOVAL) { 1759 if (checkperm && priv_check_cred(cred, PRIV_VFS_CHOWN)) 1760 drop_suid = true; 1761 if (checkperm && !groupmember(vap->va_gid, cred)) 1762 { 1763 /* 1764 * Non-root users may only chgrp to one of their own 1765 * groups 1766 */ 1767 err = priv_check_cred(cred, PRIV_VFS_CHOWN); 1768 if (err) { 1769 /* As a special case, allow the null chgrp */ 1770 err2 = fuse_internal_getattr(vp, &old_va, cred, 1771 td); 1772 if (err2) 1773 return (err2); 1774 if (vap->va_gid != old_va.va_gid) 1775 return err; 1776 accmode |= VADMIN; 1777 } else 1778 accmode |= VADMIN; 1779 } else 1780 accmode |= VADMIN; 1781 } 1782 if (vap->va_size != VNOVAL) { 1783 switch (vp->v_type) { 1784 case VDIR: 1785 return (EISDIR); 1786 case VLNK: 1787 case VREG: 1788 if (vfs_isrdonly(mp)) 1789 return (EROFS); 1790 break; 1791 default: 1792 /* 1793 * According to POSIX, the result is unspecified 1794 * for file types other than regular files, 1795 * directories and shared memory objects. We 1796 * don't support shared memory objects in the file 1797 * system, and have dubious support for truncating 1798 * symlinks. Just ignore the request in other cases. 1799 */ 1800 return (0); 1801 } 1802 /* Don't set accmode. Permission to trunc is checked upstack */ 1803 } 1804 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 1805 if (vap->va_vaflags & VA_UTIMES_NULL) 1806 accmode |= VWRITE; 1807 else 1808 accmode |= VADMIN; 1809 } 1810 if (drop_suid) { 1811 if (vap->va_mode != (mode_t)VNOVAL) 1812 vap->va_mode &= ~(S_ISUID | S_ISGID); 1813 else { 1814 err = fuse_internal_getattr(vp, &old_va, cred, td); 1815 if (err) 1816 return (err); 1817 vap->va_mode = old_va.va_mode & ~(S_ISUID | S_ISGID); 1818 } 1819 } 1820 if (vap->va_mode != (mode_t)VNOVAL) { 1821 /* Only root may set the sticky bit on non-directories */ 1822 if (checkperm && vp->v_type != VDIR && (vap->va_mode & S_ISTXT) 1823 && priv_check_cred(cred, PRIV_VFS_STICKYFILE)) 1824 return EFTYPE; 1825 if (checkperm && (vap->va_mode & S_ISGID)) { 1826 err = fuse_internal_getattr(vp, &old_va, cred, td); 1827 if (err) 1828 return (err); 1829 if (!groupmember(old_va.va_gid, cred)) { 1830 err = priv_check_cred(cred, PRIV_VFS_SETGID); 1831 if (err) 1832 return (err); 1833 } 1834 } 1835 accmode |= VADMIN; 1836 } 1837 1838 if (vfs_isrdonly(mp)) 1839 return EROFS; 1840 1841 if (checkperm) { 1842 err = fuse_internal_access(vp, accmode, td, cred); 1843 } else { 1844 err = 0; 1845 } 1846 if (err) 1847 return err; 1848 else 1849 return fuse_internal_setattr(vp, vap, td, cred); 1850 } 1851 1852 /* 1853 struct vnop_strategy_args { 1854 struct vnode *a_vp; 1855 struct buf *a_bp; 1856 }; 1857 */ 1858 static int 1859 fuse_vnop_strategy(struct vop_strategy_args *ap) 1860 { 1861 struct vnode *vp = ap->a_vp; 1862 struct buf *bp = ap->a_bp; 1863 1864 if (!vp || fuse_isdeadfs(vp)) { 1865 bp->b_ioflags |= BIO_ERROR; 1866 bp->b_error = ENXIO; 1867 bufdone(bp); 1868 return 0; 1869 } 1870 1871 /* 1872 * VOP_STRATEGY always returns zero and signals error via bp->b_ioflags. 1873 * fuse_io_strategy sets bp's error fields 1874 */ 1875 (void)fuse_io_strategy(vp, bp); 1876 1877 return 0; 1878 } 1879 1880 1881 /* 1882 struct vnop_symlink_args { 1883 struct vnode *a_dvp; 1884 struct vnode **a_vpp; 1885 struct componentname *a_cnp; 1886 struct vattr *a_vap; 1887 char *a_target; 1888 }; 1889 */ 1890 static int 1891 fuse_vnop_symlink(struct vop_symlink_args *ap) 1892 { 1893 struct vnode *dvp = ap->a_dvp; 1894 struct vnode **vpp = ap->a_vpp; 1895 struct componentname *cnp = ap->a_cnp; 1896 const char *target = ap->a_target; 1897 1898 struct fuse_dispatcher fdi; 1899 1900 int err; 1901 size_t len; 1902 1903 if (fuse_isdeadfs(dvp)) { 1904 return ENXIO; 1905 } 1906 /* 1907 * Unlike the other creator type calls, here we have to create a message 1908 * where the name of the new entry comes first, and the data describing 1909 * the entry comes second. 1910 * Hence we can't rely on our handy fuse_internal_newentry() routine, 1911 * but put together the message manually and just call the core part. 1912 */ 1913 1914 len = strlen(target) + 1; 1915 fdisp_init(&fdi, len + cnp->cn_namelen + 1); 1916 fdisp_make_vp(&fdi, FUSE_SYMLINK, dvp, curthread, NULL); 1917 1918 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 1919 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 1920 memcpy((char *)fdi.indata + cnp->cn_namelen + 1, target, len); 1921 1922 err = fuse_internal_newentry_core(dvp, vpp, cnp, VLNK, &fdi); 1923 fdisp_destroy(&fdi); 1924 return err; 1925 } 1926 1927 /* 1928 struct vnop_write_args { 1929 struct vnode *a_vp; 1930 struct uio *a_uio; 1931 int a_ioflag; 1932 struct ucred *a_cred; 1933 }; 1934 */ 1935 static int 1936 fuse_vnop_write(struct vop_write_args *ap) 1937 { 1938 struct vnode *vp = ap->a_vp; 1939 struct uio *uio = ap->a_uio; 1940 int ioflag = ap->a_ioflag; 1941 struct ucred *cred = ap->a_cred; 1942 pid_t pid = curthread->td_proc->p_pid; 1943 1944 if (fuse_isdeadfs(vp)) { 1945 return ENXIO; 1946 } 1947 1948 if (VTOFUD(vp)->flag & FN_DIRECTIO) { 1949 ioflag |= IO_DIRECT; 1950 } 1951 1952 return fuse_io_dispatch(vp, uio, ioflag, cred, pid); 1953 } 1954 1955 static daddr_t 1956 fuse_gbp_getblkno(struct vnode *vp, vm_ooffset_t off) 1957 { 1958 const int biosize = fuse_iosize(vp); 1959 1960 return (off / biosize); 1961 } 1962 1963 static int 1964 fuse_gbp_getblksz(struct vnode *vp, daddr_t lbn) 1965 { 1966 off_t filesize; 1967 int blksz, err; 1968 const int biosize = fuse_iosize(vp); 1969 1970 err = fuse_vnode_size(vp, &filesize, NULL, NULL); 1971 KASSERT(err == 0, ("vfs_bio_getpages can't handle errors here")); 1972 if (err) 1973 return biosize; 1974 1975 if ((off_t)lbn * biosize >= filesize) { 1976 blksz = 0; 1977 } else if ((off_t)(lbn + 1) * biosize > filesize) { 1978 blksz = filesize - (off_t)lbn *biosize; 1979 } else { 1980 blksz = biosize; 1981 } 1982 return (blksz); 1983 } 1984 1985 /* 1986 struct vnop_getpages_args { 1987 struct vnode *a_vp; 1988 vm_page_t *a_m; 1989 int a_count; 1990 int a_reqpage; 1991 }; 1992 */ 1993 static int 1994 fuse_vnop_getpages(struct vop_getpages_args *ap) 1995 { 1996 struct vnode *vp = ap->a_vp; 1997 1998 if (!fsess_opt_mmap(vnode_mount(vp))) { 1999 SDT_PROBE2(fusefs, , vnops, trace, 1, 2000 "called on non-cacheable vnode??\n"); 2001 return (VM_PAGER_ERROR); 2002 } 2003 2004 return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind, 2005 ap->a_rahead, fuse_gbp_getblkno, fuse_gbp_getblksz)); 2006 } 2007 2008 static const char extattr_namespace_separator = '.'; 2009 2010 /* 2011 struct vop_getextattr_args { 2012 struct vop_generic_args a_gen; 2013 struct vnode *a_vp; 2014 int a_attrnamespace; 2015 const char *a_name; 2016 struct uio *a_uio; 2017 size_t *a_size; 2018 struct ucred *a_cred; 2019 struct thread *a_td; 2020 }; 2021 */ 2022 static int 2023 fuse_vnop_getextattr(struct vop_getextattr_args *ap) 2024 { 2025 struct vnode *vp = ap->a_vp; 2026 struct uio *uio = ap->a_uio; 2027 struct fuse_dispatcher fdi; 2028 struct fuse_getxattr_in *get_xattr_in; 2029 struct fuse_getxattr_out *get_xattr_out; 2030 struct mount *mp = vnode_mount(vp); 2031 struct thread *td = ap->a_td; 2032 struct ucred *cred = ap->a_cred; 2033 char *prefix; 2034 char *attr_str; 2035 size_t len; 2036 int err; 2037 2038 if (fuse_isdeadfs(vp)) 2039 return (ENXIO); 2040 2041 if (!fsess_isimpl(mp, FUSE_GETXATTR)) 2042 return EOPNOTSUPP; 2043 2044 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD); 2045 if (err) 2046 return err; 2047 2048 /* Default to looking for user attributes. */ 2049 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2050 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2051 else 2052 prefix = EXTATTR_NAMESPACE_USER_STRING; 2053 2054 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2055 strlen(ap->a_name) + 1; 2056 2057 fdisp_init(&fdi, len + sizeof(*get_xattr_in)); 2058 fdisp_make_vp(&fdi, FUSE_GETXATTR, vp, td, cred); 2059 2060 get_xattr_in = fdi.indata; 2061 /* 2062 * Check to see whether we're querying the available size or 2063 * issuing the actual request. If we pass in 0, we get back struct 2064 * fuse_getxattr_out. If we pass in a non-zero size, we get back 2065 * that much data, without the struct fuse_getxattr_out header. 2066 */ 2067 if (uio == NULL) 2068 get_xattr_in->size = 0; 2069 else 2070 get_xattr_in->size = uio->uio_resid; 2071 2072 attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); 2073 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2074 ap->a_name); 2075 2076 err = fdisp_wait_answ(&fdi); 2077 if (err != 0) { 2078 if (err == ENOSYS) { 2079 fsess_set_notimpl(mp, FUSE_GETXATTR); 2080 err = EOPNOTSUPP; 2081 } 2082 goto out; 2083 } 2084 2085 get_xattr_out = fdi.answ; 2086 2087 if (ap->a_size != NULL) 2088 *ap->a_size = get_xattr_out->size; 2089 2090 if (uio != NULL) 2091 err = uiomove(fdi.answ, fdi.iosize, uio); 2092 2093 out: 2094 fdisp_destroy(&fdi); 2095 return (err); 2096 } 2097 2098 /* 2099 struct vop_setextattr_args { 2100 struct vop_generic_args a_gen; 2101 struct vnode *a_vp; 2102 int a_attrnamespace; 2103 const char *a_name; 2104 struct uio *a_uio; 2105 struct ucred *a_cred; 2106 struct thread *a_td; 2107 }; 2108 */ 2109 static int 2110 fuse_vnop_setextattr(struct vop_setextattr_args *ap) 2111 { 2112 struct vnode *vp = ap->a_vp; 2113 struct uio *uio = ap->a_uio; 2114 struct fuse_dispatcher fdi; 2115 struct fuse_setxattr_in *set_xattr_in; 2116 struct mount *mp = vnode_mount(vp); 2117 struct thread *td = ap->a_td; 2118 struct ucred *cred = ap->a_cred; 2119 char *prefix; 2120 size_t len; 2121 char *attr_str; 2122 int err; 2123 2124 if (fuse_isdeadfs(vp)) 2125 return (ENXIO); 2126 2127 if (!fsess_isimpl(mp, FUSE_SETXATTR)) 2128 return EOPNOTSUPP; 2129 2130 if (vfs_isrdonly(mp)) 2131 return EROFS; 2132 2133 /* Deleting xattrs must use VOP_DELETEEXTATTR instead */ 2134 if (ap->a_uio == NULL) { 2135 /* 2136 * If we got here as fallback from VOP_DELETEEXTATTR, then 2137 * return EOPNOTSUPP. 2138 */ 2139 if (!fsess_isimpl(mp, FUSE_REMOVEXATTR)) 2140 return (EOPNOTSUPP); 2141 else 2142 return (EINVAL); 2143 } 2144 2145 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, 2146 VWRITE); 2147 if (err) 2148 return err; 2149 2150 /* Default to looking for user attributes. */ 2151 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2152 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2153 else 2154 prefix = EXTATTR_NAMESPACE_USER_STRING; 2155 2156 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2157 strlen(ap->a_name) + 1; 2158 2159 fdisp_init(&fdi, len + sizeof(*set_xattr_in) + uio->uio_resid); 2160 fdisp_make_vp(&fdi, FUSE_SETXATTR, vp, td, cred); 2161 2162 set_xattr_in = fdi.indata; 2163 set_xattr_in->size = uio->uio_resid; 2164 2165 attr_str = (char *)fdi.indata + sizeof(*set_xattr_in); 2166 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2167 ap->a_name); 2168 2169 err = uiomove((char *)fdi.indata + sizeof(*set_xattr_in) + len, 2170 uio->uio_resid, uio); 2171 if (err != 0) { 2172 goto out; 2173 } 2174 2175 err = fdisp_wait_answ(&fdi); 2176 2177 if (err == ENOSYS) { 2178 fsess_set_notimpl(mp, FUSE_SETXATTR); 2179 err = EOPNOTSUPP; 2180 } 2181 if (err == ERESTART) { 2182 /* Can't restart after calling uiomove */ 2183 err = EINTR; 2184 } 2185 2186 out: 2187 fdisp_destroy(&fdi); 2188 return (err); 2189 } 2190 2191 /* 2192 * The Linux / FUSE extended attribute list is simply a collection of 2193 * NUL-terminated strings. The FreeBSD extended attribute list is a single 2194 * byte length followed by a non-NUL terminated string. So, this allows 2195 * conversion of the Linux / FUSE format to the FreeBSD format in place. 2196 * Linux attribute names are reported with the namespace as a prefix (e.g. 2197 * "user.attribute_name"), but in FreeBSD they are reported without the 2198 * namespace prefix (e.g. "attribute_name"). So, we're going from: 2199 * 2200 * user.attr_name1\0user.attr_name2\0 2201 * 2202 * to: 2203 * 2204 * <num>attr_name1<num>attr_name2 2205 * 2206 * Where "<num>" is a single byte number of characters in the attribute name. 2207 * 2208 * Args: 2209 * prefix - exattr namespace prefix string 2210 * list, list_len - input list with namespace prefixes 2211 * bsd_list, bsd_list_len - output list compatible with bsd vfs 2212 */ 2213 static int 2214 fuse_xattrlist_convert(char *prefix, const char *list, int list_len, 2215 char *bsd_list, int *bsd_list_len) 2216 { 2217 int len, pos, dist_to_next, prefix_len; 2218 2219 pos = 0; 2220 *bsd_list_len = 0; 2221 prefix_len = strlen(prefix); 2222 2223 while (pos < list_len && list[pos] != '\0') { 2224 dist_to_next = strlen(&list[pos]) + 1; 2225 if (bcmp(&list[pos], prefix, prefix_len) == 0 && 2226 list[pos + prefix_len] == extattr_namespace_separator) { 2227 len = dist_to_next - 2228 (prefix_len + sizeof(extattr_namespace_separator)) - 1; 2229 if (len >= EXTATTR_MAXNAMELEN) 2230 return (ENAMETOOLONG); 2231 2232 bsd_list[*bsd_list_len] = len; 2233 memcpy(&bsd_list[*bsd_list_len + 1], 2234 &list[pos + prefix_len + 2235 sizeof(extattr_namespace_separator)], len); 2236 2237 *bsd_list_len += len + 1; 2238 } 2239 2240 pos += dist_to_next; 2241 } 2242 2243 return (0); 2244 } 2245 2246 /* 2247 * List extended attributes 2248 * 2249 * The FUSE_LISTXATTR operation is based on Linux's listxattr(2) syscall, which 2250 * has a number of differences compared to its FreeBSD equivalent, 2251 * extattr_list_file: 2252 * 2253 * - FUSE_LISTXATTR returns all extended attributes across all namespaces, 2254 * whereas listxattr(2) only returns attributes for a single namespace 2255 * - FUSE_LISTXATTR prepends each attribute name with "namespace." 2256 * - If the provided buffer is not large enough to hold the result, 2257 * FUSE_LISTXATTR should return ERANGE, whereas listxattr is expected to 2258 * return as many results as will fit. 2259 */ 2260 /* 2261 struct vop_listextattr_args { 2262 struct vop_generic_args a_gen; 2263 struct vnode *a_vp; 2264 int a_attrnamespace; 2265 struct uio *a_uio; 2266 size_t *a_size; 2267 struct ucred *a_cred; 2268 struct thread *a_td; 2269 }; 2270 */ 2271 static int 2272 fuse_vnop_listextattr(struct vop_listextattr_args *ap) 2273 { 2274 struct vnode *vp = ap->a_vp; 2275 struct uio *uio = ap->a_uio; 2276 struct fuse_dispatcher fdi; 2277 struct fuse_listxattr_in *list_xattr_in; 2278 struct fuse_listxattr_out *list_xattr_out; 2279 struct mount *mp = vnode_mount(vp); 2280 struct thread *td = ap->a_td; 2281 struct ucred *cred = ap->a_cred; 2282 char *prefix; 2283 char *bsd_list = NULL; 2284 char *linux_list; 2285 int bsd_list_len; 2286 int linux_list_len; 2287 int err; 2288 2289 if (fuse_isdeadfs(vp)) 2290 return (ENXIO); 2291 2292 if (!fsess_isimpl(mp, FUSE_LISTXATTR)) 2293 return EOPNOTSUPP; 2294 2295 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, VREAD); 2296 if (err) 2297 return err; 2298 2299 /* 2300 * Add space for a NUL and the period separator if enabled. 2301 * Default to looking for user attributes. 2302 */ 2303 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2304 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2305 else 2306 prefix = EXTATTR_NAMESPACE_USER_STRING; 2307 2308 fdisp_init(&fdi, sizeof(*list_xattr_in)); 2309 fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); 2310 2311 /* 2312 * Retrieve Linux / FUSE compatible list size. 2313 */ 2314 list_xattr_in = fdi.indata; 2315 list_xattr_in->size = 0; 2316 2317 err = fdisp_wait_answ(&fdi); 2318 if (err != 0) { 2319 if (err == ENOSYS) { 2320 fsess_set_notimpl(mp, FUSE_LISTXATTR); 2321 err = EOPNOTSUPP; 2322 } 2323 goto out; 2324 } 2325 2326 list_xattr_out = fdi.answ; 2327 linux_list_len = list_xattr_out->size; 2328 if (linux_list_len == 0) { 2329 if (ap->a_size != NULL) 2330 *ap->a_size = linux_list_len; 2331 goto out; 2332 } 2333 2334 /* 2335 * Retrieve Linux / FUSE compatible list values. 2336 */ 2337 fdisp_refresh_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); 2338 list_xattr_in = fdi.indata; 2339 list_xattr_in->size = linux_list_len; 2340 2341 err = fdisp_wait_answ(&fdi); 2342 if (err == ERANGE) { 2343 /* 2344 * Race detected. The attribute list must've grown since the 2345 * first FUSE_LISTXATTR call. Start over. Go all the way back 2346 * to userland so we can process signals, if necessary, before 2347 * restarting. 2348 */ 2349 err = ERESTART; 2350 goto out; 2351 } else if (err != 0) 2352 goto out; 2353 2354 linux_list = fdi.answ; 2355 /* FUSE doesn't allow the server to return more data than requested */ 2356 if (fdi.iosize > linux_list_len) { 2357 printf("WARNING: FUSE protocol violation. Server returned " 2358 "more extended attribute data than requested; " 2359 "should've returned ERANGE instead"); 2360 } else { 2361 /* But returning less data is fine */ 2362 linux_list_len = fdi.iosize; 2363 } 2364 2365 /* 2366 * Retrieve the BSD compatible list values. 2367 * The Linux / FUSE attribute list format isn't the same 2368 * as FreeBSD's format. So we need to transform it into 2369 * FreeBSD's format before giving it to the user. 2370 */ 2371 bsd_list = malloc(linux_list_len, M_TEMP, M_WAITOK); 2372 err = fuse_xattrlist_convert(prefix, linux_list, linux_list_len, 2373 bsd_list, &bsd_list_len); 2374 if (err != 0) 2375 goto out; 2376 2377 if (ap->a_size != NULL) 2378 *ap->a_size = bsd_list_len; 2379 2380 if (uio != NULL) 2381 err = uiomove(bsd_list, bsd_list_len, uio); 2382 2383 out: 2384 free(bsd_list, M_TEMP); 2385 fdisp_destroy(&fdi); 2386 return (err); 2387 } 2388 2389 /* 2390 struct vop_deleteextattr_args { 2391 struct vop_generic_args a_gen; 2392 struct vnode *a_vp; 2393 int a_attrnamespace; 2394 const char *a_name; 2395 struct ucred *a_cred; 2396 struct thread *a_td; 2397 }; 2398 */ 2399 static int 2400 fuse_vnop_deleteextattr(struct vop_deleteextattr_args *ap) 2401 { 2402 struct vnode *vp = ap->a_vp; 2403 struct fuse_dispatcher fdi; 2404 struct mount *mp = vnode_mount(vp); 2405 struct thread *td = ap->a_td; 2406 struct ucred *cred = ap->a_cred; 2407 char *prefix; 2408 size_t len; 2409 char *attr_str; 2410 int err; 2411 2412 if (fuse_isdeadfs(vp)) 2413 return (ENXIO); 2414 2415 if (!fsess_isimpl(mp, FUSE_REMOVEXATTR)) 2416 return EOPNOTSUPP; 2417 2418 if (vfs_isrdonly(mp)) 2419 return EROFS; 2420 2421 err = fuse_extattr_check_cred(vp, ap->a_attrnamespace, cred, td, 2422 VWRITE); 2423 if (err) 2424 return err; 2425 2426 /* Default to looking for user attributes. */ 2427 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2428 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2429 else 2430 prefix = EXTATTR_NAMESPACE_USER_STRING; 2431 2432 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2433 strlen(ap->a_name) + 1; 2434 2435 fdisp_init(&fdi, len); 2436 fdisp_make_vp(&fdi, FUSE_REMOVEXATTR, vp, td, cred); 2437 2438 attr_str = fdi.indata; 2439 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2440 ap->a_name); 2441 2442 err = fdisp_wait_answ(&fdi); 2443 if (err == ENOSYS) { 2444 fsess_set_notimpl(mp, FUSE_REMOVEXATTR); 2445 err = EOPNOTSUPP; 2446 } 2447 2448 fdisp_destroy(&fdi); 2449 return (err); 2450 } 2451 2452 /* 2453 struct vnop_print_args { 2454 struct vnode *a_vp; 2455 }; 2456 */ 2457 static int 2458 fuse_vnop_print(struct vop_print_args *ap) 2459 { 2460 struct fuse_vnode_data *fvdat = VTOFUD(ap->a_vp); 2461 2462 printf("nodeid: %ju, parent nodeid: %ju, nlookup: %ju, flag: %#x\n", 2463 (uintmax_t)VTOILLU(ap->a_vp), (uintmax_t)fvdat->parent_nid, 2464 (uintmax_t)fvdat->nlookup, 2465 fvdat->flag); 2466 2467 return 0; 2468 } 2469 2470 /* 2471 * Get an NFS filehandle for a FUSE file. 2472 * 2473 * This will only work for FUSE file systems that guarantee the uniqueness of 2474 * nodeid:generation, which most don't. 2475 */ 2476 /* 2477 vop_vptofh { 2478 IN struct vnode *a_vp; 2479 IN struct fid *a_fhp; 2480 }; 2481 */ 2482 static int 2483 fuse_vnop_vptofh(struct vop_vptofh_args *ap) 2484 { 2485 struct vnode *vp = ap->a_vp; 2486 struct fuse_vnode_data *fvdat = VTOFUD(vp); 2487 struct fuse_fid *fhp = (struct fuse_fid *)(ap->a_fhp); 2488 _Static_assert(sizeof(struct fuse_fid) <= sizeof(struct fid), 2489 "FUSE fid type is too big"); 2490 struct mount *mp = vnode_mount(vp); 2491 struct fuse_data *data = fuse_get_mpdata(mp); 2492 struct vattr va; 2493 int err; 2494 2495 if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) 2496 return EOPNOTSUPP; 2497 2498 err = fuse_internal_getattr(vp, &va, curthread->td_ucred, curthread); 2499 if (err) 2500 return err; 2501 2502 /*ip = VTOI(ap->a_vp);*/ 2503 /*ufhp = (struct ufid *)ap->a_fhp;*/ 2504 fhp->len = sizeof(struct fuse_fid); 2505 fhp->nid = fvdat->nid; 2506 if (fvdat->generation <= UINT32_MAX) 2507 fhp->gen = fvdat->generation; 2508 else 2509 return EOVERFLOW; 2510 return (0); 2511 } 2512 2513 2514