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.43 2006/08/12 00:26:20 dillon Exp $ 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/buf.h> 46 #include <sys/conf.h> 47 #include <sys/fcntl.h> 48 #include <sys/file.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/malloc.h> 52 #include <sys/mount.h> 53 #include <sys/unistd.h> 54 #include <sys/vnode.h> 55 #include <sys/namei.h> 56 #include <sys/nlookup.h> 57 #include <sys/poll.h> 58 #include <sys/mountctl.h> 59 60 #include <machine/limits.h> 61 62 #include <vm/vm.h> 63 #include <vm/vm_object.h> 64 #include <vm/vm_page.h> 65 #include <vm/vm_pager.h> 66 #include <vm/vnode_pager.h> 67 68 static int vop_nolookup (struct vop_old_lookup_args *); 69 static int vop_nostrategy (struct vop_strategy_args *); 70 71 /* 72 * This vnode table stores what we want to do if the filesystem doesn't 73 * implement a particular VOP. 74 * 75 * If there is no specific entry here, we will return EOPNOTSUPP. 76 */ 77 struct vop_ops default_vnode_vops = { 78 .vop_default = vop_eopnotsupp, 79 .vop_advlock = (void *)vop_einval, 80 .vop_fsync = (void *)vop_null, 81 .vop_ioctl = (void *)vop_enotty, 82 .vop_mmap = (void *)vop_einval, 83 .vop_old_lookup = vop_nolookup, 84 .vop_open = vop_stdopen, 85 .vop_close = vop_stdclose, 86 .vop_pathconf = (void *)vop_einval, 87 .vop_poll = vop_nopoll, 88 .vop_readlink = (void *)vop_einval, 89 .vop_reallocblks = (void *)vop_eopnotsupp, 90 .vop_revoke = vop_stdrevoke, 91 .vop_strategy = vop_nostrategy, 92 .vop_getacl = (void *)vop_eopnotsupp, 93 .vop_setacl = (void *)vop_eopnotsupp, 94 .vop_aclcheck = (void *)vop_eopnotsupp, 95 .vop_getextattr = (void *)vop_eopnotsupp, 96 .vop_setextattr = (void *)vop_eopnotsupp, 97 .vop_nresolve = vop_compat_nresolve, 98 .vop_nlookupdotdot = vop_compat_nlookupdotdot, 99 .vop_ncreate = vop_compat_ncreate, 100 .vop_nmkdir = vop_compat_nmkdir, 101 .vop_nmknod = vop_compat_nmknod, 102 .vop_nlink = vop_compat_nlink, 103 .vop_nsymlink = vop_compat_nsymlink, 104 .vop_nwhiteout = vop_compat_nwhiteout, 105 .vop_nremove = vop_compat_nremove, 106 .vop_nrmdir = vop_compat_nrmdir, 107 .vop_nrename = vop_compat_nrename, 108 .vop_mountctl = journal_mountctl 109 }; 110 111 VNODEOP_SET(default_vnode_vops); 112 113 int 114 vop_eopnotsupp(struct vop_generic_args *ap) 115 { 116 return (EOPNOTSUPP); 117 } 118 119 int 120 vop_ebadf(struct vop_generic_args *ap) 121 { 122 return (EBADF); 123 } 124 125 int 126 vop_enotty(struct vop_generic_args *ap) 127 { 128 return (ENOTTY); 129 } 130 131 int 132 vop_einval(struct vop_generic_args *ap) 133 { 134 return (EINVAL); 135 } 136 137 int 138 vop_null(struct vop_generic_args *ap) 139 { 140 return (0); 141 } 142 143 int 144 vop_defaultop(struct vop_generic_args *ap) 145 { 146 return (VOCALL(&default_vnode_vops, ap)); 147 } 148 149 int 150 vop_panic(struct vop_generic_args *ap) 151 { 152 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name); 153 } 154 155 /* 156 * vop_compat_resolve { struct namecache *a_ncp } 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 namecache *ncp; 187 struct componentname cnp; 188 189 ncp = ap->a_ncp; /* locked namecache node */ 190 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 191 return(EPERM); 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 printf("[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(ncp, 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(ncp, 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 namecache *a_ncp, 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 namecache *ncp; 318 struct vnode *dvp; 319 int error; 320 321 /* 322 * Sanity checks, get a locked directory vnode. 323 */ 324 ncp = ap->a_ncp; /* locked namecache node */ 325 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 326 return(EPERM); 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 printf("[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(ncp); 368 cache_setvp(ncp, *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 namecache *a_ncp, 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 namecache *ncp; 400 struct vnode *dvp; 401 int error; 402 403 /* 404 * Sanity checks, get a locked directory vnode. 405 */ 406 ncp = ap->a_ncp; /* locked namecache node */ 407 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 408 return(EPERM); 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 printf("[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(ncp); 450 cache_setvp(ncp, *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 namecache *a_ncp, 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 namecache *ncp; 482 struct vnode *dvp; 483 int error; 484 485 /* 486 * Sanity checks, get a locked directory vnode. 487 */ 488 ncp = ap->a_ncp; /* locked namecache node */ 489 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 490 return(EPERM); 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 printf("[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(ncp); 532 cache_setvp(ncp, *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 namecache *a_ncp, 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 namecache *ncp; 562 struct vnode *dvp; 563 struct vnode *tvp; 564 int error; 565 566 /* 567 * Sanity checks, get a locked directory vnode. 568 */ 569 ncp = ap->a_ncp; /* locked namecache node */ 570 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 571 return(EPERM); 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 printf("[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(ncp); 613 cache_setvp(ncp, 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 namecache *ncp; 633 struct vnode *dvp; 634 struct vnode *vp; 635 int error; 636 637 /* 638 * Sanity checks, get a locked directory vnode. 639 */ 640 *ap->a_vpp = NULL; 641 ncp = ap->a_ncp; /* locked namecache node */ 642 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 643 return(EPERM); 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 printf("[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(ncp); 685 cache_setvp(ncp, 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 namecache *a_ncp, 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 namecache *ncp; 719 struct vnode *dvp; 720 struct vnode *vp; 721 int error; 722 723 /* 724 * Sanity checks, get a locked directory vnode. 725 */ 726 ncp = ap->a_ncp; /* locked namecache node */ 727 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 728 return(EPERM); 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 printf("[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(ncp); 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 namecache *a_ncp, 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 namecache *ncp; 808 struct vnode *dvp; 809 struct vnode *vp; 810 int error; 811 812 /* 813 * Sanity checks, get a locked directory vnode. 814 */ 815 ncp = ap->a_ncp; /* locked namecache node */ 816 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 817 return(EPERM); 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 printf("[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(ncp); 857 cache_setvp(ncp, NULL); 858 } 859 } 860 if (vp) { 861 if (dvp == vp) 862 vrele(vp); 863 else 864 vput(vp); 865 } 866 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 867 vn_unlock(dvp); 868 vrele(dvp); 869 return (error); 870 } 871 872 /* 873 * vop_compat_nrmdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION 874 * struct ucred *a_cred } 875 */ 876 int 877 vop_compat_nrmdir(struct vop_nrmdir_args *ap) 878 { 879 struct thread *td = curthread; 880 struct componentname cnp; 881 struct namecache *ncp; 882 struct vnode *dvp; 883 struct vnode *vp; 884 int error; 885 886 /* 887 * Sanity checks, get a locked directory vnode. 888 */ 889 ncp = ap->a_ncp; /* locked namecache node */ 890 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 891 return(EPERM); 892 if (ncp->nc_parent == NULL) 893 return(EPERM); 894 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 895 return(EPERM); 896 897 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { 898 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 899 ncp, ncp->nc_name); 900 return(EAGAIN); 901 } 902 903 /* 904 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 905 * caches all information required to delete the entry in the 906 * directory inode. We expect a return code of 0 for the DELETE 907 * case (meaning that a vp has been found). The cnp must simulated 908 * a saved-name situation. 909 */ 910 bzero(&cnp, sizeof(cnp)); 911 cnp.cn_nameiop = NAMEI_DELETE; 912 cnp.cn_flags = CNP_LOCKPARENT; 913 cnp.cn_nameptr = ncp->nc_name; 914 cnp.cn_namelen = ncp->nc_nlen; 915 cnp.cn_cred = ap->a_cred; 916 cnp.cn_td = td; 917 918 /* 919 * The vnode must be a directory and must not represent the 920 * current directory. 921 */ 922 vp = NULL; 923 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 924 if (error == 0 && vp->v_type != VDIR) 925 error = ENOTDIR; 926 if (error == 0 && vp == dvp) 927 error = EINVAL; 928 if (error == 0 && (vp->v_flag & VROOT)) 929 error = EBUSY; 930 if (error == 0) { 931 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 932 error = VOP_OLD_RMDIR(dvp, vp, &cnp); 933 934 /* 935 * Note that this invalidation will cause any process 936 * currently CD'd into the directory being removed to be 937 * disconnected from the topology and not be able to ".." 938 * back out. 939 */ 940 if (error == 0) 941 cache_inval(ncp, CINV_DESTROY); 942 } 943 if (vp) { 944 if (dvp == vp) 945 vrele(vp); 946 else 947 vput(vp); 948 } 949 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 950 vn_unlock(dvp); 951 vrele(dvp); 952 return (error); 953 } 954 955 /* 956 * vop_compat_nrename { struct namecache *a_fncp, XXX STOPGAP FUNCTION 957 * struct namecache *a_tncp, 958 * struct ucred *a_cred } 959 * 960 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that 961 * the source directory and vnode be unlocked and the target directory and 962 * vnode (if it exists) be locked. All arguments will be vrele'd and 963 * the targets will also be unlocked regardless of the return code. 964 */ 965 int 966 vop_compat_nrename(struct vop_nrename_args *ap) 967 { 968 struct thread *td = curthread; 969 struct componentname fcnp; 970 struct componentname tcnp; 971 struct namecache *fncp; 972 struct namecache *tncp; 973 struct vnode *fdvp, *fvp; 974 struct vnode *tdvp, *tvp; 975 int error; 976 977 /* 978 * Sanity checks, get referenced vnodes representing the source. 979 */ 980 fncp = ap->a_fncp; /* locked namecache node */ 981 if (fncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 982 return(EPERM); 983 if (fncp->nc_parent == NULL) 984 return(EPERM); 985 if ((fdvp = fncp->nc_parent->nc_vp) == NULL) 986 return(EPERM); 987 988 /* 989 * Temporarily lock the source directory and lookup in DELETE mode to 990 * check permissions. XXX delete permissions should have been 991 * checked by nlookup(), we need to add NLC_DELETE for delete 992 * checking. It is unclear whether VFS's require the directory setup 993 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but 994 * since it isn't locked and since UFS always does a relookup of 995 * the source, it is believed that the only side effect that matters 996 * is the permissions check. 997 */ 998 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) { 999 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 1000 fncp, fncp->nc_name); 1001 return(EAGAIN); 1002 } 1003 1004 bzero(&fcnp, sizeof(fcnp)); 1005 fcnp.cn_nameiop = NAMEI_DELETE; 1006 fcnp.cn_flags = CNP_LOCKPARENT; 1007 fcnp.cn_nameptr = fncp->nc_name; 1008 fcnp.cn_namelen = fncp->nc_nlen; 1009 fcnp.cn_cred = ap->a_cred; 1010 fcnp.cn_td = td; 1011 1012 /* 1013 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked 1014 * fvp. 1015 */ 1016 fvp = NULL; 1017 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp); 1018 if (error == 0 && (fvp->v_flag & VROOT)) { 1019 vput(fvp); /* as if vop_old_lookup had failed */ 1020 error = EBUSY; 1021 } 1022 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) { 1023 fcnp.cn_flags |= CNP_PDIRUNLOCK; 1024 vn_unlock(fdvp); 1025 } 1026 if (error) { 1027 vrele(fdvp); 1028 return (error); 1029 } 1030 vn_unlock(fvp); 1031 1032 /* 1033 * fdvp and fvp are now referenced and unlocked. 1034 * 1035 * Get a locked directory vnode for the target and lookup the target 1036 * in CREATE mode so it places the required information in the 1037 * directory inode. 1038 */ 1039 tncp = ap->a_tncp; /* locked namecache node */ 1040 if (tncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 1041 error = EPERM; 1042 if (tncp->nc_parent == NULL) 1043 error = EPERM; 1044 if ((tdvp = tncp->nc_parent->nc_vp) == NULL) 1045 error = EPERM; 1046 if (error) { 1047 vrele(fdvp); 1048 vrele(fvp); 1049 return (error); 1050 } 1051 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) { 1052 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 1053 tncp, tncp->nc_name); 1054 vrele(fdvp); 1055 vrele(fvp); 1056 return(EAGAIN); 1057 } 1058 1059 /* 1060 * Setup the cnp for a traditional vop_old_lookup() call. The lookup 1061 * caches all information required to create the entry in the 1062 * target directory inode. 1063 */ 1064 bzero(&tcnp, sizeof(tcnp)); 1065 tcnp.cn_nameiop = NAMEI_RENAME; 1066 tcnp.cn_flags = CNP_LOCKPARENT; 1067 tcnp.cn_nameptr = tncp->nc_name; 1068 tcnp.cn_namelen = tncp->nc_nlen; 1069 tcnp.cn_cred = ap->a_cred; 1070 tcnp.cn_td = td; 1071 1072 tvp = NULL; 1073 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp); 1074 1075 if (error == EJUSTRETURN) { 1076 /* 1077 * Target does not exist. tvp should be NULL. 1078 */ 1079 KKASSERT(tvp == NULL); 1080 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1081 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1082 if (error == 0) { 1083 cache_rename(fncp, tncp); 1084 cache_setvp(tncp, fvp); 1085 } 1086 } else if (error == 0) { 1087 /* 1088 * Target exists. VOP_OLD_RENAME should correctly delete the 1089 * target. 1090 */ 1091 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1092 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1093 if (error == 0) { 1094 cache_rename(fncp, tncp); 1095 cache_setvp(tncp, fvp); 1096 } 1097 } else { 1098 vrele(fdvp); 1099 vrele(fvp); 1100 if (tcnp.cn_flags & CNP_PDIRUNLOCK) 1101 vrele(tdvp); 1102 else 1103 vput(tdvp); 1104 } 1105 return (error); 1106 } 1107 1108 static int 1109 vop_nolookup(ap) 1110 struct vop_old_lookup_args /* { 1111 struct vnode *a_dvp; 1112 struct vnode **a_vpp; 1113 struct componentname *a_cnp; 1114 } */ *ap; 1115 { 1116 1117 *ap->a_vpp = NULL; 1118 return (ENOTDIR); 1119 } 1120 1121 /* 1122 * vop_nostrategy: 1123 * 1124 * Strategy routine for VFS devices that have none. 1125 * 1126 * B_ERROR and B_INVAL must be cleared prior to calling any strategy 1127 * routine. Typically this is done for a BUF_CMD_READ strategy call. 1128 * Typically B_INVAL is assumed to already be clear prior to a write 1129 * and should not be cleared manually unless you just made the buffer 1130 * invalid. B_ERROR should be cleared either way. 1131 */ 1132 1133 static int 1134 vop_nostrategy (struct vop_strategy_args *ap) 1135 { 1136 printf("No strategy for buffer at %p\n", ap->a_bio->bio_buf); 1137 vprint("", ap->a_vp); 1138 ap->a_bio->bio_buf->b_flags |= B_ERROR; 1139 ap->a_bio->bio_buf->b_error = EOPNOTSUPP; 1140 biodone(ap->a_bio); 1141 return (EOPNOTSUPP); 1142 } 1143 1144 int 1145 vop_stdpathconf(ap) 1146 struct vop_pathconf_args /* { 1147 struct vnode *a_vp; 1148 int a_name; 1149 int *a_retval; 1150 } */ *ap; 1151 { 1152 1153 switch (ap->a_name) { 1154 case _PC_LINK_MAX: 1155 *ap->a_retval = LINK_MAX; 1156 return (0); 1157 case _PC_MAX_CANON: 1158 *ap->a_retval = MAX_CANON; 1159 return (0); 1160 case _PC_MAX_INPUT: 1161 *ap->a_retval = MAX_INPUT; 1162 return (0); 1163 case _PC_PIPE_BUF: 1164 *ap->a_retval = PIPE_BUF; 1165 return (0); 1166 case _PC_CHOWN_RESTRICTED: 1167 *ap->a_retval = 1; 1168 return (0); 1169 case _PC_VDISABLE: 1170 *ap->a_retval = _POSIX_VDISABLE; 1171 return (0); 1172 default: 1173 return (EINVAL); 1174 } 1175 /* NOTREACHED */ 1176 } 1177 1178 /* 1179 * Standard open. 1180 * 1181 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp, 1182 * struct thread *a_td) 1183 * 1184 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE 1185 */ 1186 int 1187 vop_stdopen(struct vop_open_args *ap) 1188 { 1189 struct vnode *vp = ap->a_vp; 1190 struct file *fp; 1191 1192 if ((fp = ap->a_fp) != NULL) { 1193 switch(vp->v_type) { 1194 case VFIFO: 1195 fp->f_type = DTYPE_FIFO; 1196 break; 1197 default: 1198 fp->f_type = DTYPE_VNODE; 1199 break; 1200 } 1201 fp->f_flag = ap->a_mode & FMASK; 1202 fp->f_ops = &vnode_fileops; 1203 fp->f_data = vp; 1204 vref(vp); 1205 } 1206 if (ap->a_mode & FWRITE) 1207 ++vp->v_writecount; 1208 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX); 1209 ++vp->v_opencount; 1210 return (0); 1211 } 1212 1213 /* 1214 * Standard close. 1215 * 1216 * (struct vnode *a_vp, int a_fflag, struct thread *a_td) 1217 * 1218 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen? 1219 */ 1220 int 1221 vop_stdclose(struct vop_close_args *ap) 1222 { 1223 struct vnode *vp = ap->a_vp; 1224 1225 KASSERT(vp->v_opencount > 0, 1226 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d\n", vp, vp->v_opencount)); 1227 if (ap->a_fflag & FWRITE) { 1228 KASSERT(vp->v_writecount > 0, 1229 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n", 1230 vp, vp->v_writecount)); 1231 --vp->v_writecount; 1232 } 1233 --vp->v_opencount; 1234 return (0); 1235 } 1236 1237 /* 1238 * Return true for select/poll. 1239 */ 1240 int 1241 vop_nopoll(ap) 1242 struct vop_poll_args /* { 1243 struct vnode *a_vp; 1244 int a_events; 1245 struct ucred *a_cred; 1246 struct proc *a_p; 1247 } */ *ap; 1248 { 1249 /* 1250 * Return true for read/write. If the user asked for something 1251 * special, return POLLNVAL, so that clients have a way of 1252 * determining reliably whether or not the extended 1253 * functionality is present without hard-coding knowledge 1254 * of specific filesystem implementations. 1255 */ 1256 if (ap->a_events & ~POLLSTANDARD) 1257 return (POLLNVAL); 1258 1259 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1260 } 1261 1262 /* 1263 * Implement poll for local filesystems that support it. 1264 */ 1265 int 1266 vop_stdpoll(ap) 1267 struct vop_poll_args /* { 1268 struct vnode *a_vp; 1269 int a_events; 1270 struct ucred *a_cred; 1271 } */ *ap; 1272 { 1273 if (ap->a_events & ~POLLSTANDARD) 1274 return (vn_pollrecord(ap->a_vp, ap->a_events)); 1275 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 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 int 1307 vfs_stdvptofh(struct vnode *vp, struct fid *fhp) 1308 { 1309 return (EOPNOTSUPP); 1310 } 1311 1312 int 1313 vfs_stdstart(struct mount *mp, int flags) 1314 { 1315 return (0); 1316 } 1317 1318 int 1319 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid, 1320 caddr_t arg, struct ucred *cred) 1321 { 1322 return (EOPNOTSUPP); 1323 } 1324 1325 int 1326 vfs_stdsync(struct mount *mp, int waitfor) 1327 { 1328 return (0); 1329 } 1330 1331 int 1332 vfs_stdnosync(struct mount *mp, int waitfor) 1333 { 1334 return (EOPNOTSUPP); 1335 } 1336 1337 int 1338 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp) 1339 { 1340 return (EOPNOTSUPP); 1341 } 1342 1343 int 1344 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1345 { 1346 return (EOPNOTSUPP); 1347 } 1348 1349 int 1350 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, 1351 struct ucred **credanonp) 1352 { 1353 return (EOPNOTSUPP); 1354 } 1355 1356 int 1357 vfs_stdinit(struct vfsconf *vfsp) 1358 { 1359 return (0); 1360 } 1361 1362 int 1363 vfs_stduninit(struct vfsconf *vfsp) 1364 { 1365 return(0); 1366 } 1367 1368 int 1369 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname, 1370 caddr_t arg, struct ucred *cred) 1371 { 1372 return(EOPNOTSUPP); 1373 } 1374 1375 /* end of vfs default ops */ 1376