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