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