1 /* 2 * Copyright (c) 2004,2009 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 /* 35 * Implement vnode ops wrappers. All vnode ops are wrapped through 36 * these functions. 37 * 38 * These wrappers are responsible for hanlding all MPSAFE issues related 39 * to a vnode operation. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/buf.h> 45 #include <sys/conf.h> 46 #include <sys/dirent.h> 47 #include <sys/domain.h> 48 #include <sys/eventhandler.h> 49 #include <sys/fcntl.h> 50 #include <sys/kernel.h> 51 #include <sys/kthread.h> 52 #include <sys/malloc.h> 53 #include <sys/mbuf.h> 54 #include <sys/mount.h> 55 #include <sys/proc.h> 56 #include <sys/namei.h> 57 #include <sys/reboot.h> 58 #include <sys/socket.h> 59 #include <sys/stat.h> 60 #include <sys/sysctl.h> 61 #include <sys/syslog.h> 62 #include <sys/vmmeter.h> 63 #include <sys/vnode.h> 64 #include <sys/vfsops.h> 65 #include <sys/sysmsg.h> 66 #include <sys/vfs_quota.h> 67 68 #include <machine/limits.h> 69 70 #include <vm/vm.h> 71 #include <vm/vm_object.h> 72 #include <vm/vm_extern.h> 73 #include <vm/vm_kern.h> 74 #include <vm/pmap.h> 75 #include <vm/vm_map.h> 76 #include <vm/vm_page.h> 77 #include <vm/vm_pager.h> 78 #include <vm/vnode_pager.h> 79 #include <vm/vm_zone.h> 80 81 #include <sys/buf2.h> 82 #include <sys/mplock2.h> 83 84 #define VDESCNAME(name) __CONCAT(__CONCAT(vop_,name),_desc) 85 86 #define VNODEOP_DESC_INIT(name) \ 87 struct syslink_desc VDESCNAME(name) = { \ 88 __offsetof(struct vop_ops, __CONCAT(vop_, name)), \ 89 #name } 90 91 VNODEOP_DESC_INIT(default); 92 VNODEOP_DESC_INIT(old_lookup); 93 VNODEOP_DESC_INIT(old_create); 94 VNODEOP_DESC_INIT(old_whiteout); 95 VNODEOP_DESC_INIT(old_mknod); 96 VNODEOP_DESC_INIT(open); 97 VNODEOP_DESC_INIT(close); 98 VNODEOP_DESC_INIT(access); 99 VNODEOP_DESC_INIT(getattr); 100 VNODEOP_DESC_INIT(getattr_lite); 101 VNODEOP_DESC_INIT(setattr); 102 VNODEOP_DESC_INIT(read); 103 VNODEOP_DESC_INIT(write); 104 VNODEOP_DESC_INIT(ioctl); 105 VNODEOP_DESC_INIT(poll); 106 VNODEOP_DESC_INIT(kqfilter); 107 VNODEOP_DESC_INIT(mmap); 108 VNODEOP_DESC_INIT(fsync); 109 VNODEOP_DESC_INIT(fdatasync); 110 VNODEOP_DESC_INIT(old_remove); 111 VNODEOP_DESC_INIT(old_link); 112 VNODEOP_DESC_INIT(old_rename); 113 114 VNODEOP_DESC_INIT(old_mkdir); 115 VNODEOP_DESC_INIT(old_rmdir); 116 VNODEOP_DESC_INIT(old_symlink); 117 VNODEOP_DESC_INIT(readdir); 118 VNODEOP_DESC_INIT(readlink); 119 VNODEOP_DESC_INIT(inactive); 120 VNODEOP_DESC_INIT(reclaim); 121 VNODEOP_DESC_INIT(bmap); 122 VNODEOP_DESC_INIT(strategy); 123 VNODEOP_DESC_INIT(print); 124 VNODEOP_DESC_INIT(pathconf); 125 VNODEOP_DESC_INIT(advlock); 126 VNODEOP_DESC_INIT(balloc); 127 VNODEOP_DESC_INIT(reallocblks); 128 VNODEOP_DESC_INIT(getpages); 129 VNODEOP_DESC_INIT(putpages); 130 VNODEOP_DESC_INIT(freeblks); 131 VNODEOP_DESC_INIT(getacl); 132 VNODEOP_DESC_INIT(setacl); 133 VNODEOP_DESC_INIT(aclcheck); 134 VNODEOP_DESC_INIT(getextattr); 135 VNODEOP_DESC_INIT(setextattr); 136 VNODEOP_DESC_INIT(mountctl); 137 VNODEOP_DESC_INIT(markatime); 138 VNODEOP_DESC_INIT(allocate); 139 140 VNODEOP_DESC_INIT(nresolve); 141 VNODEOP_DESC_INIT(nlookupdotdot); 142 VNODEOP_DESC_INIT(ncreate); 143 VNODEOP_DESC_INIT(nmkdir); 144 VNODEOP_DESC_INIT(nmknod); 145 VNODEOP_DESC_INIT(nlink); 146 VNODEOP_DESC_INIT(nsymlink); 147 VNODEOP_DESC_INIT(nwhiteout); 148 VNODEOP_DESC_INIT(nremove); 149 VNODEOP_DESC_INIT(nrmdir); 150 VNODEOP_DESC_INIT(nrename); 151 152 #define DO_OPS(ops, error, ap, vop_field) \ 153 error = ops->vop_field(ap) 154 155 /************************************************************************ 156 * PRIMARY HIGH LEVEL VNODE OPERATIONS CALLS * 157 ************************************************************************ 158 * 159 * These procedures are called directly from the kernel and/or fileops 160 * code to perform file/device operations on the system. 161 * 162 * NOTE: The old namespace api functions such as vop_rename() are no 163 * longer available for general use and have been renamed to 164 * vop_old_*(). Only the code in vfs_default.c is allowed to call 165 * those ops. 166 * 167 * NOTE: The VFS_MPLOCK() macro handle mounts which do not set MNTK_MPSAFE. 168 * 169 * MPSAFE 170 */ 171 172 int 173 vop_old_lookup(struct vop_ops *ops, struct vnode *dvp, 174 struct vnode **vpp, struct componentname *cnp) 175 { 176 struct vop_old_lookup_args ap; 177 VFS_MPLOCK_DECLARE; 178 int error; 179 180 ap.a_head.a_desc = &vop_old_lookup_desc; 181 ap.a_head.a_ops = ops; 182 ap.a_dvp = dvp; 183 ap.a_vpp = vpp; 184 ap.a_cnp = cnp; 185 VFS_MPLOCK(dvp->v_mount); 186 DO_OPS(ops, error, &ap, vop_old_lookup); 187 VFS_MPUNLOCK(); 188 189 return(error); 190 } 191 192 /* 193 * MPSAFE 194 */ 195 int 196 vop_old_create(struct vop_ops *ops, struct vnode *dvp, 197 struct vnode **vpp, struct componentname *cnp, struct vattr *vap) 198 { 199 struct vop_old_create_args ap; 200 VFS_MPLOCK_DECLARE; 201 int error; 202 203 ap.a_head.a_desc = &vop_old_create_desc; 204 ap.a_head.a_ops = ops; 205 ap.a_dvp = dvp; 206 ap.a_vpp = vpp; 207 ap.a_cnp = cnp; 208 ap.a_vap = vap; 209 210 VFS_MPLOCK(dvp->v_mount); 211 DO_OPS(ops, error, &ap, vop_old_create); 212 VFS_MPUNLOCK(); 213 214 return(error); 215 } 216 217 /* 218 * MPSAFE 219 */ 220 int 221 vop_old_whiteout(struct vop_ops *ops, struct vnode *dvp, 222 struct componentname *cnp, int flags) 223 { 224 struct vop_old_whiteout_args ap; 225 VFS_MPLOCK_DECLARE; 226 int error; 227 228 ap.a_head.a_desc = &vop_old_whiteout_desc; 229 ap.a_head.a_ops = ops; 230 ap.a_dvp = dvp; 231 ap.a_cnp = cnp; 232 ap.a_flags = flags; 233 234 VFS_MPLOCK(dvp->v_mount); 235 DO_OPS(ops, error, &ap, vop_old_whiteout); 236 VFS_MPUNLOCK(); 237 238 return(error); 239 } 240 241 /* 242 * MPSAFE 243 */ 244 int 245 vop_old_mknod(struct vop_ops *ops, struct vnode *dvp, 246 struct vnode **vpp, struct componentname *cnp, struct vattr *vap) 247 { 248 struct vop_old_mknod_args ap; 249 VFS_MPLOCK_DECLARE; 250 int error; 251 252 ap.a_head.a_desc = &vop_old_mknod_desc; 253 ap.a_head.a_ops = ops; 254 ap.a_dvp = dvp; 255 ap.a_vpp = vpp; 256 ap.a_cnp = cnp; 257 ap.a_vap = vap; 258 259 VFS_MPLOCK(dvp->v_mount); 260 DO_OPS(ops, error, &ap, vop_old_mknod); 261 VFS_MPUNLOCK(); 262 263 return(error); 264 } 265 266 /* 267 * NOTE: VAGE is always cleared when calling VOP_OPEN(). 268 */ 269 int 270 vop_open(struct vop_ops *ops, struct vnode *vp, int mode, struct ucred *cred, 271 struct file **fpp) 272 { 273 struct vop_open_args ap; 274 VFS_MPLOCK_DECLARE; 275 int error; 276 277 /* 278 * Decrement 3-2-1-0. Does not decrement beyond 0 279 */ 280 if (vp->v_flag & VAGE0) { 281 vclrflags(vp, VAGE0); 282 } else if (vp->v_flag & VAGE1) { 283 vclrflags(vp, VAGE1); 284 vsetflags(vp, VAGE0); 285 } 286 287 ap.a_head.a_desc = &vop_open_desc; 288 ap.a_head.a_ops = ops; 289 ap.a_vp = vp; 290 ap.a_fpp = fpp; 291 ap.a_mode = mode; 292 ap.a_cred = cred; 293 294 VFS_MPLOCK(vp->v_mount); 295 DO_OPS(ops, error, &ap, vop_open); 296 VFS_MPUNLOCK(); 297 298 return(error); 299 } 300 301 /* 302 * MPSAFE 303 */ 304 int 305 vop_close(struct vop_ops *ops, struct vnode *vp, int fflag, struct file *fp) 306 { 307 struct vop_close_args ap; 308 VFS_MPLOCK_DECLARE; 309 int error; 310 311 ap.a_head.a_desc = &vop_close_desc; 312 ap.a_head.a_ops = ops; 313 ap.a_vp = vp; 314 ap.a_fp = fp; 315 ap.a_fflag = fflag; 316 317 VFS_MPLOCK(vp->v_mount); 318 DO_OPS(ops, error, &ap, vop_close); 319 VFS_MPUNLOCK(); 320 321 return(error); 322 } 323 324 /* 325 * MPSAFE 326 */ 327 int 328 vop_access(struct vop_ops *ops, struct vnode *vp, int mode, int flags, 329 struct ucred *cred) 330 { 331 struct vop_access_args ap; 332 VFS_MPLOCK_DECLARE; 333 int error; 334 335 ap.a_head.a_desc = &vop_access_desc; 336 ap.a_head.a_ops = ops; 337 ap.a_vp = vp; 338 ap.a_mode = mode; 339 ap.a_flags = flags; 340 ap.a_cred = cred; 341 342 VFS_MPLOCK(vp->v_mount); 343 DO_OPS(ops, error, &ap, vop_access); 344 VFS_MPUNLOCK(); 345 346 return(error); 347 } 348 349 /* 350 * MPSAFE 351 */ 352 int 353 vop_getattr(struct vop_ops *ops, struct vnode *vp, struct vattr *vap, 354 struct file *fp) 355 { 356 struct vop_getattr_args ap; 357 VFS_MPLOCK_DECLARE; 358 int error; 359 360 ap.a_head.a_desc = &vop_getattr_desc; 361 ap.a_head.a_ops = ops; 362 ap.a_vp = vp; 363 ap.a_vap = vap; 364 ap.a_fp = fp; 365 366 VFS_MPLOCK_FLAG(vp->v_mount, MNTK_GA_MPSAFE); 367 DO_OPS(ops, error, &ap, vop_getattr); 368 VFS_MPUNLOCK(); 369 370 return(error); 371 } 372 373 /* 374 * MPSAFE 375 */ 376 int 377 vop_getattr_lite(struct vop_ops *ops, struct vnode *vp, struct vattr_lite *lvap) 378 { 379 struct vop_getattr_lite_args ap; 380 VFS_MPLOCK_DECLARE; 381 int error; 382 383 ap.a_head.a_desc = &vop_getattr_lite_desc; 384 ap.a_head.a_ops = ops; 385 ap.a_vp = vp; 386 ap.a_lvap = lvap; 387 ap.a_fp = NULL; 388 389 VFS_MPLOCK_FLAG(vp->v_mount, MNTK_GA_MPSAFE); 390 DO_OPS(ops, error, &ap, vop_getattr_lite); 391 VFS_MPUNLOCK(); 392 393 return(error); 394 } 395 396 /* 397 * MPSAFE 398 */ 399 int 400 vop_setattr(struct vop_ops *ops, struct vnode *vp, struct vattr *vap, 401 struct ucred *cred, struct file *fp) 402 { 403 struct vop_setattr_args ap; 404 VFS_MPLOCK_DECLARE; 405 int error; 406 407 ap.a_head.a_desc = &vop_setattr_desc; 408 ap.a_head.a_ops = ops; 409 ap.a_vp = vp; 410 ap.a_vap = vap; 411 ap.a_cred = cred; 412 ap.a_fp = fp; 413 414 VFS_MPLOCK(vp->v_mount); 415 DO_OPS(ops, error, &ap, vop_setattr); 416 VFS_MPUNLOCK(); 417 418 return(error); 419 } 420 421 /* 422 * MPSAFE 423 */ 424 int 425 vop_read(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag, 426 struct ucred *cred, struct file *fp) 427 { 428 struct vop_read_args ap; 429 VFS_MPLOCK_DECLARE; 430 int error; 431 432 ap.a_head.a_desc = &vop_read_desc; 433 ap.a_head.a_ops = ops; 434 ap.a_vp = vp; 435 ap.a_uio = uio; 436 ap.a_ioflag = ioflag; 437 ap.a_cred = cred; 438 ap.a_fp = fp; 439 440 VFS_MPLOCK_FLAG(vp->v_mount, MNTK_RD_MPSAFE); 441 DO_OPS(ops, error, &ap, vop_read); 442 VFS_MPUNLOCK(); 443 444 return(error); 445 } 446 447 /* 448 * MPSAFE 449 */ 450 int 451 vop_write(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag, 452 struct ucred *cred, struct file *fp) 453 { 454 struct vop_write_args ap; 455 VFS_MPLOCK_DECLARE; 456 int error, do_accounting = 0; 457 struct vattr va; 458 uint64_t size_before=0, size_after=0; 459 struct mount *mp; 460 uint64_t offset, delta; 461 462 ap.a_head.a_desc = &vop_write_desc; 463 ap.a_head.a_ops = ops; 464 ap.a_vp = vp; 465 ap.a_uio = uio; 466 ap.a_ioflag = ioflag; 467 ap.a_cred = cred; 468 ap.a_fp = fp; 469 470 /* is this a regular vnode ? */ 471 VFS_MPLOCK_FLAG(vp->v_mount, MNTK_WR_MPSAFE); 472 if (vfs_quota_enabled && (vp->v_type == VREG)) { 473 if ((error = VOP_GETATTR(vp, &va)) != 0) 474 goto done; 475 size_before = va.va_size; 476 /* this file may already have been removed */ 477 if (va.va_nlink > 0) 478 do_accounting = 1; 479 480 offset = uio->uio_offset; 481 if (ioflag & IO_APPEND) 482 offset = size_before; 483 size_after = offset + uio->uio_resid; 484 if (size_after < size_before) 485 size_after = size_before; 486 delta = size_after - size_before; 487 mp = vq_vptomp(vp); 488 /* QUOTA CHECK */ 489 if (!vq_write_ok(mp, va.va_uid, va.va_gid, delta)) { 490 error = EDQUOT; 491 goto done; 492 } 493 } 494 DO_OPS(ops, error, &ap, vop_write); 495 if ((error == 0) && do_accounting) { 496 VFS_ACCOUNT(mp, va.va_uid, va.va_gid, size_after - size_before); 497 } 498 done: 499 VFS_MPUNLOCK(); 500 501 return(error); 502 } 503 504 /* 505 * MPSAFE 506 */ 507 int 508 vop_ioctl(struct vop_ops *ops, struct vnode *vp, u_long command, caddr_t data, 509 int fflag, struct ucred *cred, struct sysmsg *msg) 510 { 511 struct vop_ioctl_args ap; 512 VFS_MPLOCK_DECLARE; 513 int error; 514 515 ap.a_head.a_desc = &vop_ioctl_desc; 516 ap.a_head.a_ops = ops; 517 ap.a_vp = vp; 518 ap.a_command = command; 519 ap.a_data = data; 520 ap.a_fflag = fflag; 521 ap.a_cred = cred; 522 ap.a_sysmsg = msg; 523 524 VFS_MPLOCK(vp->v_mount); 525 DO_OPS(ops, error, &ap, vop_ioctl); 526 VFS_MPUNLOCK(); 527 528 return(error); 529 } 530 531 /* 532 * MPSAFE 533 */ 534 int 535 vop_poll(struct vop_ops *ops, struct vnode *vp, int events, struct ucred *cred) 536 { 537 struct vop_poll_args ap; 538 VFS_MPLOCK_DECLARE; 539 int error; 540 541 ap.a_head.a_desc = &vop_poll_desc; 542 ap.a_head.a_ops = ops; 543 ap.a_vp = vp; 544 ap.a_events = events; 545 ap.a_cred = cred; 546 547 VFS_MPLOCK(vp->v_mount); 548 DO_OPS(ops, error, &ap, vop_poll); 549 VFS_MPUNLOCK(); 550 551 return(error); 552 } 553 554 /* 555 * MPSAFE 556 */ 557 int 558 vop_kqfilter(struct vop_ops *ops, struct vnode *vp, struct knote *kn) 559 { 560 struct vop_kqfilter_args ap; 561 VFS_MPLOCK_DECLARE; 562 int error; 563 564 ap.a_head.a_desc = &vop_kqfilter_desc; 565 ap.a_head.a_ops = ops; 566 ap.a_vp = vp; 567 ap.a_kn = kn; 568 569 VFS_MPLOCK(vp->v_mount); 570 DO_OPS(ops, error, &ap, vop_kqfilter); 571 VFS_MPUNLOCK(); 572 573 return(error); 574 } 575 576 /* 577 * MPSAFE 578 */ 579 int 580 vop_mmap(struct vop_ops *ops, struct vnode *vp, int fflags, struct ucred *cred) 581 { 582 struct vop_mmap_args ap; 583 VFS_MPLOCK_DECLARE; 584 int error; 585 586 ap.a_head.a_desc = &vop_mmap_desc; 587 ap.a_head.a_ops = ops; 588 ap.a_vp = vp; 589 ap.a_fflags = fflags; 590 ap.a_cred = cred; 591 592 VFS_MPLOCK(vp->v_mount); 593 DO_OPS(ops, error, &ap, vop_mmap); 594 VFS_MPUNLOCK(); 595 596 return(error); 597 } 598 599 /* 600 * MPSAFE 601 */ 602 int 603 vop_fsync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags, 604 struct file *fp) 605 { 606 struct vop_fsync_args ap; 607 VFS_MPLOCK_DECLARE; 608 int error; 609 610 ap.a_head.a_desc = &vop_fsync_desc; 611 ap.a_head.a_ops = ops; 612 ap.a_vp = vp; 613 ap.a_waitfor = waitfor; 614 ap.a_flags = flags; 615 ap.a_fp = fp; 616 617 VFS_MPLOCK(vp->v_mount); 618 DO_OPS(ops, error, &ap, vop_fsync); 619 VFS_MPUNLOCK(); 620 621 return(error); 622 } 623 624 /* 625 * MPSAFE 626 */ 627 int 628 vop_fdatasync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags, 629 struct file *fp) 630 { 631 struct vop_fdatasync_args ap; 632 VFS_MPLOCK_DECLARE; 633 int error; 634 635 ap.a_head.a_desc = &vop_fdatasync_desc; 636 ap.a_head.a_ops = ops; 637 ap.a_vp = vp; 638 ap.a_waitfor = waitfor; 639 ap.a_flags = flags; 640 ap.a_fp = fp; 641 642 VFS_MPLOCK(vp->v_mount); 643 DO_OPS(ops, error, &ap, vop_fdatasync); 644 VFS_MPUNLOCK(); 645 646 return(error); 647 } 648 649 /* 650 * MPSAFE 651 */ 652 int 653 vop_old_remove(struct vop_ops *ops, struct vnode *dvp, 654 struct vnode *vp, struct componentname *cnp) 655 { 656 struct vop_old_remove_args ap; 657 VFS_MPLOCK_DECLARE; 658 int error; 659 660 ap.a_head.a_desc = &vop_old_remove_desc; 661 ap.a_head.a_ops = ops; 662 ap.a_dvp = dvp; 663 ap.a_vp = vp; 664 ap.a_cnp = cnp; 665 666 VFS_MPLOCK(dvp->v_mount); 667 DO_OPS(ops, error, &ap, vop_old_remove); 668 VFS_MPUNLOCK(); 669 670 return(error); 671 } 672 673 /* 674 * MPSAFE 675 */ 676 int 677 vop_old_link(struct vop_ops *ops, struct vnode *tdvp, 678 struct vnode *vp, struct componentname *cnp) 679 { 680 struct vop_old_link_args ap; 681 VFS_MPLOCK_DECLARE; 682 int error; 683 684 ap.a_head.a_desc = &vop_old_link_desc; 685 ap.a_head.a_ops = ops; 686 ap.a_tdvp = tdvp; 687 ap.a_vp = vp; 688 ap.a_cnp = cnp; 689 690 VFS_MPLOCK(tdvp->v_mount); 691 DO_OPS(ops, error, &ap, vop_old_link); 692 VFS_MPUNLOCK(); 693 694 return(error); 695 } 696 697 /* 698 * MPSAFE 699 */ 700 int 701 vop_old_rename(struct vop_ops *ops, 702 struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, 703 struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp) 704 { 705 struct vop_old_rename_args ap; 706 VFS_MPLOCK_DECLARE; 707 int error; 708 709 ap.a_head.a_desc = &vop_old_rename_desc; 710 ap.a_head.a_ops = ops; 711 ap.a_fdvp = fdvp; 712 ap.a_fvp = fvp; 713 ap.a_fcnp = fcnp; 714 ap.a_tdvp = tdvp; 715 ap.a_tvp = tvp; 716 ap.a_tcnp = tcnp; 717 718 VFS_MPLOCK(tdvp->v_mount); 719 DO_OPS(ops, error, &ap, vop_old_rename); 720 VFS_MPUNLOCK(); 721 722 return(error); 723 } 724 725 /* 726 * MPSAFE 727 */ 728 int 729 vop_old_mkdir(struct vop_ops *ops, struct vnode *dvp, 730 struct vnode **vpp, struct componentname *cnp, struct vattr *vap) 731 { 732 struct vop_old_mkdir_args ap; 733 VFS_MPLOCK_DECLARE; 734 int error; 735 736 ap.a_head.a_desc = &vop_old_mkdir_desc; 737 ap.a_head.a_ops = ops; 738 ap.a_dvp = dvp; 739 ap.a_vpp = vpp; 740 ap.a_cnp = cnp; 741 ap.a_vap = vap; 742 743 VFS_MPLOCK(dvp->v_mount); 744 DO_OPS(ops, error, &ap, vop_old_mkdir); 745 VFS_MPUNLOCK(); 746 747 return(error); 748 } 749 750 /* 751 * MPSAFE 752 */ 753 int 754 vop_old_rmdir(struct vop_ops *ops, struct vnode *dvp, 755 struct vnode *vp, struct componentname *cnp) 756 { 757 struct vop_old_rmdir_args ap; 758 VFS_MPLOCK_DECLARE; 759 int error; 760 761 ap.a_head.a_desc = &vop_old_rmdir_desc; 762 ap.a_head.a_ops = ops; 763 ap.a_dvp = dvp; 764 ap.a_vp = vp; 765 ap.a_cnp = cnp; 766 767 VFS_MPLOCK(dvp->v_mount); 768 DO_OPS(ops, error, &ap, vop_old_rmdir); 769 VFS_MPUNLOCK(); 770 771 return(error); 772 } 773 774 /* 775 * MPSAFE 776 */ 777 int 778 vop_old_symlink(struct vop_ops *ops, struct vnode *dvp, 779 struct vnode **vpp, struct componentname *cnp, 780 struct vattr *vap, char *target) 781 { 782 struct vop_old_symlink_args ap; 783 VFS_MPLOCK_DECLARE; 784 int error; 785 786 ap.a_head.a_desc = &vop_old_symlink_desc; 787 ap.a_head.a_ops = ops; 788 ap.a_dvp = dvp; 789 ap.a_vpp = vpp; 790 ap.a_cnp = cnp; 791 ap.a_vap = vap; 792 ap.a_target = target; 793 794 VFS_MPLOCK(dvp->v_mount); 795 DO_OPS(ops, error, &ap, vop_old_symlink); 796 VFS_MPUNLOCK(); 797 798 return(error); 799 } 800 801 /* 802 * MPSAFE 803 */ 804 int 805 vop_readdir(struct vop_ops *ops, struct vnode *vp, struct uio *uio, 806 struct ucred *cred, int *eofflag, int *ncookies, off_t **cookies, 807 struct file *fp) 808 { 809 struct vop_readdir_args ap; 810 VFS_MPLOCK_DECLARE; 811 int error; 812 813 ap.a_head.a_desc = &vop_readdir_desc; 814 ap.a_head.a_ops = ops; 815 ap.a_vp = vp; 816 ap.a_uio = uio; 817 ap.a_cred = cred; 818 ap.a_eofflag = eofflag; 819 ap.a_ncookies = ncookies; 820 ap.a_cookies = cookies; 821 ap.a_fp = fp; 822 823 VFS_MPLOCK(vp->v_mount); 824 DO_OPS(ops, error, &ap, vop_readdir); 825 VFS_MPUNLOCK(); 826 827 return(error); 828 } 829 830 /* 831 * MPSAFE 832 */ 833 int 834 vop_readlink(struct vop_ops *ops, struct vnode *vp, struct uio *uio, 835 struct ucred *cred) 836 { 837 struct vop_readlink_args ap; 838 VFS_MPLOCK_DECLARE; 839 int error; 840 841 ap.a_head.a_desc = &vop_readlink_desc; 842 ap.a_head.a_ops = ops; 843 ap.a_vp = vp; 844 ap.a_uio = uio; 845 ap.a_cred = cred; 846 847 VFS_MPLOCK(vp->v_mount); 848 DO_OPS(ops, error, &ap, vop_readlink); 849 VFS_MPUNLOCK(); 850 851 return(error); 852 } 853 854 /* 855 * MPSAFE 856 */ 857 int 858 vop_inactive(struct vop_ops *ops, struct vnode *vp) 859 { 860 struct vop_inactive_args ap; 861 struct mount *mp; 862 VFS_MPLOCK_DECLARE; 863 int error; 864 865 ap.a_head.a_desc = &vop_inactive_desc; 866 ap.a_head.a_ops = ops; 867 ap.a_vp = vp; 868 869 /* 870 * WARNING! Deactivation of the vnode can cause it to be recycled, 871 * clearing vp->v_mount. 872 */ 873 mp = vp->v_mount; 874 VFS_MPLOCK_FLAG(mp, MNTK_IN_MPSAFE); 875 DO_OPS(ops, error, &ap, vop_inactive); 876 VFS_MPUNLOCK(); 877 878 return(error); 879 } 880 881 /* 882 * MPSAFE 883 */ 884 int 885 vop_reclaim(struct vop_ops *ops, struct vnode *vp) 886 { 887 struct vop_reclaim_args ap; 888 struct mount *mp; 889 VFS_MPLOCK_DECLARE; 890 int error; 891 892 ap.a_head.a_desc = &vop_reclaim_desc; 893 ap.a_head.a_ops = ops; 894 ap.a_vp = vp; 895 896 /* 897 * WARNING! Reclamation of the vnode will clear vp->v_mount. 898 */ 899 mp = vp->v_mount; 900 VFS_MPLOCK(mp); 901 DO_OPS(ops, error, &ap, vop_reclaim); 902 VFS_MPUNLOCK(); 903 904 return(error); 905 } 906 907 /* 908 * MPSAFE 909 */ 910 int 911 vop_bmap(struct vop_ops *ops, struct vnode *vp, off_t loffset, 912 off_t *doffsetp, int *runp, int *runb, buf_cmd_t cmd) 913 { 914 struct vop_bmap_args ap; 915 VFS_MPLOCK_DECLARE; 916 int error; 917 918 ap.a_head.a_desc = &vop_bmap_desc; 919 ap.a_head.a_ops = ops; 920 ap.a_vp = vp; 921 ap.a_loffset = loffset; 922 ap.a_doffsetp = doffsetp; 923 ap.a_runp = runp; 924 ap.a_runb = runb; 925 ap.a_cmd = cmd; 926 927 VFS_MPLOCK(vp->v_mount); 928 DO_OPS(ops, error, &ap, vop_bmap); 929 VFS_MPUNLOCK(); 930 931 return(error); 932 } 933 934 /* 935 * WARNING! Vnode can go-away after the ops call (e.g. async flush 936 * from buffer kthread). 937 */ 938 int 939 vop_strategy(struct vop_ops *ops, struct vnode *vp, struct bio *bio) 940 { 941 struct vop_strategy_args ap; 942 VFS_MPLOCK_DECLARE; 943 int error; 944 945 ap.a_head.a_desc = &vop_strategy_desc; 946 ap.a_head.a_ops = ops; 947 ap.a_vp = vp; 948 ap.a_bio = bio; 949 950 if (vp->v_mount) { 951 VFS_MPLOCK_FLAG(vp->v_mount, MNTK_SG_MPSAFE); 952 DO_OPS(ops, error, &ap, vop_strategy); 953 VFS_MPUNLOCK(); 954 } else { 955 /* ugly hack for swap */ 956 get_mplock(); 957 DO_OPS(ops, error, &ap, vop_strategy); 958 rel_mplock(); 959 } 960 return(error); 961 } 962 963 /* 964 * MPSAFE 965 */ 966 int 967 vop_print(struct vop_ops *ops, struct vnode *vp) 968 { 969 struct vop_print_args ap; 970 VFS_MPLOCK_DECLARE; 971 int error; 972 973 ap.a_head.a_desc = &vop_print_desc; 974 ap.a_head.a_ops = ops; 975 ap.a_vp = vp; 976 977 VFS_MPLOCK(vp->v_mount); 978 DO_OPS(ops, error, &ap, vop_print); 979 VFS_MPUNLOCK(); 980 981 return(error); 982 } 983 984 /* 985 * MPSAFE 986 */ 987 int 988 vop_pathconf(struct vop_ops *ops, struct vnode *vp, int name, 989 register_t *retval) 990 { 991 struct vop_pathconf_args ap; 992 VFS_MPLOCK_DECLARE; 993 int error; 994 995 ap.a_head.a_desc = &vop_pathconf_desc; 996 ap.a_head.a_ops = ops; 997 ap.a_vp = vp; 998 ap.a_name = name; 999 ap.a_retval = retval; 1000 1001 VFS_MPLOCK(vp->v_mount); 1002 DO_OPS(ops, error, &ap, vop_pathconf); 1003 VFS_MPUNLOCK(); 1004 1005 return(error); 1006 } 1007 1008 /* 1009 * MPSAFE 1010 */ 1011 int 1012 vop_advlock(struct vop_ops *ops, struct vnode *vp, caddr_t id, int op, 1013 struct flock *fl, int flags) 1014 { 1015 struct vop_advlock_args ap; 1016 VFS_MPLOCK_DECLARE; 1017 int error; 1018 1019 ap.a_head.a_desc = &vop_advlock_desc; 1020 ap.a_head.a_ops = ops; 1021 ap.a_vp = vp; 1022 ap.a_id = id; 1023 ap.a_op = op; 1024 ap.a_fl = fl; 1025 ap.a_flags = flags; 1026 1027 VFS_MPLOCK(vp->v_mount); 1028 DO_OPS(ops, error, &ap, vop_advlock); 1029 VFS_MPUNLOCK(); 1030 1031 return(error); 1032 } 1033 1034 /* 1035 * MPSAFE 1036 */ 1037 int 1038 vop_balloc(struct vop_ops *ops, struct vnode *vp, off_t startoffset, 1039 int size, struct ucred *cred, int flags, 1040 struct buf **bpp) 1041 { 1042 struct vop_balloc_args ap; 1043 VFS_MPLOCK_DECLARE; 1044 int error; 1045 1046 ap.a_head.a_desc = &vop_balloc_desc; 1047 ap.a_head.a_ops = ops; 1048 ap.a_vp = vp; 1049 ap.a_startoffset = startoffset; 1050 ap.a_size = size; 1051 ap.a_cred = cred; 1052 ap.a_flags = flags; 1053 ap.a_bpp = bpp; 1054 1055 VFS_MPLOCK(vp->v_mount); 1056 DO_OPS(ops, error, &ap, vop_balloc); 1057 VFS_MPUNLOCK(); 1058 1059 return(error); 1060 } 1061 1062 /* 1063 * MPSAFE 1064 */ 1065 int 1066 vop_reallocblks(struct vop_ops *ops, struct vnode *vp, 1067 struct cluster_save *buflist) 1068 { 1069 struct vop_reallocblks_args ap; 1070 VFS_MPLOCK_DECLARE; 1071 int error; 1072 1073 ap.a_head.a_desc = &vop_reallocblks_desc; 1074 ap.a_head.a_ops = ops; 1075 ap.a_vp = vp; 1076 ap.a_buflist = buflist; 1077 1078 VFS_MPLOCK(vp->v_mount); 1079 DO_OPS(ops, error, &ap, vop_reallocblks); 1080 VFS_MPUNLOCK(); 1081 1082 return(error); 1083 } 1084 1085 /* 1086 * MPSAFE 1087 */ 1088 int 1089 vop_getpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, 1090 int reqpage, vm_ooffset_t offset, int seqaccess) 1091 { 1092 struct vop_getpages_args ap; 1093 VFS_MPLOCK_DECLARE; 1094 int error; 1095 1096 ap.a_head.a_desc = &vop_getpages_desc; 1097 ap.a_head.a_ops = ops; 1098 ap.a_vp = vp; 1099 ap.a_m = m; 1100 ap.a_count = count; 1101 ap.a_reqpage = reqpage; 1102 ap.a_offset = offset; 1103 ap.a_seqaccess = seqaccess; 1104 1105 VFS_MPLOCK(vp->v_mount); 1106 DO_OPS(ops, error, &ap, vop_getpages); 1107 VFS_MPUNLOCK(); 1108 1109 return(error); 1110 } 1111 1112 /* 1113 * MPSAFE 1114 */ 1115 int 1116 vop_putpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, 1117 int flags, int *rtvals, vm_ooffset_t offset) 1118 { 1119 struct vop_putpages_args ap; 1120 VFS_MPLOCK_DECLARE; 1121 int error; 1122 1123 ap.a_head.a_desc = &vop_putpages_desc; 1124 ap.a_head.a_ops = ops; 1125 ap.a_vp = vp; 1126 ap.a_m = m; 1127 ap.a_count = count; 1128 ap.a_flags = flags; 1129 ap.a_rtvals = rtvals; 1130 ap.a_offset = offset; 1131 1132 VFS_MPLOCK(vp->v_mount); 1133 DO_OPS(ops, error, &ap, vop_putpages); 1134 VFS_MPUNLOCK(); 1135 1136 return(error); 1137 } 1138 1139 /* 1140 * MPSAFE 1141 */ 1142 int 1143 vop_freeblks(struct vop_ops *ops, struct vnode *vp, off_t offset, int length) 1144 { 1145 struct vop_freeblks_args ap; 1146 VFS_MPLOCK_DECLARE; 1147 int error; 1148 1149 ap.a_head.a_desc = &vop_freeblks_desc; 1150 ap.a_head.a_ops = ops; 1151 ap.a_vp = vp; 1152 ap.a_offset = offset; 1153 ap.a_length = length; 1154 1155 VFS_MPLOCK(vp->v_mount); 1156 DO_OPS(ops, error, &ap, vop_freeblks); 1157 VFS_MPUNLOCK(); 1158 1159 return(error); 1160 } 1161 1162 /* 1163 * MPSAFE 1164 */ 1165 int 1166 vop_getacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1167 struct acl *aclp, struct ucred *cred) 1168 { 1169 struct vop_getacl_args ap; 1170 VFS_MPLOCK_DECLARE; 1171 int error; 1172 1173 ap.a_head.a_desc = &vop_getacl_desc; 1174 ap.a_head.a_ops = ops; 1175 ap.a_vp = vp; 1176 ap.a_type = type; 1177 ap.a_aclp = aclp; 1178 ap.a_cred = cred; 1179 1180 VFS_MPLOCK(vp->v_mount); 1181 DO_OPS(ops, error, &ap, vop_getacl); 1182 VFS_MPUNLOCK(); 1183 1184 return(error); 1185 } 1186 1187 /* 1188 * MPSAFE 1189 */ 1190 int 1191 vop_setacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1192 struct acl *aclp, struct ucred *cred) 1193 { 1194 struct vop_setacl_args ap; 1195 VFS_MPLOCK_DECLARE; 1196 int error; 1197 1198 ap.a_head.a_desc = &vop_setacl_desc; 1199 ap.a_head.a_ops = ops; 1200 ap.a_vp = vp; 1201 ap.a_type = type; 1202 ap.a_aclp = aclp; 1203 ap.a_cred = cred; 1204 1205 VFS_MPLOCK(vp->v_mount); 1206 DO_OPS(ops, error, &ap, vop_setacl); 1207 VFS_MPUNLOCK(); 1208 1209 return(error); 1210 } 1211 1212 /* 1213 * MPSAFE 1214 */ 1215 int 1216 vop_aclcheck(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1217 struct acl *aclp, struct ucred *cred) 1218 { 1219 struct vop_aclcheck_args ap; 1220 VFS_MPLOCK_DECLARE; 1221 int error; 1222 1223 ap.a_head.a_desc = &vop_aclcheck_desc; 1224 ap.a_head.a_ops = ops; 1225 ap.a_vp = vp; 1226 ap.a_type = type; 1227 ap.a_aclp = aclp; 1228 ap.a_cred = cred; 1229 1230 VFS_MPLOCK(vp->v_mount); 1231 DO_OPS(ops, error, &ap, vop_aclcheck); 1232 VFS_MPUNLOCK(); 1233 1234 return(error); 1235 } 1236 1237 /* 1238 * MPSAFE 1239 */ 1240 int 1241 vop_getextattr(struct vop_ops *ops, struct vnode *vp, int attrnamespace, 1242 char *attrname, struct uio *uio, struct ucred *cred) 1243 { 1244 struct vop_getextattr_args ap; 1245 VFS_MPLOCK_DECLARE; 1246 int error; 1247 1248 ap.a_head.a_desc = &vop_getextattr_desc; 1249 ap.a_head.a_ops = ops; 1250 ap.a_vp = vp; 1251 ap.a_attrnamespace = attrnamespace; 1252 ap.a_attrname = attrname; 1253 ap.a_uio = uio; 1254 ap.a_cred = cred; 1255 1256 VFS_MPLOCK(vp->v_mount); 1257 DO_OPS(ops, error, &ap, vop_getextattr); 1258 VFS_MPUNLOCK(); 1259 1260 return(error); 1261 } 1262 1263 /* 1264 * MPSAFE 1265 */ 1266 int 1267 vop_setextattr(struct vop_ops *ops, struct vnode *vp, int attrnamespace, 1268 char *attrname, struct uio *uio, struct ucred *cred) 1269 { 1270 struct vop_setextattr_args ap; 1271 VFS_MPLOCK_DECLARE; 1272 int error; 1273 1274 ap.a_head.a_desc = &vop_setextattr_desc; 1275 ap.a_head.a_ops = ops; 1276 ap.a_vp = vp; 1277 ap.a_attrnamespace = attrnamespace; 1278 ap.a_attrname = attrname; 1279 ap.a_uio = uio; 1280 ap.a_cred = cred; 1281 1282 VFS_MPLOCK(vp->v_mount); 1283 DO_OPS(ops, error, &ap, vop_setextattr); 1284 VFS_MPUNLOCK(); 1285 1286 return(error); 1287 } 1288 1289 /* 1290 * MPSAFE 1291 */ 1292 int 1293 vop_mountctl(struct vop_ops *ops, struct vnode *vp, int op, struct file *fp, 1294 const void *ctl, int ctllen, void *buf, int buflen, int *res) 1295 { 1296 struct vop_mountctl_args ap; 1297 VFS_MPLOCK_DECLARE; 1298 int error; 1299 1300 ap.a_head.a_desc = &vop_mountctl_desc; 1301 ap.a_head.a_ops = ops; 1302 ap.a_op = op; 1303 ap.a_ctl = ctl; 1304 ap.a_fp = fp; 1305 ap.a_ctllen = ctllen; 1306 ap.a_buf = buf; 1307 ap.a_buflen = buflen; 1308 ap.a_res = res; 1309 1310 VFS_MPLOCK(vp->v_mount); 1311 DO_OPS(ops, error, &ap, vop_mountctl); 1312 VFS_MPUNLOCK(); 1313 1314 return(error); 1315 } 1316 1317 /* 1318 * MPSAFE 1319 */ 1320 int 1321 vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred) 1322 { 1323 struct vop_markatime_args ap; 1324 VFS_MPLOCK_DECLARE; 1325 int error; 1326 1327 ap.a_head.a_desc = &vop_markatime_desc; 1328 ap.a_head.a_ops = ops; 1329 ap.a_vp = vp; 1330 ap.a_cred = cred; 1331 1332 VFS_MPLOCK(vp->v_mount); 1333 DO_OPS(ops, error, &ap, vop_markatime); 1334 VFS_MPUNLOCK(); 1335 1336 return(error); 1337 } 1338 1339 /* 1340 * MPSAFE 1341 */ 1342 int 1343 vop_allocate(struct vop_ops *ops, struct vnode *vp, off_t offset, off_t len) 1344 { 1345 struct vop_allocate_args ap; 1346 VFS_MPLOCK_DECLARE; 1347 int error; 1348 1349 ap.a_head.a_desc = &vop_allocate_desc; 1350 ap.a_head.a_ops = ops; 1351 ap.a_vp = vp; 1352 ap.a_offset = offset; 1353 ap.a_len = len; 1354 1355 VFS_MPLOCK(vp->v_mount); 1356 DO_OPS(ops, error, &ap, vop_allocate); 1357 VFS_MPUNLOCK(); 1358 1359 return(error); 1360 } 1361 1362 /* 1363 * NEW API FUNCTIONS 1364 * 1365 * nresolve takes a locked ncp, a referenced but unlocked dvp, and a cred, 1366 * and resolves the ncp into a positive or negative hit. 1367 * 1368 * The namecache is automatically adjusted by this function. The ncp 1369 * is left locked on return. 1370 * 1371 * MPSAFE 1372 */ 1373 int 1374 vop_nresolve(struct vop_ops *ops, struct nchandle *nch, 1375 struct vnode *dvp, struct ucred *cred) 1376 { 1377 struct vop_nresolve_args ap; 1378 VFS_MPLOCK_DECLARE; 1379 int error; 1380 1381 ap.a_head.a_desc = &vop_nresolve_desc; 1382 ap.a_head.a_ops = ops; 1383 ap.a_nch = nch; 1384 ap.a_dvp = dvp; 1385 ap.a_cred = cred; 1386 1387 VFS_MPLOCK(dvp->v_mount); 1388 DO_OPS(ops, error, &ap, vop_nresolve); 1389 VFS_MPUNLOCK(); 1390 1391 return(error); 1392 } 1393 1394 /* 1395 * nlookupdotdot takes an unlocked directory, referenced dvp, and looks 1396 * up "..", returning a locked parent directory in *vpp. If an error 1397 * occurs *vpp will be NULL. 1398 * 1399 * MPSAFE 1400 */ 1401 int 1402 vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, 1403 struct vnode **vpp, struct ucred *cred, char **fakename) 1404 { 1405 struct vop_nlookupdotdot_args ap; 1406 VFS_MPLOCK_DECLARE; 1407 int error; 1408 1409 ap.a_head.a_desc = &vop_nlookupdotdot_desc; 1410 ap.a_head.a_ops = ops; 1411 ap.a_dvp = dvp; 1412 ap.a_vpp = vpp; 1413 ap.a_cred = cred; 1414 ap.a_fakename = fakename; 1415 1416 VFS_MPLOCK(dvp->v_mount); 1417 DO_OPS(ops, error, &ap, vop_nlookupdotdot); 1418 VFS_MPUNLOCK(); 1419 1420 return(error); 1421 } 1422 1423 /* 1424 * ncreate takes a locked, resolved ncp that typically represents a negative 1425 * cache hit and creates the file or node specified by the ncp, cred, and 1426 * vattr. If no error occurs a locked vnode is returned in *vpp. 1427 * 1428 * The dvp passed in is referenced but unlocked. 1429 * 1430 * The namecache is automatically adjusted by this function. The ncp 1431 * is left locked on return. 1432 * 1433 * MPSAFE 1434 */ 1435 int 1436 vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1437 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1438 { 1439 struct vop_ncreate_args ap; 1440 VFS_MPLOCK_DECLARE; 1441 int error; 1442 1443 ap.a_head.a_desc = &vop_ncreate_desc; 1444 ap.a_head.a_ops = ops; 1445 ap.a_nch = nch; 1446 ap.a_dvp = dvp; 1447 ap.a_vpp = vpp; 1448 ap.a_cred = cred; 1449 ap.a_vap = vap; 1450 1451 VFS_MPLOCK(dvp->v_mount); 1452 DO_OPS(ops, error, &ap, vop_ncreate); 1453 VFS_MPUNLOCK(); 1454 1455 return(error); 1456 } 1457 1458 /* 1459 * nmkdir takes a locked, resolved ncp that typically represents a negative 1460 * cache hit and creates the directory specified by the ncp, cred, and 1461 * vattr. If no error occurs a locked vnode is returned in *vpp. 1462 * 1463 * The dvp passed in is referenced but unlocked. 1464 * 1465 * The namecache is automatically adjusted by this function. The ncp 1466 * is left locked on return. 1467 * 1468 * MPSAFE 1469 */ 1470 int 1471 vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1472 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1473 { 1474 struct vop_nmkdir_args ap; 1475 VFS_MPLOCK_DECLARE; 1476 int error; 1477 1478 ap.a_head.a_desc = &vop_nmkdir_desc; 1479 ap.a_head.a_ops = ops; 1480 ap.a_nch = nch; 1481 ap.a_dvp = dvp; 1482 ap.a_vpp = vpp; 1483 ap.a_cred = cred; 1484 ap.a_vap = vap; 1485 1486 VFS_MPLOCK(dvp->v_mount); 1487 DO_OPS(ops, error, &ap, vop_nmkdir); 1488 VFS_MPUNLOCK(); 1489 1490 return(error); 1491 } 1492 1493 /* 1494 * nmknod takes a locked, resolved ncp that typically represents a negative 1495 * cache hit and creates the node specified by the ncp, cred, and 1496 * vattr. If no error occurs a locked vnode is returned in *vpp. 1497 * 1498 * The dvp passed in is referenced but unlocked. 1499 * 1500 * The namecache is automatically adjusted by this function. The ncp 1501 * is left locked on return. 1502 * 1503 * MPSAFE 1504 */ 1505 int 1506 vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1507 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1508 { 1509 struct vop_nmknod_args ap; 1510 VFS_MPLOCK_DECLARE; 1511 int error; 1512 1513 ap.a_head.a_desc = &vop_nmknod_desc; 1514 ap.a_head.a_ops = ops; 1515 ap.a_nch = nch; 1516 ap.a_dvp = dvp; 1517 ap.a_vpp = vpp; 1518 ap.a_cred = cred; 1519 ap.a_vap = vap; 1520 1521 VFS_MPLOCK(dvp->v_mount); 1522 DO_OPS(ops, error, &ap, vop_nmknod); 1523 VFS_MPUNLOCK(); 1524 1525 return(error); 1526 } 1527 1528 /* 1529 * nlink takes a locked, resolved ncp that typically represents a negative 1530 * cache hit and creates the node specified by the ncp, cred, and 1531 * existing vnode. The passed vp must be locked and will remain locked 1532 * on return, as does the ncp, whether an error occurs or not. 1533 * 1534 * The dvp passed in is referenced but unlocked. 1535 * 1536 * The namecache is automatically adjusted by this function. The ncp 1537 * is left locked on return. 1538 * 1539 * MPSAFE 1540 */ 1541 int 1542 vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1543 struct vnode *vp, struct ucred *cred) 1544 { 1545 struct vop_nlink_args ap; 1546 VFS_MPLOCK_DECLARE; 1547 int error; 1548 1549 ap.a_head.a_desc = &vop_nlink_desc; 1550 ap.a_head.a_ops = ops; 1551 ap.a_nch = nch; 1552 ap.a_dvp = dvp; 1553 ap.a_vp = vp; 1554 ap.a_cred = cred; 1555 1556 VFS_MPLOCK(dvp->v_mount); 1557 DO_OPS(ops, error, &ap, vop_nlink); 1558 VFS_MPUNLOCK(); 1559 1560 return(error); 1561 } 1562 1563 /* 1564 * nsymlink takes a locked, resolved ncp that typically represents a negative 1565 * cache hit and creates a symbolic link based on cred, vap, and target (the 1566 * contents of the link). If no error occurs a locked vnode is returned in 1567 * *vpp. 1568 * 1569 * The dvp passed in is referenced but unlocked. 1570 * 1571 * The namecache is automatically adjusted by this function. The ncp 1572 * is left locked on return. 1573 * 1574 * MPSAFE 1575 */ 1576 int 1577 vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1578 struct vnode **vpp, struct ucred *cred, 1579 struct vattr *vap, char *target) 1580 { 1581 struct vop_nsymlink_args ap; 1582 VFS_MPLOCK_DECLARE; 1583 int error; 1584 1585 ap.a_head.a_desc = &vop_nsymlink_desc; 1586 ap.a_head.a_ops = ops; 1587 ap.a_nch = nch; 1588 ap.a_dvp = dvp; 1589 ap.a_vpp = vpp; 1590 ap.a_cred = cred; 1591 ap.a_vap = vap; 1592 ap.a_target = target; 1593 1594 VFS_MPLOCK(dvp->v_mount); 1595 DO_OPS(ops, error, &ap, vop_nsymlink); 1596 VFS_MPUNLOCK(); 1597 1598 return(error); 1599 } 1600 1601 /* 1602 * nwhiteout takes a locked, resolved ncp that can represent a positive or 1603 * negative hit and executes the whiteout function specified in flags. 1604 * 1605 * The dvp passed in is referenced but unlocked. 1606 * 1607 * The namecache is automatically adjusted by this function. The ncp 1608 * is left locked on return. 1609 * 1610 * MPSAFE 1611 */ 1612 int 1613 vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1614 struct ucred *cred, int flags) 1615 { 1616 struct vop_nwhiteout_args ap; 1617 VFS_MPLOCK_DECLARE; 1618 int error; 1619 1620 ap.a_head.a_desc = &vop_nwhiteout_desc; 1621 ap.a_head.a_ops = ops; 1622 ap.a_nch = nch; 1623 ap.a_dvp = dvp; 1624 ap.a_cred = cred; 1625 ap.a_flags = flags; 1626 1627 VFS_MPLOCK(dvp->v_mount); 1628 DO_OPS(ops, error, &ap, vop_nwhiteout); 1629 VFS_MPUNLOCK(); 1630 1631 return(error); 1632 } 1633 1634 /* 1635 * nremove takes a locked, resolved ncp that generally represents a 1636 * positive hit and removes the file. 1637 * 1638 * The dvp passed in is referenced but unlocked. 1639 * 1640 * The namecache is automatically adjusted by this function. The ncp 1641 * is left locked on return. 1642 * 1643 * MPSAFE 1644 */ 1645 int 1646 vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1647 struct ucred *cred) 1648 { 1649 struct vop_nremove_args ap; 1650 VFS_MPLOCK_DECLARE; 1651 int error; 1652 struct vattr va; 1653 1654 ap.a_head.a_desc = &vop_nremove_desc; 1655 ap.a_head.a_ops = ops; 1656 ap.a_nch = nch; 1657 ap.a_dvp = dvp; 1658 ap.a_cred = cred; 1659 1660 if ((error = VOP_GETATTR(nch->ncp->nc_vp, &va)) != 0) 1661 return (error); 1662 1663 VFS_MPLOCK(dvp->v_mount); 1664 DO_OPS(ops, error, &ap, vop_nremove); 1665 /* Only update space counters if this is the last hard link */ 1666 if ((error == 0) && (va.va_nlink == 1)) { 1667 VFS_ACCOUNT(nch->mount, va.va_uid, va.va_gid, -va.va_size); 1668 } 1669 VFS_MPUNLOCK(); 1670 1671 return(error); 1672 } 1673 1674 /* 1675 * nrmdir takes a locked, resolved ncp that generally represents a 1676 * directory and removes the directory. 1677 * 1678 * The dvp passed in is referenced but unlocked. 1679 * 1680 * The namecache is automatically adjusted by this function. The ncp 1681 * is left locked on return. 1682 * 1683 * MPSAFE 1684 */ 1685 int 1686 vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1687 struct ucred *cred) 1688 { 1689 struct vop_nrmdir_args ap; 1690 VFS_MPLOCK_DECLARE; 1691 int error; 1692 1693 ap.a_head.a_desc = &vop_nrmdir_desc; 1694 ap.a_head.a_ops = ops; 1695 ap.a_nch = nch; 1696 ap.a_dvp = dvp; 1697 ap.a_cred = cred; 1698 1699 VFS_MPLOCK(dvp->v_mount); 1700 DO_OPS(ops, error, &ap, vop_nrmdir); 1701 VFS_MPUNLOCK(); 1702 1703 return(error); 1704 } 1705 1706 /* 1707 * nrename takes TWO locked, resolved ncp's and the cred of the caller 1708 * and renames the source ncp to the target ncp. The target ncp may 1709 * represent a positive or negative hit. 1710 * 1711 * The fdvp and tdvp passed in are referenced but unlocked. 1712 * 1713 * The namecache is automatically adjusted by this function. The ncp 1714 * is left locked on return. The source ncp is typically changed to 1715 * a negative cache hit and the target ncp typically takes on the 1716 * source ncp's underlying file. 1717 * 1718 * MPSAFE 1719 */ 1720 int 1721 vop_nrename(struct vop_ops *ops, 1722 struct nchandle *fnch, struct nchandle *tnch, 1723 struct vnode *fdvp, struct vnode *tdvp, 1724 struct ucred *cred) 1725 { 1726 struct vop_nrename_args ap; 1727 VFS_MPLOCK_DECLARE; 1728 int error; 1729 1730 ap.a_head.a_desc = &vop_nrename_desc; 1731 ap.a_head.a_ops = ops; 1732 ap.a_fnch = fnch; 1733 ap.a_tnch = tnch; 1734 ap.a_fdvp = fdvp; 1735 ap.a_tdvp = tdvp; 1736 ap.a_cred = cred; 1737 1738 VFS_MPLOCK(fdvp->v_mount); 1739 DO_OPS(ops, error, &ap, vop_nrename); 1740 VFS_MPUNLOCK(); 1741 1742 return(error); 1743 } 1744 1745 /************************************************************************ 1746 * PRIMARY VNODE OPERATIONS FORWARDING CALLS * 1747 ************************************************************************ 1748 * 1749 * These procedures are called from VFSs such as nullfs 1750 * when they wish to forward an operation on one VFS to another. The 1751 * argument structure/message is modified and then directly passed to the 1752 * appropriate routine. This routines may also be called by initiators 1753 * who have an argument structure in hand rather then discreet arguments. 1754 * 1755 * MPSAFE - Caller expected to already hold the appropriate vfs lock. 1756 */ 1757 int 1758 vop_vnoperate_ap(struct vop_generic_args *ap) 1759 { 1760 struct vop_ops *ops; 1761 int error; 1762 1763 ops = ap->a_ops; 1764 error = VOCALL(ops, ap); 1765 1766 return (error); 1767 } 1768 1769 /* 1770 * This routine is called by the cache coherency layer to execute the actual 1771 * VFS operation. If a journaling layer is present we call though it, else 1772 * we call the native VOP functions. 1773 */ 1774 int 1775 vop_cache_operate_ap(struct vop_generic_args *ap) 1776 { 1777 struct vop_ops *ops; 1778 int error; 1779 1780 ops = ap->a_ops; 1781 if (ops->head.vv_mount->mnt_vn_journal_ops) 1782 error = VOCALL(ops->head.vv_mount->mnt_vn_journal_ops, ap); 1783 else 1784 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1785 return (error); 1786 } 1787 1788 1789 /* 1790 * This routine is called by the journaling layer to execute the actual 1791 * VFS operation. 1792 */ 1793 int 1794 vop_journal_operate_ap(struct vop_generic_args *ap) 1795 { 1796 struct vop_ops *ops; 1797 int error; 1798 1799 ops = ap->a_ops; 1800 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1801 1802 return (error); 1803 } 1804 1805 int 1806 vop_open_ap(struct vop_open_args *ap) 1807 { 1808 int error; 1809 1810 DO_OPS(ap->a_head.a_ops, error, ap, vop_open); 1811 return(error); 1812 } 1813 1814 int 1815 vop_close_ap(struct vop_close_args *ap) 1816 { 1817 int error; 1818 1819 DO_OPS(ap->a_head.a_ops, error, ap, vop_close); 1820 return(error); 1821 } 1822 1823 int 1824 vop_access_ap(struct vop_access_args *ap) 1825 { 1826 int error; 1827 1828 DO_OPS(ap->a_head.a_ops, error, ap, vop_access); 1829 return(error); 1830 } 1831 1832 int 1833 vop_getattr_ap(struct vop_getattr_args *ap) 1834 { 1835 int error; 1836 1837 DO_OPS(ap->a_head.a_ops, error, ap, vop_getattr); 1838 return(error); 1839 } 1840 1841 int 1842 vop_getattr_lite_ap(struct vop_getattr_lite_args *ap) 1843 { 1844 int error; 1845 1846 DO_OPS(ap->a_head.a_ops, error, ap, vop_getattr_lite); 1847 return(error); 1848 } 1849 1850 int 1851 vop_setattr_ap(struct vop_setattr_args *ap) 1852 { 1853 int error; 1854 1855 DO_OPS(ap->a_head.a_ops, error, ap, vop_setattr); 1856 return(error); 1857 } 1858 1859 int 1860 vop_read_ap(struct vop_read_args *ap) 1861 { 1862 int error; 1863 1864 DO_OPS(ap->a_head.a_ops, error, ap, vop_read); 1865 return(error); 1866 } 1867 1868 int 1869 vop_write_ap(struct vop_write_args *ap) 1870 { 1871 int error; 1872 1873 DO_OPS(ap->a_head.a_ops, error, ap, vop_write); 1874 return(error); 1875 } 1876 1877 int 1878 vop_ioctl_ap(struct vop_ioctl_args *ap) 1879 { 1880 int error; 1881 1882 DO_OPS(ap->a_head.a_ops, error, ap, vop_ioctl); 1883 return(error); 1884 } 1885 1886 int 1887 vop_poll_ap(struct vop_poll_args *ap) 1888 { 1889 int error; 1890 1891 DO_OPS(ap->a_head.a_ops, error, ap, vop_poll); 1892 return(error); 1893 } 1894 1895 int 1896 vop_kqfilter_ap(struct vop_kqfilter_args *ap) 1897 { 1898 int error; 1899 1900 DO_OPS(ap->a_head.a_ops, error, ap, vop_kqfilter); 1901 return(error); 1902 } 1903 1904 int 1905 vop_mmap_ap(struct vop_mmap_args *ap) 1906 { 1907 int error; 1908 1909 DO_OPS(ap->a_head.a_ops, error, ap, vop_mmap); 1910 return(error); 1911 } 1912 1913 int 1914 vop_fsync_ap(struct vop_fsync_args *ap) 1915 { 1916 int error; 1917 1918 DO_OPS(ap->a_head.a_ops, error, ap, vop_fsync); 1919 return(error); 1920 } 1921 1922 int 1923 vop_fdatasync_ap(struct vop_fdatasync_args *ap) 1924 { 1925 int error; 1926 1927 DO_OPS(ap->a_head.a_ops, error, ap, vop_fdatasync); 1928 return(error); 1929 } 1930 1931 int 1932 vop_readdir_ap(struct vop_readdir_args *ap) 1933 { 1934 int error; 1935 1936 DO_OPS(ap->a_head.a_ops, error, ap, vop_readdir); 1937 return(error); 1938 } 1939 1940 int 1941 vop_readlink_ap(struct vop_readlink_args *ap) 1942 { 1943 int error; 1944 1945 DO_OPS(ap->a_head.a_ops, error, ap, vop_readlink); 1946 return(error); 1947 } 1948 1949 int 1950 vop_inactive_ap(struct vop_inactive_args *ap) 1951 { 1952 int error; 1953 1954 DO_OPS(ap->a_head.a_ops, error, ap, vop_inactive); 1955 return(error); 1956 } 1957 1958 int 1959 vop_reclaim_ap(struct vop_reclaim_args *ap) 1960 { 1961 int error; 1962 1963 DO_OPS(ap->a_head.a_ops, error, ap, vop_reclaim); 1964 return(error); 1965 } 1966 1967 int 1968 vop_bmap_ap(struct vop_bmap_args *ap) 1969 { 1970 int error; 1971 1972 DO_OPS(ap->a_head.a_ops, error, ap, vop_bmap); 1973 return(error); 1974 } 1975 1976 int 1977 vop_strategy_ap(struct vop_strategy_args *ap) 1978 { 1979 int error; 1980 1981 DO_OPS(ap->a_head.a_ops, error, ap, vop_strategy); 1982 return(error); 1983 } 1984 1985 int 1986 vop_print_ap(struct vop_print_args *ap) 1987 { 1988 int error; 1989 1990 DO_OPS(ap->a_head.a_ops, error, ap, vop_print); 1991 return(error); 1992 } 1993 1994 int 1995 vop_pathconf_ap(struct vop_pathconf_args *ap) 1996 { 1997 int error; 1998 1999 DO_OPS(ap->a_head.a_ops, error, ap, vop_pathconf); 2000 return(error); 2001 } 2002 2003 int 2004 vop_advlock_ap(struct vop_advlock_args *ap) 2005 { 2006 int error; 2007 2008 DO_OPS(ap->a_head.a_ops, error, ap, vop_advlock); 2009 return(error); 2010 } 2011 2012 int 2013 vop_balloc_ap(struct vop_balloc_args *ap) 2014 { 2015 int error; 2016 2017 DO_OPS(ap->a_head.a_ops, error, ap, vop_balloc); 2018 return(error); 2019 } 2020 2021 int 2022 vop_reallocblks_ap(struct vop_reallocblks_args *ap) 2023 { 2024 int error; 2025 2026 DO_OPS(ap->a_head.a_ops, error, ap, vop_reallocblks); 2027 return(error); 2028 } 2029 2030 int 2031 vop_getpages_ap(struct vop_getpages_args *ap) 2032 { 2033 int error; 2034 2035 DO_OPS(ap->a_head.a_ops, error, ap, vop_getpages); 2036 return(error); 2037 } 2038 2039 int 2040 vop_putpages_ap(struct vop_putpages_args *ap) 2041 { 2042 int error; 2043 2044 DO_OPS(ap->a_head.a_ops, error, ap, vop_putpages); 2045 return(error); 2046 } 2047 2048 int 2049 vop_freeblks_ap(struct vop_freeblks_args *ap) 2050 { 2051 int error; 2052 2053 DO_OPS(ap->a_head.a_ops, error, ap, vop_freeblks); 2054 return(error); 2055 } 2056 2057 int 2058 vop_getacl_ap(struct vop_getacl_args *ap) 2059 { 2060 int error; 2061 2062 DO_OPS(ap->a_head.a_ops, error, ap, vop_getacl); 2063 return(error); 2064 } 2065 2066 int 2067 vop_setacl_ap(struct vop_setacl_args *ap) 2068 { 2069 int error; 2070 2071 DO_OPS(ap->a_head.a_ops, error, ap, vop_setacl); 2072 return(error); 2073 } 2074 2075 int 2076 vop_aclcheck_ap(struct vop_aclcheck_args *ap) 2077 { 2078 int error; 2079 2080 DO_OPS(ap->a_head.a_ops, error, ap, vop_aclcheck); 2081 return(error); 2082 } 2083 2084 int 2085 vop_getextattr_ap(struct vop_getextattr_args *ap) 2086 { 2087 int error; 2088 2089 DO_OPS(ap->a_head.a_ops, error, ap, vop_getextattr); 2090 return(error); 2091 } 2092 2093 int 2094 vop_setextattr_ap(struct vop_setextattr_args *ap) 2095 { 2096 int error; 2097 2098 DO_OPS(ap->a_head.a_ops, error, ap, vop_setextattr); 2099 return(error); 2100 } 2101 2102 int 2103 vop_mountctl_ap(struct vop_mountctl_args *ap) 2104 { 2105 int error; 2106 2107 DO_OPS(ap->a_head.a_ops, error, ap, vop_mountctl); 2108 return(error); 2109 } 2110 2111 int 2112 vop_markatime_ap(struct vop_markatime_args *ap) 2113 { 2114 int error; 2115 2116 DO_OPS(ap->a_head.a_ops, error, ap, vop_markatime); 2117 return(error); 2118 } 2119 2120 int 2121 vop_allocate_ap(struct vop_allocate_args *ap) 2122 { 2123 int error; 2124 2125 DO_OPS(ap->a_head.a_ops, error, ap, vop_allocate); 2126 return(error); 2127 } 2128 2129 int 2130 vop_nresolve_ap(struct vop_nresolve_args *ap) 2131 { 2132 int error; 2133 2134 DO_OPS(ap->a_head.a_ops, error, ap, vop_nresolve); 2135 return(error); 2136 } 2137 2138 int 2139 vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap) 2140 { 2141 int error; 2142 2143 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlookupdotdot); 2144 return(error); 2145 } 2146 2147 int 2148 vop_ncreate_ap(struct vop_ncreate_args *ap) 2149 { 2150 int error; 2151 2152 DO_OPS(ap->a_head.a_ops, error, ap, vop_ncreate); 2153 return(error); 2154 } 2155 2156 int 2157 vop_nmkdir_ap(struct vop_nmkdir_args *ap) 2158 { 2159 int error; 2160 2161 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmkdir); 2162 return(error); 2163 } 2164 2165 int 2166 vop_nmknod_ap(struct vop_nmknod_args *ap) 2167 { 2168 int error; 2169 2170 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmknod); 2171 return(error); 2172 } 2173 2174 int 2175 vop_nlink_ap(struct vop_nlink_args *ap) 2176 { 2177 int error; 2178 2179 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlink); 2180 return(error); 2181 } 2182 2183 int 2184 vop_nsymlink_ap(struct vop_nsymlink_args *ap) 2185 { 2186 int error; 2187 2188 DO_OPS(ap->a_head.a_ops, error, ap, vop_nsymlink); 2189 return(error); 2190 } 2191 2192 int 2193 vop_nwhiteout_ap(struct vop_nwhiteout_args *ap) 2194 { 2195 int error; 2196 2197 DO_OPS(ap->a_head.a_ops, error, ap, vop_nwhiteout); 2198 return(error); 2199 } 2200 2201 int 2202 vop_nremove_ap(struct vop_nremove_args *ap) 2203 { 2204 int error; 2205 2206 DO_OPS(ap->a_head.a_ops, error, ap, vop_nremove); 2207 return(error); 2208 } 2209 2210 int 2211 vop_nrmdir_ap(struct vop_nrmdir_args *ap) 2212 { 2213 int error; 2214 2215 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrmdir); 2216 return(error); 2217 } 2218 2219 int 2220 vop_nrename_ap(struct vop_nrename_args *ap) 2221 { 2222 int error; 2223 2224 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrename); 2225 return(error); 2226 } 2227 2228