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