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