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