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, char *name, 1103 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_name = name; 1113 ap.a_uio = uio; 1114 ap.a_cred = cred; 1115 1116 VFS_MPLOCK1(vp->v_mount); 1117 DO_OPS(ops, error, &ap, vop_getextattr); 1118 VFS_MPUNLOCK(vp->v_mount); 1119 return(error); 1120 } 1121 1122 /* 1123 * MPSAFE 1124 */ 1125 int 1126 vop_setextattr(struct vop_ops *ops, struct vnode *vp, char *name, 1127 struct uio *uio, struct ucred *cred) 1128 { 1129 struct vop_setextattr_args ap; 1130 VFS_MPLOCK_DECLARE; 1131 int error; 1132 1133 ap.a_head.a_desc = &vop_setextattr_desc; 1134 ap.a_head.a_ops = ops; 1135 ap.a_vp = vp; 1136 ap.a_name = name; 1137 ap.a_uio = uio; 1138 ap.a_cred = cred; 1139 1140 VFS_MPLOCK1(vp->v_mount); 1141 DO_OPS(ops, error, &ap, vop_setextattr); 1142 VFS_MPUNLOCK(vp->v_mount); 1143 return(error); 1144 } 1145 1146 /* 1147 * MPSAFE 1148 */ 1149 int 1150 vop_mountctl(struct vop_ops *ops, struct vnode *vp, int op, struct file *fp, 1151 const void *ctl, int ctllen, void *buf, int buflen, int *res) 1152 { 1153 struct vop_mountctl_args ap; 1154 VFS_MPLOCK_DECLARE; 1155 int error; 1156 1157 ap.a_head.a_desc = &vop_mountctl_desc; 1158 ap.a_head.a_ops = ops; 1159 ap.a_op = op; 1160 ap.a_ctl = ctl; 1161 ap.a_fp = fp; 1162 ap.a_ctllen = ctllen; 1163 ap.a_buf = buf; 1164 ap.a_buflen = buflen; 1165 ap.a_res = res; 1166 1167 VFS_MPLOCK1(vp->v_mount); 1168 DO_OPS(ops, error, &ap, vop_mountctl); 1169 VFS_MPUNLOCK(vp->v_mount); 1170 return(error); 1171 } 1172 1173 /* 1174 * MPSAFE 1175 */ 1176 int 1177 vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred) 1178 { 1179 struct vop_markatime_args ap; 1180 VFS_MPLOCK_DECLARE; 1181 int error; 1182 1183 ap.a_head.a_desc = &vop_markatime_desc; 1184 ap.a_head.a_ops = ops; 1185 ap.a_vp = vp; 1186 ap.a_cred = cred; 1187 1188 VFS_MPLOCK1(vp->v_mount); 1189 DO_OPS(ops, error, &ap, vop_markatime); 1190 VFS_MPUNLOCK(vp->v_mount); 1191 return(error); 1192 } 1193 1194 /* 1195 * NEW API FUNCTIONS 1196 * 1197 * nresolve takes a locked ncp, a referenced but unlocked dvp, and a cred, 1198 * and resolves the ncp into a positive or negative hit. 1199 * 1200 * The namecache is automatically adjusted by this function. The ncp 1201 * is left locked on return. 1202 * 1203 * MPSAFE 1204 */ 1205 int 1206 vop_nresolve(struct vop_ops *ops, struct nchandle *nch, 1207 struct vnode *dvp, struct ucred *cred) 1208 { 1209 struct vop_nresolve_args ap; 1210 VFS_MPLOCK_DECLARE; 1211 int error; 1212 1213 ap.a_head.a_desc = &vop_nresolve_desc; 1214 ap.a_head.a_ops = ops; 1215 ap.a_nch = nch; 1216 ap.a_dvp = dvp; 1217 ap.a_cred = cred; 1218 1219 VFS_MPLOCK1(dvp->v_mount); 1220 DO_OPS(ops, error, &ap, vop_nresolve); 1221 VFS_MPUNLOCK(dvp->v_mount); 1222 return(error); 1223 } 1224 1225 /* 1226 * nlookupdotdot takes an unlocked directory, referenced dvp, and looks 1227 * up "..", returning a locked parent directory in *vpp. If an error 1228 * occurs *vpp will be NULL. 1229 * 1230 * MPSAFE 1231 */ 1232 int 1233 vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, 1234 struct vnode **vpp, struct ucred *cred, char **fakename) 1235 { 1236 struct vop_nlookupdotdot_args ap; 1237 VFS_MPLOCK_DECLARE; 1238 int error; 1239 1240 ap.a_head.a_desc = &vop_nlookupdotdot_desc; 1241 ap.a_head.a_ops = ops; 1242 ap.a_dvp = dvp; 1243 ap.a_vpp = vpp; 1244 ap.a_cred = cred; 1245 ap.a_fakename = fakename; 1246 1247 VFS_MPLOCK1(dvp->v_mount); 1248 DO_OPS(ops, error, &ap, vop_nlookupdotdot); 1249 VFS_MPUNLOCK(dvp->v_mount); 1250 return(error); 1251 } 1252 1253 /* 1254 * ncreate takes a locked, resolved ncp that typically represents a negative 1255 * cache hit and creates the file or node specified by the ncp, cred, and 1256 * vattr. If no error occurs a locked vnode is returned in *vpp. 1257 * 1258 * The dvp passed in is referenced but unlocked. 1259 * 1260 * The namecache is automatically adjusted by this function. The ncp 1261 * is left locked on return. 1262 * 1263 * MPSAFE 1264 */ 1265 int 1266 vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1267 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1268 { 1269 struct vop_ncreate_args ap; 1270 VFS_MPLOCK_DECLARE; 1271 int error; 1272 1273 ap.a_head.a_desc = &vop_ncreate_desc; 1274 ap.a_head.a_ops = ops; 1275 ap.a_nch = nch; 1276 ap.a_dvp = dvp; 1277 ap.a_vpp = vpp; 1278 ap.a_cred = cred; 1279 ap.a_vap = vap; 1280 1281 VFS_MPLOCK1(dvp->v_mount); 1282 DO_OPS(ops, error, &ap, vop_ncreate); 1283 VFS_MPUNLOCK(dvp->v_mount); 1284 return(error); 1285 } 1286 1287 /* 1288 * nmkdir takes a locked, resolved ncp that typically represents a negative 1289 * cache hit and creates the directory specified by the ncp, cred, and 1290 * vattr. If no error occurs a locked vnode is returned in *vpp. 1291 * 1292 * The dvp passed in is referenced but unlocked. 1293 * 1294 * The namecache is automatically adjusted by this function. The ncp 1295 * is left locked on return. 1296 * 1297 * MPSAFE 1298 */ 1299 int 1300 vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1301 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1302 { 1303 struct vop_nmkdir_args ap; 1304 VFS_MPLOCK_DECLARE; 1305 int error; 1306 1307 ap.a_head.a_desc = &vop_nmkdir_desc; 1308 ap.a_head.a_ops = ops; 1309 ap.a_nch = nch; 1310 ap.a_dvp = dvp; 1311 ap.a_vpp = vpp; 1312 ap.a_cred = cred; 1313 ap.a_vap = vap; 1314 1315 VFS_MPLOCK1(dvp->v_mount); 1316 DO_OPS(ops, error, &ap, vop_nmkdir); 1317 VFS_MPUNLOCK(dvp->v_mount); 1318 return(error); 1319 } 1320 1321 /* 1322 * nmknod takes a locked, resolved ncp that typically represents a negative 1323 * cache hit and creates the node specified by the ncp, cred, and 1324 * vattr. If no error occurs a locked vnode is returned in *vpp. 1325 * 1326 * The dvp passed in is referenced but unlocked. 1327 * 1328 * The namecache is automatically adjusted by this function. The ncp 1329 * is left locked on return. 1330 * 1331 * MPSAFE 1332 */ 1333 int 1334 vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1335 struct vnode **vpp, struct ucred *cred, struct vattr *vap) 1336 { 1337 struct vop_nmknod_args ap; 1338 VFS_MPLOCK_DECLARE; 1339 int error; 1340 1341 ap.a_head.a_desc = &vop_nmknod_desc; 1342 ap.a_head.a_ops = ops; 1343 ap.a_nch = nch; 1344 ap.a_dvp = dvp; 1345 ap.a_vpp = vpp; 1346 ap.a_cred = cred; 1347 ap.a_vap = vap; 1348 1349 VFS_MPLOCK1(dvp->v_mount); 1350 DO_OPS(ops, error, &ap, vop_nmknod); 1351 VFS_MPUNLOCK(dvp->v_mount); 1352 return(error); 1353 } 1354 1355 /* 1356 * nlink takes a locked, resolved ncp that typically represents a negative 1357 * cache hit and creates the node specified by the ncp, cred, and 1358 * existing vnode. The passed vp must be locked and will remain locked 1359 * on return, as does the ncp, whether an error occurs or not. 1360 * 1361 * The dvp passed in is referenced but unlocked. 1362 * 1363 * The namecache is automatically adjusted by this function. The ncp 1364 * is left locked on return. 1365 * 1366 * MPSAFE 1367 */ 1368 int 1369 vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1370 struct vnode *vp, struct ucred *cred) 1371 { 1372 struct vop_nlink_args ap; 1373 VFS_MPLOCK_DECLARE; 1374 int error; 1375 1376 ap.a_head.a_desc = &vop_nlink_desc; 1377 ap.a_head.a_ops = ops; 1378 ap.a_nch = nch; 1379 ap.a_dvp = dvp; 1380 ap.a_vp = vp; 1381 ap.a_cred = cred; 1382 1383 VFS_MPLOCK1(dvp->v_mount); 1384 DO_OPS(ops, error, &ap, vop_nlink); 1385 VFS_MPUNLOCK(dvp->v_mount); 1386 return(error); 1387 } 1388 1389 /* 1390 * nsymlink takes a locked, resolved ncp that typically represents a negative 1391 * cache hit and creates a symbolic link based on cred, vap, and target (the 1392 * contents of the link). If no error occurs a locked vnode is returned in 1393 * *vpp. 1394 * 1395 * The dvp passed in is referenced but unlocked. 1396 * 1397 * The namecache is automatically adjusted by this function. The ncp 1398 * is left locked on return. 1399 * 1400 * MPSAFE 1401 */ 1402 int 1403 vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1404 struct vnode **vpp, struct ucred *cred, 1405 struct vattr *vap, char *target) 1406 { 1407 struct vop_nsymlink_args ap; 1408 VFS_MPLOCK_DECLARE; 1409 int error; 1410 1411 ap.a_head.a_desc = &vop_nsymlink_desc; 1412 ap.a_head.a_ops = ops; 1413 ap.a_nch = nch; 1414 ap.a_dvp = dvp; 1415 ap.a_vpp = vpp; 1416 ap.a_cred = cred; 1417 ap.a_vap = vap; 1418 ap.a_target = target; 1419 1420 VFS_MPLOCK1(dvp->v_mount); 1421 DO_OPS(ops, error, &ap, vop_nsymlink); 1422 VFS_MPUNLOCK(dvp->v_mount); 1423 return(error); 1424 } 1425 1426 /* 1427 * nwhiteout takes a locked, resolved ncp that can represent a positive or 1428 * negative hit and executes the whiteout function specified in flags. 1429 * 1430 * The dvp passed in is referenced but unlocked. 1431 * 1432 * The namecache is automatically adjusted by this function. The ncp 1433 * is left locked on return. 1434 * 1435 * MPSAFE 1436 */ 1437 int 1438 vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1439 struct ucred *cred, int flags) 1440 { 1441 struct vop_nwhiteout_args ap; 1442 VFS_MPLOCK_DECLARE; 1443 int error; 1444 1445 ap.a_head.a_desc = &vop_nwhiteout_desc; 1446 ap.a_head.a_ops = ops; 1447 ap.a_nch = nch; 1448 ap.a_dvp = dvp; 1449 ap.a_cred = cred; 1450 ap.a_flags = flags; 1451 1452 VFS_MPLOCK1(dvp->v_mount); 1453 DO_OPS(ops, error, &ap, vop_nwhiteout); 1454 VFS_MPUNLOCK(dvp->v_mount); 1455 return(error); 1456 } 1457 1458 /* 1459 * nremove takes a locked, resolved ncp that generally represents a 1460 * positive hit and removes the file. 1461 * 1462 * The dvp passed in is referenced but unlocked. 1463 * 1464 * The namecache is automatically adjusted by this function. The ncp 1465 * is left locked on return. 1466 * 1467 * MPSAFE 1468 */ 1469 int 1470 vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1471 struct ucred *cred) 1472 { 1473 struct vop_nremove_args ap; 1474 VFS_MPLOCK_DECLARE; 1475 int error; 1476 1477 ap.a_head.a_desc = &vop_nremove_desc; 1478 ap.a_head.a_ops = ops; 1479 ap.a_nch = nch; 1480 ap.a_dvp = dvp; 1481 ap.a_cred = cred; 1482 1483 VFS_MPLOCK1(dvp->v_mount); 1484 DO_OPS(ops, error, &ap, vop_nremove); 1485 VFS_MPUNLOCK(dvp->v_mount); 1486 return(error); 1487 } 1488 1489 /* 1490 * nrmdir takes a locked, resolved ncp that generally represents a 1491 * directory and removes the directory. 1492 * 1493 * The dvp passed in is referenced but unlocked. 1494 * 1495 * The namecache is automatically adjusted by this function. The ncp 1496 * is left locked on return. 1497 * 1498 * MPSAFE 1499 */ 1500 int 1501 vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp, 1502 struct ucred *cred) 1503 { 1504 struct vop_nrmdir_args ap; 1505 VFS_MPLOCK_DECLARE; 1506 int error; 1507 1508 ap.a_head.a_desc = &vop_nrmdir_desc; 1509 ap.a_head.a_ops = ops; 1510 ap.a_nch = nch; 1511 ap.a_dvp = dvp; 1512 ap.a_cred = cred; 1513 1514 VFS_MPLOCK1(dvp->v_mount); 1515 DO_OPS(ops, error, &ap, vop_nrmdir); 1516 VFS_MPUNLOCK(dvp->v_mount); 1517 return(error); 1518 } 1519 1520 /* 1521 * nrename takes TWO locked, resolved ncp's and the cred of the caller 1522 * and renames the source ncp to the target ncp. The target ncp may 1523 * represent a positive or negative hit. 1524 * 1525 * The fdvp and tdvp passed in are referenced but unlocked. 1526 * 1527 * The namecache is automatically adjusted by this function. The ncp 1528 * is left locked on return. The source ncp is typically changed to 1529 * a negative cache hit and the target ncp typically takes on the 1530 * source ncp's underlying file. 1531 * 1532 * MPSAFE 1533 */ 1534 int 1535 vop_nrename(struct vop_ops *ops, 1536 struct nchandle *fnch, struct nchandle *tnch, 1537 struct vnode *fdvp, struct vnode *tdvp, 1538 struct ucred *cred) 1539 { 1540 struct vop_nrename_args ap; 1541 VFS_MPLOCK_DECLARE; 1542 int error; 1543 1544 ap.a_head.a_desc = &vop_nrename_desc; 1545 ap.a_head.a_ops = ops; 1546 ap.a_fnch = fnch; 1547 ap.a_tnch = tnch; 1548 ap.a_fdvp = fdvp; 1549 ap.a_tdvp = tdvp; 1550 ap.a_cred = cred; 1551 1552 VFS_MPLOCK1(fdvp->v_mount); 1553 DO_OPS(ops, error, &ap, vop_nrename); 1554 VFS_MPUNLOCK(fdvp->v_mount); 1555 return(error); 1556 } 1557 1558 /************************************************************************ 1559 * PRIMARY VNODE OPERATIONS FORWARDING CALLS * 1560 ************************************************************************ 1561 * 1562 * These procedures are called from VFSs such as unionfs and nullfs 1563 * when they wish to forward an operation on one VFS to another. The 1564 * argument structure/message is modified and then directly passed to the 1565 * appropriate routine. This routines may also be called by initiators 1566 * who have an argument structure in hand rather then discreet arguments. 1567 * 1568 * MPSAFE - Caller expected to already hold the appropriate vfs lock. 1569 */ 1570 int 1571 vop_vnoperate_ap(struct vop_generic_args *ap) 1572 { 1573 struct vop_ops *ops; 1574 int error; 1575 1576 ops = ap->a_ops; 1577 error = VOCALL(ops, ap); 1578 1579 return (error); 1580 } 1581 1582 /* 1583 * This routine is called by the cache coherency layer to execute the actual 1584 * VFS operation. If a journaling layer is present we call though it, else 1585 * we call the native VOP functions. 1586 */ 1587 int 1588 vop_cache_operate_ap(struct vop_generic_args *ap) 1589 { 1590 struct vop_ops *ops; 1591 int error; 1592 1593 ops = ap->a_ops; 1594 if (ops->head.vv_mount->mnt_vn_journal_ops) 1595 error = VOCALL(ops->head.vv_mount->mnt_vn_journal_ops, ap); 1596 else 1597 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1598 return (error); 1599 } 1600 1601 1602 /* 1603 * This routine is called by the journaling layer to execute the actual 1604 * VFS operation. 1605 */ 1606 int 1607 vop_journal_operate_ap(struct vop_generic_args *ap) 1608 { 1609 struct vop_ops *ops; 1610 int error; 1611 1612 ops = ap->a_ops; 1613 error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap); 1614 1615 return (error); 1616 } 1617 1618 int 1619 vop_open_ap(struct vop_open_args *ap) 1620 { 1621 int error; 1622 1623 DO_OPS(ap->a_head.a_ops, error, ap, vop_open); 1624 return(error); 1625 } 1626 1627 int 1628 vop_close_ap(struct vop_close_args *ap) 1629 { 1630 int error; 1631 1632 DO_OPS(ap->a_head.a_ops, error, ap, vop_close); 1633 return(error); 1634 } 1635 1636 int 1637 vop_access_ap(struct vop_access_args *ap) 1638 { 1639 int error; 1640 1641 DO_OPS(ap->a_head.a_ops, error, ap, vop_access); 1642 return(error); 1643 } 1644 1645 int 1646 vop_getattr_ap(struct vop_getattr_args *ap) 1647 { 1648 int error; 1649 1650 DO_OPS(ap->a_head.a_ops, error, ap, vop_getattr); 1651 return(error); 1652 } 1653 1654 int 1655 vop_setattr_ap(struct vop_setattr_args *ap) 1656 { 1657 int error; 1658 1659 DO_OPS(ap->a_head.a_ops, error, ap, vop_setattr); 1660 return(error); 1661 } 1662 1663 int 1664 vop_read_ap(struct vop_read_args *ap) 1665 { 1666 int error; 1667 1668 DO_OPS(ap->a_head.a_ops, error, ap, vop_read); 1669 return(error); 1670 } 1671 1672 int 1673 vop_write_ap(struct vop_write_args *ap) 1674 { 1675 int error; 1676 1677 DO_OPS(ap->a_head.a_ops, error, ap, vop_write); 1678 return(error); 1679 } 1680 1681 int 1682 vop_ioctl_ap(struct vop_ioctl_args *ap) 1683 { 1684 int error; 1685 1686 DO_OPS(ap->a_head.a_ops, error, ap, vop_ioctl); 1687 return(error); 1688 } 1689 1690 int 1691 vop_poll_ap(struct vop_poll_args *ap) 1692 { 1693 int error; 1694 1695 DO_OPS(ap->a_head.a_ops, error, ap, vop_poll); 1696 return(error); 1697 } 1698 1699 int 1700 vop_kqfilter_ap(struct vop_kqfilter_args *ap) 1701 { 1702 int error; 1703 1704 DO_OPS(ap->a_head.a_ops, error, ap, vop_kqfilter); 1705 return(error); 1706 } 1707 1708 int 1709 vop_mmap_ap(struct vop_mmap_args *ap) 1710 { 1711 int error; 1712 1713 DO_OPS(ap->a_head.a_ops, error, ap, vop_mmap); 1714 return(error); 1715 } 1716 1717 int 1718 vop_fsync_ap(struct vop_fsync_args *ap) 1719 { 1720 int error; 1721 1722 DO_OPS(ap->a_head.a_ops, error, ap, vop_fsync); 1723 return(error); 1724 } 1725 1726 int 1727 vop_readdir_ap(struct vop_readdir_args *ap) 1728 { 1729 int error; 1730 1731 DO_OPS(ap->a_head.a_ops, error, ap, vop_readdir); 1732 return(error); 1733 } 1734 1735 int 1736 vop_readlink_ap(struct vop_readlink_args *ap) 1737 { 1738 int error; 1739 1740 DO_OPS(ap->a_head.a_ops, error, ap, vop_readlink); 1741 return(error); 1742 } 1743 1744 int 1745 vop_inactive_ap(struct vop_inactive_args *ap) 1746 { 1747 int error; 1748 1749 DO_OPS(ap->a_head.a_ops, error, ap, vop_inactive); 1750 return(error); 1751 } 1752 1753 int 1754 vop_reclaim_ap(struct vop_reclaim_args *ap) 1755 { 1756 int error; 1757 1758 DO_OPS(ap->a_head.a_ops, error, ap, vop_reclaim); 1759 return(error); 1760 } 1761 1762 int 1763 vop_bmap_ap(struct vop_bmap_args *ap) 1764 { 1765 int error; 1766 1767 DO_OPS(ap->a_head.a_ops, error, ap, vop_bmap); 1768 return(error); 1769 } 1770 1771 int 1772 vop_strategy_ap(struct vop_strategy_args *ap) 1773 { 1774 int error; 1775 1776 DO_OPS(ap->a_head.a_ops, error, ap, vop_strategy); 1777 return(error); 1778 } 1779 1780 int 1781 vop_print_ap(struct vop_print_args *ap) 1782 { 1783 int error; 1784 1785 DO_OPS(ap->a_head.a_ops, error, ap, vop_print); 1786 return(error); 1787 } 1788 1789 int 1790 vop_pathconf_ap(struct vop_pathconf_args *ap) 1791 { 1792 int error; 1793 1794 DO_OPS(ap->a_head.a_ops, error, ap, vop_pathconf); 1795 return(error); 1796 } 1797 1798 int 1799 vop_advlock_ap(struct vop_advlock_args *ap) 1800 { 1801 int error; 1802 1803 DO_OPS(ap->a_head.a_ops, error, ap, vop_advlock); 1804 return(error); 1805 } 1806 1807 int 1808 vop_balloc_ap(struct vop_balloc_args *ap) 1809 { 1810 int error; 1811 1812 DO_OPS(ap->a_head.a_ops, error, ap, vop_balloc); 1813 return(error); 1814 } 1815 1816 int 1817 vop_reallocblks_ap(struct vop_reallocblks_args *ap) 1818 { 1819 int error; 1820 1821 DO_OPS(ap->a_head.a_ops, error, ap, vop_reallocblks); 1822 return(error); 1823 } 1824 1825 int 1826 vop_getpages_ap(struct vop_getpages_args *ap) 1827 { 1828 int error; 1829 1830 DO_OPS(ap->a_head.a_ops, error, ap, vop_getpages); 1831 return(error); 1832 } 1833 1834 int 1835 vop_putpages_ap(struct vop_putpages_args *ap) 1836 { 1837 int error; 1838 1839 DO_OPS(ap->a_head.a_ops, error, ap, vop_putpages); 1840 return(error); 1841 } 1842 1843 int 1844 vop_freeblks_ap(struct vop_freeblks_args *ap) 1845 { 1846 int error; 1847 1848 DO_OPS(ap->a_head.a_ops, error, ap, vop_freeblks); 1849 return(error); 1850 } 1851 1852 int 1853 vop_getacl_ap(struct vop_getacl_args *ap) 1854 { 1855 int error; 1856 1857 DO_OPS(ap->a_head.a_ops, error, ap, vop_getacl); 1858 return(error); 1859 } 1860 1861 int 1862 vop_setacl_ap(struct vop_setacl_args *ap) 1863 { 1864 int error; 1865 1866 DO_OPS(ap->a_head.a_ops, error, ap, vop_setacl); 1867 return(error); 1868 } 1869 1870 int 1871 vop_aclcheck_ap(struct vop_aclcheck_args *ap) 1872 { 1873 int error; 1874 1875 DO_OPS(ap->a_head.a_ops, error, ap, vop_aclcheck); 1876 return(error); 1877 } 1878 1879 int 1880 vop_getextattr_ap(struct vop_getextattr_args *ap) 1881 { 1882 int error; 1883 1884 DO_OPS(ap->a_head.a_ops, error, ap, vop_getextattr); 1885 return(error); 1886 } 1887 1888 int 1889 vop_setextattr_ap(struct vop_setextattr_args *ap) 1890 { 1891 int error; 1892 1893 DO_OPS(ap->a_head.a_ops, error, ap, vop_setextattr); 1894 return(error); 1895 } 1896 1897 int 1898 vop_mountctl_ap(struct vop_mountctl_args *ap) 1899 { 1900 int error; 1901 1902 DO_OPS(ap->a_head.a_ops, error, ap, vop_mountctl); 1903 return(error); 1904 } 1905 1906 int 1907 vop_markatime_ap(struct vop_markatime_args *ap) 1908 { 1909 int error; 1910 1911 DO_OPS(ap->a_head.a_ops, error, ap, vop_markatime); 1912 return(error); 1913 } 1914 1915 int 1916 vop_nresolve_ap(struct vop_nresolve_args *ap) 1917 { 1918 int error; 1919 1920 DO_OPS(ap->a_head.a_ops, error, ap, vop_nresolve); 1921 return(error); 1922 } 1923 1924 int 1925 vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap) 1926 { 1927 int error; 1928 1929 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlookupdotdot); 1930 return(error); 1931 } 1932 1933 int 1934 vop_ncreate_ap(struct vop_ncreate_args *ap) 1935 { 1936 int error; 1937 1938 DO_OPS(ap->a_head.a_ops, error, ap, vop_ncreate); 1939 return(error); 1940 } 1941 1942 int 1943 vop_nmkdir_ap(struct vop_nmkdir_args *ap) 1944 { 1945 int error; 1946 1947 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmkdir); 1948 return(error); 1949 } 1950 1951 int 1952 vop_nmknod_ap(struct vop_nmknod_args *ap) 1953 { 1954 int error; 1955 1956 DO_OPS(ap->a_head.a_ops, error, ap, vop_nmknod); 1957 return(error); 1958 } 1959 1960 int 1961 vop_nlink_ap(struct vop_nlink_args *ap) 1962 { 1963 int error; 1964 1965 DO_OPS(ap->a_head.a_ops, error, ap, vop_nlink); 1966 return(error); 1967 } 1968 1969 int 1970 vop_nsymlink_ap(struct vop_nsymlink_args *ap) 1971 { 1972 int error; 1973 1974 DO_OPS(ap->a_head.a_ops, error, ap, vop_nsymlink); 1975 return(error); 1976 } 1977 1978 int 1979 vop_nwhiteout_ap(struct vop_nwhiteout_args *ap) 1980 { 1981 int error; 1982 1983 DO_OPS(ap->a_head.a_ops, error, ap, vop_nwhiteout); 1984 return(error); 1985 } 1986 1987 int 1988 vop_nremove_ap(struct vop_nremove_args *ap) 1989 { 1990 int error; 1991 1992 DO_OPS(ap->a_head.a_ops, error, ap, vop_nremove); 1993 return(error); 1994 } 1995 1996 int 1997 vop_nrmdir_ap(struct vop_nrmdir_args *ap) 1998 { 1999 int error; 2000 2001 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrmdir); 2002 return(error); 2003 } 2004 2005 int 2006 vop_nrename_ap(struct vop_nrename_args *ap) 2007 { 2008 int error; 2009 2010 DO_OPS(ap->a_head.a_ops, error, ap, vop_nrename); 2011 return(error); 2012 } 2013 2014