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