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