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