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