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