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