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