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