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