1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed 6 * to Berkeley by John Heidemann of the UCLA Ficus project. 7 * 8 * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * 39 * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ 40 * $DragonFly: src/sys/kern/vfs_default.c,v 1.52 2008/01/18 19:13:16 dillon Exp $ 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/buf.h> 46 #include <sys/conf.h> 47 #include <sys/fcntl.h> 48 #include <sys/file.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/malloc.h> 52 #include <sys/mount.h> 53 #include <sys/unistd.h> 54 #include <sys/vnode.h> 55 #include <sys/namei.h> 56 #include <sys/nlookup.h> 57 #include <sys/poll.h> 58 #include <sys/mountctl.h> 59 60 #include <machine/limits.h> 61 62 #include <vm/vm.h> 63 #include <vm/vm_object.h> 64 #include <vm/vm_page.h> 65 #include <vm/vm_pager.h> 66 #include <vm/vnode_pager.h> 67 68 static int vop_nolookup (struct vop_old_lookup_args *); 69 static int vop_nostrategy (struct vop_strategy_args *); 70 71 /* 72 * This vnode table stores what we want to do if the filesystem doesn't 73 * implement a particular VOP. 74 * 75 * If there is no specific entry here, we will return EOPNOTSUPP. 76 */ 77 struct vop_ops default_vnode_vops = { 78 .vop_default = vop_eopnotsupp, 79 .vop_advlock = (void *)vop_einval, 80 .vop_fsync = (void *)vop_null, 81 .vop_ioctl = (void *)vop_enotty, 82 .vop_mmap = (void *)vop_einval, 83 .vop_old_lookup = vop_nolookup, 84 .vop_open = vop_stdopen, 85 .vop_close = vop_stdclose, 86 .vop_pathconf = (void *)vop_einval, 87 .vop_poll = vop_nopoll, 88 .vop_readlink = (void *)vop_einval, 89 .vop_reallocblks = (void *)vop_eopnotsupp, 90 .vop_revoke = vop_stdrevoke, 91 .vop_strategy = vop_nostrategy, 92 .vop_getacl = (void *)vop_eopnotsupp, 93 .vop_setacl = (void *)vop_eopnotsupp, 94 .vop_aclcheck = (void *)vop_eopnotsupp, 95 .vop_getextattr = (void *)vop_eopnotsupp, 96 .vop_setextattr = (void *)vop_eopnotsupp, 97 .vop_nresolve = vop_compat_nresolve, 98 .vop_nlookupdotdot = vop_compat_nlookupdotdot, 99 .vop_ncreate = vop_compat_ncreate, 100 .vop_nmkdir = vop_compat_nmkdir, 101 .vop_nmknod = vop_compat_nmknod, 102 .vop_nlink = vop_compat_nlink, 103 .vop_nsymlink = vop_compat_nsymlink, 104 .vop_nwhiteout = vop_compat_nwhiteout, 105 .vop_nremove = vop_compat_nremove, 106 .vop_nrmdir = vop_compat_nrmdir, 107 .vop_nrename = vop_compat_nrename, 108 .vop_mountctl = journal_mountctl 109 }; 110 111 VNODEOP_SET(default_vnode_vops); 112 113 int 114 vop_eopnotsupp(struct vop_generic_args *ap) 115 { 116 return (EOPNOTSUPP); 117 } 118 119 int 120 vop_ebadf(struct vop_generic_args *ap) 121 { 122 return (EBADF); 123 } 124 125 int 126 vop_enotty(struct vop_generic_args *ap) 127 { 128 return (ENOTTY); 129 } 130 131 int 132 vop_einval(struct vop_generic_args *ap) 133 { 134 return (EINVAL); 135 } 136 137 int 138 vop_null(struct vop_generic_args *ap) 139 { 140 return (0); 141 } 142 143 int 144 vop_defaultop(struct vop_generic_args *ap) 145 { 146 return (VOCALL(&default_vnode_vops, ap)); 147 } 148 149 int 150 vop_panic(struct vop_generic_args *ap) 151 { 152 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name); 153 } 154 155 /* 156 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp } 157 * XXX STOPGAP FUNCTION 158 * 159 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE 160 * WILL BE REMOVED. This procedure exists for all VFSs which have not 161 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a 162 * vop_old_lookup() and does appropriate translations. 163 * 164 * Resolve a ncp for VFSs which do not support the VOP. Eventually all 165 * VFSs will support this VOP and this routine can be removed, since 166 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP 167 * API. 168 * 169 * A locked ncp is passed in to be resolved. The NCP is resolved by 170 * figuring out the vnode (if any) and calling cache_setvp() to attach the 171 * vnode to the entry. If the entry represents a non-existant node then 172 * cache_setvp() is called with a NULL vnode to resolve the entry into a 173 * negative cache entry. No vnode locks are retained and the 174 * ncp is left locked on return. 175 * 176 * The ncp will NEVER represent "", "." or "..", or contain any slashes. 177 * 178 * There is a potential directory and vnode interlock. The lock order 179 * requirement is: namecache, governing directory, resolved vnode. 180 */ 181 int 182 vop_compat_nresolve(struct vop_nresolve_args *ap) 183 { 184 int error; 185 struct vnode *dvp; 186 struct vnode *vp; 187 struct nchandle *nch; 188 struct namecache *ncp; 189 struct componentname cnp; 190 191 nch = ap->a_nch; /* locked namecache node */ 192 ncp = nch->ncp; 193 dvp = ap->a_dvp; 194 195 /* 196 * UFS currently stores all sorts of side effects, including a loop 197 * variable, in the directory inode. That needs to be fixed and the 198 * other VFS's audited before we can switch to LK_SHARED. 199 */ 200 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 201 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 202 ncp, ncp->nc_name); 203 return(EAGAIN); 204 } 205 206 bzero(&cnp, sizeof(cnp)); 207 cnp.cn_nameiop = NAMEI_LOOKUP; 208 cnp.cn_flags = 0; 209 cnp.cn_nameptr = ncp->nc_name; 210 cnp.cn_namelen = ncp->nc_nlen; 211 cnp.cn_cred = ap->a_cred; 212 cnp.cn_td = curthread; /* XXX */ 213 214 /* 215 * vop_old_lookup() always returns vp locked. dvp may or may not be 216 * left locked depending on CNP_PDIRUNLOCK. 217 */ 218 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 219 if (error == 0) 220 vn_unlock(vp); 221 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 222 vn_unlock(dvp); 223 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) { 224 /* was resolved by another process while we were unlocked */ 225 if (error == 0) 226 vrele(vp); 227 } else if (error == 0) { 228 KKASSERT(vp != NULL); 229 cache_setvp(nch, vp); 230 vrele(vp); 231 } else if (error == ENOENT) { 232 KKASSERT(vp == NULL); 233 if (cnp.cn_flags & CNP_ISWHITEOUT) 234 ncp->nc_flag |= NCF_WHITEOUT; 235 cache_setvp(nch, NULL); 236 } 237 vrele(dvp); 238 return (error); 239 } 240 241 /* 242 * vop_compat_nlookupdotdot { struct vnode *a_dvp, 243 * struct vnode **a_vpp, 244 * struct ucred *a_cred } 245 * 246 * Lookup the vnode representing the parent directory of the specified 247 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp 248 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL. 249 * 250 * This function is designed to aid NFS server-side operations and is 251 * used by cache_fromdvp() to create a consistent, connected namecache 252 * topology. 253 * 254 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT 255 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time 256 * permits VFSs will implement the remaining *_n*() calls and finally get 257 * rid of their *_lookup() call. 258 */ 259 int 260 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap) 261 { 262 struct componentname cnp; 263 int error; 264 265 /* 266 * UFS currently stores all sorts of side effects, including a loop 267 * variable, in the directory inode. That needs to be fixed and the 268 * other VFS's audited before we can switch to LK_SHARED. 269 */ 270 *ap->a_vpp = NULL; 271 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE)) != 0) 272 return (error); 273 if (ap->a_dvp->v_type != VDIR) { 274 vput(ap->a_dvp); 275 return (ENOTDIR); 276 } 277 278 bzero(&cnp, sizeof(cnp)); 279 cnp.cn_nameiop = NAMEI_LOOKUP; 280 cnp.cn_flags = CNP_ISDOTDOT; 281 cnp.cn_nameptr = ".."; 282 cnp.cn_namelen = 2; 283 cnp.cn_cred = ap->a_cred; 284 cnp.cn_td = curthread; /* XXX */ 285 286 /* 287 * vop_old_lookup() always returns vp locked. dvp may or may not be 288 * left locked depending on CNP_PDIRUNLOCK. 289 */ 290 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp); 291 if (error == 0) 292 vn_unlock(*ap->a_vpp); 293 if (cnp.cn_flags & CNP_PDIRUNLOCK) 294 vrele(ap->a_dvp); 295 else 296 vput(ap->a_dvp); 297 return (error); 298 } 299 300 /* 301 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION 302 * struct vnode *a_dvp, 303 * struct vnode **a_vpp, 304 * struct ucred *a_cred, 305 * struct vattr *a_vap } 306 * 307 * Create a file as specified by a_vap. Compatibility requires us to issue 308 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order 309 * to setup the directory inode's i_offset and i_count (e.g. in UFS). 310 */ 311 int 312 vop_compat_ncreate(struct vop_ncreate_args *ap) 313 { 314 struct thread *td = curthread; 315 struct componentname cnp; 316 struct nchandle *nch; 317 struct namecache *ncp; 318 struct vnode *dvp; 319 int error; 320 321 /* 322 * Sanity checks, get a locked directory vnode. 323 */ 324 nch = ap->a_nch; /* locked namecache node */ 325 dvp = ap->a_dvp; 326 ncp = nch->ncp; 327 328 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 329 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 330 ncp, ncp->nc_name); 331 return(EAGAIN); 332 } 333 334 /* 335 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 336 * caches all information required to create the entry in the 337 * directory inode. We expect a return code of EJUSTRETURN for 338 * the CREATE case. The cnp must simulated a saved-name situation. 339 */ 340 bzero(&cnp, sizeof(cnp)); 341 cnp.cn_nameiop = NAMEI_CREATE; 342 cnp.cn_flags = CNP_LOCKPARENT; 343 cnp.cn_nameptr = ncp->nc_name; 344 cnp.cn_namelen = ncp->nc_nlen; 345 cnp.cn_cred = ap->a_cred; 346 cnp.cn_td = td; 347 *ap->a_vpp = NULL; 348 349 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 350 351 /* 352 * EJUSTRETURN should be returned for this case, which means that 353 * the VFS has setup the directory inode for the create. The dvp we 354 * passed in is expected to remain in a locked state. 355 * 356 * If the VOP_OLD_CREATE is successful we are responsible for updating 357 * the cache state of the locked ncp that was passed to us. 358 */ 359 if (error == EJUSTRETURN) { 360 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 361 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap); 362 if (error == 0) { 363 cache_setunresolved(nch); 364 cache_setvp(nch, *ap->a_vpp); 365 } 366 } else { 367 if (error == 0) { 368 vput(*ap->a_vpp); 369 *ap->a_vpp = NULL; 370 error = EEXIST; 371 } 372 KKASSERT(*ap->a_vpp == NULL); 373 } 374 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 375 vn_unlock(dvp); 376 vrele(dvp); 377 return (error); 378 } 379 380 /* 381 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION 382 * struct vnode *a_dvp, 383 * struct vnode **a_vpp, 384 * struct ucred *a_cred, 385 * struct vattr *a_vap } 386 * 387 * Create a directory as specified by a_vap. Compatibility requires us to 388 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in 389 * order to setup the directory inode's i_offset and i_count (e.g. in UFS). 390 */ 391 int 392 vop_compat_nmkdir(struct vop_nmkdir_args *ap) 393 { 394 struct thread *td = curthread; 395 struct componentname cnp; 396 struct nchandle *nch; 397 struct namecache *ncp; 398 struct vnode *dvp; 399 int error; 400 401 /* 402 * Sanity checks, get a locked directory vnode. 403 */ 404 nch = ap->a_nch; /* locked namecache node */ 405 ncp = nch->ncp; 406 dvp = ap->a_dvp; 407 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 408 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 409 ncp, ncp->nc_name); 410 return(EAGAIN); 411 } 412 413 /* 414 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 415 * caches all information required to create the entry in the 416 * directory inode. We expect a return code of EJUSTRETURN for 417 * the CREATE case. The cnp must simulated a saved-name situation. 418 */ 419 bzero(&cnp, sizeof(cnp)); 420 cnp.cn_nameiop = NAMEI_CREATE; 421 cnp.cn_flags = CNP_LOCKPARENT; 422 cnp.cn_nameptr = ncp->nc_name; 423 cnp.cn_namelen = ncp->nc_nlen; 424 cnp.cn_cred = ap->a_cred; 425 cnp.cn_td = td; 426 *ap->a_vpp = NULL; 427 428 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 429 430 /* 431 * EJUSTRETURN should be returned for this case, which means that 432 * the VFS has setup the directory inode for the create. The dvp we 433 * passed in is expected to remain in a locked state. 434 * 435 * If the VOP_OLD_MKDIR is successful we are responsible for updating 436 * the cache state of the locked ncp that was passed to us. 437 */ 438 if (error == EJUSTRETURN) { 439 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 440 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap); 441 if (error == 0) { 442 cache_setunresolved(nch); 443 cache_setvp(nch, *ap->a_vpp); 444 } 445 } else { 446 if (error == 0) { 447 vput(*ap->a_vpp); 448 *ap->a_vpp = NULL; 449 error = EEXIST; 450 } 451 KKASSERT(*ap->a_vpp == NULL); 452 } 453 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 454 vn_unlock(dvp); 455 vrele(dvp); 456 return (error); 457 } 458 459 /* 460 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION 461 * struct vnode *a_dvp, 462 * struct vnode **a_vpp, 463 * struct ucred *a_cred, 464 * struct vattr *a_vap } 465 * 466 * Create a device or fifo node as specified by a_vap. Compatibility requires 467 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD 468 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS). 469 */ 470 int 471 vop_compat_nmknod(struct vop_nmknod_args *ap) 472 { 473 struct thread *td = curthread; 474 struct componentname cnp; 475 struct nchandle *nch; 476 struct namecache *ncp; 477 struct vnode *dvp; 478 int error; 479 480 /* 481 * Sanity checks, get a locked directory vnode. 482 */ 483 nch = ap->a_nch; /* locked namecache node */ 484 ncp = nch->ncp; 485 dvp = ap->a_dvp; 486 487 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 488 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 489 ncp, ncp->nc_name); 490 return(EAGAIN); 491 } 492 493 /* 494 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 495 * caches all information required to create the entry in the 496 * directory inode. We expect a return code of EJUSTRETURN for 497 * the CREATE case. The cnp must simulated a saved-name situation. 498 */ 499 bzero(&cnp, sizeof(cnp)); 500 cnp.cn_nameiop = NAMEI_CREATE; 501 cnp.cn_flags = CNP_LOCKPARENT; 502 cnp.cn_nameptr = ncp->nc_name; 503 cnp.cn_namelen = ncp->nc_nlen; 504 cnp.cn_cred = ap->a_cred; 505 cnp.cn_td = td; 506 *ap->a_vpp = NULL; 507 508 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 509 510 /* 511 * EJUSTRETURN should be returned for this case, which means that 512 * the VFS has setup the directory inode for the create. The dvp we 513 * passed in is expected to remain in a locked state. 514 * 515 * If the VOP_OLD_MKNOD is successful we are responsible for updating 516 * the cache state of the locked ncp that was passed to us. 517 */ 518 if (error == EJUSTRETURN) { 519 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 520 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap); 521 if (error == 0) { 522 cache_setunresolved(nch); 523 cache_setvp(nch, *ap->a_vpp); 524 } 525 } else { 526 if (error == 0) { 527 vput(*ap->a_vpp); 528 *ap->a_vpp = NULL; 529 error = EEXIST; 530 } 531 KKASSERT(*ap->a_vpp == NULL); 532 } 533 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 534 vn_unlock(dvp); 535 vrele(dvp); 536 return (error); 537 } 538 539 /* 540 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION 541 * struct vnode *a_dvp, 542 * struct vnode *a_vp, 543 * struct ucred *a_cred } 544 * 545 * The passed vp is locked and represents the source. The passed ncp is 546 * locked and represents the target to create. 547 */ 548 int 549 vop_compat_nlink(struct vop_nlink_args *ap) 550 { 551 struct thread *td = curthread; 552 struct componentname cnp; 553 struct nchandle *nch; 554 struct namecache *ncp; 555 struct vnode *dvp; 556 struct vnode *tvp; 557 int error; 558 559 /* 560 * Sanity checks, get a locked directory vnode. 561 */ 562 nch = ap->a_nch; /* locked namecache node */ 563 ncp = nch->ncp; 564 dvp = ap->a_dvp; 565 566 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 567 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 568 ncp, ncp->nc_name); 569 return(EAGAIN); 570 } 571 572 /* 573 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 574 * caches all information required to create the entry in the 575 * directory inode. We expect a return code of EJUSTRETURN for 576 * the CREATE case. The cnp must simulated a saved-name situation. 577 */ 578 bzero(&cnp, sizeof(cnp)); 579 cnp.cn_nameiop = NAMEI_CREATE; 580 cnp.cn_flags = CNP_LOCKPARENT; 581 cnp.cn_nameptr = ncp->nc_name; 582 cnp.cn_namelen = ncp->nc_nlen; 583 cnp.cn_cred = ap->a_cred; 584 cnp.cn_td = td; 585 586 tvp = NULL; 587 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp); 588 589 /* 590 * EJUSTRETURN should be returned for this case, which means that 591 * the VFS has setup the directory inode for the create. The dvp we 592 * passed in is expected to remain in a locked state. 593 * 594 * If the VOP_OLD_LINK is successful we are responsible for updating 595 * the cache state of the locked ncp that was passed to us. 596 */ 597 if (error == EJUSTRETURN) { 598 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 599 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp); 600 if (error == 0) { 601 cache_setunresolved(nch); 602 cache_setvp(nch, ap->a_vp); 603 } 604 } else { 605 if (error == 0) { 606 vput(tvp); 607 error = EEXIST; 608 } 609 } 610 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 611 vn_unlock(dvp); 612 vrele(dvp); 613 return (error); 614 } 615 616 int 617 vop_compat_nsymlink(struct vop_nsymlink_args *ap) 618 { 619 struct thread *td = curthread; 620 struct componentname cnp; 621 struct nchandle *nch; 622 struct namecache *ncp; 623 struct vnode *dvp; 624 struct vnode *vp; 625 int error; 626 627 /* 628 * Sanity checks, get a locked directory vnode. 629 */ 630 *ap->a_vpp = NULL; 631 nch = ap->a_nch; /* locked namecache node */ 632 ncp = nch->ncp; 633 dvp = ap->a_dvp; 634 635 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 636 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 637 ncp, ncp->nc_name); 638 return(EAGAIN); 639 } 640 641 /* 642 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 643 * caches all information required to create the entry in the 644 * directory inode. We expect a return code of EJUSTRETURN for 645 * the CREATE case. The cnp must simulated a saved-name situation. 646 */ 647 bzero(&cnp, sizeof(cnp)); 648 cnp.cn_nameiop = NAMEI_CREATE; 649 cnp.cn_flags = CNP_LOCKPARENT; 650 cnp.cn_nameptr = ncp->nc_name; 651 cnp.cn_namelen = ncp->nc_nlen; 652 cnp.cn_cred = ap->a_cred; 653 cnp.cn_td = td; 654 655 vp = NULL; 656 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 657 658 /* 659 * EJUSTRETURN should be returned for this case, which means that 660 * the VFS has setup the directory inode for the create. The dvp we 661 * passed in is expected to remain in a locked state. 662 * 663 * If the VOP_OLD_SYMLINK is successful we are responsible for updating 664 * the cache state of the locked ncp that was passed to us. 665 */ 666 if (error == EJUSTRETURN) { 667 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 668 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target); 669 if (error == 0) { 670 cache_setunresolved(nch); 671 cache_setvp(nch, vp); 672 *ap->a_vpp = vp; 673 } 674 } else { 675 if (error == 0) { 676 vput(vp); 677 vp = NULL; 678 error = EEXIST; 679 } 680 KKASSERT(vp == NULL); 681 } 682 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 683 vn_unlock(dvp); 684 vrele(dvp); 685 return (error); 686 } 687 688 /* 689 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION 690 * struct vnode *a_dvp, 691 * struct ucred *a_cred, 692 * int a_flags } 693 * 694 * Issie a whiteout operation (create, lookup, or delete). Compatibility 695 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue 696 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count 697 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP 698 * no lookup is necessary. 699 */ 700 int 701 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) 702 { 703 struct thread *td = curthread; 704 struct componentname cnp; 705 struct nchandle *nch; 706 struct namecache *ncp; 707 struct vnode *dvp; 708 struct vnode *vp; 709 int error; 710 711 /* 712 * Sanity checks, get a locked directory vnode. 713 */ 714 nch = ap->a_nch; /* locked namecache node */ 715 ncp = nch->ncp; 716 dvp = ap->a_dvp; 717 718 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 719 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 720 ncp, ncp->nc_name); 721 return(EAGAIN); 722 } 723 724 /* 725 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 726 * caches all information required to create the entry in the 727 * directory inode. We expect a return code of EJUSTRETURN for 728 * the CREATE case. The cnp must simulated a saved-name situation. 729 */ 730 bzero(&cnp, sizeof(cnp)); 731 cnp.cn_nameiop = ap->a_flags; 732 cnp.cn_flags = CNP_LOCKPARENT; 733 cnp.cn_nameptr = ncp->nc_name; 734 cnp.cn_namelen = ncp->nc_nlen; 735 cnp.cn_cred = ap->a_cred; 736 cnp.cn_td = td; 737 738 vp = NULL; 739 740 /* 741 * EJUSTRETURN should be returned for the CREATE or DELETE cases. 742 * The VFS has setup the directory inode for the create. The dvp we 743 * passed in is expected to remain in a locked state. 744 * 745 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating 746 * the cache state of the locked ncp that was passed to us. 747 */ 748 switch(ap->a_flags) { 749 case NAMEI_DELETE: 750 cnp.cn_flags |= CNP_DOWHITEOUT; 751 /* fall through */ 752 case NAMEI_CREATE: 753 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 754 if (error == EJUSTRETURN) { 755 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 756 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags); 757 if (error == 0) 758 cache_setunresolved(nch); 759 } else { 760 if (error == 0) { 761 vput(vp); 762 vp = NULL; 763 error = EEXIST; 764 } 765 KKASSERT(vp == NULL); 766 } 767 break; 768 case NAMEI_LOOKUP: 769 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags); 770 break; 771 default: 772 error = EINVAL; 773 break; 774 } 775 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 776 vn_unlock(dvp); 777 vrele(dvp); 778 return (error); 779 } 780 781 782 /* 783 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION 784 * struct vnode *a_dvp, 785 * struct ucred *a_cred } 786 */ 787 int 788 vop_compat_nremove(struct vop_nremove_args *ap) 789 { 790 struct thread *td = curthread; 791 struct componentname cnp; 792 struct nchandle *nch; 793 struct namecache *ncp; 794 struct vnode *dvp; 795 struct vnode *vp; 796 int error; 797 798 /* 799 * Sanity checks, get a locked directory vnode. 800 */ 801 nch = ap->a_nch; /* locked namecache node */ 802 ncp = nch->ncp; 803 dvp = ap->a_dvp; 804 805 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 806 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 807 ncp, ncp->nc_name); 808 return(EAGAIN); 809 } 810 811 /* 812 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 813 * caches all information required to delete the entry in the 814 * directory inode. We expect a return code of 0 for the DELETE 815 * case (meaning that a vp has been found). The cnp must simulated 816 * a saved-name situation. 817 */ 818 bzero(&cnp, sizeof(cnp)); 819 cnp.cn_nameiop = NAMEI_DELETE; 820 cnp.cn_flags = CNP_LOCKPARENT; 821 cnp.cn_nameptr = ncp->nc_name; 822 cnp.cn_namelen = ncp->nc_nlen; 823 cnp.cn_cred = ap->a_cred; 824 cnp.cn_td = td; 825 826 /* 827 * The vnode must be a directory and must not represent the 828 * current directory. 829 */ 830 vp = NULL; 831 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 832 if (error == 0 && vp->v_type == VDIR) 833 error = EPERM; 834 if (error == 0) { 835 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 836 error = VOP_OLD_REMOVE(dvp, vp, &cnp); 837 if (error == 0) { 838 cache_setunresolved(nch); 839 cache_setvp(nch, NULL); 840 cache_inval_vp(vp, CINV_DESTROY); 841 } 842 } 843 if (vp) { 844 if (dvp == vp) 845 vrele(vp); 846 else 847 vput(vp); 848 } 849 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 850 vn_unlock(dvp); 851 vrele(dvp); 852 return (error); 853 } 854 855 /* 856 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION 857 * struct vnode *dvp, 858 * struct ucred *a_cred } 859 */ 860 int 861 vop_compat_nrmdir(struct vop_nrmdir_args *ap) 862 { 863 struct thread *td = curthread; 864 struct componentname cnp; 865 struct nchandle *nch; 866 struct namecache *ncp; 867 struct vnode *dvp; 868 struct vnode *vp; 869 int error; 870 871 /* 872 * Sanity checks, get a locked directory vnode. 873 */ 874 nch = ap->a_nch; /* locked namecache node */ 875 ncp = nch->ncp; 876 dvp = ap->a_dvp; 877 878 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 879 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 880 ncp, ncp->nc_name); 881 return(EAGAIN); 882 } 883 884 /* 885 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 886 * caches all information required to delete the entry in the 887 * directory inode. We expect a return code of 0 for the DELETE 888 * case (meaning that a vp has been found). The cnp must simulated 889 * a saved-name situation. 890 */ 891 bzero(&cnp, sizeof(cnp)); 892 cnp.cn_nameiop = NAMEI_DELETE; 893 cnp.cn_flags = CNP_LOCKPARENT; 894 cnp.cn_nameptr = ncp->nc_name; 895 cnp.cn_namelen = ncp->nc_nlen; 896 cnp.cn_cred = ap->a_cred; 897 cnp.cn_td = td; 898 899 /* 900 * The vnode must be a directory and must not represent the 901 * current directory. 902 */ 903 vp = NULL; 904 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 905 if (error == 0 && vp->v_type != VDIR) 906 error = ENOTDIR; 907 if (error == 0 && vp == dvp) 908 error = EINVAL; 909 if (error == 0 && (vp->v_flag & VROOT)) 910 error = EBUSY; 911 if (error == 0) { 912 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 913 error = VOP_OLD_RMDIR(dvp, vp, &cnp); 914 915 /* 916 * Note that this invalidation will cause any process 917 * currently CD'd into the directory being removed to be 918 * disconnected from the topology and not be able to ".." 919 * back out. 920 */ 921 if (error == 0) { 922 cache_inval(nch, CINV_DESTROY); 923 cache_inval_vp(vp, CINV_DESTROY); 924 } 925 } 926 if (vp) { 927 if (dvp == vp) 928 vrele(vp); 929 else 930 vput(vp); 931 } 932 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 933 vn_unlock(dvp); 934 vrele(dvp); 935 return (error); 936 } 937 938 /* 939 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION 940 * struct nchandle *a_tnch, 941 * struct ucred *a_cred } 942 * 943 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that 944 * the source directory and vnode be unlocked and the target directory and 945 * vnode (if it exists) be locked. All arguments will be vrele'd and 946 * the targets will also be unlocked regardless of the return code. 947 */ 948 int 949 vop_compat_nrename(struct vop_nrename_args *ap) 950 { 951 struct thread *td = curthread; 952 struct componentname fcnp; 953 struct componentname tcnp; 954 struct nchandle *fnch; 955 struct nchandle *tnch; 956 struct namecache *fncp; 957 struct namecache *tncp; 958 struct vnode *fdvp, *fvp; 959 struct vnode *tdvp, *tvp; 960 int error; 961 962 /* 963 * Sanity checks, get referenced vnodes representing the source. 964 */ 965 fnch = ap->a_fnch; /* locked namecache node */ 966 fncp = fnch->ncp; 967 fdvp = ap->a_fdvp; 968 969 /* 970 * Temporarily lock the source directory and lookup in DELETE mode to 971 * check permissions. XXX delete permissions should have been 972 * checked by nlookup(), we need to add NLC_DELETE for delete 973 * checking. It is unclear whether VFS's require the directory setup 974 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but 975 * since it isn't locked and since UFS always does a relookup of 976 * the source, it is believed that the only side effect that matters 977 * is the permissions check. 978 */ 979 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) { 980 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 981 fncp, fncp->nc_name); 982 return(EAGAIN); 983 } 984 985 bzero(&fcnp, sizeof(fcnp)); 986 fcnp.cn_nameiop = NAMEI_DELETE; 987 fcnp.cn_flags = CNP_LOCKPARENT; 988 fcnp.cn_nameptr = fncp->nc_name; 989 fcnp.cn_namelen = fncp->nc_nlen; 990 fcnp.cn_cred = ap->a_cred; 991 fcnp.cn_td = td; 992 993 /* 994 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked 995 * fvp. 996 */ 997 fvp = NULL; 998 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp); 999 if (error == 0 && (fvp->v_flag & VROOT)) { 1000 vput(fvp); /* as if vop_old_lookup had failed */ 1001 error = EBUSY; 1002 } 1003 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) { 1004 fcnp.cn_flags |= CNP_PDIRUNLOCK; 1005 vn_unlock(fdvp); 1006 } 1007 if (error) { 1008 vrele(fdvp); 1009 return (error); 1010 } 1011 vn_unlock(fvp); 1012 1013 /* 1014 * fdvp and fvp are now referenced and unlocked. 1015 * 1016 * Get a locked directory vnode for the target and lookup the target 1017 * in CREATE mode so it places the required information in the 1018 * directory inode. 1019 */ 1020 tnch = ap->a_tnch; /* locked namecache node */ 1021 tncp = tnch->ncp; 1022 tdvp = ap->a_tdvp; 1023 if (error) { 1024 vrele(fdvp); 1025 vrele(fvp); 1026 return (error); 1027 } 1028 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) { 1029 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 1030 tncp, tncp->nc_name); 1031 vrele(fdvp); 1032 vrele(fvp); 1033 return(EAGAIN); 1034 } 1035 1036 /* 1037 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 1038 * caches all information required to create the entry in the 1039 * target directory inode. 1040 */ 1041 bzero(&tcnp, sizeof(tcnp)); 1042 tcnp.cn_nameiop = NAMEI_RENAME; 1043 tcnp.cn_flags = CNP_LOCKPARENT; 1044 tcnp.cn_nameptr = tncp->nc_name; 1045 tcnp.cn_namelen = tncp->nc_nlen; 1046 tcnp.cn_cred = ap->a_cred; 1047 tcnp.cn_td = td; 1048 1049 tvp = NULL; 1050 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp); 1051 1052 if (error == EJUSTRETURN) { 1053 /* 1054 * Target does not exist. tvp should be NULL. 1055 */ 1056 KKASSERT(tvp == NULL); 1057 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1058 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1059 if (error == 0) 1060 cache_rename(fnch, tnch); 1061 } else if (error == 0) { 1062 /* 1063 * Target exists. VOP_OLD_RENAME should correctly delete the 1064 * target. 1065 */ 1066 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1067 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1068 if (error == 0) 1069 cache_rename(fnch, tnch); 1070 } else { 1071 vrele(fdvp); 1072 vrele(fvp); 1073 if (tcnp.cn_flags & CNP_PDIRUNLOCK) 1074 vrele(tdvp); 1075 else 1076 vput(tdvp); 1077 } 1078 return (error); 1079 } 1080 1081 static int 1082 vop_nolookup(struct vop_old_lookup_args *ap) 1083 { 1084 1085 *ap->a_vpp = NULL; 1086 return (ENOTDIR); 1087 } 1088 1089 /* 1090 * vop_nostrategy: 1091 * 1092 * Strategy routine for VFS devices that have none. 1093 * 1094 * B_ERROR and B_INVAL must be cleared prior to calling any strategy 1095 * routine. Typically this is done for a BUF_CMD_READ strategy call. 1096 * Typically B_INVAL is assumed to already be clear prior to a write 1097 * and should not be cleared manually unless you just made the buffer 1098 * invalid. B_ERROR should be cleared either way. 1099 */ 1100 1101 static int 1102 vop_nostrategy (struct vop_strategy_args *ap) 1103 { 1104 kprintf("No strategy for buffer at %p\n", ap->a_bio->bio_buf); 1105 vprint("", ap->a_vp); 1106 ap->a_bio->bio_buf->b_flags |= B_ERROR; 1107 ap->a_bio->bio_buf->b_error = EOPNOTSUPP; 1108 biodone(ap->a_bio); 1109 return (EOPNOTSUPP); 1110 } 1111 1112 int 1113 vop_stdpathconf(struct vop_pathconf_args *ap) 1114 { 1115 1116 switch (ap->a_name) { 1117 case _PC_LINK_MAX: 1118 *ap->a_retval = LINK_MAX; 1119 return (0); 1120 case _PC_MAX_CANON: 1121 *ap->a_retval = MAX_CANON; 1122 return (0); 1123 case _PC_MAX_INPUT: 1124 *ap->a_retval = MAX_INPUT; 1125 return (0); 1126 case _PC_PIPE_BUF: 1127 *ap->a_retval = PIPE_BUF; 1128 return (0); 1129 case _PC_CHOWN_RESTRICTED: 1130 *ap->a_retval = 1; 1131 return (0); 1132 case _PC_VDISABLE: 1133 *ap->a_retval = _POSIX_VDISABLE; 1134 return (0); 1135 default: 1136 return (EINVAL); 1137 } 1138 /* NOTREACHED */ 1139 } 1140 1141 /* 1142 * Standard open. 1143 * 1144 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp) 1145 * 1146 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE 1147 */ 1148 int 1149 vop_stdopen(struct vop_open_args *ap) 1150 { 1151 struct vnode *vp = ap->a_vp; 1152 struct file *fp; 1153 1154 if ((fp = ap->a_fp) != NULL) { 1155 switch(vp->v_type) { 1156 case VFIFO: 1157 fp->f_type = DTYPE_FIFO; 1158 break; 1159 default: 1160 fp->f_type = DTYPE_VNODE; 1161 break; 1162 } 1163 fp->f_flag = ap->a_mode & FMASK; 1164 fp->f_ops = &vnode_fileops; 1165 fp->f_data = vp; 1166 vref(vp); 1167 } 1168 if (ap->a_mode & FWRITE) 1169 ++vp->v_writecount; 1170 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX); 1171 ++vp->v_opencount; 1172 return (0); 1173 } 1174 1175 /* 1176 * Standard close. 1177 * 1178 * (struct vnode *a_vp, int a_fflag) 1179 * 1180 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen? 1181 */ 1182 int 1183 vop_stdclose(struct vop_close_args *ap) 1184 { 1185 struct vnode *vp = ap->a_vp; 1186 1187 KASSERT(vp->v_opencount > 0, 1188 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x\n", 1189 vp, vp->v_opencount, vp->v_type, *vp->v_ops, vp->v_flag)); 1190 if (ap->a_fflag & FWRITE) { 1191 KASSERT(vp->v_writecount > 0, 1192 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n", 1193 vp, vp->v_writecount)); 1194 --vp->v_writecount; 1195 } 1196 --vp->v_opencount; 1197 return (0); 1198 } 1199 1200 /* 1201 * Return true for select/poll. 1202 */ 1203 int 1204 vop_nopoll(struct vop_poll_args *ap) 1205 { 1206 /* 1207 * Return true for read/write. If the user asked for something 1208 * special, return POLLNVAL, so that clients have a way of 1209 * determining reliably whether or not the extended 1210 * functionality is present without hard-coding knowledge 1211 * of specific filesystem implementations. 1212 */ 1213 if (ap->a_events & ~POLLSTANDARD) 1214 return (POLLNVAL); 1215 1216 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1217 } 1218 1219 /* 1220 * Implement poll for local filesystems that support it. 1221 */ 1222 int 1223 vop_stdpoll(struct vop_poll_args *ap) 1224 { 1225 if (ap->a_events & ~POLLSTANDARD) 1226 return (vn_pollrecord(ap->a_vp, ap->a_events)); 1227 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1228 } 1229 1230 /* 1231 * Implement standard getpages and putpages. All filesystems must use 1232 * the buffer cache to back regular files. 1233 */ 1234 int 1235 vop_stdgetpages(struct vop_getpages_args *ap) 1236 { 1237 struct mount *mp; 1238 int error; 1239 1240 if ((mp = ap->a_vp->v_mount) != NULL) { 1241 error = vnode_pager_generic_getpages( 1242 ap->a_vp, ap->a_m, ap->a_count, 1243 ap->a_reqpage); 1244 } else { 1245 error = VM_PAGER_BAD; 1246 } 1247 return (error); 1248 } 1249 1250 int 1251 vop_stdputpages(struct vop_putpages_args *ap) 1252 { 1253 struct mount *mp; 1254 int error; 1255 1256 if ((mp = ap->a_vp->v_mount) != NULL) { 1257 error = vnode_pager_generic_putpages( 1258 ap->a_vp, ap->a_m, ap->a_count, 1259 ap->a_sync, ap->a_rtvals); 1260 } else { 1261 error = VM_PAGER_BAD; 1262 } 1263 return (error); 1264 } 1265 1266 /* 1267 * vfs default ops 1268 * used to fill the vfs fucntion table to get reasonable default return values. 1269 */ 1270 int 1271 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred) 1272 { 1273 return (0); 1274 } 1275 1276 int 1277 vfs_stdunmount(struct mount *mp, int mntflags) 1278 { 1279 return (0); 1280 } 1281 1282 int 1283 vfs_stdroot(struct mount *mp, struct vnode **vpp) 1284 { 1285 return (EOPNOTSUPP); 1286 } 1287 1288 int 1289 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) 1290 { 1291 return (EOPNOTSUPP); 1292 } 1293 1294 int 1295 vfs_stdvptofh(struct vnode *vp, struct fid *fhp) 1296 { 1297 return (EOPNOTSUPP); 1298 } 1299 1300 int 1301 vfs_stdstart(struct mount *mp, int flags) 1302 { 1303 return (0); 1304 } 1305 1306 int 1307 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid, 1308 caddr_t arg, struct ucred *cred) 1309 { 1310 return (EOPNOTSUPP); 1311 } 1312 1313 int 1314 vfs_stdsync(struct mount *mp, int waitfor) 1315 { 1316 return (0); 1317 } 1318 1319 int 1320 vfs_stdnosync(struct mount *mp, int waitfor) 1321 { 1322 return (EOPNOTSUPP); 1323 } 1324 1325 int 1326 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp) 1327 { 1328 return (EOPNOTSUPP); 1329 } 1330 1331 int 1332 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1333 { 1334 return (EOPNOTSUPP); 1335 } 1336 1337 int 1338 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, 1339 struct ucred **credanonp) 1340 { 1341 return (EOPNOTSUPP); 1342 } 1343 1344 int 1345 vfs_stdinit(struct vfsconf *vfsp) 1346 { 1347 return (0); 1348 } 1349 1350 int 1351 vfs_stduninit(struct vfsconf *vfsp) 1352 { 1353 return(0); 1354 } 1355 1356 int 1357 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname, 1358 caddr_t arg, struct ucred *cred) 1359 { 1360 return(EOPNOTSUPP); 1361 } 1362 1363 /* end of vfs default ops */ 1364