1 /* $OpenBSD: tmpfs_vnops.c,v 1.56 2024/10/18 05:52:32 miod Exp $ */ 2 /* $NetBSD: tmpfs_vnops.c,v 1.100 2012/11/05 17:27:39 dholland Exp $ */ 3 4 /* 5 * Copyright (c) 2005, 2006, 2007, 2012 The NetBSD Foundation, Inc. 6 * Copyright (c) 2013 Pedro Martelletto 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 11 * 2005 program, and by Taylor R Campbell. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* 36 * tmpfs vnode interface. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/fcntl.h> 42 #include <sys/event.h> 43 #include <sys/namei.h> 44 #include <sys/stat.h> 45 #include <sys/uio.h> 46 #include <sys/unistd.h> 47 #include <sys/vnode.h> 48 #include <sys/lockf.h> 49 #include <sys/file.h> 50 51 #include <miscfs/fifofs/fifo.h> 52 #include <tmpfs/tmpfs_vnops.h> 53 #include <tmpfs/tmpfs.h> 54 55 int tmpfs_kqfilter(void *v); 56 57 /* 58 * vnode operations vector used for files stored in a tmpfs file system. 59 */ 60 const struct vops tmpfs_vops = { 61 .vop_lookup = tmpfs_lookup, 62 .vop_create = tmpfs_create, 63 .vop_mknod = tmpfs_mknod, 64 .vop_open = tmpfs_open, 65 .vop_close = tmpfs_close, 66 .vop_access = tmpfs_access, 67 .vop_getattr = tmpfs_getattr, 68 .vop_setattr = tmpfs_setattr, 69 .vop_read = tmpfs_read, 70 .vop_write = tmpfs_write, 71 .vop_ioctl = tmpfs_ioctl, 72 .vop_kqfilter = tmpfs_kqfilter, 73 .vop_revoke = vop_generic_revoke, 74 .vop_fsync = tmpfs_fsync, 75 .vop_remove = tmpfs_remove, 76 .vop_link = tmpfs_link, 77 .vop_rename = tmpfs_rename, 78 .vop_mkdir = tmpfs_mkdir, 79 .vop_rmdir = tmpfs_rmdir, 80 .vop_symlink = tmpfs_symlink, 81 .vop_readdir = tmpfs_readdir, 82 .vop_readlink = tmpfs_readlink, 83 .vop_abortop = vop_generic_abortop, 84 .vop_inactive = tmpfs_inactive, 85 .vop_reclaim = tmpfs_reclaim, 86 .vop_lock = tmpfs_lock, 87 .vop_unlock = tmpfs_unlock, 88 .vop_bmap = vop_generic_bmap, 89 .vop_strategy = tmpfs_strategy, 90 .vop_print = tmpfs_print, 91 .vop_islocked = tmpfs_islocked, 92 .vop_pathconf = tmpfs_pathconf, 93 .vop_advlock = tmpfs_advlock, 94 .vop_bwrite = tmpfs_bwrite, 95 }; 96 97 /* 98 * tmpfs_lookup: path name traversal routine. 99 * 100 * Arguments: dvp (directory being searched), vpp (result), 101 * cnp (component name - path). 102 * 103 * => Caller holds a reference and lock on dvp. 104 * => We return looked-up vnode (vpp) locked, with a reference held. 105 */ 106 int 107 tmpfs_lookup(void *v) 108 { 109 struct vop_lookup_args /* { 110 struct vnode *a_dvp; 111 struct vnode **a_vpp; 112 struct componentname *a_cnp; 113 } */ *ap = v; 114 struct vnode *dvp = ap->a_dvp, **vpp = ap->a_vpp; 115 struct componentname *cnp = ap->a_cnp; 116 struct ucred *cred = cnp->cn_cred; 117 const int lastcn = (cnp->cn_flags & ISLASTCN) != 0; 118 const int lockparent = (cnp->cn_flags & LOCKPARENT) != 0; 119 tmpfs_node_t *dnode, *tnode; 120 tmpfs_dirent_t *de; 121 int cachefound; 122 int error; 123 124 KASSERT(VOP_ISLOCKED(dvp)); 125 126 dnode = VP_TO_TMPFS_DIR(dvp); 127 cnp->cn_flags &= ~PDIRUNLOCK; 128 *vpp = NULL; 129 130 /* Check accessibility of directory. */ 131 error = VOP_ACCESS(dvp, VEXEC, cred, curproc); 132 if (error) { 133 goto out; 134 } 135 136 /* 137 * If requesting the last path component on a read-only file system 138 * with a write operation, deny it. 139 */ 140 if (lastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) != 0 && 141 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 142 error = EROFS; 143 goto out; 144 } 145 146 /* 147 * Avoid doing a linear scan of the directory if the requested 148 * directory/name couple is already in the cache. 149 */ 150 cachefound = cache_lookup(dvp, vpp, cnp); 151 if (cachefound == ENOENT /* && *vpp == NULLVP */) 152 return ENOENT; /* Negative cache hit. */ 153 else if (cachefound != -1) 154 return 0; /* Found in cache. */ 155 156 if (cnp->cn_flags & ISDOTDOT) { 157 tmpfs_node_t *pnode; 158 159 /* 160 * Lookup of ".." case. 161 */ 162 if (lastcn) { 163 if (cnp->cn_nameiop == RENAME) { 164 error = EINVAL; 165 goto out; 166 } 167 if (cnp->cn_nameiop == DELETE) { 168 /* Keep the name for tmpfs_rmdir(). */ 169 cnp->cn_flags |= SAVENAME; 170 } 171 } 172 KASSERT(dnode->tn_type == VDIR); 173 pnode = dnode->tn_spec.tn_dir.tn_parent; 174 if (pnode == NULL) { 175 error = ENOENT; 176 goto out; 177 } 178 179 /* 180 * Lock the parent tn_nlock before releasing the vnode lock, 181 * and thus prevents parent from disappearing. 182 */ 183 rw_enter_write(&pnode->tn_nlock); 184 VOP_UNLOCK(dvp); 185 186 /* 187 * Get a vnode of the '..' entry and re-acquire the lock. 188 * Release the tn_nlock. 189 */ 190 error = tmpfs_vnode_get(dvp->v_mount, pnode, vpp); 191 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 192 goto out; 193 194 } else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { 195 /* 196 * Lookup of "." case. 197 */ 198 if (lastcn && cnp->cn_nameiop == RENAME) { 199 error = EISDIR; 200 goto out; 201 } 202 vref(dvp); 203 *vpp = dvp; 204 error = 0; 205 goto done; 206 } 207 208 /* 209 * Other lookup cases: perform directory scan. 210 */ 211 de = tmpfs_dir_lookup(dnode, cnp); 212 if (de == NULL) { 213 /* 214 * The entry was not found in the directory. This is valid 215 * if we are creating or renaming an entry and are working 216 * on the last component of the path name. 217 */ 218 if (lastcn && (cnp->cn_nameiop == CREATE || 219 cnp->cn_nameiop == RENAME)) { 220 error = VOP_ACCESS(dvp, VWRITE, cred, curproc); 221 if (error) { 222 goto out; 223 } 224 /* 225 * We are creating an entry in the file system, so 226 * save its name for further use by tmpfs_create(). 227 */ 228 cnp->cn_flags |= SAVENAME; 229 error = EJUSTRETURN; 230 } else { 231 error = ENOENT; 232 } 233 goto done; 234 } 235 236 tnode = de->td_node; 237 238 /* 239 * If it is not the last path component and found a non-directory 240 * or non-link entry (which may itself be pointing to a directory), 241 * raise an error. 242 */ 243 if (!lastcn && tnode->tn_type != VDIR && tnode->tn_type != VLNK) { 244 error = ENOTDIR; 245 goto out; 246 } 247 248 /* Check the permissions. */ 249 if (lastcn && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 250 error = VOP_ACCESS(dvp, VWRITE, cred, curproc); 251 if (error) 252 goto out; 253 254 /* 255 * If not root and directory is sticky, check for permission 256 * on directory or on file. This implements append-only 257 * directories. 258 */ 259 if ((dnode->tn_mode & S_ISTXT) != 0) { 260 if (cred->cr_uid != 0 && 261 cred->cr_uid != dnode->tn_uid && 262 cred->cr_uid != tnode->tn_uid) { 263 error = EPERM; 264 goto out; 265 } 266 } 267 268 /* 269 * XXX pedro: We might need cn_nameptr later in tmpfs_remove() 270 * or tmpfs_rmdir() for a tmpfs_dir_lookup(). We should really 271 * get rid of SAVENAME at some point. 272 */ 273 if (cnp->cn_nameiop == DELETE) 274 cnp->cn_flags |= SAVENAME; 275 } 276 277 /* Get a vnode for the matching entry. */ 278 rw_enter_write(&tnode->tn_nlock); 279 error = tmpfs_vnode_get(dvp->v_mount, tnode, vpp); 280 done: 281 /* 282 * Cache the result, unless request was for creation (as it does 283 * not improve the performance). 284 */ 285 if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) { 286 cache_enter(dvp, *vpp, cnp); 287 } 288 out: 289 /* 290 * If (1) we succeeded, (2) found a distinct vnode != .. to return and (3) 291 * were either explicitly told to keep the parent locked or are in the 292 * middle of a lookup, unlock the parent vnode. 293 */ 294 if ((error == 0 || error == EJUSTRETURN) && /* (1) */ 295 (*vpp != dvp || (cnp->cn_flags & ISDOTDOT)) && /* (2) */ 296 (!lockparent || !lastcn)) { /* (3) */ 297 VOP_UNLOCK(dvp); 298 cnp->cn_flags |= PDIRUNLOCK; 299 } else 300 KASSERT(VOP_ISLOCKED(dvp)); 301 302 KASSERT((*vpp && VOP_ISLOCKED(*vpp)) || error); 303 304 return error; 305 } 306 307 int 308 tmpfs_create(void *v) 309 { 310 struct vop_create_args /* { 311 struct vnode *a_dvp; 312 struct vnode **a_vpp; 313 struct componentname *a_cnp; 314 struct vattr *a_vap; 315 } */ *ap = v; 316 struct vnode *dvp = ap->a_dvp, **vpp = ap->a_vpp; 317 struct componentname *cnp = ap->a_cnp; 318 struct vattr *vap = ap->a_vap; 319 320 KASSERT(VOP_ISLOCKED(dvp)); 321 KASSERT(cnp->cn_flags & HASBUF); 322 KASSERT(vap->va_type == VREG || vap->va_type == VSOCK); 323 return tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); 324 } 325 326 int 327 tmpfs_mknod(void *v) 328 { 329 struct vop_mknod_args /* { 330 struct vnode *a_dvp; 331 struct vnode **a_vpp; 332 struct componentname *a_cnp; 333 struct vattr *a_vap; 334 } */ *ap = v; 335 struct vnode *dvp = ap->a_dvp, **vpp = ap->a_vpp; 336 struct componentname *cnp = ap->a_cnp; 337 struct vattr *vap = ap->a_vap; 338 enum vtype vt = vap->va_type; 339 int error; 340 341 if (vt != VBLK && vt != VCHR && vt != VFIFO) 342 return EINVAL; 343 344 error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); 345 346 if (error == 0) 347 vput(*vpp); 348 349 return error; 350 } 351 352 int 353 tmpfs_open(void *v) 354 { 355 struct vop_open_args /* { 356 struct vnode *a_vp; 357 int a_mode; 358 kauth_cred_t a_cred; 359 } */ *ap = v; 360 struct vnode *vp = ap->a_vp; 361 mode_t mode = ap->a_mode; 362 tmpfs_node_t *node; 363 364 KASSERT(VOP_ISLOCKED(vp)); 365 366 node = VP_TO_TMPFS_NODE(vp); 367 if (node->tn_links < 1) { 368 /* 369 * The file is still active, but all its names have been 370 * removed (e.g. by a "rmdir $(pwd)"). It cannot be opened 371 * any more, as it is about to be destroyed. 372 */ 373 return ENOENT; 374 } 375 376 /* If the file is marked append-only, deny write requests. */ 377 if ((node->tn_flags & APPEND) != 0 && 378 (mode & (FWRITE | O_APPEND)) == FWRITE) { 379 return EPERM; 380 } 381 return 0; 382 } 383 384 int 385 tmpfs_close(void *v) 386 { 387 #ifdef DIAGNOSTIC 388 struct vop_close_args /* { 389 struct vnode *a_vp; 390 int a_fflag; 391 kauth_cred_t a_cred; 392 } */ *ap = v; 393 struct vnode *vp = ap->a_vp; 394 395 KASSERT(VOP_ISLOCKED(vp)); 396 #endif 397 return 0; 398 } 399 400 int 401 tmpfs_access(void *v) 402 { 403 struct vop_access_args /* { 404 struct vnode *a_vp; 405 int a_mode; 406 kauth_cred_t a_cred; 407 } */ *ap = v; 408 struct vnode *vp = ap->a_vp; 409 mode_t mode = ap->a_mode; 410 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 411 const int writing = (mode & VWRITE) != 0; 412 413 KASSERT(VOP_ISLOCKED(vp)); 414 415 /* Possible? */ 416 switch (vp->v_type) { 417 case VDIR: 418 case VLNK: 419 case VREG: 420 if (writing && (vp->v_mount->mnt_flag & MNT_RDONLY) != 0) { 421 return EROFS; 422 } 423 break; 424 case VBLK: 425 case VCHR: 426 case VSOCK: 427 case VFIFO: 428 break; 429 default: 430 return EINVAL; 431 } 432 if (writing && (node->tn_flags & IMMUTABLE) != 0) { 433 return EPERM; 434 } 435 436 return (vaccess(vp->v_type, node->tn_mode, node->tn_uid, node->tn_gid, 437 mode, ap->a_cred)); 438 } 439 440 int 441 tmpfs_getattr(void *v) 442 { 443 struct vop_getattr_args /* { 444 struct vnode *a_vp; 445 struct vattr *a_vap; 446 kauth_cred_t a_cred; 447 } */ *ap = v; 448 struct vnode *vp = ap->a_vp; 449 struct vattr *vap = ap->a_vap; 450 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 451 452 vattr_null(vap); 453 454 vap->va_type = vp->v_type; 455 vap->va_mode = node->tn_mode; 456 vap->va_nlink = node->tn_links; 457 vap->va_uid = node->tn_uid; 458 vap->va_gid = node->tn_gid; 459 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 460 vap->va_fileid = node->tn_id; 461 vap->va_size = node->tn_size; 462 vap->va_blocksize = PAGE_SIZE; 463 vap->va_atime = node->tn_atime; 464 vap->va_mtime = node->tn_mtime; 465 vap->va_ctime = node->tn_ctime; 466 /* vap->va_birthtime = node->tn_birthtime; */ 467 vap->va_gen = TMPFS_NODE_GEN(node); 468 vap->va_flags = node->tn_flags; 469 vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ? 470 node->tn_spec.tn_dev.tn_rdev : VNOVAL; 471 vap->va_bytes = round_page(node->tn_size); 472 vap->va_filerev = VNOVAL; 473 vap->va_vaflags = 0; 474 vap->va_spare = VNOVAL; /* XXX */ 475 476 return 0; 477 } 478 479 #define GOODTIME(tv) ((tv)->tv_nsec != VNOVAL) 480 /* XXX Should this operation be atomic? I think it should, but code in 481 * XXX other places (e.g., ufs) doesn't seem to be... */ 482 int 483 tmpfs_setattr(void *v) 484 { 485 struct vop_setattr_args /* { 486 struct vnode *a_vp; 487 struct vattr *a_vap; 488 kauth_cred_t a_cred; 489 } */ *ap = v; 490 struct vnode *vp = ap->a_vp; 491 struct vattr *vap = ap->a_vap; 492 struct ucred *cred = ap->a_cred; 493 struct proc *p = curproc; 494 int error = 0; 495 496 KASSERT(VOP_ISLOCKED(vp)); 497 498 /* Abort if any unsettable attribute is given. */ 499 if (vap->va_type != VNON || vap->va_nlink != VNOVAL || 500 vap->va_fsid != VNOVAL || vap->va_fileid != VNOVAL || 501 vap->va_blocksize != VNOVAL || GOODTIME(&vap->va_ctime) || 502 vap->va_gen != VNOVAL || vap->va_rdev != VNOVAL || 503 vap->va_bytes != VNOVAL) { 504 return EINVAL; 505 } 506 if (error == 0 && (vap->va_flags != VNOVAL)) 507 error = tmpfs_chflags(vp, vap->va_flags, cred, p); 508 509 if (error == 0 && (vap->va_size != VNOVAL)) 510 error = tmpfs_chsize(vp, vap->va_size, cred, p); 511 512 if (error == 0 && (vap->va_uid != VNOVAL || vap->va_gid != VNOVAL)) 513 error = tmpfs_chown(vp, vap->va_uid, vap->va_gid, cred, p); 514 515 if (error == 0 && (vap->va_mode != VNOVAL)) 516 error = tmpfs_chmod(vp, vap->va_mode, cred, p); 517 518 if (error == 0 && ((vap->va_vaflags & VA_UTIMES_CHANGE) 519 || GOODTIME(&vap->va_atime) 520 || GOODTIME(&vap->va_mtime))) 521 error = tmpfs_chtimes(vp, &vap->va_atime, &vap->va_mtime, 522 vap->va_vaflags, cred, p); 523 524 return error; 525 } 526 527 int 528 tmpfs_read(void *v) 529 { 530 struct vop_read_args /* { 531 struct vnode *a_vp; 532 struct uio *a_uio; 533 int a_ioflag; 534 struct ucred *a_cred; 535 } */ *ap = v; 536 struct vnode *vp = ap->a_vp; 537 struct uio *uio = ap->a_uio; 538 /* const int ioflag = ap->a_ioflag; */ 539 tmpfs_node_t *node; 540 int error; 541 542 KASSERT(VOP_ISLOCKED(vp)); 543 544 if (vp->v_type != VREG) { 545 return EISDIR; 546 } 547 if (uio->uio_offset < 0) { 548 return EINVAL; 549 } 550 if (uio->uio_resid == 0) 551 return 0; 552 553 node = VP_TO_TMPFS_NODE(vp); 554 error = 0; 555 556 while (error == 0 && uio->uio_resid > 0) { 557 vsize_t len; 558 559 if (node->tn_size <= uio->uio_offset) { 560 break; 561 } 562 len = MIN(node->tn_size - uio->uio_offset, uio->uio_resid); 563 if (len == 0) { 564 break; 565 } 566 error = tmpfs_uiomove(node, uio, len); 567 } 568 569 if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) 570 tmpfs_update(node, TMPFS_NODE_ACCESSED); 571 572 return error; 573 } 574 575 int 576 tmpfs_write(void *v) 577 { 578 struct vop_write_args /* { 579 struct vnode *a_vp; 580 struct uio *a_uio; 581 int a_ioflag; 582 kauth_cred_t a_cred; 583 } */ *ap = v; 584 struct vnode *vp = ap->a_vp; 585 struct uio *uio = ap->a_uio; 586 const int ioflag = ap->a_ioflag; 587 tmpfs_node_t *node; 588 off_t oldsize; 589 ssize_t overrun; 590 int extended; 591 int error; 592 593 KASSERT(VOP_ISLOCKED(vp)); 594 595 node = VP_TO_TMPFS_NODE(vp); 596 oldsize = node->tn_size; 597 598 if (vp->v_type != VREG) 599 return (EINVAL); 600 601 if (uio->uio_resid == 0) 602 return (0); 603 604 if (ioflag & IO_APPEND) { 605 uio->uio_offset = node->tn_size; 606 } 607 608 if (uio->uio_offset < 0 || 609 (u_int64_t)uio->uio_offset + uio->uio_resid > LLONG_MAX) 610 return (EFBIG); 611 612 /* do the filesize rlimit check */ 613 if ((error = vn_fsizechk(vp, uio, ioflag, &overrun))) 614 return (error); 615 616 extended = uio->uio_offset + uio->uio_resid > node->tn_size; 617 if (extended) { 618 error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid); 619 if (error) 620 goto out; 621 } 622 623 error = 0; 624 while (error == 0 && uio->uio_resid > 0) { 625 vsize_t len; 626 uvm_vnp_uncache(vp); 627 len = MIN(node->tn_size - uio->uio_offset, uio->uio_resid); 628 if (len == 0) { 629 break; 630 } 631 error = tmpfs_uiomove(node, uio, len); 632 } 633 if (error) { 634 (void)tmpfs_reg_resize(vp, oldsize); 635 } 636 637 tmpfs_update(node, TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED); 638 if (extended) 639 VN_KNOTE(vp, NOTE_WRITE | NOTE_EXTEND); 640 else 641 VN_KNOTE(vp, NOTE_WRITE); 642 out: 643 if (error) { 644 KASSERT(oldsize == node->tn_size); 645 } else { 646 KASSERT(uio->uio_resid == 0); 647 648 /* correct the result for writes clamped by vn_fsizechk() */ 649 uio->uio_resid += overrun; 650 651 } 652 return error; 653 } 654 655 int 656 tmpfs_fsync(void *v) 657 { 658 #ifdef DIAGNOSTIC 659 struct vop_fsync_args /* { 660 struct vnode *a_vp; 661 struct ucred *a_cred; 662 int a_flags; 663 off_t a_offlo; 664 off_t a_offhi; 665 struct lwp *a_l; 666 } */ *ap = v; 667 struct vnode *vp = ap->a_vp; 668 669 /* Nothing to do. Just update. */ 670 KASSERT(VOP_ISLOCKED(vp)); 671 #endif 672 return 0; 673 } 674 675 /* 676 * tmpfs_remove: unlink a file. 677 * 678 * => Both directory (dvp) and file (vp) are locked. 679 * => We unlock and drop the reference on both. 680 */ 681 int 682 tmpfs_remove(void *v) 683 { 684 struct vop_remove_args /* { 685 struct vnode *a_dvp; 686 struct vnode *a_vp; 687 struct componentname *a_cnp; 688 } */ *ap = v; 689 struct vnode *dvp = ap->a_dvp, *vp = ap->a_vp; 690 struct componentname *cnp = ap->a_cnp; 691 tmpfs_node_t *dnode, *node; 692 tmpfs_dirent_t *de; 693 int error; 694 695 KASSERT(cnp->cn_flags & HASBUF); 696 697 if (vp->v_type == VDIR) { 698 error = EPERM; 699 goto out; 700 } 701 702 dnode = VP_TO_TMPFS_NODE(dvp); 703 node = VP_TO_TMPFS_NODE(vp); 704 705 /* Files marked as immutable or append-only cannot be deleted. */ 706 if (node->tn_flags & (IMMUTABLE | APPEND)) { 707 error = EPERM; 708 goto out; 709 } 710 711 /* 712 * Likewise, files residing on directories marked as append-only cannot 713 * be deleted. 714 */ 715 if (dnode->tn_flags & APPEND) { 716 error = EPERM; 717 goto out; 718 } 719 720 /* Lookup the directory entry (check the cached hint first). */ 721 de = tmpfs_dir_cached(node); 722 if (de == NULL) { 723 de = tmpfs_dir_lookup(dnode, cnp); 724 } 725 726 KASSERT(de && de->td_node == node); 727 728 /* 729 * Remove the entry from the directory (drops the link count) and 730 * destroy it. 731 * Note: the inode referred by it will not be destroyed 732 * until the vnode is reclaimed/recycled. 733 */ 734 tmpfs_dir_detach(dnode, de); 735 tmpfs_free_dirent(VFS_TO_TMPFS(vp->v_mount), de); 736 if (node->tn_links > 0) { 737 /* We removed a hard link. */ 738 tmpfs_update(node, TMPFS_NODE_CHANGED); 739 } 740 error = 0; 741 out: 742 pool_put(&namei_pool, cnp->cn_pnbuf); 743 return error; 744 } 745 746 /* 747 * tmpfs_link: create a hard link. 748 */ 749 int 750 tmpfs_link(void *v) 751 { 752 struct vop_link_args /* { 753 struct vnode *a_dvp; 754 struct vnode *a_vp; 755 struct componentname *a_cnp; 756 } */ *ap = v; 757 struct vnode *dvp = ap->a_dvp; 758 struct vnode *vp = ap->a_vp; 759 struct componentname *cnp = ap->a_cnp; 760 tmpfs_node_t *dnode, *node; 761 tmpfs_dirent_t *de; 762 int error; 763 764 KASSERT(VOP_ISLOCKED(dvp)); 765 KASSERT(dvp != vp); 766 767 dnode = VP_TO_TMPFS_DIR(dvp); 768 node = VP_TO_TMPFS_NODE(vp); 769 770 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 771 772 /* Check for maximum number of links limit. */ 773 if (node->tn_links == LINK_MAX) { 774 error = EMLINK; 775 goto out; 776 } 777 KASSERT(node->tn_links < LINK_MAX); 778 779 /* We cannot create links of files marked immutable or append-only. */ 780 if (node->tn_flags & (IMMUTABLE | APPEND)) { 781 error = EPERM; 782 goto out; 783 } 784 785 if (TMPFS_DIRSEQ_FULL(dnode)) { 786 error = ENOSPC; 787 goto out; 788 } 789 790 /* Allocate a new directory entry to represent the inode. */ 791 error = tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), 792 cnp->cn_nameptr, cnp->cn_namelen, &de); 793 if (error) { 794 goto out; 795 } 796 797 /* 798 * Insert the entry into the directory. 799 * It will increase the inode link count. 800 */ 801 tmpfs_dir_attach(dnode, de, node); 802 803 /* Update the timestamps and trigger the event. */ 804 if (node->tn_vnode) { 805 VN_KNOTE(node->tn_vnode, NOTE_LINK); 806 } 807 tmpfs_update(node, TMPFS_NODE_CHANGED); 808 error = 0; 809 out: 810 pool_put(&namei_pool, cnp->cn_pnbuf); 811 VOP_UNLOCK(vp); 812 vput(dvp); 813 return error; 814 } 815 816 int 817 tmpfs_mkdir(void *v) 818 { 819 struct vop_mkdir_args /* { 820 struct vnode *a_dvp; 821 struct vnode **a_vpp; 822 struct componentname *a_cnp; 823 struct vattr *a_vap; 824 } */ *ap = v; 825 struct vnode *dvp = ap->a_dvp; 826 struct vnode **vpp = ap->a_vpp; 827 struct componentname *cnp = ap->a_cnp; 828 struct vattr *vap = ap->a_vap; 829 int error; 830 831 KASSERT(vap->va_type == VDIR); 832 error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); 833 vput(dvp); 834 return error; 835 } 836 837 int 838 tmpfs_rmdir(void *v) 839 { 840 struct vop_rmdir_args /* { 841 struct vnode *a_dvp; 842 struct vnode *a_vp; 843 struct componentname *a_cnp; 844 } */ *ap = v; 845 struct vnode *dvp = ap->a_dvp; 846 struct vnode *vp = ap->a_vp; 847 struct componentname *cnp = ap->a_cnp; 848 tmpfs_mount_t *tmp = VFS_TO_TMPFS(dvp->v_mount); 849 tmpfs_node_t *dnode = VP_TO_TMPFS_DIR(dvp); 850 tmpfs_node_t *node = VP_TO_TMPFS_DIR(vp); 851 tmpfs_dirent_t *de; 852 int error = 0; 853 854 KASSERT(VOP_ISLOCKED(dvp)); 855 KASSERT(VOP_ISLOCKED(vp)); 856 KASSERT(cnp->cn_flags & HASBUF); 857 858 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[0] == '.' && 859 cnp->cn_nameptr[1] == '.') { 860 error = ENOTEMPTY; 861 goto out; 862 } 863 864 KASSERT(node->tn_spec.tn_dir.tn_parent == dnode); 865 866 /* 867 * Directories with more than two entries ('.' and '..') cannot be 868 * removed. 869 */ 870 if (node->tn_size > 0) { 871 KASSERT(error == 0); 872 TAILQ_FOREACH(de, &node->tn_spec.tn_dir.tn_dir, td_entries) { 873 error = ENOTEMPTY; 874 break; 875 } 876 if (error) 877 goto out; 878 } 879 880 /* Lookup the directory entry (check the cached hint first). */ 881 de = tmpfs_dir_cached(node); 882 if (de == NULL) 883 de = tmpfs_dir_lookup(dnode, cnp); 884 885 KASSERT(de && de->td_node == node); 886 887 /* Check flags to see if we are allowed to remove the directory. */ 888 if (dnode->tn_flags & APPEND || node->tn_flags & (IMMUTABLE | APPEND)) { 889 error = EPERM; 890 goto out; 891 } 892 893 /* Decrement the link count for the virtual '.' entry. */ 894 node->tn_links--; 895 tmpfs_update(node, TMPFS_NODE_STATUSALL); 896 897 /* Detach the directory entry from the directory. */ 898 tmpfs_dir_detach(dnode, de); 899 900 /* Purge the cache for parent. */ 901 cache_purge(dvp); 902 903 /* 904 * Destroy the directory entry. 905 * Note: the inode referred by it will not be destroyed 906 * until the vnode is reclaimed. 907 */ 908 tmpfs_free_dirent(tmp, de); 909 KASSERT(TAILQ_FIRST(&node->tn_spec.tn_dir.tn_dir) == NULL); 910 911 KASSERT(node->tn_links == 0); 912 out: 913 pool_put(&namei_pool, cnp->cn_pnbuf); 914 /* Release the nodes. */ 915 vput(dvp); 916 vput(vp); 917 return error; 918 } 919 920 int 921 tmpfs_symlink(void *v) 922 { 923 struct vop_symlink_args /* { 924 struct vnode *a_dvp; 925 struct vnode **a_vpp; 926 struct componentname *a_cnp; 927 struct vattr *a_vap; 928 char *a_target; 929 } */ *ap = v; 930 struct vnode *dvp = ap->a_dvp; 931 struct vnode **vpp = ap->a_vpp; 932 struct componentname *cnp = ap->a_cnp; 933 struct vattr *vap = ap->a_vap; 934 char *target = ap->a_target; 935 int error; 936 937 KASSERT(vap->va_type == 0); 938 vap->va_type = VLNK; 939 940 error = tmpfs_alloc_file(dvp, vpp, vap, cnp, target); 941 vput(dvp); 942 if (error == 0) 943 vput(*vpp); 944 945 return error; 946 } 947 948 int 949 tmpfs_readdir(void *v) 950 { 951 struct vop_readdir_args /* { 952 struct vnode *a_vp; 953 struct uio *a_uio; 954 kauth_cred_t a_cred; 955 int *a_eofflag; 956 } */ *ap = v; 957 struct vnode *vp = ap->a_vp; 958 struct uio *uio = ap->a_uio; 959 int *eofflag = ap->a_eofflag; 960 tmpfs_node_t *node; 961 int error; 962 963 KASSERT(VOP_ISLOCKED(vp)); 964 965 /* This operation only makes sense on directory nodes. */ 966 if (vp->v_type != VDIR) { 967 return ENOTDIR; 968 } 969 node = VP_TO_TMPFS_DIR(vp); 970 /* 971 * Retrieve the directory entries, unless it is being destroyed. 972 */ 973 if (node->tn_links) { 974 error = tmpfs_dir_getdents(node, uio); 975 } else { 976 error = 0; 977 } 978 979 if (eofflag != NULL) { 980 *eofflag = !error && uio->uio_offset == TMPFS_DIRSEQ_EOF; 981 } 982 return error; 983 } 984 985 int 986 tmpfs_readlink(void *v) 987 { 988 struct vop_readlink_args /* { 989 struct vnode *a_vp; 990 struct uio *a_uio; 991 kauth_cred_t a_cred; 992 } */ *ap = v; 993 struct vnode *vp = ap->a_vp; 994 struct uio *uio = ap->a_uio; 995 tmpfs_node_t *node; 996 int error; 997 998 KASSERT(VOP_ISLOCKED(vp)); 999 KASSERT(uio->uio_offset == 0); 1000 KASSERT(vp->v_type == VLNK); 1001 1002 node = VP_TO_TMPFS_NODE(vp); 1003 error = uiomove(node->tn_spec.tn_lnk.tn_link, 1004 MIN((size_t)node->tn_size, uio->uio_resid), uio); 1005 1006 if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) 1007 tmpfs_update(node, TMPFS_NODE_ACCESSED); 1008 1009 return error; 1010 } 1011 1012 int 1013 tmpfs_inactive(void *v) 1014 { 1015 struct vop_inactive_args /* { 1016 struct vnode *a_vp; 1017 int *a_recycle; 1018 } */ *ap = v; 1019 struct vnode *vp = ap->a_vp; 1020 tmpfs_node_t *node; 1021 1022 KASSERT(VOP_ISLOCKED(vp)); 1023 1024 node = VP_TO_TMPFS_NODE(vp); 1025 1026 if (vp->v_type == VREG && tmpfs_uio_cached(node)) 1027 tmpfs_uio_uncache(node); 1028 1029 VOP_UNLOCK(vp); 1030 1031 /* 1032 * If we are done with the node, reclaim it so that it can be reused 1033 * immediately. 1034 */ 1035 if (node->tn_links == 0) 1036 vrecycle(vp, curproc); 1037 1038 return 0; 1039 } 1040 1041 int 1042 tmpfs_reclaim(void *v) 1043 { 1044 struct vop_reclaim_args /* { 1045 struct vnode *a_vp; 1046 } */ *ap = v; 1047 struct vnode *vp = ap->a_vp; 1048 tmpfs_mount_t *tmp = VFS_TO_TMPFS(vp->v_mount); 1049 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 1050 int racing; 1051 1052 /* Disassociate inode from vnode. */ 1053 rw_enter_write(&node->tn_nlock); 1054 node->tn_vnode = NULL; 1055 vp->v_data = NULL; 1056 /* Check if tmpfs_vnode_get() is racing with us. */ 1057 racing = TMPFS_NODE_RECLAIMING(node); 1058 rw_exit_write(&node->tn_nlock); 1059 1060 cache_purge(vp); 1061 1062 /* 1063 * If inode is not referenced, i.e. no links, then destroy it. 1064 * Note: if racing - inode is about to get a new vnode, leave it. 1065 */ 1066 if (node->tn_links == 0 && !racing) { 1067 tmpfs_free_node(tmp, node); 1068 } 1069 return 0; 1070 } 1071 1072 int 1073 tmpfs_pathconf(void *v) 1074 { 1075 struct vop_pathconf_args /* { 1076 struct vnode *a_vp; 1077 int a_name; 1078 register_t *a_retval; 1079 } */ *ap = v; 1080 const int name = ap->a_name; 1081 register_t *retval = ap->a_retval; 1082 int error = 0; 1083 1084 switch (name) { 1085 case _PC_LINK_MAX: 1086 *retval = LINK_MAX; 1087 break; 1088 case _PC_NAME_MAX: 1089 *retval = TMPFS_MAXNAMLEN; 1090 break; 1091 case _PC_CHOWN_RESTRICTED: 1092 *retval = 1; 1093 break; 1094 case _PC_NO_TRUNC: 1095 *retval = 1; 1096 break; 1097 case _PC_FILESIZEBITS: 1098 *retval = 64; 1099 break; 1100 case _PC_TIMESTAMP_RESOLUTION: 1101 *retval = 1; 1102 break; 1103 default: 1104 error = EINVAL; 1105 } 1106 return error; 1107 } 1108 1109 int 1110 tmpfs_advlock(void *v) 1111 { 1112 struct vop_advlock_args /* { 1113 struct vnode *a_vp; 1114 void * a_id; 1115 int a_op; 1116 struct flock *a_fl; 1117 int a_flags; 1118 } */ *ap = v; 1119 struct vnode *vp = ap->a_vp; 1120 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 1121 1122 return lf_advlock(&node->tn_lockf, node->tn_size, ap->a_id, ap->a_op, 1123 ap->a_fl, ap->a_flags); 1124 } 1125 1126 int 1127 tmpfs_print(void *v) 1128 { 1129 #if defined(DEBUG) || defined(DIAGNOSTIC) || defined(VFSLCKDEBUG) 1130 struct vop_print_args /* { 1131 struct vnode *a_vp; 1132 } */ *ap = v; 1133 struct vnode *vp = ap->a_vp; 1134 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 1135 1136 printf("tag VT_TMPFS, tmpfs_node %p, flags 0x%x, links %d\n" 1137 "\tmode 0%o, owner %d, group %d, size %lld", 1138 node, node->tn_flags, node->tn_links, node->tn_mode, node->tn_uid, 1139 node->tn_gid, node->tn_size); 1140 #ifdef FIFO 1141 if (vp->v_type == VFIFO) 1142 fifo_printinfo(vp); 1143 #endif 1144 printf("\n"); 1145 #endif 1146 return 0; 1147 } 1148 1149 /* a null op */ 1150 int 1151 tmpfs_bwrite(void *v) 1152 { 1153 return 0; 1154 } 1155 1156 int 1157 tmpfs_strategy(void *v) 1158 { 1159 return EOPNOTSUPP; 1160 } 1161 1162 int 1163 tmpfs_ioctl(void *v) 1164 { 1165 return ENOTTY; 1166 } 1167 1168 int 1169 tmpfs_lock(void *v) 1170 { 1171 struct vop_lock_args *ap = v; 1172 tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); 1173 1174 return rrw_enter(&tnp->tn_vlock, ap->a_flags & LK_RWFLAGS); 1175 } 1176 1177 int 1178 tmpfs_unlock(void *v) 1179 { 1180 struct vop_unlock_args *ap = v; 1181 tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); 1182 1183 rrw_exit(&tnp->tn_vlock); 1184 return 0; 1185 } 1186 1187 int 1188 tmpfs_islocked(void *v) 1189 { 1190 struct vop_islocked_args *ap = v; 1191 tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); 1192 1193 return rrw_status(&tnp->tn_vlock); 1194 } 1195 1196 /* 1197 * tmpfs_rename: rename routine, the hairiest system call, with the 1198 * insane API. 1199 * 1200 * Arguments: fdvp (from-parent vnode), fvp (from-leaf), tdvp (to-parent) 1201 * and tvp (to-leaf), if exists (NULL if not). 1202 * 1203 * => Caller holds a reference on fdvp and fvp, they are unlocked. 1204 * Note: fdvp and fvp can refer to the same object (i.e. when it is root). 1205 * 1206 * => Both tdvp and tvp are referenced and locked. It is our responsibility 1207 * to release the references and unlock them (or destroy). 1208 */ 1209 1210 /* 1211 * First, some forward declarations of subroutines. 1212 */ 1213 1214 int tmpfs_sane_rename(struct vnode *, struct componentname *, 1215 struct vnode *, struct componentname *, struct ucred *, int); 1216 int tmpfs_rename_enter(struct mount *, struct tmpfs_mount *, 1217 struct ucred *, 1218 struct vnode *, struct tmpfs_node *, struct componentname *, 1219 struct tmpfs_dirent **, struct vnode **, 1220 struct vnode *, struct tmpfs_node *, struct componentname *, 1221 struct tmpfs_dirent **, struct vnode **); 1222 int tmpfs_rename_enter_common(struct mount *, struct tmpfs_mount *, 1223 struct ucred *, 1224 struct vnode *, struct tmpfs_node *, 1225 struct componentname *, struct tmpfs_dirent **, struct vnode **, 1226 struct componentname *, struct tmpfs_dirent **, struct vnode **); 1227 int tmpfs_rename_enter_separate(struct mount *, struct tmpfs_mount *, 1228 struct ucred *, 1229 struct vnode *, struct tmpfs_node *, struct componentname *, 1230 struct tmpfs_dirent **, struct vnode **, 1231 struct vnode *, struct tmpfs_node *, struct componentname *, 1232 struct tmpfs_dirent **, struct vnode **); 1233 void tmpfs_rename_exit(struct tmpfs_mount *, 1234 struct vnode *, struct vnode *, struct vnode *, struct vnode *); 1235 int tmpfs_rename_lock_directory(struct vnode *, struct tmpfs_node *); 1236 int tmpfs_rename_genealogy(struct tmpfs_node *, struct tmpfs_node *, 1237 struct tmpfs_node **); 1238 int tmpfs_rename_lock(struct mount *, struct ucred *, int, 1239 struct vnode *, struct tmpfs_node *, struct componentname *, int, 1240 struct tmpfs_dirent **, struct vnode **, 1241 struct vnode *, struct tmpfs_node *, struct componentname *, int, 1242 struct tmpfs_dirent **, struct vnode **); 1243 void tmpfs_rename_attachdetach(struct tmpfs_mount *, 1244 struct vnode *, struct tmpfs_dirent *, struct vnode *, 1245 struct vnode *, struct tmpfs_dirent *, struct vnode *); 1246 int tmpfs_do_remove(struct tmpfs_mount *, struct vnode *, 1247 struct tmpfs_node *, struct tmpfs_dirent *, struct vnode *, struct ucred *); 1248 int tmpfs_rename_check_possible(struct tmpfs_node *, 1249 struct tmpfs_node *, struct tmpfs_node *, struct tmpfs_node *); 1250 int tmpfs_rename_check_permitted(struct ucred *, 1251 struct tmpfs_node *, struct tmpfs_node *, 1252 struct tmpfs_node *, struct tmpfs_node *); 1253 int tmpfs_remove_check_possible(struct tmpfs_node *, 1254 struct tmpfs_node *); 1255 int tmpfs_remove_check_permitted(struct ucred *, 1256 struct tmpfs_node *, struct tmpfs_node *); 1257 int tmpfs_check_sticky(struct ucred *, 1258 struct tmpfs_node *, struct tmpfs_node *); 1259 void tmpfs_rename_cache_purge(struct vnode *, struct vnode *, struct vnode *, 1260 struct vnode *); 1261 void tmpfs_rename_abort(void *); 1262 1263 int 1264 tmpfs_rename(void *v) 1265 { 1266 struct vop_rename_args /* { 1267 struct vnode *a_fdvp; 1268 struct vnode *a_fvp; 1269 struct componentname *a_fcnp; 1270 struct vnode *a_tdvp; 1271 struct vnode *a_tvp; 1272 struct componentname *a_tcnp; 1273 } */ *ap = v; 1274 struct vnode *fdvp = ap->a_fdvp; 1275 struct vnode *fvp = ap->a_fvp; 1276 struct componentname *fcnp = ap->a_fcnp; 1277 struct vnode *tdvp = ap->a_tdvp; 1278 struct vnode *tvp = ap->a_tvp; 1279 struct componentname *tcnp = ap->a_tcnp; 1280 struct ucred *cred; 1281 int error; 1282 1283 KASSERT(fdvp != NULL); 1284 KASSERT(fvp != NULL); 1285 KASSERT(fcnp != NULL); 1286 KASSERT(fcnp->cn_nameptr != NULL); 1287 KASSERT(tdvp != NULL); 1288 KASSERT(tcnp != NULL); 1289 KASSERT(fcnp->cn_nameptr != NULL); 1290 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */ 1291 /* KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */ 1292 KASSERT(fdvp->v_type == VDIR); 1293 KASSERT(tdvp->v_type == VDIR); 1294 KASSERT(fcnp->cn_flags & HASBUF); 1295 KASSERT(tcnp->cn_flags & HASBUF); 1296 1297 cred = fcnp->cn_cred; 1298 KASSERT(tcnp->cn_cred == cred); 1299 1300 /* 1301 * Check for cross-device rename. 1302 * Also don't allow renames of mount points. 1303 */ 1304 if (fvp->v_mount != tdvp->v_mount || 1305 fdvp->v_mount != fvp->v_mount || 1306 (tvp != NULL && (fvp->v_mount != tvp->v_mount))) { 1307 tmpfs_rename_abort(v); 1308 return EXDEV; 1309 } 1310 1311 /* 1312 * Can't check the locks on these until we know they're on 1313 * the same FS, as not all FS do locking the same way. 1314 */ 1315 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1316 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 1317 1318 /* 1319 * Reject renaming '.' and '..'. 1320 */ 1321 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || 1322 (fcnp->cn_namelen == 2 && fcnp->cn_nameptr[0] == '.' && 1323 fcnp->cn_nameptr[1] == '.')) { 1324 tmpfs_rename_abort(v); 1325 return EINVAL; 1326 } 1327 1328 /* 1329 * Sanitize our world from the VFS insanity. Unlock the target 1330 * directory and node, which are locked. Release the children, 1331 * which are referenced. Check for rename("x", "y/."), which 1332 * it is our responsibility to reject, not the caller's. (But 1333 * the caller does reject rename("x/.", "y"). Go figure.) 1334 */ 1335 1336 VOP_UNLOCK(tdvp); 1337 if ((tvp != NULL) && (tvp != tdvp)) 1338 VOP_UNLOCK(tvp); 1339 1340 vrele(fvp); 1341 if (tvp != NULL) 1342 vrele(tvp); 1343 1344 if (tvp == tdvp) { 1345 error = EINVAL; 1346 goto out; 1347 } 1348 1349 error = tmpfs_sane_rename(fdvp, fcnp, tdvp, tcnp, cred, 0); 1350 1351 out: /* 1352 * All done, whether with success or failure. Release the 1353 * directory nodes now, as the caller expects from the VFS 1354 * protocol. 1355 */ 1356 vrele(fdvp); 1357 vrele(tdvp); 1358 1359 return error; 1360 } 1361 1362 /* 1363 * tmpfs_sane_rename: rename routine, the hairiest system call, with 1364 * the sane API. 1365 * 1366 * Arguments: 1367 * 1368 * . fdvp (from directory vnode), 1369 * . fcnp (from component name), 1370 * . tdvp (to directory vnode), and 1371 * . tcnp (to component name). 1372 * 1373 * fdvp and tdvp must be referenced and unlocked. 1374 */ 1375 int 1376 tmpfs_sane_rename(struct vnode *fdvp, struct componentname *fcnp, 1377 struct vnode *tdvp, struct componentname *tcnp, struct ucred *cred, 1378 int posixly_correct) 1379 { 1380 struct mount *mount; 1381 struct tmpfs_mount *tmpfs; 1382 struct tmpfs_node *fdnode, *tdnode; 1383 struct tmpfs_dirent *fde, *tde; 1384 struct vnode *fvp, *tvp; 1385 char *newname; 1386 int error; 1387 1388 KASSERT(fdvp != NULL); 1389 KASSERT(fcnp != NULL); 1390 KASSERT(tdvp != NULL); 1391 KASSERT(tcnp != NULL); 1392 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */ 1393 /* KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */ 1394 KASSERT(fdvp->v_type == VDIR); 1395 KASSERT(tdvp->v_type == VDIR); 1396 KASSERT(fdvp->v_mount == tdvp->v_mount); 1397 KASSERT((fcnp->cn_flags & ISDOTDOT) == 0); 1398 KASSERT((tcnp->cn_flags & ISDOTDOT) == 0); 1399 KASSERT((fcnp->cn_namelen != 1) || (fcnp->cn_nameptr[0] != '.')); 1400 KASSERT((tcnp->cn_namelen != 1) || (tcnp->cn_nameptr[0] != '.')); 1401 KASSERT((fcnp->cn_namelen != 2) || (fcnp->cn_nameptr[0] != '.') || 1402 (fcnp->cn_nameptr[1] != '.')); 1403 KASSERT((tcnp->cn_namelen != 2) || (tcnp->cn_nameptr[0] != '.') || 1404 (tcnp->cn_nameptr[1] != '.')); 1405 1406 /* 1407 * Pull out the tmpfs data structures. 1408 */ 1409 fdnode = VP_TO_TMPFS_NODE(fdvp); 1410 tdnode = VP_TO_TMPFS_NODE(tdvp); 1411 KASSERT(fdnode != NULL); 1412 KASSERT(tdnode != NULL); 1413 KASSERT(fdnode->tn_vnode == fdvp); 1414 KASSERT(tdnode->tn_vnode == tdvp); 1415 KASSERT(fdnode->tn_type == VDIR); 1416 KASSERT(tdnode->tn_type == VDIR); 1417 1418 mount = fdvp->v_mount; 1419 KASSERT(mount != NULL); 1420 KASSERT(mount == tdvp->v_mount); 1421 /* XXX How can we be sure this stays true? (Not that you're 1422 * likely to mount a tmpfs read-only...) */ 1423 KASSERT((mount->mnt_flag & MNT_RDONLY) == 0); 1424 tmpfs = VFS_TO_TMPFS(mount); 1425 KASSERT(tmpfs != NULL); 1426 1427 /* 1428 * Decide whether we need a new name, and allocate memory for 1429 * it if so. Do this before locking anything or taking 1430 * destructive actions so that we can back out safely and sleep 1431 * safely. XXX Is sleeping an issue here? Can this just be 1432 * moved into tmpfs_rename_attachdetach? 1433 */ 1434 if (tmpfs_strname_neqlen(fcnp, tcnp)) { 1435 newname = tmpfs_strname_alloc(tmpfs, tcnp->cn_namelen); 1436 if (newname == NULL) { 1437 error = ENOSPC; 1438 goto out_unlocked; 1439 } 1440 } else { 1441 newname = NULL; 1442 } 1443 1444 /* 1445 * Lock and look up everything. GCC is not very clever. 1446 */ 1447 fde = tde = NULL; 1448 fvp = tvp = NULL; 1449 error = tmpfs_rename_enter(mount, tmpfs, cred, 1450 fdvp, fdnode, fcnp, &fde, &fvp, 1451 tdvp, tdnode, tcnp, &tde, &tvp); 1452 if (error) 1453 goto out_unlocked; 1454 1455 /* 1456 * Check that everything is locked and looks right. 1457 */ 1458 KASSERT(fde != NULL); 1459 KASSERT(fvp != NULL); 1460 KASSERT(fde->td_node != NULL); 1461 KASSERT(fde->td_node->tn_vnode == fvp); 1462 KASSERT(fde->td_node->tn_type == fvp->v_type); 1463 KASSERT((tde == NULL) == (tvp == NULL)); 1464 KASSERT((tde == NULL) || (tde->td_node != NULL)); 1465 KASSERT((tde == NULL) || (tde->td_node->tn_vnode == tvp)); 1466 KASSERT((tde == NULL) || (tde->td_node->tn_type == tvp->v_type)); 1467 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 1468 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1469 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 1470 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 1471 1472 /* 1473 * If the source and destination are the same object, we need 1474 * only at most delete the source entry. 1475 */ 1476 if (fvp == tvp) { 1477 KASSERT(tvp != NULL); 1478 if (fde->td_node->tn_type == VDIR) { 1479 /* XXX How can this possibly happen? */ 1480 error = EINVAL; 1481 goto out_locked; 1482 } 1483 if (!posixly_correct && (fde != tde)) { 1484 /* XXX Doesn't work because of locking. 1485 * error = VOP_REMOVE(fdvp, fvp); 1486 */ 1487 error = tmpfs_do_remove(tmpfs, fdvp, fdnode, fde, fvp, 1488 cred); 1489 if (error) 1490 goto out_locked; 1491 } 1492 goto success; 1493 } 1494 KASSERT(fde != tde); 1495 KASSERT(fvp != tvp); 1496 1497 /* 1498 * If the target exists, refuse to rename a directory over a 1499 * non-directory or vice versa, or to clobber a non-empty 1500 * directory. 1501 */ 1502 if (tvp != NULL) { 1503 KASSERT(tde != NULL); 1504 KASSERT(tde->td_node != NULL); 1505 if (fvp->v_type == VDIR && tvp->v_type == VDIR) 1506 error = ((tde->td_node->tn_size > 0)? ENOTEMPTY : 0); 1507 else if (fvp->v_type == VDIR && tvp->v_type != VDIR) 1508 error = ENOTDIR; 1509 else if (fvp->v_type != VDIR && tvp->v_type == VDIR) 1510 error = EISDIR; 1511 else 1512 error = 0; 1513 if (error) 1514 goto out_locked; 1515 KASSERT((fvp->v_type == VDIR) == (tvp->v_type == VDIR)); 1516 } 1517 1518 /* 1519 * Authorize the rename. 1520 */ 1521 error = tmpfs_rename_check_possible(fdnode, fde->td_node, 1522 tdnode, (tde? tde->td_node : NULL)); 1523 if (error) 1524 goto out_locked; 1525 error = tmpfs_rename_check_permitted(cred, fdnode, fde->td_node, 1526 tdnode, (tde? tde->td_node : NULL)); 1527 if (error) 1528 goto out_locked; 1529 1530 /* 1531 * Everything is hunky-dory. Shuffle the directory entries. 1532 */ 1533 tmpfs_rename_attachdetach(tmpfs, fdvp, fde, fvp, tdvp, tde, tvp); 1534 1535 /* 1536 * Update the directory entry's name necessary, and flag 1537 * metadata updates. A memory allocation failure here is not 1538 * OK because we've already committed some changes that we 1539 * can't back out at this point, and we have things locked so 1540 * we can't sleep, hence the early allocation above. 1541 */ 1542 if (newname != NULL) { 1543 KASSERT(tcnp->cn_namelen <= TMPFS_MAXNAMLEN); 1544 1545 tmpfs_strname_free(tmpfs, fde->td_name, fde->td_namelen); 1546 fde->td_namelen = (uint16_t)tcnp->cn_namelen; 1547 (void)memcpy(newname, tcnp->cn_nameptr, tcnp->cn_namelen); 1548 /* Commit newname and don't free it on the way out. */ 1549 fde->td_name = newname; 1550 newname = NULL; 1551 1552 tmpfs_update(fde->td_node, TMPFS_NODE_CHANGED); 1553 tmpfs_update(tdnode, TMPFS_NODE_MODIFIED); 1554 } 1555 1556 success: 1557 VN_KNOTE(fvp, NOTE_RENAME); 1558 tmpfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); 1559 error = 0; 1560 1561 out_locked: 1562 tmpfs_rename_exit(tmpfs, fdvp, fvp, tdvp, tvp); 1563 1564 out_unlocked: 1565 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */ 1566 /* KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */ 1567 /* KASSERT((fvp == NULL) || (VOP_ISLOCKED(fvp) != LK_EXCLUSIVE)); */ 1568 /* KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) != LK_EXCLUSIVE)); */ 1569 1570 if (newname != NULL) 1571 tmpfs_strname_free(tmpfs, newname, tcnp->cn_namelen); 1572 1573 return error; 1574 } 1575 1576 /* 1577 * Look up fcnp in fdnode/fdvp and store its directory entry in fde_ret 1578 * and the associated vnode in fvp_ret; fail if not found. Look up 1579 * tcnp in tdnode/tdvp and store its directory entry in tde_ret and the 1580 * associated vnode in tvp_ret; store null instead if not found. Fail 1581 * if anything has been mounted on any of the nodes involved. 1582 * 1583 * fdvp and tdvp must be referenced. 1584 * 1585 * On entry, nothing is locked. 1586 * 1587 * On success, everything is locked, and *fvp_ret, and *tvp_ret if 1588 * nonnull, are referenced. The only pairs of vnodes that may be 1589 * identical are {fdvp, tdvp} and {fvp, tvp}. 1590 * 1591 * On failure, everything remains as was. 1592 * 1593 * Locking everything including the source and target nodes is 1594 * necessary to make sure that, e.g., link count updates are OK. The 1595 * locking order is, in general, ancestor-first, matching the order you 1596 * need to use to look up a descendant anyway. 1597 */ 1598 int 1599 tmpfs_rename_enter(struct mount *mount, struct tmpfs_mount *tmpfs, 1600 struct ucred *cred, 1601 struct vnode *fdvp, struct tmpfs_node *fdnode, struct componentname *fcnp, 1602 struct tmpfs_dirent **fde_ret, struct vnode **fvp_ret, 1603 struct vnode *tdvp, struct tmpfs_node *tdnode, struct componentname *tcnp, 1604 struct tmpfs_dirent **tde_ret, struct vnode **tvp_ret) 1605 { 1606 int error; 1607 1608 KASSERT(mount != NULL); 1609 KASSERT(tmpfs != NULL); 1610 KASSERT(fdvp != NULL); 1611 KASSERT(fdnode != NULL); 1612 KASSERT(fcnp != NULL); 1613 KASSERT(fde_ret != NULL); 1614 KASSERT(fvp_ret != NULL); 1615 KASSERT(tdvp != NULL); 1616 KASSERT(tdnode != NULL); 1617 KASSERT(tcnp != NULL); 1618 KASSERT(tde_ret != NULL); 1619 KASSERT(tvp_ret != NULL); 1620 KASSERT(fdnode->tn_vnode == fdvp); 1621 KASSERT(tdnode->tn_vnode == tdvp); 1622 KASSERT(fdnode->tn_type == VDIR); 1623 KASSERT(tdnode->tn_type == VDIR); 1624 1625 if (fdvp == tdvp) { 1626 KASSERT(fdnode == tdnode); 1627 error = tmpfs_rename_enter_common(mount, tmpfs, cred, fdvp, 1628 fdnode, fcnp, fde_ret, fvp_ret, tcnp, tde_ret, tvp_ret); 1629 } else { 1630 KASSERT(fdnode != tdnode); 1631 error = tmpfs_rename_enter_separate(mount, tmpfs, cred, 1632 fdvp, fdnode, fcnp, fde_ret, fvp_ret, 1633 tdvp, tdnode, tcnp, tde_ret, tvp_ret); 1634 } 1635 1636 if (error) 1637 return error; 1638 1639 KASSERT(*fde_ret != NULL); 1640 KASSERT(*fvp_ret != NULL); 1641 KASSERT((*tde_ret == NULL) == (*tvp_ret == NULL)); 1642 KASSERT((*tde_ret == NULL) || ((*tde_ret)->td_node != NULL)); 1643 KASSERT((*tde_ret == NULL) || 1644 ((*tde_ret)->td_node->tn_vnode == *tvp_ret)); 1645 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 1646 KASSERT(VOP_ISLOCKED(*fvp_ret) == LK_EXCLUSIVE); 1647 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1648 KASSERT((*tvp_ret == NULL) || 1649 (VOP_ISLOCKED(*tvp_ret) == LK_EXCLUSIVE)); 1650 KASSERT(*fvp_ret != fdvp); 1651 KASSERT(*fvp_ret != tdvp); 1652 KASSERT(*tvp_ret != fdvp); 1653 KASSERT(*tvp_ret != tdvp); 1654 return 0; 1655 } 1656 1657 /* 1658 * Lock and look up with a common source/target directory. 1659 */ 1660 int 1661 tmpfs_rename_enter_common(struct mount *mount, struct tmpfs_mount *tmpfs, 1662 struct ucred *cred, 1663 struct vnode *dvp, struct tmpfs_node *dnode, 1664 struct componentname *fcnp, 1665 struct tmpfs_dirent **fde_ret, struct vnode **fvp_ret, 1666 struct componentname *tcnp, 1667 struct tmpfs_dirent **tde_ret, struct vnode **tvp_ret) 1668 { 1669 struct tmpfs_dirent *fde, *tde; 1670 struct vnode *fvp, *tvp; 1671 int error; 1672 1673 error = tmpfs_rename_lock_directory(dvp, dnode); 1674 if (error) 1675 goto fail0; 1676 1677 /* Did we lose a race with mount? */ 1678 if (dvp->v_mountedhere != NULL) { 1679 error = EBUSY; 1680 goto fail1; 1681 } 1682 1683 /* Make sure the caller may read the directory. */ 1684 error = VOP_ACCESS(dvp, VEXEC, cred, curproc); 1685 if (error) 1686 goto fail1; 1687 1688 /* 1689 * The order in which we lock the source and target nodes is 1690 * irrelevant because there can only be one rename on this 1691 * directory in flight at a time, and we have it locked. 1692 */ 1693 1694 fde = tmpfs_dir_lookup(dnode, fcnp); 1695 if (fde == NULL) { 1696 error = ENOENT; 1697 goto fail1; 1698 } 1699 1700 KASSERT(fde->td_node != NULL); 1701 /* We ruled out `.' earlier. */ 1702 KASSERT(fde->td_node != dnode); 1703 /* We ruled out `..' earlier. */ 1704 KASSERT(fde->td_node != dnode->tn_spec.tn_dir.tn_parent); 1705 rw_enter_write(&fde->td_node->tn_nlock); 1706 error = tmpfs_vnode_get(mount, fde->td_node, &fvp); 1707 if (error) 1708 goto fail1; 1709 KASSERT(fvp != NULL); 1710 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 1711 KASSERT(fvp != dvp); 1712 KASSERT(fvp->v_mount == mount); 1713 1714 /* Refuse to rename a mount point. */ 1715 if ((fvp->v_type == VDIR) && (fvp->v_mountedhere != NULL)) { 1716 error = EBUSY; 1717 goto fail2; 1718 } 1719 1720 tde = tmpfs_dir_lookup(dnode, tcnp); 1721 if (tde == NULL) { 1722 tvp = NULL; 1723 } else { 1724 KASSERT(tde->td_node != NULL); 1725 /* We ruled out `.' earlier. */ 1726 KASSERT(tde->td_node != dnode); 1727 /* We ruled out `..' earlier. */ 1728 KASSERT(tde->td_node != dnode->tn_spec.tn_dir.tn_parent); 1729 if (tde->td_node != fde->td_node) { 1730 rw_enter_write(&tde->td_node->tn_nlock); 1731 error = tmpfs_vnode_get(mount, tde->td_node, &tvp); 1732 if (error) 1733 goto fail2; 1734 KASSERT(tvp->v_mount == mount); 1735 /* Refuse to rename over a mount point. */ 1736 if ((tvp->v_type == VDIR) && 1737 (tvp->v_mountedhere != NULL)) { 1738 error = EBUSY; 1739 goto fail3; 1740 } 1741 } else { 1742 tvp = fvp; 1743 vref(tvp); 1744 } 1745 KASSERT(tvp != NULL); 1746 KASSERT(VOP_ISLOCKED(tvp) == LK_EXCLUSIVE); 1747 } 1748 KASSERT(tvp != dvp); 1749 1750 *fde_ret = fde; 1751 *fvp_ret = fvp; 1752 *tde_ret = tde; 1753 *tvp_ret = tvp; 1754 return 0; 1755 1756 fail3: if (tvp != NULL) { 1757 if (tvp != fvp) 1758 vput(tvp); 1759 else 1760 vrele(tvp); 1761 } 1762 1763 fail2: vput(fvp); 1764 fail1: VOP_UNLOCK(dvp); 1765 fail0: return error; 1766 } 1767 1768 /* 1769 * Lock and look up with separate source and target directories. 1770 */ 1771 int 1772 tmpfs_rename_enter_separate(struct mount *mount, struct tmpfs_mount *tmpfs, 1773 struct ucred *cred, 1774 struct vnode *fdvp, struct tmpfs_node *fdnode, struct componentname *fcnp, 1775 struct tmpfs_dirent **fde_ret, struct vnode **fvp_ret, 1776 struct vnode *tdvp, struct tmpfs_node *tdnode, struct componentname *tcnp, 1777 struct tmpfs_dirent **tde_ret, struct vnode **tvp_ret) 1778 { 1779 struct tmpfs_node *intermediate_node; 1780 struct tmpfs_dirent *fde, *tde; 1781 struct vnode *fvp, *tvp; 1782 int error; 1783 1784 KASSERT(fdvp != tdvp); 1785 KASSERT(fdnode != tdnode); 1786 1787 #if 0 /* XXX */ 1788 mutex_enter(&tmpfs->tm_rename_lock); 1789 #endif 1790 1791 error = tmpfs_rename_genealogy(fdnode, tdnode, &intermediate_node); 1792 if (error) 1793 goto fail; 1794 1795 /* 1796 * intermediate_node == NULL means fdnode is not an ancestor of 1797 * tdnode. 1798 */ 1799 if (intermediate_node == NULL) 1800 error = tmpfs_rename_lock(mount, cred, ENOTEMPTY, 1801 tdvp, tdnode, tcnp, 1, &tde, &tvp, 1802 fdvp, fdnode, fcnp, 0, &fde, &fvp); 1803 else 1804 error = tmpfs_rename_lock(mount, cred, EINVAL, 1805 fdvp, fdnode, fcnp, 0, &fde, &fvp, 1806 tdvp, tdnode, tcnp, 1, &tde, &tvp); 1807 if (error) 1808 goto fail; 1809 1810 KASSERT(fde != NULL); 1811 KASSERT(fde->td_node != NULL); 1812 1813 /* 1814 * Reject rename("foo/bar", "foo/bar/baz/quux/zot"). 1815 */ 1816 if (fde->td_node == intermediate_node) { 1817 tmpfs_rename_exit(tmpfs, fdvp, fvp, tdvp, tvp); 1818 return EINVAL; 1819 } 1820 1821 *fde_ret = fde; 1822 *fvp_ret = fvp; 1823 *tde_ret = tde; 1824 *tvp_ret = tvp; 1825 return 0; 1826 1827 fail: 1828 #if 0 /* XXX */ 1829 mutex_exit(&tmpfs->tm_rename_lock); 1830 #endif 1831 return error; 1832 } 1833 1834 /* 1835 * Unlock everything we locked for rename. 1836 * 1837 * fdvp and tdvp must be referenced. 1838 * 1839 * On entry, everything is locked, and fvp and tvp referenced. 1840 * 1841 * On exit, everything is unlocked, and fvp and tvp are released. 1842 */ 1843 void 1844 tmpfs_rename_exit(struct tmpfs_mount *tmpfs, 1845 struct vnode *fdvp, struct vnode *fvp, 1846 struct vnode *tdvp, struct vnode *tvp) 1847 { 1848 1849 KASSERT(tmpfs != NULL); 1850 KASSERT(fdvp != NULL); 1851 KASSERT(fvp != NULL); 1852 KASSERT(fdvp != fvp); 1853 KASSERT(fdvp != tvp); 1854 KASSERT(tdvp != tvp); 1855 KASSERT(tdvp != fvp); 1856 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 1857 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1858 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 1859 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 1860 1861 if (tvp != NULL) { 1862 if (tvp != fvp) 1863 vput(tvp); 1864 else 1865 vrele(tvp); 1866 } 1867 VOP_UNLOCK(tdvp); 1868 vput(fvp); 1869 if (fdvp != tdvp) 1870 VOP_UNLOCK(fdvp); 1871 1872 #if 0 /* XXX */ 1873 if (fdvp != tdvp) 1874 mutex_exit(&tmpfs->tm_rename_lock); 1875 #endif 1876 } 1877 1878 /* 1879 * Lock a directory, but fail if it has been rmdir'd. 1880 * 1881 * vp must be referenced. 1882 */ 1883 int 1884 tmpfs_rename_lock_directory(struct vnode *vp, struct tmpfs_node *node) 1885 { 1886 1887 KASSERT(vp != NULL); 1888 KASSERT(node != NULL); 1889 KASSERT(node->tn_vnode == vp); 1890 KASSERT(node->tn_type == VDIR); 1891 1892 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1893 if (node->tn_spec.tn_dir.tn_parent == NULL) { 1894 VOP_UNLOCK(vp); 1895 return ENOENT; 1896 } 1897 1898 return 0; 1899 } 1900 1901 /* 1902 * Analyze the genealogy of the source and target nodes. 1903 * 1904 * On success, stores in *intermediate_node_ret either the child of 1905 * fdnode of which tdnode is a descendant, or null if tdnode is not a 1906 * descendant of fdnode at all. 1907 * 1908 * fdnode and tdnode must be unlocked and referenced. The file 1909 * system's rename lock must also be held, to exclude concurrent 1910 * changes to the file system's genealogy other than rmdir. 1911 * 1912 * XXX This causes an extra lock/unlock of tdnode in the case when 1913 * we're just about to lock it again before locking anything else. 1914 * However, changing that requires reorganizing the code to make it 1915 * even more horrifically obscure. 1916 */ 1917 int 1918 tmpfs_rename_genealogy(struct tmpfs_node *fdnode, struct tmpfs_node *tdnode, 1919 struct tmpfs_node **intermediate_node_ret) 1920 { 1921 struct tmpfs_node *node = tdnode, *parent; 1922 int error; 1923 1924 KASSERT(fdnode != NULL); 1925 KASSERT(tdnode != NULL); 1926 KASSERT(fdnode != tdnode); 1927 KASSERT(intermediate_node_ret != NULL); 1928 1929 KASSERT(fdnode->tn_vnode != NULL); 1930 KASSERT(tdnode->tn_vnode != NULL); 1931 KASSERT(fdnode->tn_type == VDIR); 1932 KASSERT(tdnode->tn_type == VDIR); 1933 1934 /* 1935 * We need to provisionally lock tdnode->tn_vnode to keep rmdir 1936 * from deleting it -- or any ancestor -- at an inopportune 1937 * moment. 1938 */ 1939 error = tmpfs_rename_lock_directory(tdnode->tn_vnode, tdnode); 1940 if (error) 1941 return error; 1942 1943 for (;;) { 1944 parent = node->tn_spec.tn_dir.tn_parent; 1945 KASSERT(parent != NULL); 1946 KASSERT(parent->tn_type == VDIR); 1947 1948 /* Did we hit the root without finding fdnode? */ 1949 if (parent == node) { 1950 *intermediate_node_ret = NULL; 1951 break; 1952 } 1953 1954 /* Did we find that fdnode is an ancestor? */ 1955 if (parent == fdnode) { 1956 *intermediate_node_ret = node; 1957 break; 1958 } 1959 1960 /* Neither -- keep ascending the family tree. */ 1961 node = parent; 1962 } 1963 1964 VOP_UNLOCK(tdnode->tn_vnode); 1965 return 0; 1966 } 1967 1968 /* 1969 * Lock directories a and b, which must be distinct, and look up and 1970 * lock nodes a and b. Do a first and then b. Directory b may not be 1971 * an ancestor of directory a, although directory a may be an ancestor 1972 * of directory b. Fail with overlap_error if node a is directory b. 1973 * Neither componentname may be `.' or `..'. 1974 * 1975 * a_dvp and b_dvp must be referenced. 1976 * 1977 * On entry, a_dvp and b_dvp are unlocked. 1978 * 1979 * On success, 1980 * . a_dvp and b_dvp are locked, 1981 * . *a_dirent_ret is filled with a directory entry whose node is 1982 * locked and referenced, 1983 * . *b_vp_ret is filled with the corresponding vnode, 1984 * . *b_dirent_ret is filled either with null or with a directory entry 1985 * whose node is locked and referenced, 1986 * . *b_vp is filled either with null or with the corresponding vnode, 1987 * and 1988 * . the only pair of vnodes that may be identical is a_vp and b_vp. 1989 * 1990 * On failure, a_dvp and b_dvp are left unlocked, and *a_dirent_ret, 1991 * *a_vp, *b_dirent_ret, and *b_vp are left alone. 1992 */ 1993 int 1994 tmpfs_rename_lock(struct mount *mount, struct ucred *cred, int overlap_error, 1995 struct vnode *a_dvp, struct tmpfs_node *a_dnode, 1996 struct componentname *a_cnp, int a_missing_ok, 1997 struct tmpfs_dirent **a_dirent_ret, struct vnode **a_vp_ret, 1998 struct vnode *b_dvp, struct tmpfs_node *b_dnode, 1999 struct componentname *b_cnp, int b_missing_ok, 2000 struct tmpfs_dirent **b_dirent_ret, struct vnode **b_vp_ret) 2001 { 2002 struct tmpfs_dirent *a_dirent, *b_dirent; 2003 struct vnode *a_vp, *b_vp; 2004 int error; 2005 2006 KASSERT(a_dvp != NULL); 2007 KASSERT(a_dnode != NULL); 2008 KASSERT(a_cnp != NULL); 2009 KASSERT(a_dirent_ret != NULL); 2010 KASSERT(a_vp_ret != NULL); 2011 KASSERT(b_dvp != NULL); 2012 KASSERT(b_dnode != NULL); 2013 KASSERT(b_cnp != NULL); 2014 KASSERT(b_dirent_ret != NULL); 2015 KASSERT(b_vp_ret != NULL); 2016 KASSERT(a_dvp != b_dvp); 2017 KASSERT(a_dnode != b_dnode); 2018 KASSERT(a_dnode->tn_vnode == a_dvp); 2019 KASSERT(b_dnode->tn_vnode == b_dvp); 2020 KASSERT(a_dnode->tn_type == VDIR); 2021 KASSERT(b_dnode->tn_type == VDIR); 2022 KASSERT(a_missing_ok != b_missing_ok); 2023 2024 error = tmpfs_rename_lock_directory(a_dvp, a_dnode); 2025 if (error) 2026 goto fail0; 2027 2028 /* Did we lose a race with mount? */ 2029 if (a_dvp->v_mountedhere != NULL) { 2030 error = EBUSY; 2031 goto fail1; 2032 } 2033 2034 /* Make sure the caller may read the directory. */ 2035 error = VOP_ACCESS(a_dvp, VEXEC, cred, curproc); 2036 if (error) 2037 goto fail1; 2038 2039 a_dirent = tmpfs_dir_lookup(a_dnode, a_cnp); 2040 if (a_dirent != NULL) { 2041 KASSERT(a_dirent->td_node != NULL); 2042 /* We ruled out `.' earlier. */ 2043 KASSERT(a_dirent->td_node != a_dnode); 2044 /* We ruled out `..' earlier. */ 2045 KASSERT(a_dirent->td_node != 2046 a_dnode->tn_spec.tn_dir.tn_parent); 2047 if (a_dirent->td_node == b_dnode) { 2048 error = overlap_error; 2049 goto fail1; 2050 } 2051 rw_enter_write(&a_dirent->td_node->tn_nlock); 2052 error = tmpfs_vnode_get(mount, a_dirent->td_node, &a_vp); 2053 if (error) 2054 goto fail1; 2055 KASSERT(a_vp->v_mount == mount); 2056 /* Refuse to rename (over) a mount point. */ 2057 if ((a_vp->v_type == VDIR) && (a_vp->v_mountedhere != NULL)) { 2058 error = EBUSY; 2059 goto fail2; 2060 } 2061 } else if (!a_missing_ok) { 2062 error = ENOENT; 2063 goto fail1; 2064 } else { 2065 a_vp = NULL; 2066 } 2067 KASSERT(a_vp != a_dvp); 2068 KASSERT(a_vp != b_dvp); 2069 2070 error = tmpfs_rename_lock_directory(b_dvp, b_dnode); 2071 if (error) 2072 goto fail2; 2073 2074 /* Did we lose a race with mount? */ 2075 if (b_dvp->v_mountedhere != NULL) { 2076 error = EBUSY; 2077 goto fail3; 2078 } 2079 2080 /* Make sure the caller may read the directory. */ 2081 error = VOP_ACCESS(b_dvp, VEXEC, cred, curproc); 2082 if (error) 2083 goto fail3; 2084 2085 b_dirent = tmpfs_dir_lookup(b_dnode, b_cnp); 2086 if (b_dirent != NULL) { 2087 KASSERT(b_dirent->td_node != NULL); 2088 /* We ruled out `.' earlier. */ 2089 KASSERT(b_dirent->td_node != b_dnode); 2090 /* We ruled out `..' earlier. */ 2091 KASSERT(b_dirent->td_node != 2092 b_dnode->tn_spec.tn_dir.tn_parent); 2093 /* b is not an ancestor of a. */ 2094 KASSERT(b_dirent->td_node != a_dnode); 2095 /* But the source and target nodes might be the same. */ 2096 if ((a_dirent == NULL) || 2097 (a_dirent->td_node != b_dirent->td_node)) { 2098 rw_enter_write(&b_dirent->td_node->tn_nlock); 2099 error = tmpfs_vnode_get(mount, b_dirent->td_node, 2100 &b_vp); 2101 if (error) 2102 goto fail3; 2103 KASSERT(b_vp->v_mount == mount); 2104 KASSERT(a_vp != b_vp); 2105 /* Refuse to rename (over) a mount point. */ 2106 if ((b_vp->v_type == VDIR) && 2107 (b_vp->v_mountedhere != NULL)) { 2108 error = EBUSY; 2109 goto fail4; 2110 } 2111 } else { 2112 b_vp = a_vp; 2113 vref(b_vp); 2114 } 2115 } else if (!b_missing_ok) { 2116 error = ENOENT; 2117 goto fail3; 2118 } else { 2119 b_vp = NULL; 2120 } 2121 KASSERT(b_vp != a_dvp); 2122 KASSERT(b_vp != b_dvp); 2123 2124 KASSERT(VOP_ISLOCKED(a_dvp) == LK_EXCLUSIVE); 2125 KASSERT(VOP_ISLOCKED(b_dvp) == LK_EXCLUSIVE); 2126 KASSERT(a_missing_ok || (a_dirent != NULL)); 2127 KASSERT(a_missing_ok || (a_dirent->td_node != NULL)); 2128 KASSERT(b_missing_ok || (b_dirent != NULL)); 2129 KASSERT(b_missing_ok || (b_dirent->td_node != NULL)); 2130 KASSERT((a_dirent == NULL) || (a_dirent->td_node != NULL)); 2131 KASSERT((a_dirent == NULL) || (a_dirent->td_node->tn_vnode == a_vp)); 2132 KASSERT((b_dirent == NULL) || (b_dirent->td_node != NULL)); 2133 KASSERT((b_dirent == NULL) || (b_dirent->td_node->tn_vnode == b_vp)); 2134 KASSERT((a_vp == NULL) || (VOP_ISLOCKED(a_vp) == LK_EXCLUSIVE)); 2135 KASSERT((b_vp == NULL) || (VOP_ISLOCKED(b_vp) == LK_EXCLUSIVE)); 2136 2137 *a_dirent_ret = a_dirent; 2138 *b_dirent_ret = b_dirent; 2139 *a_vp_ret = a_vp; 2140 *b_vp_ret = b_vp; 2141 return 0; 2142 2143 fail4: if (b_vp != NULL) { 2144 KASSERT(VOP_ISLOCKED(b_vp) == LK_EXCLUSIVE); 2145 if (b_vp != a_vp) 2146 vput(b_vp); 2147 else 2148 vrele(a_vp); 2149 } 2150 2151 fail3: KASSERT(VOP_ISLOCKED(b_dvp) == LK_EXCLUSIVE); 2152 VOP_UNLOCK(b_dvp); 2153 2154 fail2: if (a_vp != NULL) { 2155 KASSERT(VOP_ISLOCKED(a_vp) == LK_EXCLUSIVE); 2156 vput(a_vp); 2157 } 2158 2159 fail1: KASSERT(VOP_ISLOCKED(a_dvp) == LK_EXCLUSIVE); 2160 VOP_UNLOCK(a_dvp); 2161 2162 fail0: /* KASSERT(VOP_ISLOCKED(a_dvp) != LK_EXCLUSIVE); */ 2163 /* KASSERT(VOP_ISLOCKED(b_dvp) != LK_EXCLUSIVE); */ 2164 /* KASSERT((a_vp == NULL) || (VOP_ISLOCKED(a_vp) != LK_EXCLUSIVE)); */ 2165 /* KASSERT((b_vp == NULL) || (VOP_ISLOCKED(b_vp) != LK_EXCLUSIVE)); */ 2166 return error; 2167 } 2168 2169 /* 2170 * Shuffle the directory entries to move fvp from the directory fdvp 2171 * into the directory tdvp. fde is fvp's directory entry in fdvp. If 2172 * we are overwriting a target node, it is tvp, and tde is its 2173 * directory entry in tdvp. 2174 * 2175 * fdvp, fvp, tdvp, and tvp must all be locked and referenced. 2176 */ 2177 void 2178 tmpfs_rename_attachdetach(struct tmpfs_mount *tmpfs, 2179 struct vnode *fdvp, struct tmpfs_dirent *fde, struct vnode *fvp, 2180 struct vnode *tdvp, struct tmpfs_dirent *tde, struct vnode *tvp) 2181 { 2182 2183 KASSERT(tmpfs != NULL); 2184 KASSERT(fdvp != NULL); 2185 KASSERT(fde != NULL); 2186 KASSERT(fvp != NULL); 2187 KASSERT(tdvp != NULL); 2188 KASSERT(fde->td_node != NULL); 2189 KASSERT(fde->td_node->tn_vnode == fvp); 2190 KASSERT((tde == NULL) == (tvp == NULL)); 2191 KASSERT((tde == NULL) || (tde->td_node != NULL)); 2192 KASSERT((tde == NULL) || (tde->td_node->tn_vnode == tvp)); 2193 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 2194 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 2195 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 2196 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 2197 2198 /* 2199 * If we are moving from one directory to another, detach the 2200 * source entry and reattach it to the target directory. 2201 */ 2202 if (fdvp != tdvp) { 2203 /* tmpfs_dir_detach clobbers fde->td_node, so save it. */ 2204 struct tmpfs_node *fnode = fde->td_node; 2205 tmpfs_node_t *fdnode = VP_TO_TMPFS_DIR(fdvp); 2206 tmpfs_node_t *tdnode = VP_TO_TMPFS_DIR(tdvp); 2207 tmpfs_dir_detach(fdnode, fde); 2208 tmpfs_dir_attach(tdnode, fde, fnode); 2209 } else if (tvp == NULL) { 2210 /* 2211 * We are changing the directory. tmpfs_dir_attach and 2212 * tmpfs_dir_detach note the events for us, but for 2213 * this case we don't call them, so we must note the 2214 * event explicitly. 2215 */ 2216 VN_KNOTE(fdvp, NOTE_WRITE); 2217 } 2218 2219 /* 2220 * If we are replacing an existing target entry, delete it. 2221 */ 2222 if (tde != NULL) { 2223 tmpfs_node_t *tdnode = VP_TO_TMPFS_DIR(tdvp); 2224 KASSERT(tvp != NULL); 2225 KASSERT(tde->td_node != NULL); 2226 KASSERT((fvp->v_type == VDIR) == (tvp->v_type == VDIR)); 2227 if (tde->td_node->tn_type == VDIR) { 2228 KASSERT(tde->td_node->tn_size == 0); 2229 KASSERT(tde->td_node->tn_links == 2); 2230 /* Decrement the extra link count for `.' so 2231 * the vnode will be recycled when released. */ 2232 tde->td_node->tn_links--; 2233 } 2234 tmpfs_dir_detach(tdnode, tde); 2235 tmpfs_free_dirent(tmpfs, tde); 2236 } 2237 } 2238 2239 /* 2240 * Remove the entry de for the non-directory vp from the directory dvp. 2241 * 2242 * Everything must be locked and referenced. 2243 */ 2244 int 2245 tmpfs_do_remove(struct tmpfs_mount *tmpfs, struct vnode *dvp, 2246 struct tmpfs_node *dnode, struct tmpfs_dirent *de, struct vnode *vp, 2247 struct ucred *cred) 2248 { 2249 int error; 2250 2251 KASSERT(tmpfs != NULL); 2252 KASSERT(dvp != NULL); 2253 KASSERT(dnode != NULL); 2254 KASSERT(de != NULL); 2255 KASSERT(vp != NULL); 2256 KASSERT(dnode->tn_vnode == dvp); 2257 KASSERT(de->td_node != NULL); 2258 KASSERT(de->td_node->tn_vnode == vp); 2259 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 2260 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 2261 2262 error = tmpfs_remove_check_possible(dnode, de->td_node); 2263 if (error) 2264 return error; 2265 2266 error = tmpfs_remove_check_permitted(cred, dnode, de->td_node); 2267 if (error) 2268 return error; 2269 2270 /* 2271 * If not root and directory is sticky, check for permission on 2272 * directory or on file. This implements append-only directories. 2273 */ 2274 if ((dnode->tn_mode & S_ISTXT) != 0) 2275 if (cred->cr_uid != 0 && cred->cr_uid != dnode->tn_uid && 2276 cred->cr_uid != de->td_node->tn_uid) 2277 return EPERM; 2278 2279 tmpfs_dir_detach(dnode, de); 2280 tmpfs_free_dirent(tmpfs, de); 2281 2282 return 0; 2283 } 2284 2285 /* 2286 * Check whether a rename is possible independent of credentials. 2287 * 2288 * Everything must be locked and referenced. 2289 */ 2290 int 2291 tmpfs_rename_check_possible( 2292 struct tmpfs_node *fdnode, struct tmpfs_node *fnode, 2293 struct tmpfs_node *tdnode, struct tmpfs_node *tnode) 2294 { 2295 2296 KASSERT(fdnode != NULL); 2297 KASSERT(fnode != NULL); 2298 KASSERT(tdnode != NULL); 2299 KASSERT(fdnode != fnode); 2300 KASSERT(tdnode != tnode); 2301 KASSERT(fnode != tnode); 2302 KASSERT(fdnode->tn_vnode != NULL); 2303 KASSERT(fnode->tn_vnode != NULL); 2304 KASSERT(tdnode->tn_vnode != NULL); 2305 KASSERT((tnode == NULL) || (tnode->tn_vnode != NULL)); 2306 KASSERT(VOP_ISLOCKED(fdnode->tn_vnode) == LK_EXCLUSIVE); 2307 KASSERT(VOP_ISLOCKED(fnode->tn_vnode) == LK_EXCLUSIVE); 2308 KASSERT(VOP_ISLOCKED(tdnode->tn_vnode) == LK_EXCLUSIVE); 2309 KASSERT((tnode == NULL) || 2310 (VOP_ISLOCKED(tnode->tn_vnode) == LK_EXCLUSIVE)); 2311 2312 /* 2313 * If fdnode is immutable, we can't write to it. If fdnode is 2314 * append-only, the only change we can make is to add entries 2315 * to it. If fnode is immutable, we can't change the links to 2316 * it. If fnode is append-only...well, this is what UFS does. 2317 */ 2318 if ((fdnode->tn_flags | fnode->tn_flags) & (IMMUTABLE | APPEND)) 2319 return EPERM; 2320 2321 /* 2322 * If tdnode is immutable, we can't write to it. If tdnode is 2323 * append-only, we can add entries, but we can't change 2324 * existing entries. 2325 */ 2326 if (tdnode->tn_flags & (IMMUTABLE | (tnode? APPEND : 0))) 2327 return EPERM; 2328 2329 /* 2330 * If tnode is immutable, we can't replace links to it. If 2331 * tnode is append-only...well, this is what UFS does. 2332 */ 2333 if (tnode != NULL) { 2334 KASSERT(tnode != NULL); 2335 if ((tnode->tn_flags & (IMMUTABLE | APPEND)) != 0) 2336 return EPERM; 2337 } 2338 2339 return 0; 2340 } 2341 2342 /* 2343 * Check whether a rename is permitted given our credentials. 2344 * 2345 * Everything must be locked and referenced. 2346 */ 2347 int 2348 tmpfs_rename_check_permitted(struct ucred *cred, 2349 struct tmpfs_node *fdnode, struct tmpfs_node *fnode, 2350 struct tmpfs_node *tdnode, struct tmpfs_node *tnode) 2351 { 2352 int error; 2353 2354 KASSERT(fdnode != NULL); 2355 KASSERT(fnode != NULL); 2356 KASSERT(tdnode != NULL); 2357 KASSERT(fdnode != fnode); 2358 KASSERT(tdnode != tnode); 2359 KASSERT(fnode != tnode); 2360 KASSERT(fdnode->tn_vnode != NULL); 2361 KASSERT(fnode->tn_vnode != NULL); 2362 KASSERT(tdnode->tn_vnode != NULL); 2363 KASSERT((tnode == NULL) || (tnode->tn_vnode != NULL)); 2364 KASSERT(VOP_ISLOCKED(fdnode->tn_vnode) == LK_EXCLUSIVE); 2365 KASSERT(VOP_ISLOCKED(fnode->tn_vnode) == LK_EXCLUSIVE); 2366 KASSERT(VOP_ISLOCKED(tdnode->tn_vnode) == LK_EXCLUSIVE); 2367 KASSERT((tnode == NULL) || 2368 (VOP_ISLOCKED(tnode->tn_vnode) == LK_EXCLUSIVE)); 2369 2370 /* 2371 * We need to remove or change an entry in the source directory. 2372 */ 2373 error = VOP_ACCESS(fdnode->tn_vnode, VWRITE, cred, curproc); 2374 if (error) 2375 return error; 2376 2377 /* 2378 * If we are changing directories, then we need to write to the 2379 * target directory to add or change an entry. Also, if fnode 2380 * is a directory, we need to write to it to change its `..' 2381 * entry. 2382 */ 2383 if (fdnode != tdnode) { 2384 error = VOP_ACCESS(tdnode->tn_vnode, VWRITE, cred, curproc); 2385 if (error) 2386 return error; 2387 if (fnode->tn_type == VDIR) { 2388 error = VOP_ACCESS(fnode->tn_vnode, VWRITE, cred, 2389 curproc); 2390 if (error) 2391 return error; 2392 } 2393 } 2394 2395 error = tmpfs_check_sticky(cred, fdnode, fnode); 2396 if (error) 2397 return error; 2398 2399 if (TMPFS_DIRSEQ_FULL(tdnode)) 2400 return (ENOSPC); 2401 2402 error = tmpfs_check_sticky(cred, tdnode, tnode); 2403 if (error) 2404 return error; 2405 2406 return 0; 2407 } 2408 2409 /* 2410 * Check whether removing node's entry in dnode is possible independent 2411 * of credentials. 2412 * 2413 * Everything must be locked and referenced. 2414 */ 2415 int 2416 tmpfs_remove_check_possible(struct tmpfs_node *dnode, struct tmpfs_node *node) 2417 { 2418 2419 KASSERT(dnode != NULL); 2420 KASSERT(dnode->tn_vnode != NULL); 2421 KASSERT(node != NULL); 2422 KASSERT(dnode != node); 2423 KASSERT(VOP_ISLOCKED(dnode->tn_vnode) == LK_EXCLUSIVE); 2424 KASSERT(VOP_ISLOCKED(node->tn_vnode) == LK_EXCLUSIVE); 2425 2426 /* 2427 * We want to delete the entry. If dnode is immutable, we 2428 * can't write to it to delete the entry. If dnode is 2429 * append-only, the only change we can make is to add entries, 2430 * so we can't delete entries. If node is immutable, we can't 2431 * change the links to it, so we can't delete the entry. If 2432 * node is append-only...well, this is what UFS does. 2433 */ 2434 if ((dnode->tn_flags | node->tn_flags) & (IMMUTABLE | APPEND)) 2435 return EPERM; 2436 2437 return 0; 2438 } 2439 2440 /* 2441 * Check whether removing node's entry in dnode is permitted given our 2442 * credentials. 2443 * 2444 * Everything must be locked and referenced. 2445 */ 2446 int 2447 tmpfs_remove_check_permitted(struct ucred *cred, 2448 struct tmpfs_node *dnode, struct tmpfs_node *node) 2449 { 2450 int error; 2451 2452 KASSERT(dnode != NULL); 2453 KASSERT(dnode->tn_vnode != NULL); 2454 KASSERT(node != NULL); 2455 KASSERT(dnode != node); 2456 KASSERT(VOP_ISLOCKED(dnode->tn_vnode) == LK_EXCLUSIVE); 2457 KASSERT(VOP_ISLOCKED(node->tn_vnode) == LK_EXCLUSIVE); 2458 2459 /* 2460 * Check whether we are permitted to write to the source 2461 * directory in order to delete an entry from it. 2462 */ 2463 error = VOP_ACCESS(dnode->tn_vnode, VWRITE, cred, curproc); 2464 if (error) 2465 return error; 2466 2467 error = tmpfs_check_sticky(cred, dnode, node); 2468 if (error) 2469 return error; 2470 2471 return 0; 2472 } 2473 2474 /* 2475 * Check whether we may change an entry in a sticky directory. If the 2476 * directory is sticky, the user must own either the directory or, if 2477 * it exists, the node, in order to change the entry. 2478 * 2479 * Everything must be locked and referenced. 2480 */ 2481 int 2482 tmpfs_check_sticky(struct ucred *cred, 2483 struct tmpfs_node *dnode, struct tmpfs_node *node) 2484 { 2485 2486 KASSERT(dnode != NULL); 2487 KASSERT(dnode->tn_vnode != NULL); 2488 KASSERT(VOP_ISLOCKED(dnode->tn_vnode) == LK_EXCLUSIVE); 2489 KASSERT((node == NULL) || (node->tn_vnode != NULL)); 2490 KASSERT((node == NULL) || 2491 (VOP_ISLOCKED(dnode->tn_vnode) == LK_EXCLUSIVE)); 2492 2493 if (node == NULL) 2494 return 0; 2495 2496 if (dnode->tn_mode & S_ISTXT) { 2497 if (cred->cr_uid != 0 && 2498 cred->cr_uid != dnode->tn_uid && 2499 cred->cr_uid != node->tn_uid) 2500 return EPERM; 2501 } 2502 2503 return 0; 2504 } 2505 2506 void 2507 tmpfs_rename_cache_purge(struct vnode *fdvp, struct vnode *fvp, 2508 struct vnode *tdvp, struct vnode *tvp) 2509 { 2510 2511 KASSERT(fdvp != NULL); 2512 KASSERT(fvp != NULL); 2513 KASSERT(tdvp != NULL); 2514 KASSERT(fdvp != fvp); 2515 KASSERT(fdvp != tvp); 2516 KASSERT(tdvp != fvp); 2517 KASSERT(tdvp != tvp); 2518 KASSERT(fvp != tvp); 2519 KASSERT(fdvp->v_type == VDIR); 2520 KASSERT(tdvp->v_type == VDIR); 2521 2522 /* 2523 * XXX What actually needs to be purged? 2524 */ 2525 2526 cache_purge(fdvp); 2527 2528 if (fvp->v_type == VDIR) 2529 cache_purge(fvp); 2530 2531 if (tdvp != fdvp) 2532 cache_purge(tdvp); 2533 2534 if ((tvp != NULL) && (tvp->v_type == VDIR)) 2535 cache_purge(tvp); 2536 } 2537 2538 void 2539 tmpfs_rename_abort(void *v) 2540 { 2541 struct vop_rename_args *ap = v; 2542 struct vnode *fdvp = ap->a_fdvp; 2543 struct vnode *fvp = ap->a_fvp; 2544 struct componentname *fcnp = ap->a_fcnp; 2545 struct vnode *tdvp = ap->a_tdvp; 2546 struct vnode *tvp = ap->a_tvp; 2547 struct componentname *tcnp = ap->a_tcnp; 2548 2549 VOP_ABORTOP(tdvp, tcnp); 2550 if (tdvp == tvp) 2551 vrele(tdvp); 2552 else 2553 vput(tdvp); 2554 if (tvp != NULL) 2555 vput(tvp); 2556 VOP_ABORTOP(fdvp, fcnp); 2557 vrele(fdvp); 2558 vrele(fvp); 2559 } 2560 2561 void filt_tmpfsdetach(struct knote *kn); 2562 int filt_tmpfsread(struct knote *kn, long hint); 2563 int filt_tmpfswrite(struct knote *kn, long hint); 2564 int filt_tmpfsvnode(struct knote *kn, long hint); 2565 2566 const struct filterops tmpfsread_filtops = { 2567 .f_flags = FILTEROP_ISFD, 2568 .f_attach = NULL, 2569 .f_detach = filt_tmpfsdetach, 2570 .f_event = filt_tmpfsread, 2571 }; 2572 2573 const struct filterops tmpfswrite_filtops = { 2574 .f_flags = FILTEROP_ISFD, 2575 .f_attach = NULL, 2576 .f_detach = filt_tmpfsdetach, 2577 .f_event = filt_tmpfswrite, 2578 }; 2579 2580 const struct filterops tmpfsvnode_filtops = { 2581 .f_flags = FILTEROP_ISFD, 2582 .f_attach = NULL, 2583 .f_detach = filt_tmpfsdetach, 2584 .f_event = filt_tmpfsvnode, 2585 }; 2586 2587 int 2588 tmpfs_kqfilter(void *v) 2589 { 2590 struct vop_kqfilter_args *ap = v; 2591 struct vnode *vp = ap->a_vp; 2592 struct knote *kn = ap->a_kn; 2593 2594 switch (kn->kn_filter) { 2595 case EVFILT_READ: 2596 kn->kn_fop = &tmpfsread_filtops; 2597 break; 2598 case EVFILT_WRITE: 2599 kn->kn_fop = &tmpfswrite_filtops; 2600 break; 2601 case EVFILT_VNODE: 2602 kn->kn_fop = &tmpfsvnode_filtops; 2603 break; 2604 default: 2605 return (EINVAL); 2606 } 2607 2608 kn->kn_hook = (caddr_t)vp; 2609 2610 klist_insert_locked(&vp->v_klist, kn); 2611 2612 return (0); 2613 } 2614 2615 void 2616 filt_tmpfsdetach(struct knote *kn) 2617 { 2618 struct vnode *vp = (struct vnode *)kn->kn_hook; 2619 2620 klist_remove_locked(&vp->v_klist, kn); 2621 } 2622 2623 int 2624 filt_tmpfsread(struct knote *kn, long hint) 2625 { 2626 struct vnode *vp = (struct vnode *)kn->kn_hook; 2627 tmpfs_node_t *node = VP_TO_TMPFS_NODE(vp); 2628 2629 /* 2630 * filesystem is gone, so set the EOF flag and schedule 2631 * the knote for deletion. 2632 */ 2633 if (hint == NOTE_REVOKE) { 2634 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 2635 return (1); 2636 } 2637 2638 kn->kn_data = node->tn_size - foffset(kn->kn_fp); 2639 if (kn->kn_data == 0 && kn->kn_sfflags & NOTE_EOF) { 2640 kn->kn_fflags |= NOTE_EOF; 2641 return (1); 2642 } 2643 2644 if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) 2645 return (1); 2646 2647 return (kn->kn_data != 0); 2648 } 2649 2650 int 2651 filt_tmpfswrite(struct knote *kn, long hint) 2652 { 2653 /* 2654 * filesystem is gone, so set the EOF flag and schedule 2655 * the knote for deletion. 2656 */ 2657 if (hint == NOTE_REVOKE) { 2658 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 2659 return (1); 2660 } 2661 2662 kn->kn_data = 0; 2663 return (1); 2664 } 2665 2666 int 2667 filt_tmpfsvnode(struct knote *kn, long hint) 2668 { 2669 if (kn->kn_sfflags & hint) 2670 kn->kn_fflags |= hint; 2671 if (hint == NOTE_REVOKE) { 2672 kn->kn_flags |= EV_EOF; 2673 return (1); 2674 } 2675 return (kn->kn_fflags != 0); 2676 } 2677