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 VFS_MPLOCK1(vp->v_mount); 822 DO_OPS(ops, error, &ap, vop_strategy); 823 VFS_MPUNLOCK(vp->v_mount); 824 return(error); 825 } 826 827 /* 828 * MPSAFE 829 */ 830 int 831 vop_print(struct vop_ops *ops, struct vnode *vp) 832 { 833 struct vop_print_args ap; 834 VFS_MPLOCK_DECLARE; 835 int error; 836 837 ap.a_head.a_desc = &vop_print_desc; 838 ap.a_head.a_ops = ops; 839 ap.a_vp = vp; 840 841 VFS_MPLOCK1(vp->v_mount); 842 DO_OPS(ops, error, &ap, vop_print); 843 VFS_MPUNLOCK(vp->v_mount); 844 return(error); 845 } 846 847 /* 848 * MPSAFE 849 */ 850 int 851 vop_pathconf(struct vop_ops *ops, struct vnode *vp, int name, 852 register_t *retval) 853 { 854 struct vop_pathconf_args ap; 855 VFS_MPLOCK_DECLARE; 856 int error; 857 858 ap.a_head.a_desc = &vop_pathconf_desc; 859 ap.a_head.a_ops = ops; 860 ap.a_vp = vp; 861 ap.a_name = name; 862 ap.a_retval = retval; 863 864 VFS_MPLOCK1(vp->v_mount); 865 DO_OPS(ops, error, &ap, vop_pathconf); 866 VFS_MPUNLOCK(vp->v_mount); 867 return(error); 868 } 869 870 /* 871 * MPSAFE 872 */ 873 int 874 vop_advlock(struct vop_ops *ops, struct vnode *vp, caddr_t id, int op, 875 struct flock *fl, int flags) 876 { 877 struct vop_advlock_args ap; 878 VFS_MPLOCK_DECLARE; 879 int error; 880 881 ap.a_head.a_desc = &vop_advlock_desc; 882 ap.a_head.a_ops = ops; 883 ap.a_vp = vp; 884 ap.a_id = id; 885 ap.a_op = op; 886 ap.a_fl = fl; 887 ap.a_flags = flags; 888 889 VFS_MPLOCK1(vp->v_mount); 890 DO_OPS(ops, error, &ap, vop_advlock); 891 VFS_MPUNLOCK(vp->v_mount); 892 return(error); 893 } 894 895 /* 896 * MPSAFE 897 */ 898 int 899 vop_balloc(struct vop_ops *ops, struct vnode *vp, off_t startoffset, 900 int size, struct ucred *cred, int flags, 901 struct buf **bpp) 902 { 903 struct vop_balloc_args ap; 904 VFS_MPLOCK_DECLARE; 905 int error; 906 907 ap.a_head.a_desc = &vop_balloc_desc; 908 ap.a_head.a_ops = ops; 909 ap.a_vp = vp; 910 ap.a_startoffset = startoffset; 911 ap.a_size = size; 912 ap.a_cred = cred; 913 ap.a_flags = flags; 914 ap.a_bpp = bpp; 915 916 VFS_MPLOCK1(vp->v_mount); 917 DO_OPS(ops, error, &ap, vop_balloc); 918 VFS_MPUNLOCK(vp->v_mount); 919 return(error); 920 } 921 922 /* 923 * MPSAFE 924 */ 925 int 926 vop_reallocblks(struct vop_ops *ops, struct vnode *vp, 927 struct cluster_save *buflist) 928 { 929 struct vop_reallocblks_args ap; 930 VFS_MPLOCK_DECLARE; 931 int error; 932 933 ap.a_head.a_desc = &vop_reallocblks_desc; 934 ap.a_head.a_ops = ops; 935 ap.a_vp = vp; 936 ap.a_buflist = buflist; 937 938 VFS_MPLOCK1(vp->v_mount); 939 DO_OPS(ops, error, &ap, vop_reallocblks); 940 VFS_MPUNLOCK(vp->v_mount); 941 return(error); 942 } 943 944 /* 945 * MPSAFE 946 */ 947 int 948 vop_getpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, 949 int reqpage, vm_ooffset_t offset) 950 { 951 struct vop_getpages_args ap; 952 VFS_MPLOCK_DECLARE; 953 int error; 954 955 ap.a_head.a_desc = &vop_getpages_desc; 956 ap.a_head.a_ops = ops; 957 ap.a_vp = vp; 958 ap.a_m = m; 959 ap.a_count = count; 960 ap.a_reqpage = reqpage; 961 ap.a_offset = offset; 962 963 VFS_MPLOCK1(vp->v_mount); 964 DO_OPS(ops, error, &ap, vop_getpages); 965 VFS_MPUNLOCK(vp->v_mount); 966 return(error); 967 } 968 969 /* 970 * MPSAFE 971 */ 972 int 973 vop_putpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, 974 int sync, int *rtvals, vm_ooffset_t offset) 975 { 976 struct vop_putpages_args ap; 977 VFS_MPLOCK_DECLARE; 978 int error; 979 980 ap.a_head.a_desc = &vop_putpages_desc; 981 ap.a_head.a_ops = ops; 982 ap.a_vp = vp; 983 ap.a_m = m; 984 ap.a_count = count; 985 ap.a_sync = sync; 986 ap.a_rtvals = rtvals; 987 ap.a_offset = offset; 988 989 VFS_MPLOCK1(vp->v_mount); 990 DO_OPS(ops, error, &ap, vop_putpages); 991 VFS_MPUNLOCK(vp->v_mount); 992 return(error); 993 } 994 995 /* 996 * MPSAFE 997 */ 998 int 999 vop_freeblks(struct vop_ops *ops, struct vnode *vp, off_t offset, int length) 1000 { 1001 struct vop_freeblks_args ap; 1002 VFS_MPLOCK_DECLARE; 1003 int error; 1004 1005 ap.a_head.a_desc = &vop_freeblks_desc; 1006 ap.a_head.a_ops = ops; 1007 ap.a_vp = vp; 1008 ap.a_offset = offset; 1009 ap.a_length = length; 1010 1011 VFS_MPLOCK1(vp->v_mount); 1012 DO_OPS(ops, error, &ap, vop_freeblks); 1013 VFS_MPUNLOCK(vp->v_mount); 1014 return(error); 1015 } 1016 1017 /* 1018 * MPSAFE 1019 */ 1020 int 1021 vop_getacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1022 struct acl *aclp, struct ucred *cred) 1023 { 1024 struct vop_getacl_args ap; 1025 VFS_MPLOCK_DECLARE; 1026 int error; 1027 1028 ap.a_head.a_desc = &vop_getacl_desc; 1029 ap.a_head.a_ops = ops; 1030 ap.a_vp = vp; 1031 ap.a_type = type; 1032 ap.a_aclp = aclp; 1033 ap.a_cred = cred; 1034 1035 VFS_MPLOCK1(vp->v_mount); 1036 DO_OPS(ops, error, &ap, vop_getacl); 1037 VFS_MPUNLOCK(vp->v_mount); 1038 return(error); 1039 } 1040 1041 /* 1042 * MPSAFE 1043 */ 1044 int 1045 vop_setacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1046 struct acl *aclp, struct ucred *cred) 1047 { 1048 struct vop_setacl_args ap; 1049 VFS_MPLOCK_DECLARE; 1050 int error; 1051 1052 ap.a_head.a_desc = &vop_setacl_desc; 1053 ap.a_head.a_ops = ops; 1054 ap.a_vp = vp; 1055 ap.a_type = type; 1056 ap.a_aclp = aclp; 1057 ap.a_cred = cred; 1058 1059 VFS_MPLOCK1(vp->v_mount); 1060 DO_OPS(ops, error, &ap, vop_setacl); 1061 VFS_MPUNLOCK(vp->v_mount); 1062 return(error); 1063 } 1064 1065 /* 1066 * MPSAFE 1067 */ 1068 int 1069 vop_aclcheck(struct vop_ops *ops, struct vnode *vp, acl_type_t type, 1070 struct acl *aclp, struct ucred *cred) 1071 { 1072 struct vop_aclcheck_args ap; 1073 VFS_MPLOCK_DECLARE; 1074 int error; 1075 1076 ap.a_head.a_desc = &vop_aclcheck_desc; 1077 ap.a_head.a_ops = ops; 1078 ap.a_vp = vp; 1079 ap.a_type = type; 1080 ap.a_aclp = aclp; 1081 ap.a_cred = cred; 1082 1083 VFS_MPLOCK1(vp->v_mount); 1084 DO_OPS(ops, error, &ap, vop_aclcheck); 1085 VFS_MPUNLOCK(vp->v_mount); 1086 return(error); 1087 } 1088 1089 /* 1090 * MPSAFE 1091 */ 1092 int 1093 vop_getextattr(struct vop_ops *ops, struct vnode *vp, char *name, 1094 struct uio *uio, struct ucred *cred) 1095 { 1096 struct vop_getextattr_args ap; 1097 VFS_MPLOCK_DECLARE; 1098 int error; 1099 1100 ap.a_head.a_desc = &vop_getextattr_desc; 1101 ap.a_head.a_ops = ops; 1102 ap.a_vp = vp; 1103 ap.a_name = name; 1104 ap.a_uio = uio; 1105 ap.a_cred = cred; 1106 1107 VFS_MPLOCK1(vp->v_mount); 1108 DO_OPS(ops, error, &ap, vop_getextattr); 1109 VFS_MPUNLOCK(vp->v_mount); 1110 return(error); 1111 } 1112 1113 /* 1114 * MPSAFE 1115 */ 1116 int 1117 vop_setextattr(struct vop_ops *ops, struct vnode *vp, char *name, 1118 struct uio *uio, struct ucred *cred) 1119 { 1120 struct vop_setextattr_args ap; 1121 VFS_MPLOCK_DECLARE; 1122 int error; 1123 1124 ap.a_head.a_desc = &vop_setextattr_desc; 1125 ap.a_head.a_ops = ops; 1126 ap.a_vp = vp; 1127 ap.a_name = name; 1128 ap.a_uio = uio; 1129 ap.a_cred = cred; 1130 1131 VFS_MPLOCK1(vp->v_mount); 1132 DO_OPS(ops, error, &ap, vop_setextattr); 1133 VFS_MPUNLOCK(vp->v_mount); 1134 return(error); 1135 } 1136 1137 /* 1138 * MPSAFE 1139 */ 1140 int 1141 vop_mountctl(struct vop_ops *ops, struct vnode *vp, int op, struct file *fp, 1142 const void *ctl, int ctllen, void *buf, int buflen, int *res) 1143 { 1144 struct vop_mountctl_args ap; 1145 VFS_MPLOCK_DECLARE; 1146 int error; 1147 1148 ap.a_head.a_desc = &vop_mountctl_desc; 1149 ap.a_head.a_ops = ops; 1150 ap.a_op = op; 1151 ap.a_ctl = ctl; 1152 ap.a_fp = fp; 1153 ap.a_ctllen = ctllen; 1154 ap.a_buf = buf; 1155 ap.a_buflen = buflen; 1156 ap.a_res = res; 1157 1158 VFS_MPLOCK1(vp->v_mount); 1159 DO_OPS(ops, error, &ap, vop_mountctl); 1160 VFS_MPUNLOCK(vp->v_mount); 1161 return(error); 1162 } 1163 1164 /* 1165 * MPSAFE 1166 */ 1167 int 1168 vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred) 1169 { 1170 struct vop_markatime_args ap; 1171 VFS_MPLOCK_DECLARE; 1172 int error; 1173 1174 ap.a_head.a_desc = &vop_markatime_desc; 1175 ap.a_head.a_ops = ops; 1176 ap.a_vp = vp; 1177 ap.a_cred = cred; 1178 1179 VFS_MPLOCK1(vp->v_mount); 1180 DO_OPS(ops, error, &ap, vop_markatime); 1181 VFS_MPUNLOCK(vp->v_mount); 1182 return(error); 1183 } 1184 1185 /* 1186 * NEW API FUNCTIONS 1187 * 1188 * nresolve takes a locked ncp, a referenced but unlocked dvp, and a cred, 1189 * and resolves the ncp into a positive or negative hit. 1190 * 1191 * The namecache is automatically adjusted by this function. The ncp 1192 * is left locked on return. 1193 * 1194 * MPSAFE 1195 */ 1196 int 1197 vop_nresolve(struct vop_ops *ops, struct nchandle *nch, 1198 struct vnode *dvp, struct ucred *cred) 1199 { 1200 struct vop_nresolve_args ap; 1201 VFS_MPLOCK_DECLARE; 1202 int error; 1203 1204 ap.a_head.a_desc = &vop_nresolve_desc; 1205 ap.a_head.a_ops = ops; 1206 ap.a_nch = nch; 1207 ap.a_dvp = dvp; 1208 ap.a_cred = cred; 1209 1210 VFS_MPLOCK1(dvp->v_mount); 1211 DO_OPS(ops, error, &ap, vop_nresolve); 1212 VFS_MPUNLOCK(dvp->v_mount); 1213 return(error); 1214 } 1215 1216 /* 1217 * nlookupdotdot takes an unlocked directory, referenced dvp, and looks 1218 * up "..", returning a locked parent directory in *vpp. If an error 1219 * occurs *vpp will be NULL. 1220 * 1221 * MPSAFE 1222 */ 1223 int 1224 vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, 1225 struct vnode **vpp, struct ucred *cred, char **fakename) 1226 { 1227 struct vop_nlookupdotdot_args ap; 1228 VFS_MPLOCK_DECLARE; 1229 int error; 1230 1231 ap.a_head.a_desc = &vop_nlookupdotdot_desc; 1232 ap.a_head.a_ops = ops; 1233 ap.a_dvp = dvp; 1234 ap.a_vpp = vpp; 1235 ap.a_cred = cred; 1236 ap.a_fakename = fakename; 1237 1238 VFS_MPLOCK1(dvp->v_mount); 1239 DO_OPS(ops, error, &ap, vop_nlookupdotdot); 1240 VFS_MPUNLOCK(dvp->v_mount); 1241 return(error); 1242 } 1243 1244 /* 1245 * ncreate takes a locked, resolved ncp that typically represents a negative 1246 * cache hit and creates the file or node specified by the ncp, cred, and 1247 * vattr. If no error occurs a locked vnode is returned in *vpp. 1248 * 1249 * The dvp passed in is referenced but unlocked. 1250 * 1251 * The namecache is automatically adjusted by this function. The ncp 1252 * is left locked on return. 1253 * 1254 * MPSAFE 1255 */ 1256 int 1257 vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1258 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1259 { 1260 struct vop_ncreate_args ap; 1261 VFS_MPLOCK_DECLARE; 1262 int error; 1263 1264 ap.a_head.a_desc = &vop_ncreate_desc; 1265 ap.a_head.a_ops = ops; 1266 ap.a_nch = nch; 1267 ap.a_dvp = dvp; 1268 ap.a_vpp = vpp; 1269 ap.a_cred = cred; 1270 ap.a_vap = vap; 1271 1272 VFS_MPLOCK1(dvp->v_mount); 1273 DO_OPS(ops, error, &ap, vop_ncreate); 1274 VFS_MPUNLOCK(dvp->v_mount); 1275 return(error); 1276 } 1277 1278 /* 1279 * nmkdir takes a locked, resolved ncp that typically represents a negative 1280 * cache hit and creates the directory specified by the ncp, cred, and 1281 * vattr. If no error occurs a locked vnode is returned in *vpp. 1282 * 1283 * The dvp passed in is referenced but unlocked. 1284 * 1285 * The namecache is automatically adjusted by this function. The ncp 1286 * is left locked on return. 1287 * 1288 * MPSAFE 1289 */ 1290 int 1291 vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1292 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1293 { 1294 struct vop_nmkdir_args ap; 1295 VFS_MPLOCK_DECLARE; 1296 int error; 1297 1298 ap.a_head.a_desc = &vop_nmkdir_desc; 1299 ap.a_head.a_ops = ops; 1300 ap.a_nch = nch; 1301 ap.a_dvp = dvp; 1302 ap.a_vpp = vpp; 1303 ap.a_cred = cred; 1304 ap.a_vap = vap; 1305 1306 VFS_MPLOCK1(dvp->v_mount); 1307 DO_OPS(ops, error, &ap, vop_nmkdir); 1308 VFS_MPUNLOCK(dvp->v_mount); 1309 return(error); 1310 } 1311 1312 /* 1313 * nmknod takes a locked, resolved ncp that typically represents a negative 1314 * cache hit and creates the node specified by the ncp, cred, and 1315 * vattr. If no error occurs a locked vnode is returned in *vpp. 1316 * 1317 * The dvp passed in is referenced but unlocked. 1318 * 1319 * The namecache is automatically adjusted by this function. The ncp 1320 * is left locked on return. 1321 * 1322 * MPSAFE 1323 */ 1324 int 1325 vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1326 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1327 { 1328 struct vop_nmknod_args ap; 1329 VFS_MPLOCK_DECLARE; 1330 int error; 1331 1332 ap.a_head.a_desc = &vop_nmknod_desc; 1333 ap.a_head.a_ops = ops; 1334 ap.a_nch = nch; 1335 ap.a_dvp = dvp; 1336 ap.a_vpp = vpp; 1337 ap.a_cred = cred; 1338 ap.a_vap = vap; 1339 1340 VFS_MPLOCK1(dvp->v_mount); 1341 DO_OPS(ops, error, &ap, vop_nmknod); 1342 VFS_MPUNLOCK(dvp->v_mount); 1343 return(error); 1344 } 1345 1346 /* 1347 * nlink takes a locked, resolved ncp that typically represents a negative 1348 * cache hit and creates the node specified by the ncp, cred, and 1349 * existing vnode. The passed vp must be locked and will remain locked 1350 * on return, as does the ncp, whether an error occurs or not. 1351 * 1352 * The dvp passed in is referenced but unlocked. 1353 * 1354 * The namecache is automatically adjusted by this function. The ncp 1355 * is left locked on return. 1356 * 1357 * MPSAFE 1358 */ 1359 int 1360 vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1361 struct vnode *vp, struct ucred *cred) 1362 { 1363 struct vop_nlink_args ap; 1364 VFS_MPLOCK_DECLARE; 1365 int error; 1366 1367 ap.a_head.a_desc = &vop_nlink_desc; 1368 ap.a_head.a_ops = ops; 1369 ap.a_nch = nch; 1370 ap.a_dvp = dvp; 1371 ap.a_vp = vp; 1372 ap.a_cred = cred; 1373 1374 VFS_MPLOCK1(dvp->v_mount); 1375 DO_OPS(ops, error, &ap, vop_nlink); 1376 VFS_MPUNLOCK(dvp->v_mount); 1377 return(error); 1378 } 1379 1380 /* 1381 * nsymlink takes a locked, resolved ncp that typically represents a negative 1382 * cache hit and creates a symbolic link based on cred, vap, and target (the 1383 * contents of the link). If no error occurs a locked vnode is returned in 1384 * *vpp. 1385 * 1386 * The dvp passed in is referenced but unlocked. 1387 * 1388 * The namecache is automatically adjusted by this function. The ncp 1389 * is left locked on return. 1390 * 1391 * MPSAFE 1392 */ 1393 int 1394 vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1395 struct vnode **vpp, struct ucred *cred, 1396 struct vattr *vap, char *target) 1397 { 1398 struct vop_nsymlink_args ap; 1399 VFS_MPLOCK_DECLARE; 1400 int error; 1401 1402 ap.a_head.a_desc = &vop_nsymlink_desc; 1403 ap.a_head.a_ops = ops; 1404 ap.a_nch = nch; 1405 ap.a_dvp = dvp; 1406 ap.a_vpp = vpp; 1407 ap.a_cred = cred; 1408 ap.a_vap = vap; 1409 ap.a_target = target; 1410 1411 VFS_MPLOCK1(dvp->v_mount); 1412 DO_OPS(ops, error, &ap, vop_nsymlink); 1413 VFS_MPUNLOCK(dvp->v_mount); 1414 return(error); 1415 } 1416 1417 /* 1418 * nwhiteout takes a locked, resolved ncp that can represent a positive or 1419 * negative hit and executes the whiteout function specified in flags. 1420 * 1421 * The dvp passed in is referenced but unlocked. 1422 * 1423 * The namecache is automatically adjusted by this function. The ncp 1424 * is left locked on return. 1425 * 1426 * MPSAFE 1427 */ 1428 int 1429 vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1430 struct ucred *cred, int flags) 1431 { 1432 struct vop_nwhiteout_args ap; 1433 VFS_MPLOCK_DECLARE; 1434 int error; 1435 1436 ap.a_head.a_desc = &vop_nwhiteout_desc; 1437 ap.a_head.a_ops = ops; 1438 ap.a_nch = nch; 1439 ap.a_dvp = dvp; 1440 ap.a_cred = cred; 1441 ap.a_flags = flags; 1442 1443 VFS_MPLOCK1(dvp->v_mount); 1444 DO_OPS(ops, error, &ap, vop_nwhiteout); 1445 VFS_MPUNLOCK(dvp->v_mount); 1446 return(error); 1447 } 1448 1449 /* 1450 * nremove takes a locked, resolved ncp that generally represents a 1451 * positive hit and removes the file. 1452 * 1453 * The dvp passed in is referenced but unlocked. 1454 * 1455 * The namecache is automatically adjusted by this function. The ncp 1456 * is left locked on return. 1457 * 1458 * MPSAFE 1459 */ 1460 int 1461 vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1462 struct ucred *cred) 1463 { 1464 struct vop_nremove_args ap; 1465 VFS_MPLOCK_DECLARE; 1466 int error; 1467 1468 ap.a_head.a_desc = &vop_nremove_desc; 1469 ap.a_head.a_ops = ops; 1470 ap.a_nch = nch; 1471 ap.a_dvp = dvp; 1472 ap.a_cred = cred; 1473 1474 VFS_MPLOCK1(dvp->v_mount); 1475 DO_OPS(ops, error, &ap, vop_nremove); 1476 VFS_MPUNLOCK(dvp->v_mount); 1477 return(error); 1478 } 1479 1480 /* 1481 * nrmdir takes a locked, resolved ncp that generally represents a 1482 * directory and removes the directory. 1483 * 1484 * The dvp passed in is referenced but unlocked. 1485 * 1486 * The namecache is automatically adjusted by this function. The ncp 1487 * is left locked on return. 1488 * 1489 * MPSAFE 1490 */ 1491 int 1492 vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1493 struct ucred *cred) 1494 { 1495 struct vop_nrmdir_args ap; 1496 VFS_MPLOCK_DECLARE; 1497 int error; 1498 1499 ap.a_head.a_desc = &vop_nrmdir_desc; 1500 ap.a_head.a_ops = ops; 1501 ap.a_nch = nch; 1502 ap.a_dvp = dvp; 1503 ap.a_cred = cred; 1504 1505 VFS_MPLOCK1(dvp->v_mount); 1506 DO_OPS(ops, error, &ap, vop_nrmdir); 1507 VFS_MPUNLOCK(dvp->v_mount); 1508 return(error); 1509 } 1510 1511 /* 1512 * nrename takes TWO locked, resolved ncp's and the cred of the caller 1513 * and renames the source ncp to the target ncp. The target ncp may 1514 * represent a positive or negative hit. 1515 * 1516 * The fdvp and tdvp passed in are referenced but unlocked. 1517 * 1518 * The namecache is automatically adjusted by this function. The ncp 1519 * is left locked on return. The source ncp is typically changed to 1520 * a negative cache hit and the target ncp typically takes on the 1521 * source ncp's underlying file. 1522 * 1523 * MPSAFE 1524 */ 1525 int 1526 vop_nrename(struct vop_ops *ops, 1527 struct nchandle *fnch, struct nchandle *tnch, 1528 struct vnode *fdvp, struct vnode *tdvp, 1529 struct ucred *cred) 1530 { 1531 struct vop_nrename_args ap; 1532 VFS_MPLOCK_DECLARE; 1533 int error; 1534 1535 ap.a_head.a_desc = &vop_nrename_desc; 1536 ap.a_head.a_ops = ops; 1537 ap.a_fnch = fnch; 1538 ap.a_tnch = tnch; 1539 ap.a_fdvp = fdvp; 1540 ap.a_tdvp = tdvp; 1541 ap.a_cred = cred; 1542 1543 VFS_MPLOCK1(fdvp->v_mount); 1544 DO_OPS(ops, error, &ap, vop_nrename); 1545 VFS_MPUNLOCK(fdvp->v_mount); 1546 return(error); 1547 } 1548 1549 /************************************************************************ 1550 * PRIMARY VNODE OPERATIONS FORWARDING CALLS * 1551 ************************************************************************ 1552 * 1553 * These procedures are called from VFSs such as unionfs and nullfs 1554 * when they wish to forward an operation on one VFS to another. The 1555 * argument structure/message is modified and then directly passed to the 1556 * appropriate routine. This routines may also be called by initiators 1557 * who have an argument structure in hand rather then discreet arguments. 1558 * 1559 * MPSAFE - Caller expected to already hold the appropriate vfs lock. 1560 */ 1561 int 1562 vop_vnoperate_ap(struct vop_generic_args *ap) 1563 { 1564 struct vop_ops *ops; 1565 int error; 1566 1567 ops = ap->a_ops; 1568 error = VOCALL(ops, ap); 1569 1570 return (error); 1571 } 1572 1573 /* 1574 * This routine is called by the cache coherency layer to execute the actual 1575 * VFS operation. If a journaling layer is present we call though it, else 1576 * we call the native VOP functions. 1577 */ 1578 int 1579 vop_cache_operate_ap(struct vop_generic_args *ap) 1580 { 1581 struct vop_ops *ops; 1582 int error; 1583 1584 ops = ap->a_ops; 1585 if (ops->head.vv_mount->mnt_vn_journal_ops) 1586 error = VOCALL(ops->head.vv_mount->mnt_vn_journal_ops, ap); 1587 else 1588 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1589 return (error); 1590 } 1591 1592 1593 /* 1594 * This routine is called by the journaling layer to execute the actual 1595 * VFS operation. 1596 */ 1597 int 1598 vop_journal_operate_ap(struct vop_generic_args *ap) 1599 { 1600 struct vop_ops *ops; 1601 int error; 1602 1603 ops = ap->a_ops; 1604 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1605 1606 return (error); 1607 } 1608 1609 int 1610 vop_open_ap(struct vop_open_args *ap) 1611 { 1612 int error; 1613 1614 DO_OPS(ap->a_head.a_ops, error, ap, vop_open); 1615 return(error); 1616 } 1617 1618 int 1619 vop_close_ap(struct vop_close_args *ap) 1620 { 1621 int error; 1622 1623 DO_OPS(ap->a_head.a_ops, error, ap, vop_close); 1624 return(error); 1625 } 1626 1627 int 1628 vop_access_ap(struct vop_access_args *ap) 1629 { 1630 int error; 1631 1632 DO_OPS(ap->a_head.a_ops, error, ap, vop_access); 1633 return(error); 1634 } 1635 1636 int 1637 vop_getattr_ap(struct vop_getattr_args *ap) 1638 { 1639 int error; 1640 1641 DO_OPS(ap->a_head.a_ops, error, ap, vop_getattr); 1642 return(error); 1643 } 1644 1645 int 1646 vop_setattr_ap(struct vop_setattr_args *ap) 1647 { 1648 int error; 1649 1650 DO_OPS(ap->a_head.a_ops, error, ap, vop_setattr); 1651 return(error); 1652 } 1653 1654 int 1655 vop_read_ap(struct vop_read_args *ap) 1656 { 1657 int error; 1658 1659 DO_OPS(ap->a_head.a_ops, error, ap, vop_read); 1660 return(error); 1661 } 1662 1663 int 1664 vop_write_ap(struct vop_write_args *ap) 1665 { 1666 int error; 1667 1668 DO_OPS(ap->a_head.a_ops, error, ap, vop_write); 1669 return(error); 1670 } 1671 1672 int 1673 vop_ioctl_ap(struct vop_ioctl_args *ap) 1674 { 1675 int error; 1676 1677 DO_OPS(ap->a_head.a_ops, error, ap, vop_ioctl); 1678 return(error); 1679 } 1680 1681 int 1682 vop_poll_ap(struct vop_poll_args *ap) 1683 { 1684 int error; 1685 1686 DO_OPS(ap->a_head.a_ops, error, ap, vop_poll); 1687 return(error); 1688 } 1689 1690 int 1691 vop_kqfilter_ap(struct vop_kqfilter_args *ap) 1692 { 1693 int error; 1694 1695 DO_OPS(ap->a_head.a_ops, error, ap, vop_kqfilter); 1696 return(error); 1697 } 1698 1699 int 1700 vop_mmap_ap(struct vop_mmap_args *ap) 1701 { 1702 int error; 1703 1704 DO_OPS(ap->a_head.a_ops, error, ap, vop_mmap); 1705 return(error); 1706 } 1707 1708 int 1709 vop_fsync_ap(struct vop_fsync_args *ap) 1710 { 1711 int error; 1712 1713 DO_OPS(ap->a_head.a_ops, error, ap, vop_fsync); 1714 return(error); 1715 } 1716 1717 int 1718 vop_readdir_ap(struct vop_readdir_args *ap) 1719 { 1720 int error; 1721 1722 DO_OPS(ap->a_head.a_ops, error, ap, vop_readdir); 1723 return(error); 1724 } 1725 1726 int 1727 vop_readlink_ap(struct vop_readlink_args *ap) 1728 { 1729 int error; 1730 1731 DO_OPS(ap->a_head.a_ops, error, ap, vop_readlink); 1732 return(error); 1733 } 1734 1735 int 1736 vop_inactive_ap(struct vop_inactive_args *ap) 1737 { 1738 int error; 1739 1740 DO_OPS(ap->a_head.a_ops, error, ap, vop_inactive); 1741 return(error); 1742 } 1743 1744 int 1745 vop_reclaim_ap(struct vop_reclaim_args *ap) 1746 { 1747 int error; 1748 1749 DO_OPS(ap->a_head.a_ops, error, ap, vop_reclaim); 1750 return(error); 1751 } 1752 1753 int 1754 vop_bmap_ap(struct vop_bmap_args *ap) 1755 { 1756 int error; 1757 1758 DO_OPS(ap->a_head.a_ops, error, ap, vop_bmap); 1759 return(error); 1760 } 1761 1762 int 1763 vop_strategy_ap(struct vop_strategy_args *ap) 1764 { 1765 int error; 1766 1767 DO_OPS(ap->a_head.a_ops, error, ap, vop_strategy); 1768 return(error); 1769 } 1770 1771 int 1772 vop_print_ap(struct vop_print_args *ap) 1773 { 1774 int error; 1775 1776 DO_OPS(ap->a_head.a_ops, error, ap, vop_print); 1777 return(error); 1778 } 1779 1780 int 1781 vop_pathconf_ap(struct vop_pathconf_args *ap) 1782 { 1783 int error; 1784 1785 DO_OPS(ap->a_head.a_ops, error, ap, vop_pathconf); 1786 return(error); 1787 } 1788 1789 int 1790 vop_advlock_ap(struct vop_advlock_args *ap) 1791 { 1792 int error; 1793 1794 DO_OPS(ap->a_head.a_ops, error, ap, vop_advlock); 1795 return(error); 1796 } 1797 1798 int 1799 vop_balloc_ap(struct vop_balloc_args *ap) 1800 { 1801 int error; 1802 1803 DO_OPS(ap->a_head.a_ops, error, ap, vop_balloc); 1804 return(error); 1805 } 1806 1807 int 1808 vop_reallocblks_ap(struct vop_reallocblks_args *ap) 1809 { 1810 int error; 1811 1812 DO_OPS(ap->a_head.a_ops, error, ap, vop_reallocblks); 1813 return(error); 1814 } 1815 1816 int 1817 vop_getpages_ap(struct vop_getpages_args *ap) 1818 { 1819 int error; 1820 1821 DO_OPS(ap->a_head.a_ops, error, ap, vop_getpages); 1822 return(error); 1823 } 1824 1825 int 1826 vop_putpages_ap(struct vop_putpages_args *ap) 1827 { 1828 int error; 1829 1830 DO_OPS(ap->a_head.a_ops, error, ap, vop_putpages); 1831 return(error); 1832 } 1833 1834 int 1835 vop_freeblks_ap(struct vop_freeblks_args *ap) 1836 { 1837 int error; 1838 1839 DO_OPS(ap->a_head.a_ops, error, ap, vop_freeblks); 1840 return(error); 1841 } 1842 1843 int 1844 vop_getacl_ap(struct vop_getacl_args *ap) 1845 { 1846 int error; 1847 1848 DO_OPS(ap->a_head.a_ops, error, ap, vop_getacl); 1849 return(error); 1850 } 1851 1852 int 1853 vop_setacl_ap(struct vop_setacl_args *ap) 1854 { 1855 int error; 1856 1857 DO_OPS(ap->a_head.a_ops, error, ap, vop_setacl); 1858 return(error); 1859 } 1860 1861 int 1862 vop_aclcheck_ap(struct vop_aclcheck_args *ap) 1863 { 1864 int error; 1865 1866 DO_OPS(ap->a_head.a_ops, error, ap, vop_aclcheck); 1867 return(error); 1868 } 1869 1870 int 1871 vop_getextattr_ap(struct vop_getextattr_args *ap) 1872 { 1873 int error; 1874 1875 DO_OPS(ap->a_head.a_ops, error, ap, vop_getextattr); 1876 return(error); 1877 } 1878 1879 int 1880 vop_setextattr_ap(struct vop_setextattr_args *ap) 1881 { 1882 int error; 1883 1884 DO_OPS(ap->a_head.a_ops, error, ap, vop_setextattr); 1885 return(error); 1886 } 1887 1888 int 1889 vop_mountctl_ap(struct vop_mountctl_args *ap) 1890 { 1891 int error; 1892 1893 DO_OPS(ap->a_head.a_ops, error, ap, vop_mountctl); 1894 return(error); 1895 } 1896 1897 int 1898 vop_markatime_ap(struct vop_markatime_args *ap) 1899 { 1900 int error; 1901 1902 DO_OPS(ap->a_head.a_ops, error, ap, vop_markatime); 1903 return(error); 1904 } 1905 1906 int 1907 vop_nresolve_ap(struct vop_nresolve_args *ap) 1908 { 1909 int error; 1910 1911 DO_OPS(ap->a_head.a_ops, error, ap, vop_nresolve); 1912 return(error); 1913 } 1914 1915 int 1916 vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap) 1917 { 1918 int error; 1919 1920 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlookupdotdot); 1921 return(error); 1922 } 1923 1924 int 1925 vop_ncreate_ap(struct vop_ncreate_args *ap) 1926 { 1927 int error; 1928 1929 DO_OPS(ap->a_head.a_ops, error, ap, vop_ncreate); 1930 return(error); 1931 } 1932 1933 int 1934 vop_nmkdir_ap(struct vop_nmkdir_args *ap) 1935 { 1936 int error; 1937 1938 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmkdir); 1939 return(error); 1940 } 1941 1942 int 1943 vop_nmknod_ap(struct vop_nmknod_args *ap) 1944 { 1945 int error; 1946 1947 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmknod); 1948 return(error); 1949 } 1950 1951 int 1952 vop_nlink_ap(struct vop_nlink_args *ap) 1953 { 1954 int error; 1955 1956 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlink); 1957 return(error); 1958 } 1959 1960 int 1961 vop_nsymlink_ap(struct vop_nsymlink_args *ap) 1962 { 1963 int error; 1964 1965 DO_OPS(ap->a_head.a_ops, error, ap, vop_nsymlink); 1966 return(error); 1967 } 1968 1969 int 1970 vop_nwhiteout_ap(struct vop_nwhiteout_args *ap) 1971 { 1972 int error; 1973 1974 DO_OPS(ap->a_head.a_ops, error, ap, vop_nwhiteout); 1975 return(error); 1976 } 1977 1978 int 1979 vop_nremove_ap(struct vop_nremove_args *ap) 1980 { 1981 int error; 1982 1983 DO_OPS(ap->a_head.a_ops, error, ap, vop_nremove); 1984 return(error); 1985 } 1986 1987 int 1988 vop_nrmdir_ap(struct vop_nrmdir_args *ap) 1989 { 1990 int error; 1991 1992 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrmdir); 1993 return(error); 1994 } 1995 1996 int 1997 vop_nrename_ap(struct vop_nrename_args *ap) 1998 { 1999 int error; 2000 2001 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrename); 2002 return(error); 2003 } 2004 2005