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 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58 #include <sys/cdefs.h> 59 __FBSDID("$FreeBSD$"); 60 61 #include <sys/types.h> 62 #include <sys/module.h> 63 #include <sys/systm.h> 64 #include <sys/errno.h> 65 #include <sys/param.h> 66 #include <sys/kernel.h> 67 #include <sys/conf.h> 68 #include <sys/uio.h> 69 #include <sys/malloc.h> 70 #include <sys/queue.h> 71 #include <sys/lock.h> 72 #include <sys/rwlock.h> 73 #include <sys/sx.h> 74 #include <sys/proc.h> 75 #include <sys/mount.h> 76 #include <sys/vnode.h> 77 #include <sys/namei.h> 78 #include <sys/extattr.h> 79 #include <sys/stat.h> 80 #include <sys/unistd.h> 81 #include <sys/filedesc.h> 82 #include <sys/file.h> 83 #include <sys/fcntl.h> 84 #include <sys/dirent.h> 85 #include <sys/bio.h> 86 #include <sys/buf.h> 87 #include <sys/sysctl.h> 88 #include <sys/vmmeter.h> 89 90 #include <vm/vm.h> 91 #include <vm/vm_extern.h> 92 #include <vm/pmap.h> 93 #include <vm/vm_map.h> 94 #include <vm/vm_page.h> 95 #include <vm/vm_param.h> 96 #include <vm/vm_object.h> 97 #include <vm/vm_pager.h> 98 #include <vm/vnode_pager.h> 99 #include <vm/vm_object.h> 100 101 #include "fuse.h" 102 #include "fuse_file.h" 103 #include "fuse_internal.h" 104 #include "fuse_ipc.h" 105 #include "fuse_node.h" 106 #include "fuse_param.h" 107 #include "fuse_io.h" 108 109 #include <sys/priv.h> 110 111 #define FUSE_DEBUG_MODULE VNOPS 112 #include "fuse_debug.h" 113 114 /* vnode ops */ 115 static vop_access_t fuse_vnop_access; 116 static vop_close_t fuse_vnop_close; 117 static vop_create_t fuse_vnop_create; 118 static vop_deleteextattr_t fuse_vnop_deleteextattr; 119 static vop_fsync_t fuse_vnop_fsync; 120 static vop_getattr_t fuse_vnop_getattr; 121 static vop_getextattr_t fuse_vnop_getextattr; 122 static vop_inactive_t fuse_vnop_inactive; 123 static vop_link_t fuse_vnop_link; 124 static vop_listextattr_t fuse_vnop_listextattr; 125 static vop_lookup_t fuse_vnop_lookup; 126 static vop_mkdir_t fuse_vnop_mkdir; 127 static vop_mknod_t fuse_vnop_mknod; 128 static vop_open_t fuse_vnop_open; 129 static vop_read_t fuse_vnop_read; 130 static vop_readdir_t fuse_vnop_readdir; 131 static vop_readlink_t fuse_vnop_readlink; 132 static vop_reclaim_t fuse_vnop_reclaim; 133 static vop_remove_t fuse_vnop_remove; 134 static vop_rename_t fuse_vnop_rename; 135 static vop_rmdir_t fuse_vnop_rmdir; 136 static vop_setattr_t fuse_vnop_setattr; 137 static vop_setextattr_t fuse_vnop_setextattr; 138 static vop_strategy_t fuse_vnop_strategy; 139 static vop_symlink_t fuse_vnop_symlink; 140 static vop_write_t fuse_vnop_write; 141 static vop_getpages_t fuse_vnop_getpages; 142 static vop_putpages_t fuse_vnop_putpages; 143 static vop_print_t fuse_vnop_print; 144 145 struct vop_vector fuse_vnops = { 146 .vop_default = &default_vnodeops, 147 .vop_access = fuse_vnop_access, 148 .vop_close = fuse_vnop_close, 149 .vop_create = fuse_vnop_create, 150 .vop_deleteextattr = fuse_vnop_deleteextattr, 151 .vop_fsync = fuse_vnop_fsync, 152 .vop_getattr = fuse_vnop_getattr, 153 .vop_getextattr = fuse_vnop_getextattr, 154 .vop_inactive = fuse_vnop_inactive, 155 .vop_link = fuse_vnop_link, 156 .vop_listextattr = fuse_vnop_listextattr, 157 .vop_lookup = fuse_vnop_lookup, 158 .vop_mkdir = fuse_vnop_mkdir, 159 .vop_mknod = fuse_vnop_mknod, 160 .vop_open = fuse_vnop_open, 161 .vop_pathconf = vop_stdpathconf, 162 .vop_read = fuse_vnop_read, 163 .vop_readdir = fuse_vnop_readdir, 164 .vop_readlink = fuse_vnop_readlink, 165 .vop_reclaim = fuse_vnop_reclaim, 166 .vop_remove = fuse_vnop_remove, 167 .vop_rename = fuse_vnop_rename, 168 .vop_rmdir = fuse_vnop_rmdir, 169 .vop_setattr = fuse_vnop_setattr, 170 .vop_setextattr = fuse_vnop_setextattr, 171 .vop_strategy = fuse_vnop_strategy, 172 .vop_symlink = fuse_vnop_symlink, 173 .vop_write = fuse_vnop_write, 174 .vop_getpages = fuse_vnop_getpages, 175 .vop_putpages = fuse_vnop_putpages, 176 .vop_print = fuse_vnop_print, 177 }; 178 179 static u_long fuse_lookup_cache_hits = 0; 180 181 SYSCTL_ULONG(_vfs_fuse, OID_AUTO, lookup_cache_hits, CTLFLAG_RD, 182 &fuse_lookup_cache_hits, 0, ""); 183 184 static u_long fuse_lookup_cache_misses = 0; 185 186 SYSCTL_ULONG(_vfs_fuse, OID_AUTO, lookup_cache_misses, CTLFLAG_RD, 187 &fuse_lookup_cache_misses, 0, ""); 188 189 int fuse_lookup_cache_enable = 1; 190 191 SYSCTL_INT(_vfs_fuse, OID_AUTO, lookup_cache_enable, CTLFLAG_RW, 192 &fuse_lookup_cache_enable, 0, ""); 193 194 /* 195 * XXX: This feature is highly experimental and can bring to instabilities, 196 * needs revisiting before to be enabled by default. 197 */ 198 static int fuse_reclaim_revoked = 0; 199 200 SYSCTL_INT(_vfs_fuse, OID_AUTO, reclaim_revoked, CTLFLAG_RW, 201 &fuse_reclaim_revoked, 0, ""); 202 203 int fuse_pbuf_freecnt = -1; 204 205 #define fuse_vm_page_lock(m) vm_page_lock((m)); 206 #define fuse_vm_page_unlock(m) vm_page_unlock((m)); 207 #define fuse_vm_page_lock_queues() ((void)0) 208 #define fuse_vm_page_unlock_queues() ((void)0) 209 210 /* 211 struct vnop_access_args { 212 struct vnode *a_vp; 213 #if VOP_ACCESS_TAKES_ACCMODE_T 214 accmode_t a_accmode; 215 #else 216 int a_mode; 217 #endif 218 struct ucred *a_cred; 219 struct thread *a_td; 220 }; 221 */ 222 static int 223 fuse_vnop_access(struct vop_access_args *ap) 224 { 225 struct vnode *vp = ap->a_vp; 226 int accmode = ap->a_accmode; 227 struct ucred *cred = ap->a_cred; 228 229 struct fuse_access_param facp; 230 struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp)); 231 232 int err; 233 234 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 235 236 if (fuse_isdeadfs(vp)) { 237 if (vnode_isvroot(vp)) { 238 return 0; 239 } 240 return ENXIO; 241 } 242 if (!(data->dataflags & FSESS_INITED)) { 243 if (vnode_isvroot(vp)) { 244 if (priv_check_cred(cred, PRIV_VFS_ADMIN, 0) || 245 (fuse_match_cred(data->daemoncred, cred) == 0)) { 246 return 0; 247 } 248 } 249 return EBADF; 250 } 251 if (vnode_islnk(vp)) { 252 return 0; 253 } 254 bzero(&facp, sizeof(facp)); 255 256 err = fuse_internal_access(vp, accmode, &facp, ap->a_td, ap->a_cred); 257 FS_DEBUG2G("err=%d accmode=0x%x\n", err, accmode); 258 return err; 259 } 260 261 /* 262 struct vnop_close_args { 263 struct vnode *a_vp; 264 int a_fflag; 265 struct ucred *a_cred; 266 struct thread *a_td; 267 }; 268 */ 269 static int 270 fuse_vnop_close(struct vop_close_args *ap) 271 { 272 struct vnode *vp = ap->a_vp; 273 struct ucred *cred = ap->a_cred; 274 int fflag = ap->a_fflag; 275 fufh_type_t fufh_type; 276 277 fuse_trace_printf_vnop(); 278 279 if (fuse_isdeadfs(vp)) { 280 return 0; 281 } 282 if (vnode_isdir(vp)) { 283 if (fuse_filehandle_valid(vp, FUFH_RDONLY)) { 284 fuse_filehandle_close(vp, FUFH_RDONLY, NULL, cred); 285 } 286 return 0; 287 } 288 if (fflag & IO_NDELAY) { 289 return 0; 290 } 291 fufh_type = fuse_filehandle_xlate_from_fflags(fflag); 292 293 if (!fuse_filehandle_valid(vp, fufh_type)) { 294 int i; 295 296 for (i = 0; i < FUFH_MAXTYPE; i++) 297 if (fuse_filehandle_valid(vp, i)) 298 break; 299 if (i == FUFH_MAXTYPE) 300 panic("FUSE: fufh type %d found to be invalid in close" 301 " (fflag=0x%x)\n", 302 fufh_type, fflag); 303 } 304 if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) { 305 fuse_vnode_savesize(vp, cred); 306 } 307 return 0; 308 } 309 310 /* 311 struct vnop_create_args { 312 struct vnode *a_dvp; 313 struct vnode **a_vpp; 314 struct componentname *a_cnp; 315 struct vattr *a_vap; 316 }; 317 */ 318 static int 319 fuse_vnop_create(struct vop_create_args *ap) 320 { 321 struct vnode *dvp = ap->a_dvp; 322 struct vnode **vpp = ap->a_vpp; 323 struct componentname *cnp = ap->a_cnp; 324 struct vattr *vap = ap->a_vap; 325 struct thread *td = cnp->cn_thread; 326 struct ucred *cred = cnp->cn_cred; 327 328 struct fuse_open_in *foi; 329 struct fuse_entry_out *feo; 330 struct fuse_dispatcher fdi; 331 struct fuse_dispatcher *fdip = &fdi; 332 333 int err; 334 335 struct mount *mp = vnode_mount(dvp); 336 uint64_t parentnid = VTOFUD(dvp)->nid; 337 mode_t mode = MAKEIMODE(vap->va_type, vap->va_mode); 338 uint64_t x_fh_id; 339 uint32_t x_open_flags; 340 341 fuse_trace_printf_vnop(); 342 343 if (fuse_isdeadfs(dvp)) { 344 return ENXIO; 345 } 346 bzero(&fdi, sizeof(fdi)); 347 348 /* XXX: Will we ever want devices ? */ 349 if ((vap->va_type != VREG)) { 350 printf("fuse_vnop_create: unsupported va_type %d\n", 351 vap->va_type); 352 return (EINVAL); 353 } 354 debug_printf("parent nid = %ju, mode = %x\n", (uintmax_t)parentnid, 355 mode); 356 357 fdisp_init(fdip, sizeof(*foi) + cnp->cn_namelen + 1); 358 if (!fsess_isimpl(mp, FUSE_CREATE)) { 359 debug_printf("eh, daemon doesn't implement create?\n"); 360 return (EINVAL); 361 } 362 fdisp_make(fdip, FUSE_CREATE, vnode_mount(dvp), parentnid, td, cred); 363 364 foi = fdip->indata; 365 foi->mode = mode; 366 foi->flags = O_CREAT | O_RDWR; 367 368 memcpy((char *)fdip->indata + sizeof(*foi), cnp->cn_nameptr, 369 cnp->cn_namelen); 370 ((char *)fdip->indata)[sizeof(*foi) + cnp->cn_namelen] = '\0'; 371 372 err = fdisp_wait_answ(fdip); 373 374 if (err) { 375 if (err == ENOSYS) 376 fsess_set_notimpl(mp, FUSE_CREATE); 377 debug_printf("create: got err=%d from daemon\n", err); 378 goto out; 379 } 380 381 feo = fdip->answ; 382 383 if ((err = fuse_internal_checkentry(feo, VREG))) { 384 goto out; 385 } 386 err = fuse_vnode_get(mp, feo->nodeid, dvp, vpp, cnp, VREG); 387 if (err) { 388 struct fuse_release_in *fri; 389 uint64_t nodeid = feo->nodeid; 390 uint64_t fh_id = ((struct fuse_open_out *)(feo + 1))->fh; 391 392 fdisp_init(fdip, sizeof(*fri)); 393 fdisp_make(fdip, FUSE_RELEASE, mp, nodeid, td, cred); 394 fri = fdip->indata; 395 fri->fh = fh_id; 396 fri->flags = OFLAGS(mode); 397 fuse_insert_callback(fdip->tick, fuse_internal_forget_callback); 398 fuse_insert_message(fdip->tick); 399 return err; 400 } 401 ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create"); 402 403 fdip->answ = feo + 1; 404 405 x_fh_id = ((struct fuse_open_out *)(feo + 1))->fh; 406 x_open_flags = ((struct fuse_open_out *)(feo + 1))->open_flags; 407 fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, x_fh_id); 408 fuse_vnode_open(*vpp, x_open_flags, td); 409 cache_purge_negative(dvp); 410 411 out: 412 fdisp_destroy(fdip); 413 return err; 414 } 415 416 /* 417 * Our vnop_fsync roughly corresponds to the FUSE_FSYNC method. The Linux 418 * version of FUSE also has a FUSE_FLUSH method. 419 * 420 * On Linux, fsync() synchronizes a file's complete in-core state with that 421 * on disk. The call is not supposed to return until the system has completed 422 * that action or until an error is detected. 423 * 424 * Linux also has an fdatasync() call that is similar to fsync() but is not 425 * required to update the metadata such as access time and modification time. 426 */ 427 428 /* 429 struct vnop_fsync_args { 430 struct vnodeop_desc *a_desc; 431 struct vnode * a_vp; 432 struct ucred * a_cred; 433 int a_waitfor; 434 struct thread * a_td; 435 }; 436 */ 437 static int 438 fuse_vnop_fsync(struct vop_fsync_args *ap) 439 { 440 struct vnode *vp = ap->a_vp; 441 struct thread *td = ap->a_td; 442 443 struct fuse_filehandle *fufh; 444 struct fuse_vnode_data *fvdat = VTOFUD(vp); 445 446 int type, err = 0; 447 448 fuse_trace_printf_vnop(); 449 450 if (fuse_isdeadfs(vp)) { 451 return 0; 452 } 453 if ((err = vop_stdfsync(ap))) 454 return err; 455 456 if (!fsess_isimpl(vnode_mount(vp), 457 (vnode_vtype(vp) == VDIR ? FUSE_FSYNCDIR : FUSE_FSYNC))) { 458 goto out; 459 } 460 for (type = 0; type < FUFH_MAXTYPE; type++) { 461 fufh = &(fvdat->fufh[type]); 462 if (FUFH_IS_VALID(fufh)) { 463 fuse_internal_fsync(vp, td, NULL, fufh); 464 } 465 } 466 467 out: 468 return 0; 469 } 470 471 /* 472 struct vnop_getattr_args { 473 struct vnode *a_vp; 474 struct vattr *a_vap; 475 struct ucred *a_cred; 476 struct thread *a_td; 477 }; 478 */ 479 static int 480 fuse_vnop_getattr(struct vop_getattr_args *ap) 481 { 482 struct vnode *vp = ap->a_vp; 483 struct vattr *vap = ap->a_vap; 484 struct ucred *cred = ap->a_cred; 485 struct thread *td = curthread; 486 struct fuse_vnode_data *fvdat = VTOFUD(vp); 487 488 int err = 0; 489 int dataflags; 490 struct fuse_dispatcher fdi; 491 492 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 493 494 dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; 495 496 /* Note that we are not bailing out on a dead file system just yet. */ 497 498 if (!(dataflags & FSESS_INITED)) { 499 if (!vnode_isvroot(vp)) { 500 fdata_set_dead(fuse_get_mpdata(vnode_mount(vp))); 501 err = ENOTCONN; 502 debug_printf("fuse_getattr b: returning ENOTCONN\n"); 503 return err; 504 } else { 505 goto fake; 506 } 507 } 508 fdisp_init(&fdi, 0); 509 if ((err = fdisp_simple_putget_vp(&fdi, FUSE_GETATTR, vp, td, cred))) { 510 if ((err == ENOTCONN) && vnode_isvroot(vp)) { 511 /* see comment at similar place in fuse_statfs() */ 512 fdisp_destroy(&fdi); 513 goto fake; 514 } 515 if (err == ENOENT) { 516 fuse_internal_vnode_disappear(vp); 517 } 518 goto out; 519 } 520 cache_attrs(vp, (struct fuse_attr_out *)fdi.answ); 521 if (vap != VTOVA(vp)) { 522 memcpy(vap, VTOVA(vp), sizeof(*vap)); 523 } 524 if (vap->va_type != vnode_vtype(vp)) { 525 fuse_internal_vnode_disappear(vp); 526 err = ENOENT; 527 goto out; 528 } 529 if ((fvdat->flag & FN_SIZECHANGE) != 0) 530 vap->va_size = fvdat->filesize; 531 532 if (vnode_isreg(vp) && (fvdat->flag & FN_SIZECHANGE) == 0) { 533 /* 534 * This is for those cases when the file size changed without us 535 * knowing, and we want to catch up. 536 */ 537 off_t new_filesize = ((struct fuse_attr_out *) 538 fdi.answ)->attr.size; 539 540 if (fvdat->filesize != new_filesize) { 541 fuse_vnode_setsize(vp, cred, new_filesize); 542 } 543 } 544 debug_printf("fuse_getattr e: returning 0\n"); 545 546 out: 547 fdisp_destroy(&fdi); 548 return err; 549 550 fake: 551 bzero(vap, sizeof(*vap)); 552 vap->va_type = vnode_vtype(vp); 553 554 return 0; 555 } 556 557 /* 558 struct vnop_inactive_args { 559 struct vnode *a_vp; 560 struct thread *a_td; 561 }; 562 */ 563 static int 564 fuse_vnop_inactive(struct vop_inactive_args *ap) 565 { 566 struct vnode *vp = ap->a_vp; 567 struct thread *td = ap->a_td; 568 569 struct fuse_vnode_data *fvdat = VTOFUD(vp); 570 struct fuse_filehandle *fufh = NULL; 571 572 int type, need_flush = 1; 573 574 FS_DEBUG("inode=%ju\n", (uintmax_t)VTOI(vp)); 575 576 for (type = 0; type < FUFH_MAXTYPE; type++) { 577 fufh = &(fvdat->fufh[type]); 578 if (FUFH_IS_VALID(fufh)) { 579 if (need_flush && vp->v_type == VREG) { 580 if ((VTOFUD(vp)->flag & FN_SIZECHANGE) != 0) { 581 fuse_vnode_savesize(vp, NULL); 582 } 583 if (fuse_data_cache_invalidate || 584 (fvdat->flag & FN_REVOKED) != 0) 585 fuse_io_invalbuf(vp, td); 586 else 587 fuse_io_flushbuf(vp, MNT_WAIT, td); 588 need_flush = 0; 589 } 590 fuse_filehandle_close(vp, type, td, NULL); 591 } 592 } 593 594 if ((fvdat->flag & FN_REVOKED) != 0 && fuse_reclaim_revoked) { 595 vrecycle(vp); 596 } 597 return 0; 598 } 599 600 /* 601 struct vnop_link_args { 602 struct vnode *a_tdvp; 603 struct vnode *a_vp; 604 struct componentname *a_cnp; 605 }; 606 */ 607 static int 608 fuse_vnop_link(struct vop_link_args *ap) 609 { 610 struct vnode *vp = ap->a_vp; 611 struct vnode *tdvp = ap->a_tdvp; 612 struct componentname *cnp = ap->a_cnp; 613 614 struct vattr *vap = VTOVA(vp); 615 616 struct fuse_dispatcher fdi; 617 struct fuse_entry_out *feo; 618 struct fuse_link_in fli; 619 620 int err; 621 622 fuse_trace_printf_vnop(); 623 624 if (fuse_isdeadfs(vp)) { 625 return ENXIO; 626 } 627 if (vnode_mount(tdvp) != vnode_mount(vp)) { 628 return EXDEV; 629 } 630 if (vap->va_nlink >= FUSE_LINK_MAX) { 631 return EMLINK; 632 } 633 fli.oldnodeid = VTOI(vp); 634 635 fdisp_init(&fdi, 0); 636 fuse_internal_newentry_makerequest(vnode_mount(tdvp), VTOI(tdvp), cnp, 637 FUSE_LINK, &fli, sizeof(fli), &fdi); 638 if ((err = fdisp_wait_answ(&fdi))) { 639 goto out; 640 } 641 feo = fdi.answ; 642 643 err = fuse_internal_checkentry(feo, vnode_vtype(vp)); 644 out: 645 fdisp_destroy(&fdi); 646 return err; 647 } 648 649 /* 650 struct vnop_lookup_args { 651 struct vnodeop_desc *a_desc; 652 struct vnode *a_dvp; 653 struct vnode **a_vpp; 654 struct componentname *a_cnp; 655 }; 656 */ 657 int 658 fuse_vnop_lookup(struct vop_lookup_args *ap) 659 { 660 struct vnode *dvp = ap->a_dvp; 661 struct vnode **vpp = ap->a_vpp; 662 struct componentname *cnp = ap->a_cnp; 663 struct thread *td = cnp->cn_thread; 664 struct ucred *cred = cnp->cn_cred; 665 666 int nameiop = cnp->cn_nameiop; 667 int flags = cnp->cn_flags; 668 int wantparent = flags & (LOCKPARENT | WANTPARENT); 669 int islastcn = flags & ISLASTCN; 670 struct mount *mp = vnode_mount(dvp); 671 672 int err = 0; 673 int lookup_err = 0; 674 struct vnode *vp = NULL; 675 676 struct fuse_dispatcher fdi; 677 enum fuse_opcode op; 678 679 uint64_t nid; 680 struct fuse_access_param facp; 681 682 FS_DEBUG2G("parent_inode=%ju - %*s\n", 683 (uintmax_t)VTOI(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); 684 685 if (fuse_isdeadfs(dvp)) { 686 *vpp = NULL; 687 return ENXIO; 688 } 689 if (!vnode_isdir(dvp)) { 690 return ENOTDIR; 691 } 692 if (islastcn && vfs_isrdonly(mp) && (nameiop != LOOKUP)) { 693 return EROFS; 694 } 695 /* 696 * We do access check prior to doing anything else only in the case 697 * when we are at fs root (we'd like to say, "we are at the first 698 * component", but that's not exactly the same... nevermind). 699 * See further comments at further access checks. 700 */ 701 702 bzero(&facp, sizeof(facp)); 703 if (vnode_isvroot(dvp)) { /* early permission check hack */ 704 if ((err = fuse_internal_access(dvp, VEXEC, &facp, td, cred))) { 705 return err; 706 } 707 } 708 if (flags & ISDOTDOT) { 709 nid = VTOFUD(dvp)->parent_nid; 710 if (nid == 0) { 711 return ENOENT; 712 } 713 fdisp_init(&fdi, 0); 714 op = FUSE_GETATTR; 715 goto calldaemon; 716 } else if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') { 717 nid = VTOI(dvp); 718 fdisp_init(&fdi, 0); 719 op = FUSE_GETATTR; 720 goto calldaemon; 721 } else if (fuse_lookup_cache_enable) { 722 err = cache_lookup(dvp, vpp, cnp, NULL, NULL); 723 switch (err) { 724 725 case -1: /* positive match */ 726 atomic_add_acq_long(&fuse_lookup_cache_hits, 1); 727 return 0; 728 729 case 0: /* no match in cache */ 730 atomic_add_acq_long(&fuse_lookup_cache_misses, 1); 731 break; 732 733 case ENOENT: /* negative match */ 734 /* fall through */ 735 default: 736 return err; 737 } 738 } 739 nid = VTOI(dvp); 740 fdisp_init(&fdi, cnp->cn_namelen + 1); 741 op = FUSE_LOOKUP; 742 743 calldaemon: 744 fdisp_make(&fdi, op, mp, nid, td, cred); 745 746 if (op == FUSE_LOOKUP) { 747 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 748 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 749 } 750 lookup_err = fdisp_wait_answ(&fdi); 751 752 if ((op == FUSE_LOOKUP) && !lookup_err) { /* lookup call succeeded */ 753 nid = ((struct fuse_entry_out *)fdi.answ)->nodeid; 754 if (!nid) { 755 /* 756 * zero nodeid is the same as "not found", 757 * but it's also cacheable (which we keep 758 * keep on doing not as of writing this) 759 */ 760 lookup_err = ENOENT; 761 } else if (nid == FUSE_ROOT_ID) { 762 lookup_err = EINVAL; 763 } 764 } 765 if (lookup_err && 766 (!fdi.answ_stat || lookup_err != ENOENT || op != FUSE_LOOKUP)) { 767 fdisp_destroy(&fdi); 768 return lookup_err; 769 } 770 /* lookup_err, if non-zero, must be ENOENT at this point */ 771 772 if (lookup_err) { 773 774 if ((nameiop == CREATE || nameiop == RENAME) && islastcn 775 /* && directory dvp has not been removed */ ) { 776 777 if (vfs_isrdonly(mp)) { 778 err = EROFS; 779 goto out; 780 } 781 #if 0 /* THINK_ABOUT_THIS */ 782 if ((err = fuse_internal_access(dvp, VWRITE, cred, td, &facp))) { 783 goto out; 784 } 785 #endif 786 787 /* 788 * Possibly record the position of a slot in the 789 * directory large enough for the new component name. 790 * This can be recorded in the vnode private data for 791 * dvp. Set the SAVENAME flag to hold onto the 792 * pathname for use later in VOP_CREATE or VOP_RENAME. 793 */ 794 cnp->cn_flags |= SAVENAME; 795 796 err = EJUSTRETURN; 797 goto out; 798 } 799 /* Consider inserting name into cache. */ 800 801 /* 802 * No we can't use negative caching, as the fs 803 * changes are out of our control. 804 * False positives' falseness turns out just as things 805 * go by, but false negatives' falseness doesn't. 806 * (and aiding the caching mechanism with extra control 807 * mechanisms comes quite close to beating the whole purpose 808 * caching...) 809 */ 810 #if 0 811 if ((cnp->cn_flags & MAKEENTRY) != 0) { 812 FS_DEBUG("inserting NULL into cache\n"); 813 cache_enter(dvp, NULL, cnp); 814 } 815 #endif 816 err = ENOENT; 817 goto out; 818 819 } else { 820 821 /* !lookup_err */ 822 823 struct fuse_entry_out *feo = NULL; 824 struct fuse_attr *fattr = NULL; 825 826 if (op == FUSE_GETATTR) { 827 fattr = &((struct fuse_attr_out *)fdi.answ)->attr; 828 } else { 829 feo = (struct fuse_entry_out *)fdi.answ; 830 fattr = &(feo->attr); 831 } 832 833 /* 834 * If deleting, and at end of pathname, return parameters 835 * which can be used to remove file. If the wantparent flag 836 * isn't set, we return only the directory, otherwise we go on 837 * and lock the inode, being careful with ".". 838 */ 839 if (nameiop == DELETE && islastcn) { 840 /* 841 * Check for write access on directory. 842 */ 843 facp.xuid = fattr->uid; 844 facp.facc_flags |= FACCESS_STICKY; 845 err = fuse_internal_access(dvp, VWRITE, &facp, td, cred); 846 facp.facc_flags &= ~FACCESS_XQUERIES; 847 848 if (err) { 849 goto out; 850 } 851 if (nid == VTOI(dvp)) { 852 vref(dvp); 853 *vpp = dvp; 854 } else { 855 err = fuse_vnode_get(dvp->v_mount, nid, dvp, 856 &vp, cnp, IFTOVT(fattr->mode)); 857 if (err) 858 goto out; 859 *vpp = vp; 860 } 861 862 /* 863 * Save the name for use in VOP_RMDIR and VOP_REMOVE 864 * later. 865 */ 866 cnp->cn_flags |= SAVENAME; 867 goto out; 868 869 } 870 /* 871 * If rewriting (RENAME), return the inode and the 872 * information required to rewrite the present directory 873 * Must get inode of directory entry to verify it's a 874 * regular file, or empty directory. 875 */ 876 if (nameiop == RENAME && wantparent && islastcn) { 877 878 #if 0 /* THINK_ABOUT_THIS */ 879 if ((err = fuse_internal_access(dvp, VWRITE, cred, td, &facp))) { 880 goto out; 881 } 882 #endif 883 884 /* 885 * Check for "." 886 */ 887 if (nid == VTOI(dvp)) { 888 err = EISDIR; 889 goto out; 890 } 891 err = fuse_vnode_get(vnode_mount(dvp), 892 nid, 893 dvp, 894 &vp, 895 cnp, 896 IFTOVT(fattr->mode)); 897 if (err) { 898 goto out; 899 } 900 *vpp = vp; 901 /* 902 * Save the name for use in VOP_RENAME later. 903 */ 904 cnp->cn_flags |= SAVENAME; 905 906 goto out; 907 } 908 if (flags & ISDOTDOT) { 909 struct mount *mp; 910 int ltype; 911 912 /* 913 * Expanded copy of vn_vget_ino() so that 914 * fuse_vnode_get() can be used. 915 */ 916 mp = dvp->v_mount; 917 ltype = VOP_ISLOCKED(dvp); 918 err = vfs_busy(mp, MBF_NOWAIT); 919 if (err != 0) { 920 vfs_ref(mp); 921 VOP_UNLOCK(dvp, 0); 922 err = vfs_busy(mp, 0); 923 vn_lock(dvp, ltype | LK_RETRY); 924 vfs_rel(mp); 925 if (err) 926 goto out; 927 if ((dvp->v_iflag & VI_DOOMED) != 0) { 928 err = ENOENT; 929 vfs_unbusy(mp); 930 goto out; 931 } 932 } 933 VOP_UNLOCK(dvp, 0); 934 err = fuse_vnode_get(vnode_mount(dvp), 935 nid, 936 NULL, 937 &vp, 938 cnp, 939 IFTOVT(fattr->mode)); 940 vfs_unbusy(mp); 941 vn_lock(dvp, ltype | LK_RETRY); 942 if ((dvp->v_iflag & VI_DOOMED) != 0) { 943 if (err == 0) 944 vput(vp); 945 err = ENOENT; 946 } 947 if (err) 948 goto out; 949 *vpp = vp; 950 } else if (nid == VTOI(dvp)) { 951 vref(dvp); 952 *vpp = dvp; 953 } else { 954 err = fuse_vnode_get(vnode_mount(dvp), 955 nid, 956 dvp, 957 &vp, 958 cnp, 959 IFTOVT(fattr->mode)); 960 if (err) { 961 goto out; 962 } 963 fuse_vnode_setparent(vp, dvp); 964 *vpp = vp; 965 } 966 967 if (op == FUSE_GETATTR) { 968 cache_attrs(*vpp, (struct fuse_attr_out *)fdi.answ); 969 } else { 970 cache_attrs(*vpp, (struct fuse_entry_out *)fdi.answ); 971 } 972 973 /* Insert name into cache if appropriate. */ 974 975 /* 976 * Nooo, caching is evil. With caching, we can't avoid stale 977 * information taking over the playground (cached info is not 978 * just positive/negative, it does have qualitative aspects, 979 * too). And a (VOP/FUSE)_GETATTR is always thrown anyway, when 980 * walking down along cached path components, and that's not 981 * any cheaper than FUSE_LOOKUP. This might change with 982 * implementing kernel side attr caching, but... In Linux, 983 * lookup results are not cached, and the daemon is bombarded 984 * with FUSE_LOOKUPS on and on. This shows that by design, the 985 * daemon is expected to handle frequent lookup queries 986 * efficiently, do its caching in userspace, and so on. 987 * 988 * So just leave the name cache alone. 989 */ 990 991 /* 992 * Well, now I know, Linux caches lookups, but with a 993 * timeout... So it's the same thing as attribute caching: 994 * we can deal with it when implement timeouts. 995 */ 996 #if 0 997 if (cnp->cn_flags & MAKEENTRY) { 998 cache_enter(dvp, *vpp, cnp); 999 } 1000 #endif 1001 } 1002 out: 1003 if (!lookup_err) { 1004 1005 /* No lookup error; need to clean up. */ 1006 1007 if (err) { /* Found inode; exit with no vnode. */ 1008 if (op == FUSE_LOOKUP) { 1009 fuse_internal_forget_send(vnode_mount(dvp), td, cred, 1010 nid, 1); 1011 } 1012 fdisp_destroy(&fdi); 1013 return err; 1014 } else { 1015 #ifndef NO_EARLY_PERM_CHECK_HACK 1016 if (!islastcn) { 1017 /* 1018 * We have the attributes of the next item 1019 * *now*, and it's a fact, and we do not 1020 * have to do extra work for it (ie, beg the 1021 * daemon), and it neither depends on such 1022 * accidental things like attr caching. So 1023 * the big idea: check credentials *now*, 1024 * not at the beginning of the next call to 1025 * lookup. 1026 * 1027 * The first item of the lookup chain (fs root) 1028 * won't be checked then here, of course, as 1029 * its never "the next". But go and see that 1030 * the root is taken care about at the very 1031 * beginning of this function. 1032 * 1033 * Now, given we want to do the access check 1034 * this way, one might ask: so then why not 1035 * do the access check just after fetching 1036 * the inode and its attributes from the 1037 * daemon? Why bother with producing the 1038 * corresponding vnode at all if something 1039 * is not OK? We know what's the deal as 1040 * soon as we get those attrs... There is 1041 * one bit of info though not given us by 1042 * the daemon: whether his response is 1043 * authoritative or not... His response should 1044 * be ignored if something is mounted over 1045 * the dir in question. But that can be 1046 * known only by having the vnode... 1047 */ 1048 int tmpvtype = vnode_vtype(*vpp); 1049 1050 bzero(&facp, sizeof(facp)); 1051 /*the early perm check hack */ 1052 facp.facc_flags |= FACCESS_VA_VALID; 1053 1054 if ((tmpvtype != VDIR) && (tmpvtype != VLNK)) { 1055 err = ENOTDIR; 1056 } 1057 if (!err && !vnode_mountedhere(*vpp)) { 1058 err = fuse_internal_access(*vpp, VEXEC, &facp, td, cred); 1059 } 1060 if (err) { 1061 if (tmpvtype == VLNK) 1062 FS_DEBUG("weird, permission error with a symlink?\n"); 1063 vput(*vpp); 1064 *vpp = NULL; 1065 } 1066 } 1067 #endif 1068 } 1069 } 1070 fdisp_destroy(&fdi); 1071 1072 return err; 1073 } 1074 1075 /* 1076 struct vnop_mkdir_args { 1077 struct vnode *a_dvp; 1078 struct vnode **a_vpp; 1079 struct componentname *a_cnp; 1080 struct vattr *a_vap; 1081 }; 1082 */ 1083 static int 1084 fuse_vnop_mkdir(struct vop_mkdir_args *ap) 1085 { 1086 struct vnode *dvp = ap->a_dvp; 1087 struct vnode **vpp = ap->a_vpp; 1088 struct componentname *cnp = ap->a_cnp; 1089 struct vattr *vap = ap->a_vap; 1090 1091 struct fuse_mkdir_in fmdi; 1092 1093 fuse_trace_printf_vnop(); 1094 1095 if (fuse_isdeadfs(dvp)) { 1096 return ENXIO; 1097 } 1098 fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode); 1099 1100 return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi, 1101 sizeof(fmdi), VDIR)); 1102 } 1103 1104 /* 1105 struct vnop_mknod_args { 1106 struct vnode *a_dvp; 1107 struct vnode **a_vpp; 1108 struct componentname *a_cnp; 1109 struct vattr *a_vap; 1110 }; 1111 */ 1112 static int 1113 fuse_vnop_mknod(struct vop_mknod_args *ap) 1114 { 1115 1116 return (EINVAL); 1117 } 1118 1119 1120 /* 1121 struct vnop_open_args { 1122 struct vnode *a_vp; 1123 int a_mode; 1124 struct ucred *a_cred; 1125 struct thread *a_td; 1126 int a_fdidx; / struct file *a_fp; 1127 }; 1128 */ 1129 static int 1130 fuse_vnop_open(struct vop_open_args *ap) 1131 { 1132 struct vnode *vp = ap->a_vp; 1133 int mode = ap->a_mode; 1134 struct thread *td = ap->a_td; 1135 struct ucred *cred = ap->a_cred; 1136 1137 fufh_type_t fufh_type; 1138 struct fuse_vnode_data *fvdat; 1139 1140 int error, isdir = 0; 1141 int32_t fuse_open_flags; 1142 1143 FS_DEBUG2G("inode=%ju mode=0x%x\n", (uintmax_t)VTOI(vp), mode); 1144 1145 if (fuse_isdeadfs(vp)) { 1146 return ENXIO; 1147 } 1148 fvdat = VTOFUD(vp); 1149 1150 if (vnode_isdir(vp)) { 1151 isdir = 1; 1152 } 1153 fuse_open_flags = 0; 1154 if (isdir) { 1155 fufh_type = FUFH_RDONLY; 1156 } else { 1157 fufh_type = fuse_filehandle_xlate_from_fflags(mode); 1158 /* 1159 * For WRONLY opens, force DIRECT_IO. This is necessary 1160 * since writing a partial block through the buffer cache 1161 * will result in a read of the block and that read won't 1162 * be allowed by the WRONLY open. 1163 */ 1164 if (fufh_type == FUFH_WRONLY || 1165 (fvdat->flag & FN_DIRECTIO) != 0) 1166 fuse_open_flags = FOPEN_DIRECT_IO; 1167 } 1168 1169 if (fuse_filehandle_validrw(vp, fufh_type) != FUFH_INVALID) { 1170 fuse_vnode_open(vp, fuse_open_flags, td); 1171 return 0; 1172 } 1173 error = fuse_filehandle_open(vp, fufh_type, NULL, td, cred); 1174 1175 return error; 1176 } 1177 1178 /* 1179 struct vnop_read_args { 1180 struct vnode *a_vp; 1181 struct uio *a_uio; 1182 int a_ioflag; 1183 struct ucred *a_cred; 1184 }; 1185 */ 1186 static int 1187 fuse_vnop_read(struct vop_read_args *ap) 1188 { 1189 struct vnode *vp = ap->a_vp; 1190 struct uio *uio = ap->a_uio; 1191 int ioflag = ap->a_ioflag; 1192 struct ucred *cred = ap->a_cred; 1193 1194 FS_DEBUG2G("inode=%ju offset=%jd resid=%zd\n", 1195 (uintmax_t)VTOI(vp), uio->uio_offset, uio->uio_resid); 1196 1197 if (fuse_isdeadfs(vp)) { 1198 return ENXIO; 1199 } 1200 1201 if (VTOFUD(vp)->flag & FN_DIRECTIO) { 1202 ioflag |= IO_DIRECT; 1203 } 1204 1205 return fuse_io_dispatch(vp, uio, ioflag, cred); 1206 } 1207 1208 /* 1209 struct vnop_readdir_args { 1210 struct vnode *a_vp; 1211 struct uio *a_uio; 1212 struct ucred *a_cred; 1213 int *a_eofflag; 1214 int *ncookies; 1215 u_long **a_cookies; 1216 }; 1217 */ 1218 static int 1219 fuse_vnop_readdir(struct vop_readdir_args *ap) 1220 { 1221 struct vnode *vp = ap->a_vp; 1222 struct uio *uio = ap->a_uio; 1223 struct ucred *cred = ap->a_cred; 1224 1225 struct fuse_filehandle *fufh = NULL; 1226 struct fuse_vnode_data *fvdat; 1227 struct fuse_iov cookediov; 1228 1229 int err = 0; 1230 int freefufh = 0; 1231 1232 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 1233 1234 if (fuse_isdeadfs(vp)) { 1235 return ENXIO; 1236 } 1237 if ( /* XXXIP ((uio_iovcnt(uio) > 1)) || */ 1238 (uio_resid(uio) < sizeof(struct dirent))) { 1239 return EINVAL; 1240 } 1241 fvdat = VTOFUD(vp); 1242 1243 if (!fuse_filehandle_valid(vp, FUFH_RDONLY)) { 1244 FS_DEBUG("calling readdir() before open()"); 1245 err = fuse_filehandle_open(vp, FUFH_RDONLY, &fufh, NULL, cred); 1246 freefufh = 1; 1247 } else { 1248 err = fuse_filehandle_get(vp, FUFH_RDONLY, &fufh); 1249 } 1250 if (err) { 1251 return (err); 1252 } 1253 #define DIRCOOKEDSIZE FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + MAXNAMLEN + 1) 1254 fiov_init(&cookediov, DIRCOOKEDSIZE); 1255 1256 err = fuse_internal_readdir(vp, uio, fufh, &cookediov); 1257 1258 fiov_teardown(&cookediov); 1259 if (freefufh) { 1260 fuse_filehandle_close(vp, FUFH_RDONLY, NULL, cred); 1261 } 1262 return err; 1263 } 1264 1265 /* 1266 struct vnop_readlink_args { 1267 struct vnode *a_vp; 1268 struct uio *a_uio; 1269 struct ucred *a_cred; 1270 }; 1271 */ 1272 static int 1273 fuse_vnop_readlink(struct vop_readlink_args *ap) 1274 { 1275 struct vnode *vp = ap->a_vp; 1276 struct uio *uio = ap->a_uio; 1277 struct ucred *cred = ap->a_cred; 1278 1279 struct fuse_dispatcher fdi; 1280 int err; 1281 1282 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 1283 1284 if (fuse_isdeadfs(vp)) { 1285 return ENXIO; 1286 } 1287 if (!vnode_islnk(vp)) { 1288 return EINVAL; 1289 } 1290 fdisp_init(&fdi, 0); 1291 err = fdisp_simple_putget_vp(&fdi, FUSE_READLINK, vp, curthread, cred); 1292 if (err) { 1293 goto out; 1294 } 1295 if (((char *)fdi.answ)[0] == '/' && 1296 fuse_get_mpdata(vnode_mount(vp))->dataflags & FSESS_PUSH_SYMLINKS_IN) { 1297 char *mpth = vnode_mount(vp)->mnt_stat.f_mntonname; 1298 1299 err = uiomove(mpth, strlen(mpth), uio); 1300 } 1301 if (!err) { 1302 err = uiomove(fdi.answ, fdi.iosize, uio); 1303 } 1304 out: 1305 fdisp_destroy(&fdi); 1306 return err; 1307 } 1308 1309 /* 1310 struct vnop_reclaim_args { 1311 struct vnode *a_vp; 1312 struct thread *a_td; 1313 }; 1314 */ 1315 static int 1316 fuse_vnop_reclaim(struct vop_reclaim_args *ap) 1317 { 1318 struct vnode *vp = ap->a_vp; 1319 struct thread *td = ap->a_td; 1320 1321 struct fuse_vnode_data *fvdat = VTOFUD(vp); 1322 struct fuse_filehandle *fufh = NULL; 1323 1324 int type; 1325 1326 if (!fvdat) { 1327 panic("FUSE: no vnode data during recycling"); 1328 } 1329 FS_DEBUG("inode=%ju\n", (uintmax_t)VTOI(vp)); 1330 1331 for (type = 0; type < FUFH_MAXTYPE; type++) { 1332 fufh = &(fvdat->fufh[type]); 1333 if (FUFH_IS_VALID(fufh)) { 1334 printf("FUSE: vnode being reclaimed but fufh (type=%d) is valid", 1335 type); 1336 fuse_filehandle_close(vp, type, td, NULL); 1337 } 1338 } 1339 1340 if ((!fuse_isdeadfs(vp)) && (fvdat->nlookup)) { 1341 fuse_internal_forget_send(vnode_mount(vp), td, NULL, VTOI(vp), 1342 fvdat->nlookup); 1343 } 1344 fuse_vnode_setparent(vp, NULL); 1345 cache_purge(vp); 1346 vfs_hash_remove(vp); 1347 vnode_destroy_vobject(vp); 1348 fuse_vnode_destroy(vp); 1349 1350 return 0; 1351 } 1352 1353 /* 1354 struct vnop_remove_args { 1355 struct vnode *a_dvp; 1356 struct vnode *a_vp; 1357 struct componentname *a_cnp; 1358 }; 1359 */ 1360 static int 1361 fuse_vnop_remove(struct vop_remove_args *ap) 1362 { 1363 struct vnode *dvp = ap->a_dvp; 1364 struct vnode *vp = ap->a_vp; 1365 struct componentname *cnp = ap->a_cnp; 1366 1367 int err; 1368 1369 FS_DEBUG2G("inode=%ju name=%*s\n", 1370 (uintmax_t)VTOI(vp), (int)cnp->cn_namelen, cnp->cn_nameptr); 1371 1372 if (fuse_isdeadfs(vp)) { 1373 return ENXIO; 1374 } 1375 if (vnode_isdir(vp)) { 1376 return EPERM; 1377 } 1378 cache_purge(vp); 1379 1380 err = fuse_internal_remove(dvp, vp, cnp, FUSE_UNLINK); 1381 1382 if (err == 0) 1383 fuse_internal_vnode_disappear(vp); 1384 return err; 1385 } 1386 1387 /* 1388 struct vnop_rename_args { 1389 struct vnode *a_fdvp; 1390 struct vnode *a_fvp; 1391 struct componentname *a_fcnp; 1392 struct vnode *a_tdvp; 1393 struct vnode *a_tvp; 1394 struct componentname *a_tcnp; 1395 }; 1396 */ 1397 static int 1398 fuse_vnop_rename(struct vop_rename_args *ap) 1399 { 1400 struct vnode *fdvp = ap->a_fdvp; 1401 struct vnode *fvp = ap->a_fvp; 1402 struct componentname *fcnp = ap->a_fcnp; 1403 struct vnode *tdvp = ap->a_tdvp; 1404 struct vnode *tvp = ap->a_tvp; 1405 struct componentname *tcnp = ap->a_tcnp; 1406 struct fuse_data *data; 1407 1408 int err = 0; 1409 1410 FS_DEBUG2G("from: inode=%ju name=%*s -> to: inode=%ju name=%*s\n", 1411 (uintmax_t)VTOI(fvp), (int)fcnp->cn_namelen, fcnp->cn_nameptr, 1412 (uintmax_t)(tvp == NULL ? -1 : VTOI(tvp)), 1413 (int)tcnp->cn_namelen, tcnp->cn_nameptr); 1414 1415 if (fuse_isdeadfs(fdvp)) { 1416 return ENXIO; 1417 } 1418 if (fvp->v_mount != tdvp->v_mount || 1419 (tvp && fvp->v_mount != tvp->v_mount)) { 1420 FS_DEBUG("cross-device rename: %s -> %s\n", 1421 fcnp->cn_nameptr, (tcnp != NULL ? tcnp->cn_nameptr : "(NULL)")); 1422 err = EXDEV; 1423 goto out; 1424 } 1425 cache_purge(fvp); 1426 1427 /* 1428 * FUSE library is expected to check if target directory is not 1429 * under the source directory in the file system tree. 1430 * Linux performs this check at VFS level. 1431 */ 1432 data = fuse_get_mpdata(vnode_mount(tdvp)); 1433 sx_xlock(&data->rename_lock); 1434 err = fuse_internal_rename(fdvp, fcnp, tdvp, tcnp); 1435 if (err == 0) { 1436 if (tdvp != fdvp) 1437 fuse_vnode_setparent(fvp, tdvp); 1438 if (tvp != NULL) 1439 fuse_vnode_setparent(tvp, NULL); 1440 } 1441 sx_unlock(&data->rename_lock); 1442 1443 if (tvp != NULL && tvp != fvp) { 1444 cache_purge(tvp); 1445 } 1446 if (vnode_isdir(fvp)) { 1447 if ((tvp != NULL) && vnode_isdir(tvp)) { 1448 cache_purge(tdvp); 1449 } 1450 cache_purge(fdvp); 1451 } 1452 out: 1453 if (tdvp == tvp) { 1454 vrele(tdvp); 1455 } else { 1456 vput(tdvp); 1457 } 1458 if (tvp != NULL) { 1459 vput(tvp); 1460 } 1461 vrele(fdvp); 1462 vrele(fvp); 1463 1464 return err; 1465 } 1466 1467 /* 1468 struct vnop_rmdir_args { 1469 struct vnode *a_dvp; 1470 struct vnode *a_vp; 1471 struct componentname *a_cnp; 1472 } *ap; 1473 */ 1474 static int 1475 fuse_vnop_rmdir(struct vop_rmdir_args *ap) 1476 { 1477 struct vnode *dvp = ap->a_dvp; 1478 struct vnode *vp = ap->a_vp; 1479 1480 int err; 1481 1482 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 1483 1484 if (fuse_isdeadfs(vp)) { 1485 return ENXIO; 1486 } 1487 if (VTOFUD(vp) == VTOFUD(dvp)) { 1488 return EINVAL; 1489 } 1490 err = fuse_internal_remove(dvp, vp, ap->a_cnp, FUSE_RMDIR); 1491 1492 if (err == 0) 1493 fuse_internal_vnode_disappear(vp); 1494 return err; 1495 } 1496 1497 /* 1498 struct vnop_setattr_args { 1499 struct vnode *a_vp; 1500 struct vattr *a_vap; 1501 struct ucred *a_cred; 1502 struct thread *a_td; 1503 }; 1504 */ 1505 static int 1506 fuse_vnop_setattr(struct vop_setattr_args *ap) 1507 { 1508 struct vnode *vp = ap->a_vp; 1509 struct vattr *vap = ap->a_vap; 1510 struct ucred *cred = ap->a_cred; 1511 struct thread *td = curthread; 1512 1513 struct fuse_dispatcher fdi; 1514 struct fuse_setattr_in *fsai; 1515 struct fuse_access_param facp; 1516 1517 int err = 0; 1518 enum vtype vtyp; 1519 int sizechanged = 0; 1520 uint64_t newsize = 0; 1521 1522 FS_DEBUG2G("inode=%ju\n", (uintmax_t)VTOI(vp)); 1523 1524 if (fuse_isdeadfs(vp)) { 1525 return ENXIO; 1526 } 1527 fdisp_init(&fdi, sizeof(*fsai)); 1528 fdisp_make_vp(&fdi, FUSE_SETATTR, vp, td, cred); 1529 fsai = fdi.indata; 1530 fsai->valid = 0; 1531 1532 bzero(&facp, sizeof(facp)); 1533 1534 facp.xuid = vap->va_uid; 1535 facp.xgid = vap->va_gid; 1536 1537 if (vap->va_uid != (uid_t)VNOVAL) { 1538 facp.facc_flags |= FACCESS_CHOWN; 1539 fsai->uid = vap->va_uid; 1540 fsai->valid |= FATTR_UID; 1541 } 1542 if (vap->va_gid != (gid_t)VNOVAL) { 1543 facp.facc_flags |= FACCESS_CHOWN; 1544 fsai->gid = vap->va_gid; 1545 fsai->valid |= FATTR_GID; 1546 } 1547 if (vap->va_size != VNOVAL) { 1548 1549 struct fuse_filehandle *fufh = NULL; 1550 1551 /*Truncate to a new value. */ 1552 fsai->size = vap->va_size; 1553 sizechanged = 1; 1554 newsize = vap->va_size; 1555 fsai->valid |= FATTR_SIZE; 1556 1557 fuse_filehandle_getrw(vp, FUFH_WRONLY, &fufh); 1558 if (fufh) { 1559 fsai->fh = fufh->fh_id; 1560 fsai->valid |= FATTR_FH; 1561 } 1562 } 1563 if (vap->va_atime.tv_sec != VNOVAL) { 1564 fsai->atime = vap->va_atime.tv_sec; 1565 fsai->atimensec = vap->va_atime.tv_nsec; 1566 fsai->valid |= FATTR_ATIME; 1567 } 1568 if (vap->va_mtime.tv_sec != VNOVAL) { 1569 fsai->mtime = vap->va_mtime.tv_sec; 1570 fsai->mtimensec = vap->va_mtime.tv_nsec; 1571 fsai->valid |= FATTR_MTIME; 1572 } 1573 if (vap->va_mode != (mode_t)VNOVAL) { 1574 fsai->mode = vap->va_mode & ALLPERMS; 1575 fsai->valid |= FATTR_MODE; 1576 } 1577 if (!fsai->valid) { 1578 goto out; 1579 } 1580 vtyp = vnode_vtype(vp); 1581 1582 if (fsai->valid & FATTR_SIZE && vtyp == VDIR) { 1583 err = EISDIR; 1584 goto out; 1585 } 1586 if (vfs_isrdonly(vnode_mount(vp)) && (fsai->valid & ~FATTR_SIZE || vtyp == VREG)) { 1587 err = EROFS; 1588 goto out; 1589 } 1590 if (fsai->valid & ~FATTR_SIZE) { 1591 /*err = fuse_internal_access(vp, VADMIN, context, &facp); */ 1592 /*XXX */ 1593 err = 0; 1594 } 1595 facp.facc_flags &= ~FACCESS_XQUERIES; 1596 1597 if (err && !(fsai->valid & ~(FATTR_ATIME | FATTR_MTIME)) && 1598 vap->va_vaflags & VA_UTIMES_NULL) { 1599 err = fuse_internal_access(vp, VWRITE, &facp, td, cred); 1600 } 1601 if (err) 1602 goto out; 1603 if ((err = fdisp_wait_answ(&fdi))) 1604 goto out; 1605 vtyp = IFTOVT(((struct fuse_attr_out *)fdi.answ)->attr.mode); 1606 1607 if (vnode_vtype(vp) != vtyp) { 1608 if (vnode_vtype(vp) == VNON && vtyp != VNON) { 1609 debug_printf("FUSE: Dang! vnode_vtype is VNON and vtype isn't.\n"); 1610 } else { 1611 /* 1612 * STALE vnode, ditch 1613 * 1614 * The vnode has changed its type "behind our back". There's 1615 * nothing really we can do, so let us just force an internal 1616 * revocation and tell the caller to try again, if interested. 1617 */ 1618 fuse_internal_vnode_disappear(vp); 1619 err = EAGAIN; 1620 } 1621 } 1622 if (!err && !sizechanged) { 1623 cache_attrs(vp, (struct fuse_attr_out *)fdi.answ); 1624 } 1625 out: 1626 fdisp_destroy(&fdi); 1627 if (!err && sizechanged) { 1628 fuse_vnode_setsize(vp, cred, newsize); 1629 VTOFUD(vp)->flag &= ~FN_SIZECHANGE; 1630 } 1631 return err; 1632 } 1633 1634 /* 1635 struct vnop_strategy_args { 1636 struct vnode *a_vp; 1637 struct buf *a_bp; 1638 }; 1639 */ 1640 static int 1641 fuse_vnop_strategy(struct vop_strategy_args *ap) 1642 { 1643 struct vnode *vp = ap->a_vp; 1644 struct buf *bp = ap->a_bp; 1645 1646 fuse_trace_printf_vnop(); 1647 1648 if (!vp || fuse_isdeadfs(vp)) { 1649 bp->b_ioflags |= BIO_ERROR; 1650 bp->b_error = ENXIO; 1651 bufdone(bp); 1652 return ENXIO; 1653 } 1654 if (bp->b_iocmd == BIO_WRITE) 1655 fuse_vnode_refreshsize(vp, NOCRED); 1656 1657 (void)fuse_io_strategy(vp, bp); 1658 1659 /* 1660 * This is a dangerous function. If returns error, that might mean a 1661 * panic. We prefer pretty much anything over being forced to panic 1662 * by a malicious daemon (a demon?). So we just return 0 anyway. You 1663 * should never mind this: this function has its own error 1664 * propagation mechanism via the argument buffer, so 1665 * not-that-melodramatic residents of the call chain still will be 1666 * able to know what to do. 1667 */ 1668 return 0; 1669 } 1670 1671 1672 /* 1673 struct vnop_symlink_args { 1674 struct vnode *a_dvp; 1675 struct vnode **a_vpp; 1676 struct componentname *a_cnp; 1677 struct vattr *a_vap; 1678 char *a_target; 1679 }; 1680 */ 1681 static int 1682 fuse_vnop_symlink(struct vop_symlink_args *ap) 1683 { 1684 struct vnode *dvp = ap->a_dvp; 1685 struct vnode **vpp = ap->a_vpp; 1686 struct componentname *cnp = ap->a_cnp; 1687 char *target = ap->a_target; 1688 1689 struct fuse_dispatcher fdi; 1690 1691 int err; 1692 size_t len; 1693 1694 FS_DEBUG2G("inode=%ju name=%*s\n", 1695 (uintmax_t)VTOI(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); 1696 1697 if (fuse_isdeadfs(dvp)) { 1698 return ENXIO; 1699 } 1700 /* 1701 * Unlike the other creator type calls, here we have to create a message 1702 * where the name of the new entry comes first, and the data describing 1703 * the entry comes second. 1704 * Hence we can't rely on our handy fuse_internal_newentry() routine, 1705 * but put together the message manually and just call the core part. 1706 */ 1707 1708 len = strlen(target) + 1; 1709 fdisp_init(&fdi, len + cnp->cn_namelen + 1); 1710 fdisp_make_vp(&fdi, FUSE_SYMLINK, dvp, curthread, NULL); 1711 1712 memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen); 1713 ((char *)fdi.indata)[cnp->cn_namelen] = '\0'; 1714 memcpy((char *)fdi.indata + cnp->cn_namelen + 1, target, len); 1715 1716 err = fuse_internal_newentry_core(dvp, vpp, cnp, VLNK, &fdi); 1717 fdisp_destroy(&fdi); 1718 return err; 1719 } 1720 1721 /* 1722 struct vnop_write_args { 1723 struct vnode *a_vp; 1724 struct uio *a_uio; 1725 int a_ioflag; 1726 struct ucred *a_cred; 1727 }; 1728 */ 1729 static int 1730 fuse_vnop_write(struct vop_write_args *ap) 1731 { 1732 struct vnode *vp = ap->a_vp; 1733 struct uio *uio = ap->a_uio; 1734 int ioflag = ap->a_ioflag; 1735 struct ucred *cred = ap->a_cred; 1736 1737 fuse_trace_printf_vnop(); 1738 1739 if (fuse_isdeadfs(vp)) { 1740 return ENXIO; 1741 } 1742 fuse_vnode_refreshsize(vp, cred); 1743 1744 if (VTOFUD(vp)->flag & FN_DIRECTIO) { 1745 ioflag |= IO_DIRECT; 1746 } 1747 1748 return fuse_io_dispatch(vp, uio, ioflag, cred); 1749 } 1750 1751 /* 1752 struct vnop_getpages_args { 1753 struct vnode *a_vp; 1754 vm_page_t *a_m; 1755 int a_count; 1756 int a_reqpage; 1757 }; 1758 */ 1759 static int 1760 fuse_vnop_getpages(struct vop_getpages_args *ap) 1761 { 1762 int i, error, nextoff, size, toff, count, npages; 1763 struct uio uio; 1764 struct iovec iov; 1765 vm_offset_t kva; 1766 struct buf *bp; 1767 struct vnode *vp; 1768 struct thread *td; 1769 struct ucred *cred; 1770 vm_page_t *pages; 1771 1772 FS_DEBUG2G("heh\n"); 1773 1774 vp = ap->a_vp; 1775 KASSERT(vp->v_object, ("objectless vp passed to getpages")); 1776 td = curthread; /* XXX */ 1777 cred = curthread->td_ucred; /* XXX */ 1778 pages = ap->a_m; 1779 npages = ap->a_count; 1780 1781 if (!fsess_opt_mmap(vnode_mount(vp))) { 1782 FS_DEBUG("called on non-cacheable vnode??\n"); 1783 return (VM_PAGER_ERROR); 1784 } 1785 1786 /* 1787 * If the last page is partially valid, just return it and allow 1788 * the pager to zero-out the blanks. Partially valid pages can 1789 * only occur at the file EOF. 1790 * 1791 * XXXGL: is that true for FUSE, which is a local filesystem, 1792 * but still somewhat disconnected from the kernel? 1793 */ 1794 VM_OBJECT_WLOCK(vp->v_object); 1795 if (pages[npages - 1]->valid != 0 && --npages == 0) 1796 goto out; 1797 VM_OBJECT_WUNLOCK(vp->v_object); 1798 1799 /* 1800 * We use only the kva address for the buffer, but this is extremely 1801 * convenient and fast. 1802 */ 1803 bp = getpbuf(&fuse_pbuf_freecnt); 1804 1805 kva = (vm_offset_t)bp->b_data; 1806 pmap_qenter(kva, pages, npages); 1807 VM_CNT_INC(v_vnodein); 1808 VM_CNT_ADD(v_vnodepgsin, npages); 1809 1810 count = npages << PAGE_SHIFT; 1811 iov.iov_base = (caddr_t)kva; 1812 iov.iov_len = count; 1813 uio.uio_iov = &iov; 1814 uio.uio_iovcnt = 1; 1815 uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); 1816 uio.uio_resid = count; 1817 uio.uio_segflg = UIO_SYSSPACE; 1818 uio.uio_rw = UIO_READ; 1819 uio.uio_td = td; 1820 1821 error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); 1822 pmap_qremove(kva, npages); 1823 1824 relpbuf(bp, &fuse_pbuf_freecnt); 1825 1826 if (error && (uio.uio_resid == count)) { 1827 FS_DEBUG("error %d\n", error); 1828 return VM_PAGER_ERROR; 1829 } 1830 /* 1831 * Calculate the number of bytes read and validate only that number 1832 * of bytes. Note that due to pending writes, size may be 0. This 1833 * does not mean that the remaining data is invalid! 1834 */ 1835 1836 size = count - uio.uio_resid; 1837 VM_OBJECT_WLOCK(vp->v_object); 1838 fuse_vm_page_lock_queues(); 1839 for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { 1840 vm_page_t m; 1841 1842 nextoff = toff + PAGE_SIZE; 1843 m = pages[i]; 1844 1845 if (nextoff <= size) { 1846 /* 1847 * Read operation filled an entire page 1848 */ 1849 m->valid = VM_PAGE_BITS_ALL; 1850 KASSERT(m->dirty == 0, 1851 ("fuse_getpages: page %p is dirty", m)); 1852 } else if (size > toff) { 1853 /* 1854 * Read operation filled a partial page. 1855 */ 1856 m->valid = 0; 1857 vm_page_set_valid_range(m, 0, size - toff); 1858 KASSERT(m->dirty == 0, 1859 ("fuse_getpages: page %p is dirty", m)); 1860 } else { 1861 /* 1862 * Read operation was short. If no error occurred 1863 * we may have hit a zero-fill section. We simply 1864 * leave valid set to 0. 1865 */ 1866 ; 1867 } 1868 } 1869 fuse_vm_page_unlock_queues(); 1870 out: 1871 VM_OBJECT_WUNLOCK(vp->v_object); 1872 if (ap->a_rbehind) 1873 *ap->a_rbehind = 0; 1874 if (ap->a_rahead) 1875 *ap->a_rahead = 0; 1876 return (VM_PAGER_OK); 1877 } 1878 1879 /* 1880 struct vnop_putpages_args { 1881 struct vnode *a_vp; 1882 vm_page_t *a_m; 1883 int a_count; 1884 int a_sync; 1885 int *a_rtvals; 1886 vm_ooffset_t a_offset; 1887 }; 1888 */ 1889 static int 1890 fuse_vnop_putpages(struct vop_putpages_args *ap) 1891 { 1892 struct uio uio; 1893 struct iovec iov; 1894 vm_offset_t kva; 1895 struct buf *bp; 1896 int i, error, npages, count; 1897 off_t offset; 1898 int *rtvals; 1899 struct vnode *vp; 1900 struct thread *td; 1901 struct ucred *cred; 1902 vm_page_t *pages; 1903 vm_ooffset_t fsize; 1904 1905 FS_DEBUG2G("heh\n"); 1906 1907 vp = ap->a_vp; 1908 KASSERT(vp->v_object, ("objectless vp passed to putpages")); 1909 fsize = vp->v_object->un_pager.vnp.vnp_size; 1910 td = curthread; /* XXX */ 1911 cred = curthread->td_ucred; /* XXX */ 1912 pages = ap->a_m; 1913 count = ap->a_count; 1914 rtvals = ap->a_rtvals; 1915 npages = btoc(count); 1916 offset = IDX_TO_OFF(pages[0]->pindex); 1917 1918 if (!fsess_opt_mmap(vnode_mount(vp))) { 1919 FS_DEBUG("called on non-cacheable vnode??\n"); 1920 } 1921 for (i = 0; i < npages; i++) 1922 rtvals[i] = VM_PAGER_AGAIN; 1923 1924 /* 1925 * When putting pages, do not extend file past EOF. 1926 */ 1927 1928 if (offset + count > fsize) { 1929 count = fsize - offset; 1930 if (count < 0) 1931 count = 0; 1932 } 1933 /* 1934 * We use only the kva address for the buffer, but this is extremely 1935 * convenient and fast. 1936 */ 1937 bp = getpbuf(&fuse_pbuf_freecnt); 1938 1939 kva = (vm_offset_t)bp->b_data; 1940 pmap_qenter(kva, pages, npages); 1941 VM_CNT_INC(v_vnodeout); 1942 VM_CNT_ADD(v_vnodepgsout, count); 1943 1944 iov.iov_base = (caddr_t)kva; 1945 iov.iov_len = count; 1946 uio.uio_iov = &iov; 1947 uio.uio_iovcnt = 1; 1948 uio.uio_offset = offset; 1949 uio.uio_resid = count; 1950 uio.uio_segflg = UIO_SYSSPACE; 1951 uio.uio_rw = UIO_WRITE; 1952 uio.uio_td = td; 1953 1954 error = fuse_io_dispatch(vp, &uio, IO_DIRECT, cred); 1955 1956 pmap_qremove(kva, npages); 1957 relpbuf(bp, &fuse_pbuf_freecnt); 1958 1959 if (!error) { 1960 int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; 1961 1962 for (i = 0; i < nwritten; i++) { 1963 rtvals[i] = VM_PAGER_OK; 1964 VM_OBJECT_WLOCK(pages[i]->object); 1965 vm_page_undirty(pages[i]); 1966 VM_OBJECT_WUNLOCK(pages[i]->object); 1967 } 1968 } 1969 return rtvals[0]; 1970 } 1971 1972 static const char extattr_namespace_separator = '.'; 1973 1974 /* 1975 struct vop_getextattr_args { 1976 struct vop_generic_args a_gen; 1977 struct vnode *a_vp; 1978 int a_attrnamespace; 1979 const char *a_name; 1980 struct uio *a_uio; 1981 size_t *a_size; 1982 struct ucred *a_cred; 1983 struct thread *a_td; 1984 }; 1985 */ 1986 static int 1987 fuse_vnop_getextattr(struct vop_getextattr_args *ap) 1988 { 1989 struct vnode *vp = ap->a_vp; 1990 struct uio *uio = ap->a_uio; 1991 struct fuse_dispatcher fdi = {0}; 1992 struct fuse_getxattr_in *get_xattr_in; 1993 struct fuse_getxattr_out *get_xattr_out; 1994 struct mount *mp = vnode_mount(vp); 1995 char *prefix; 1996 size_t len; 1997 char *attr_str; 1998 struct thread *td = ap->a_td; 1999 struct ucred *cred = ap->a_cred; 2000 int err = 0; 2001 2002 fuse_trace_printf_vnop(); 2003 2004 if (fuse_isdeadfs(vp)) 2005 return ENXIO; 2006 2007 /* Default to looking for user attributes. */ 2008 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2009 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2010 else 2011 prefix = EXTATTR_NAMESPACE_USER_STRING; 2012 2013 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2014 strlen(ap->a_name) + 1; 2015 2016 fdisp_init(&fdi, len + sizeof(*get_xattr_in)); 2017 fdisp_make_vp(&fdi, FUSE_GETXATTR, vp, td, cred); 2018 2019 get_xattr_in = fdi.indata; 2020 /* 2021 * Check to see whether we're querying the available size or 2022 * issuing the actual request. If we pass in 0, we get back struct 2023 * fuse_getxattr_out. If we pass in a non-zero size, we get back 2024 * that much data, without the struct fuse_getxattr_out header. 2025 */ 2026 if (ap->a_size != NULL) 2027 get_xattr_in->size = 0; 2028 else 2029 get_xattr_in->size = uio->uio_resid; 2030 2031 attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); 2032 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2033 ap->a_name); 2034 2035 err = fdisp_wait_answ(&fdi); 2036 2037 if (err != 0) { 2038 if (err == ENOSYS) 2039 fsess_set_notimpl(mp, FUSE_GETXATTR); 2040 debug_printf("getxattr: got err=%d from daemon\n", err); 2041 goto out; 2042 } 2043 2044 /* 2045 * If we get to this point (i.e. no error), we should have a valid 2046 * answer of some sort. i.e. non-zero iosize and a valid pointer. 2047 */ 2048 if ((fdi.answ == NULL) || (fdi.iosize == 0)) { 2049 debug_printf("getxattr: err = 0, but answ = %p, iosize = %zu\n", 2050 fdi.answ, fdi.iosize); 2051 err = EINVAL; 2052 goto out; 2053 } 2054 get_xattr_out = fdi.answ; 2055 2056 if (ap->a_size != NULL) { 2057 *ap->a_size = get_xattr_out->size; 2058 } else if (fdi.iosize > 0) { 2059 err = uiomove(fdi.answ, fdi.iosize, uio); 2060 } else { 2061 err = EINVAL; 2062 } 2063 2064 out: 2065 fdisp_destroy(&fdi); 2066 return (err); 2067 } 2068 2069 /* 2070 struct vop_setextattr_args { 2071 struct vop_generic_args a_gen; 2072 struct vnode *a_vp; 2073 int a_attrnamespace; 2074 const char *a_name; 2075 struct uio *a_uio; 2076 struct ucred *a_cred; 2077 struct thread *a_td; 2078 }; 2079 */ 2080 static int 2081 fuse_vnop_setextattr(struct vop_setextattr_args *ap) 2082 { 2083 struct vnode *vp = ap->a_vp; 2084 struct uio *uio = ap->a_uio; 2085 struct fuse_dispatcher fdi = {0}; 2086 struct fuse_setxattr_in *set_xattr_in; 2087 struct mount *mp = vnode_mount(vp); 2088 char *prefix; 2089 size_t len; 2090 char *attr_str; 2091 struct thread *td = ap->a_td; 2092 struct ucred *cred = ap->a_cred; 2093 int err = 0; 2094 2095 fuse_trace_printf_vnop(); 2096 2097 if (fuse_isdeadfs(vp)) 2098 return ENXIO; 2099 2100 /* Default to looking for user attributes. */ 2101 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2102 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2103 else 2104 prefix = EXTATTR_NAMESPACE_USER_STRING; 2105 2106 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2107 strlen(ap->a_name) + 1; 2108 2109 fdisp_init(&fdi, len + sizeof(*set_xattr_in) + uio->uio_resid); 2110 fdisp_make_vp(&fdi, FUSE_SETXATTR, vp, td, cred); 2111 2112 set_xattr_in = fdi.indata; 2113 set_xattr_in->size = uio->uio_resid; 2114 2115 attr_str = (char *)fdi.indata + sizeof(*set_xattr_in); 2116 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2117 ap->a_name); 2118 2119 err = uiomove((char *)fdi.indata + sizeof(*set_xattr_in) + len, 2120 uio->uio_resid, uio); 2121 if (err != 0) { 2122 debug_printf("setxattr: got error %d from uiomove\n", err); 2123 goto out; 2124 } 2125 2126 err = fdisp_wait_answ(&fdi); 2127 2128 if (err != 0) { 2129 if (err == ENOSYS) 2130 fsess_set_notimpl(mp, FUSE_SETXATTR); 2131 debug_printf("setxattr: got err=%d from daemon\n", err); 2132 goto out; 2133 } 2134 2135 out: 2136 fdisp_destroy(&fdi); 2137 return (err); 2138 } 2139 2140 /* 2141 * The Linux / FUSE extended attribute list is simply a collection of 2142 * NUL-terminated strings. The FreeBSD extended attribute list is a single 2143 * byte length followed by a non-NUL terminated string. So, this allows 2144 * conversion of the Linux / FUSE format to the FreeBSD format in place. 2145 * Linux attribute names are reported with the namespace as a prefix (e.g. 2146 * "user.attribute_name"), but in FreeBSD they are reported without the 2147 * namespace prefix (e.g. "attribute_name"). So, we're going from: 2148 * 2149 * user.attr_name1\0user.attr_name2\0 2150 * 2151 * to: 2152 * 2153 * <num>attr_name1<num>attr_name2 2154 * 2155 * Where "<num>" is a single byte number of characters in the attribute name. 2156 * 2157 * Args: 2158 * prefix - exattr namespace prefix string 2159 * list, list_len - input list with namespace prefixes 2160 * bsd_list, bsd_list_len - output list compatible with bsd vfs 2161 */ 2162 static int 2163 fuse_xattrlist_convert(char *prefix, const char *list, int list_len, 2164 char *bsd_list, int *bsd_list_len) 2165 { 2166 int len, pos, dist_to_next, prefix_len; 2167 2168 pos = 0; 2169 *bsd_list_len = 0; 2170 prefix_len = strlen(prefix); 2171 2172 while (pos < list_len && list[pos] != '\0') { 2173 dist_to_next = strlen(&list[pos]) + 1; 2174 if (bcmp(&list[pos], prefix, prefix_len) == 0 && 2175 list[pos + prefix_len] == extattr_namespace_separator) { 2176 len = dist_to_next - 2177 (prefix_len + sizeof(extattr_namespace_separator)) - 1; 2178 if (len >= EXTATTR_MAXNAMELEN) 2179 return (ENAMETOOLONG); 2180 2181 bsd_list[*bsd_list_len] = len; 2182 memcpy(&bsd_list[*bsd_list_len + 1], 2183 &list[pos + prefix_len + 2184 sizeof(extattr_namespace_separator)], len); 2185 2186 *bsd_list_len += len + 1; 2187 } 2188 2189 pos += dist_to_next; 2190 } 2191 2192 return (0); 2193 } 2194 2195 /* 2196 struct vop_listextattr_args { 2197 struct vop_generic_args a_gen; 2198 struct vnode *a_vp; 2199 int a_attrnamespace; 2200 struct uio *a_uio; 2201 size_t *a_size; 2202 struct ucred *a_cred; 2203 struct thread *a_td; 2204 }; 2205 */ 2206 static int 2207 fuse_vnop_listextattr(struct vop_listextattr_args *ap) 2208 { 2209 struct vnode *vp = ap->a_vp; 2210 struct uio *uio = ap->a_uio; 2211 struct fuse_dispatcher fdi = {0}; 2212 struct fuse_getxattr_in *get_xattr_in; 2213 struct fuse_getxattr_out *get_xattr_out; 2214 struct mount *mp = vnode_mount(vp); 2215 size_t len; 2216 char *prefix; 2217 char *attr_str; 2218 char *bsd_list = NULL; 2219 int bsd_list_len; 2220 struct thread *td = ap->a_td; 2221 struct ucred *cred = ap->a_cred; 2222 int err = 0; 2223 2224 fuse_trace_printf_vnop(); 2225 2226 if (fuse_isdeadfs(vp)) 2227 return ENXIO; 2228 2229 /* 2230 * Add space for a NUL and the period separator if enabled. 2231 * Default to looking for user attributes. 2232 */ 2233 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2234 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2235 else 2236 prefix = EXTATTR_NAMESPACE_USER_STRING; 2237 2238 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 1; 2239 2240 fdisp_init(&fdi, sizeof(*get_xattr_in) + len); 2241 fdisp_make_vp(&fdi, FUSE_LISTXATTR, vp, td, cred); 2242 2243 get_xattr_in = fdi.indata; 2244 if (ap->a_size != NULL) 2245 get_xattr_in->size = 0; 2246 else 2247 get_xattr_in->size = uio->uio_resid + sizeof(*get_xattr_out); 2248 2249 2250 attr_str = (char *)fdi.indata + sizeof(*get_xattr_in); 2251 snprintf(attr_str, len, "%s%c", prefix, extattr_namespace_separator); 2252 2253 err = fdisp_wait_answ(&fdi); 2254 if (err != 0) { 2255 if (err == ENOSYS) 2256 fsess_set_notimpl(mp, FUSE_LISTXATTR); 2257 debug_printf("listextattr: got err=%d from daemon\n", err); 2258 goto out; 2259 } 2260 2261 if ((fdi.answ == NULL) || (fdi.iosize == 0)) { 2262 err = EINVAL; 2263 goto out; 2264 } 2265 get_xattr_out = fdi.answ; 2266 2267 if (ap->a_size != NULL) { 2268 *ap->a_size = get_xattr_out->size; 2269 } else if (fdi.iosize > 0) { 2270 /* 2271 * The Linux / FUSE attribute list format isn't the same 2272 * as FreeBSD's format. So we need to transform it into 2273 * FreeBSD's format before giving it to the user. 2274 */ 2275 bsd_list = malloc(fdi.iosize, M_TEMP, M_WAITOK); 2276 err = fuse_xattrlist_convert(prefix, fdi.answ, fdi.iosize, 2277 bsd_list, &bsd_list_len); 2278 if (err != 0) 2279 goto out; 2280 2281 err = uiomove(bsd_list, bsd_list_len, uio); 2282 } else { 2283 debug_printf("listextattr: returned iosize %zu for %s attribute list is " 2284 "too small\n", fdi.iosize, prefix); 2285 err = EINVAL; 2286 } 2287 2288 out: 2289 free(bsd_list, M_TEMP); 2290 fdisp_destroy(&fdi); 2291 return (err); 2292 } 2293 2294 /* 2295 struct vop_deleteextattr_args { 2296 struct vop_generic_args a_gen; 2297 struct vnode *a_vp; 2298 int a_attrnamespace; 2299 const char *a_name; 2300 struct ucred *a_cred; 2301 struct thread *a_td; 2302 }; 2303 */ 2304 static int 2305 fuse_vnop_deleteextattr(struct vop_deleteextattr_args *ap) 2306 { 2307 struct vnode *vp = ap->a_vp; 2308 struct fuse_dispatcher fdi = {0}; 2309 struct mount *mp = vnode_mount(vp); 2310 char *prefix; 2311 size_t len; 2312 char *attr_str; 2313 struct thread *td = ap->a_td; 2314 struct ucred *cred = ap->a_cred; 2315 int err; 2316 2317 fuse_trace_printf_vnop(); 2318 2319 if (fuse_isdeadfs(vp)) 2320 return ENXIO; 2321 2322 /* Default to looking for user attributes. */ 2323 if (ap->a_attrnamespace == EXTATTR_NAMESPACE_SYSTEM) 2324 prefix = EXTATTR_NAMESPACE_SYSTEM_STRING; 2325 else 2326 prefix = EXTATTR_NAMESPACE_USER_STRING; 2327 2328 len = strlen(prefix) + sizeof(extattr_namespace_separator) + 2329 strlen(ap->a_name) + 1; 2330 2331 fdisp_init(&fdi, len); 2332 fdisp_make_vp(&fdi, FUSE_REMOVEXATTR, vp, td, cred); 2333 2334 attr_str = fdi.indata; 2335 snprintf(attr_str, len, "%s%c%s", prefix, extattr_namespace_separator, 2336 ap->a_name); 2337 2338 err = fdisp_wait_answ(&fdi); 2339 if (err != 0) { 2340 if (err == ENOSYS) 2341 fsess_set_notimpl(mp, FUSE_REMOVEXATTR); 2342 debug_printf("removexattr: got err=%d from daemon\n", err); 2343 } 2344 2345 fdisp_destroy(&fdi); 2346 return (err); 2347 } 2348 2349 /* 2350 struct vnop_print_args { 2351 struct vnode *a_vp; 2352 }; 2353 */ 2354 static int 2355 fuse_vnop_print(struct vop_print_args *ap) 2356 { 2357 struct fuse_vnode_data *fvdat = VTOFUD(ap->a_vp); 2358 2359 printf("nodeid: %ju, parent nodeid: %ju, nlookup: %ju, flag: %#x\n", 2360 (uintmax_t)VTOILLU(ap->a_vp), (uintmax_t)fvdat->parent_nid, 2361 (uintmax_t)fvdat->nlookup, 2362 fvdat->flag); 2363 2364 return 0; 2365 } 2366