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.26 2005/07/26 15:43:35 hmp 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/kernel.h> 48 #include <sys/lock.h> 49 #include <sys/malloc.h> 50 #include <sys/mount.h> 51 #include <sys/unistd.h> 52 #include <sys/vnode.h> 53 #include <sys/namei.h> 54 #include <sys/nlookup.h> 55 #include <sys/poll.h> 56 #include <sys/mountctl.h> 57 58 #include <machine/limits.h> 59 60 #include <vm/vm.h> 61 #include <vm/vm_object.h> 62 #include <vm/vm_page.h> 63 #include <vm/vm_pager.h> 64 #include <vm/vnode_pager.h> 65 66 static int vop_nolookup (struct vop_lookup_args *); 67 static int vop_nostrategy (struct vop_strategy_args *); 68 69 /* 70 * This vnode table stores what we want to do if the filesystem doesn't 71 * implement a particular VOP. 72 * 73 * If there is no specific entry here, we will return EOPNOTSUPP. 74 */ 75 struct vop_ops *default_vnode_vops; 76 static struct vnodeopv_entry_desc default_vnodeop_entries[] = { 77 { &vop_default_desc, vop_eopnotsupp }, 78 { &vop_advlock_desc, vop_einval }, 79 { &vop_bwrite_desc, (void *) vop_stdbwrite }, 80 { &vop_close_desc, vop_null }, 81 { &vop_createvobject_desc, (void *) vop_stdcreatevobject }, 82 { &vop_destroyvobject_desc, (void *) vop_stddestroyvobject }, 83 { &vop_fsync_desc, vop_null }, 84 { &vop_getvobject_desc, (void *) vop_stdgetvobject }, 85 { &vop_ioctl_desc, vop_enotty }, 86 { &vop_islocked_desc, (void *) vop_stdislocked }, 87 { &vop_lease_desc, vop_null }, 88 { &vop_lock_desc, (void *) vop_stdlock }, 89 { &vop_mmap_desc, vop_einval }, 90 { &vop_lookup_desc, (void *) vop_nolookup }, 91 { &vop_open_desc, vop_null }, 92 { &vop_pathconf_desc, vop_einval }, 93 { &vop_poll_desc, (void *) vop_nopoll }, 94 { &vop_readlink_desc, vop_einval }, 95 { &vop_reallocblks_desc, vop_eopnotsupp }, 96 { &vop_revoke_desc, (void *) vop_stdrevoke }, 97 { &vop_strategy_desc, (void *) vop_nostrategy }, 98 { &vop_unlock_desc, (void *) vop_stdunlock }, 99 { &vop_getacl_desc, vop_eopnotsupp }, 100 { &vop_setacl_desc, vop_eopnotsupp }, 101 { &vop_aclcheck_desc, vop_eopnotsupp }, 102 { &vop_getextattr_desc, vop_eopnotsupp }, 103 { &vop_setextattr_desc, vop_eopnotsupp }, 104 { &vop_nresolve_desc, (void *) vop_compat_nresolve }, 105 { &vop_nlookupdotdot_desc, (void *) vop_compat_nlookupdotdot }, 106 { &vop_ncreate_desc, (void *) vop_compat_ncreate }, 107 { &vop_nmkdir_desc, (void *) vop_compat_nmkdir }, 108 { &vop_nmknod_desc, (void *) vop_compat_nmknod }, 109 { &vop_nlink_desc, (void *) vop_compat_nlink }, 110 { &vop_nsymlink_desc, (void *) vop_compat_nsymlink }, 111 { &vop_nwhiteout_desc, (void *) vop_compat_nwhiteout }, 112 { &vop_nremove_desc, (void *) vop_compat_nremove }, 113 { &vop_nrmdir_desc, (void *) vop_compat_nrmdir }, 114 { &vop_nrename_desc, (void *) vop_compat_nrename }, 115 { &vop_mountctl_desc, (void *) journal_mountctl }, 116 { NULL, NULL } 117 }; 118 119 static struct vnodeopv_desc default_vnodeop_opv_desc = 120 { &default_vnode_vops, default_vnodeop_entries }; 121 122 VNODEOP_SET(default_vnodeop_opv_desc); 123 124 int 125 vop_eopnotsupp(struct vop_generic_args *ap) 126 { 127 return (EOPNOTSUPP); 128 } 129 130 int 131 vop_ebadf(struct vop_generic_args *ap) 132 { 133 return (EBADF); 134 } 135 136 int 137 vop_enotty(struct vop_generic_args *ap) 138 { 139 return (ENOTTY); 140 } 141 142 int 143 vop_einval(struct vop_generic_args *ap) 144 { 145 return (EINVAL); 146 } 147 148 int 149 vop_null(struct vop_generic_args *ap) 150 { 151 return (0); 152 } 153 154 int 155 vop_defaultop(struct vop_generic_args *ap) 156 { 157 return (VOCALL(default_vnode_vops, ap)); 158 } 159 160 int 161 vop_panic(struct vop_generic_args *ap) 162 { 163 164 panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 165 } 166 167 /* 168 * vop_compat_resolve { struct namecache *a_ncp } XXX STOPGAP FUNCTION 169 * 170 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE 171 * WILL BE REMOVED. This procedure exists for all VFSs which have not 172 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a 173 * vop_lookup() and does appropriate translations. 174 * 175 * Resolve a ncp for VFSs which do not support the VOP. Eventually all 176 * VFSs will support this VOP and this routine can be removed, since 177 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP 178 * API. 179 * 180 * A locked ncp is passed in to be resolved. The NCP is resolved by 181 * figuring out the vnode (if any) and calling cache_setvp() to attach the 182 * vnode to the entry. If the entry represents a non-existant node then 183 * cache_setvp() is called with a NULL vnode to resolve the entry into a 184 * negative cache entry. No vnode locks are retained and the 185 * ncp is left locked on return. 186 * 187 * The ncp will NEVER represent "", "." or "..", or contain any slashes. 188 * 189 * There is a potential directory and vnode interlock. The lock order 190 * requirement is: namecache, governing directory, resolved vnode. 191 */ 192 int 193 vop_compat_nresolve(struct vop_nresolve_args *ap) 194 { 195 int error; 196 struct vnode *dvp; 197 struct vnode *vp; 198 struct namecache *ncp; 199 struct componentname cnp; 200 201 ncp = ap->a_ncp; /* locked namecache node */ 202 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 203 return(EPERM); 204 if (ncp->nc_parent == NULL) 205 return(EPERM); 206 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 207 return(EPERM); 208 209 /* 210 * UFS currently stores all sorts of side effects, including a loop 211 * variable, in the directory inode. That needs to be fixed and the 212 * other VFS's audited before we can switch to LK_SHARED. 213 */ 214 if ((error = vget(dvp, LK_EXCLUSIVE, curthread)) != 0) { 215 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 216 ncp, ncp->nc_name); 217 return(EAGAIN); 218 } 219 220 bzero(&cnp, sizeof(cnp)); 221 cnp.cn_nameiop = NAMEI_LOOKUP; 222 cnp.cn_flags = 0; 223 cnp.cn_nameptr = ncp->nc_name; 224 cnp.cn_namelen = ncp->nc_nlen; 225 cnp.cn_cred = ap->a_cred; 226 cnp.cn_td = curthread; /* XXX */ 227 228 /* 229 * vop_lookup() always returns vp locked. dvp may or may not be 230 * left locked depending on CNP_PDIRUNLOCK. 231 */ 232 error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 233 if (error == 0) 234 VOP_UNLOCK(vp, 0, curthread); 235 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 236 VOP_UNLOCK(dvp, 0, curthread); 237 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) { 238 /* was resolved by another process while we were unlocked */ 239 if (error == 0) 240 vrele(vp); 241 } else if (error == 0) { 242 KKASSERT(vp != NULL); 243 cache_setvp(ncp, vp); 244 vrele(vp); 245 } else if (error == ENOENT) { 246 KKASSERT(vp == NULL); 247 if (cnp.cn_flags & CNP_ISWHITEOUT) 248 ncp->nc_flag |= NCF_WHITEOUT; 249 cache_setvp(ncp, NULL); 250 } 251 vrele(dvp); 252 return (error); 253 } 254 255 /* 256 * vop_compat_nlookupdotdot { struct vnode *a_dvp, 257 * struct vnode **a_vpp, 258 * struct ucred *a_cred } 259 * 260 * Lookup the vnode representing the parent directory of the specified 261 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp 262 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL. 263 * 264 * This function is designed to aid NFS server-side operations and is 265 * used by cache_fromdvp() to create a consistent, connected namecache 266 * topology. 267 * 268 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT 269 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time 270 * permits VFSs will implement the remaining *_n*() calls and finally get 271 * rid of their *_lookup() call. 272 */ 273 int 274 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap) 275 { 276 struct componentname cnp; 277 int error; 278 279 /* 280 * UFS currently stores all sorts of side effects, including a loop 281 * variable, in the directory inode. That needs to be fixed and the 282 * other VFS's audited before we can switch to LK_SHARED. 283 */ 284 *ap->a_vpp = NULL; 285 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE, curthread)) != 0) 286 return (error); 287 if (ap->a_dvp->v_type != VDIR) { 288 vput(ap->a_dvp); 289 return (ENOTDIR); 290 } 291 292 bzero(&cnp, sizeof(cnp)); 293 cnp.cn_nameiop = NAMEI_LOOKUP; 294 cnp.cn_flags = CNP_ISDOTDOT; 295 cnp.cn_nameptr = ".."; 296 cnp.cn_namelen = 2; 297 cnp.cn_cred = ap->a_cred; 298 cnp.cn_td = curthread; /* XXX */ 299 300 /* 301 * vop_lookup() always returns vp locked. dvp may or may not be 302 * left locked depending on CNP_PDIRUNLOCK. 303 */ 304 error = vop_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp); 305 if (error == 0) 306 VOP_UNLOCK(*ap->a_vpp, 0, curthread); 307 if (cnp.cn_flags & CNP_PDIRUNLOCK) 308 vrele(ap->a_dvp); 309 else 310 vput(ap->a_dvp); 311 return (error); 312 } 313 314 /* 315 * vop_compat_ncreate { struct namecache *a_ncp, XXX STOPGAP FUNCTION 316 * struct vnode *a_vpp, 317 * struct ucred *a_cred, 318 * struct vattr *a_vap } 319 * 320 * Create a file as specified by a_vap. Compatibility requires us to issue 321 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order 322 * to setup the directory inode's i_offset and i_count (e.g. in UFS). 323 */ 324 int 325 vop_compat_ncreate(struct vop_ncreate_args *ap) 326 { 327 struct thread *td = curthread; 328 struct componentname cnp; 329 struct namecache *ncp; 330 struct vnode *dvp; 331 int error; 332 333 /* 334 * Sanity checks, get a locked directory vnode. 335 */ 336 ncp = ap->a_ncp; /* locked namecache node */ 337 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 338 return(EPERM); 339 if (ncp->nc_parent == NULL) 340 return(EPERM); 341 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 342 return(EPERM); 343 344 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 345 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 346 ncp, ncp->nc_name); 347 return(EAGAIN); 348 } 349 350 /* 351 * Setup the cnp for a traditional vop_lookup() call. The lookup 352 * caches all information required to create the entry in the 353 * directory inode. We expect a return code of EJUSTRETURN for 354 * the CREATE case. The cnp must simulated a saved-name situation. 355 */ 356 bzero(&cnp, sizeof(cnp)); 357 cnp.cn_nameiop = NAMEI_CREATE; 358 cnp.cn_flags = CNP_LOCKPARENT; 359 cnp.cn_nameptr = ncp->nc_name; 360 cnp.cn_namelen = ncp->nc_nlen; 361 cnp.cn_cred = ap->a_cred; 362 cnp.cn_td = td; 363 *ap->a_vpp = NULL; 364 365 error = vop_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 366 367 /* 368 * EJUSTRETURN should be returned for this case, which means that 369 * the VFS has setup the directory inode for the create. The dvp we 370 * passed in is expected to remain in a locked state. 371 * 372 * If the VOP_OLD_CREATE is successful we are responsible for updating 373 * the cache state of the locked ncp that was passed to us. 374 */ 375 if (error == EJUSTRETURN) { 376 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 377 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 378 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap); 379 if (error == 0) { 380 cache_setunresolved(ncp); 381 cache_setvp(ncp, *ap->a_vpp); 382 } 383 } else { 384 if (error == 0) { 385 vput(*ap->a_vpp); 386 *ap->a_vpp = NULL; 387 error = EEXIST; 388 } 389 KKASSERT(*ap->a_vpp == NULL); 390 } 391 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 392 VOP_UNLOCK(dvp, 0, td); 393 vrele(dvp); 394 return (error); 395 } 396 397 /* 398 * vop_compat_nmkdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION 399 * struct vnode *a_vpp, 400 * struct ucred *a_cred, 401 * struct vattr *a_vap } 402 * 403 * Create a directory as specified by a_vap. Compatibility requires us to 404 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in 405 * order to setup the directory inode's i_offset and i_count (e.g. in UFS). 406 */ 407 int 408 vop_compat_nmkdir(struct vop_nmkdir_args *ap) 409 { 410 struct thread *td = curthread; 411 struct componentname cnp; 412 struct namecache *ncp; 413 struct vnode *dvp; 414 int error; 415 416 /* 417 * Sanity checks, get a locked directory vnode. 418 */ 419 ncp = ap->a_ncp; /* locked namecache node */ 420 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 421 return(EPERM); 422 if (ncp->nc_parent == NULL) 423 return(EPERM); 424 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 425 return(EPERM); 426 427 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 428 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 429 ncp, ncp->nc_name); 430 return(EAGAIN); 431 } 432 433 /* 434 * Setup the cnp for a traditional vop_lookup() call. The lookup 435 * caches all information required to create the entry in the 436 * directory inode. We expect a return code of EJUSTRETURN for 437 * the CREATE case. The cnp must simulated a saved-name situation. 438 */ 439 bzero(&cnp, sizeof(cnp)); 440 cnp.cn_nameiop = NAMEI_CREATE; 441 cnp.cn_flags = CNP_LOCKPARENT; 442 cnp.cn_nameptr = ncp->nc_name; 443 cnp.cn_namelen = ncp->nc_nlen; 444 cnp.cn_cred = ap->a_cred; 445 cnp.cn_td = td; 446 *ap->a_vpp = NULL; 447 448 error = vop_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 449 450 /* 451 * EJUSTRETURN should be returned for this case, which means that 452 * the VFS has setup the directory inode for the create. The dvp we 453 * passed in is expected to remain in a locked state. 454 * 455 * If the VOP_OLD_MKDIR is successful we are responsible for updating 456 * the cache state of the locked ncp that was passed to us. 457 */ 458 if (error == EJUSTRETURN) { 459 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 460 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 461 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap); 462 if (error == 0) { 463 cache_setunresolved(ncp); 464 cache_setvp(ncp, *ap->a_vpp); 465 } 466 } else { 467 if (error == 0) { 468 vput(*ap->a_vpp); 469 *ap->a_vpp = NULL; 470 error = EEXIST; 471 } 472 KKASSERT(*ap->a_vpp == NULL); 473 } 474 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 475 VOP_UNLOCK(dvp, 0, td); 476 vrele(dvp); 477 return (error); 478 } 479 480 /* 481 * vop_compat_nmknod { struct namecache *a_ncp, XXX STOPGAP FUNCTION 482 * struct vnode *a_vpp, 483 * struct ucred *a_cred, 484 * struct vattr *a_vap } 485 * 486 * Create a device or fifo node as specified by a_vap. Compatibility requires 487 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD 488 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS). 489 */ 490 int 491 vop_compat_nmknod(struct vop_nmknod_args *ap) 492 { 493 struct thread *td = curthread; 494 struct componentname cnp; 495 struct namecache *ncp; 496 struct vnode *dvp; 497 int error; 498 499 /* 500 * Sanity checks, get a locked directory vnode. 501 */ 502 ncp = ap->a_ncp; /* locked namecache node */ 503 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 504 return(EPERM); 505 if (ncp->nc_parent == NULL) 506 return(EPERM); 507 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 508 return(EPERM); 509 510 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 511 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 512 ncp, ncp->nc_name); 513 return(EAGAIN); 514 } 515 516 /* 517 * Setup the cnp for a traditional vop_lookup() call. The lookup 518 * caches all information required to create the entry in the 519 * directory inode. We expect a return code of EJUSTRETURN for 520 * the CREATE case. The cnp must simulated a saved-name situation. 521 */ 522 bzero(&cnp, sizeof(cnp)); 523 cnp.cn_nameiop = NAMEI_CREATE; 524 cnp.cn_flags = CNP_LOCKPARENT; 525 cnp.cn_nameptr = ncp->nc_name; 526 cnp.cn_namelen = ncp->nc_nlen; 527 cnp.cn_cred = ap->a_cred; 528 cnp.cn_td = td; 529 *ap->a_vpp = NULL; 530 531 error = vop_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp); 532 533 /* 534 * EJUSTRETURN should be returned for this case, which means that 535 * the VFS has setup the directory inode for the create. The dvp we 536 * passed in is expected to remain in a locked state. 537 * 538 * If the VOP_OLD_MKNOD is successful we are responsible for updating 539 * the cache state of the locked ncp that was passed to us. 540 */ 541 if (error == EJUSTRETURN) { 542 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 543 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 544 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap); 545 if (error == 0) { 546 cache_setunresolved(ncp); 547 cache_setvp(ncp, *ap->a_vpp); 548 } 549 } else { 550 if (error == 0) { 551 vput(*ap->a_vpp); 552 *ap->a_vpp = NULL; 553 error = EEXIST; 554 } 555 KKASSERT(*ap->a_vpp == NULL); 556 } 557 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 558 VOP_UNLOCK(dvp, 0, td); 559 vrele(dvp); 560 return (error); 561 } 562 563 /* 564 * vop_compat_nlink { struct namecache *a_ncp, XXX STOPGAP FUNCTION 565 * struct vnode *a_vp, 566 * struct ucred *a_cred } 567 * 568 * The passed vp is locked and represents the source. The passed ncp is 569 * locked and represents the target to create. 570 */ 571 int 572 vop_compat_nlink(struct vop_nlink_args *ap) 573 { 574 struct thread *td = curthread; 575 struct componentname cnp; 576 struct namecache *ncp; 577 struct vnode *dvp; 578 struct vnode *tvp; 579 int error; 580 581 /* 582 * Sanity checks, get a locked directory vnode. 583 */ 584 ncp = ap->a_ncp; /* locked namecache node */ 585 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 586 return(EPERM); 587 if (ncp->nc_parent == NULL) 588 return(EPERM); 589 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 590 return(EPERM); 591 592 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 593 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 594 ncp, ncp->nc_name); 595 return(EAGAIN); 596 } 597 598 /* 599 * Setup the cnp for a traditional vop_lookup() call. The lookup 600 * caches all information required to create the entry in the 601 * directory inode. We expect a return code of EJUSTRETURN for 602 * the CREATE case. The cnp must simulated a saved-name situation. 603 */ 604 bzero(&cnp, sizeof(cnp)); 605 cnp.cn_nameiop = NAMEI_CREATE; 606 cnp.cn_flags = CNP_LOCKPARENT; 607 cnp.cn_nameptr = ncp->nc_name; 608 cnp.cn_namelen = ncp->nc_nlen; 609 cnp.cn_cred = ap->a_cred; 610 cnp.cn_td = td; 611 612 tvp = NULL; 613 error = vop_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp); 614 615 /* 616 * EJUSTRETURN should be returned for this case, which means that 617 * the VFS has setup the directory inode for the create. The dvp we 618 * passed in is expected to remain in a locked state. 619 * 620 * If the VOP_OLD_LINK is successful we are responsible for updating 621 * the cache state of the locked ncp that was passed to us. 622 */ 623 if (error == EJUSTRETURN) { 624 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 625 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 626 VOP_LEASE(ap->a_vp, td, ap->a_cred, LEASE_WRITE); 627 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp); 628 if (error == 0) { 629 cache_setunresolved(ncp); 630 cache_setvp(ncp, ap->a_vp); 631 } 632 } else { 633 if (error == 0) { 634 vput(tvp); 635 error = EEXIST; 636 } 637 } 638 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 639 VOP_UNLOCK(dvp, 0, td); 640 vrele(dvp); 641 return (error); 642 } 643 644 int 645 vop_compat_nsymlink(struct vop_nsymlink_args *ap) 646 { 647 struct thread *td = curthread; 648 struct componentname cnp; 649 struct namecache *ncp; 650 struct vnode *dvp; 651 struct vnode *vp; 652 int error; 653 654 /* 655 * Sanity checks, get a locked directory vnode. 656 */ 657 *ap->a_vpp = NULL; 658 ncp = ap->a_ncp; /* locked namecache node */ 659 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 660 return(EPERM); 661 if (ncp->nc_parent == NULL) 662 return(EPERM); 663 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 664 return(EPERM); 665 666 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 667 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 668 ncp, ncp->nc_name); 669 return(EAGAIN); 670 } 671 672 /* 673 * Setup the cnp for a traditional vop_lookup() call. The lookup 674 * caches all information required to create the entry in the 675 * directory inode. We expect a return code of EJUSTRETURN for 676 * the CREATE case. The cnp must simulated a saved-name situation. 677 */ 678 bzero(&cnp, sizeof(cnp)); 679 cnp.cn_nameiop = NAMEI_CREATE; 680 cnp.cn_flags = CNP_LOCKPARENT; 681 cnp.cn_nameptr = ncp->nc_name; 682 cnp.cn_namelen = ncp->nc_nlen; 683 cnp.cn_cred = ap->a_cred; 684 cnp.cn_td = td; 685 686 vp = NULL; 687 error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 688 689 /* 690 * EJUSTRETURN should be returned for this case, which means that 691 * the VFS has setup the directory inode for the create. The dvp we 692 * passed in is expected to remain in a locked state. 693 * 694 * If the VOP_OLD_SYMLINK is successful we are responsible for updating 695 * the cache state of the locked ncp that was passed to us. 696 */ 697 if (error == EJUSTRETURN) { 698 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 699 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 700 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target); 701 if (error == 0) { 702 cache_setunresolved(ncp); 703 cache_setvp(ncp, vp); 704 *ap->a_vpp = vp; 705 } 706 } else { 707 if (error == 0) { 708 vput(vp); 709 vp = NULL; 710 error = EEXIST; 711 } 712 KKASSERT(vp == NULL); 713 } 714 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 715 VOP_UNLOCK(dvp, 0, td); 716 vrele(dvp); 717 return (error); 718 } 719 720 /* 721 * vop_compat_nwhiteout { struct namecache *a_ncp, XXX STOPGAP FUNCTION 722 * struct ucred *a_cred, 723 * int a_flags } 724 * 725 * Issie a whiteout operation (create, lookup, or delete). Compatibility 726 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue 727 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count 728 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP 729 * no lookup is necessary. 730 */ 731 int 732 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap) 733 { 734 struct thread *td = curthread; 735 struct componentname cnp; 736 struct namecache *ncp; 737 struct vnode *dvp; 738 struct vnode *vp; 739 int error; 740 741 /* 742 * Sanity checks, get a locked directory vnode. 743 */ 744 ncp = ap->a_ncp; /* locked namecache node */ 745 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 746 return(EPERM); 747 if (ncp->nc_parent == NULL) 748 return(EPERM); 749 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 750 return(EPERM); 751 752 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 753 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 754 ncp, ncp->nc_name); 755 return(EAGAIN); 756 } 757 758 /* 759 * Setup the cnp for a traditional vop_lookup() call. The lookup 760 * caches all information required to create the entry in the 761 * directory inode. We expect a return code of EJUSTRETURN for 762 * the CREATE case. The cnp must simulated a saved-name situation. 763 */ 764 bzero(&cnp, sizeof(cnp)); 765 cnp.cn_nameiop = ap->a_flags; 766 cnp.cn_flags = CNP_LOCKPARENT; 767 cnp.cn_nameptr = ncp->nc_name; 768 cnp.cn_namelen = ncp->nc_nlen; 769 cnp.cn_cred = ap->a_cred; 770 cnp.cn_td = td; 771 772 vp = NULL; 773 774 /* 775 * EJUSTRETURN should be returned for the CREATE or DELETE cases. 776 * The VFS has setup the directory inode for the create. The dvp we 777 * passed in is expected to remain in a locked state. 778 * 779 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating 780 * the cache state of the locked ncp that was passed to us. 781 */ 782 switch(ap->a_flags) { 783 case NAMEI_DELETE: 784 cnp.cn_flags |= CNP_DOWHITEOUT; 785 /* fall through */ 786 case NAMEI_CREATE: 787 error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 788 if (error == EJUSTRETURN) { 789 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 790 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 791 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags); 792 if (error == 0) 793 cache_setunresolved(ncp); 794 } else { 795 if (error == 0) { 796 vput(vp); 797 vp = NULL; 798 error = EEXIST; 799 } 800 KKASSERT(vp == NULL); 801 } 802 break; 803 case NAMEI_LOOKUP: 804 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags); 805 break; 806 default: 807 error = EINVAL; 808 break; 809 } 810 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 811 VOP_UNLOCK(dvp, 0, td); 812 vrele(dvp); 813 return (error); 814 } 815 816 817 /* 818 * vop_compat_nremove { struct namecache *a_ncp, XXX STOPGAP FUNCTION 819 * struct ucred *a_cred } 820 */ 821 int 822 vop_compat_nremove(struct vop_nremove_args *ap) 823 { 824 struct thread *td = curthread; 825 struct componentname cnp; 826 struct namecache *ncp; 827 struct vnode *dvp; 828 struct vnode *vp; 829 int error; 830 831 /* 832 * Sanity checks, get a locked directory vnode. 833 */ 834 ncp = ap->a_ncp; /* locked namecache node */ 835 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 836 return(EPERM); 837 if (ncp->nc_parent == NULL) 838 return(EPERM); 839 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 840 return(EPERM); 841 842 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 843 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 844 ncp, ncp->nc_name); 845 return(EAGAIN); 846 } 847 848 /* 849 * Setup the cnp for a traditional vop_lookup() call. The lookup 850 * caches all information required to delete the entry in the 851 * directory inode. We expect a return code of 0 for the DELETE 852 * case (meaning that a vp has been found). The cnp must simulated 853 * a saved-name situation. 854 */ 855 bzero(&cnp, sizeof(cnp)); 856 cnp.cn_nameiop = NAMEI_DELETE; 857 cnp.cn_flags = CNP_LOCKPARENT; 858 cnp.cn_nameptr = ncp->nc_name; 859 cnp.cn_namelen = ncp->nc_nlen; 860 cnp.cn_cred = ap->a_cred; 861 cnp.cn_td = td; 862 863 /* 864 * The vnode must be a directory and must not represent the 865 * current directory. 866 */ 867 vp = NULL; 868 error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 869 if (error == 0 && vp->v_type == VDIR) 870 error = EPERM; 871 if (error == 0) { 872 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 873 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 874 VOP_LEASE(vp, td, ap->a_cred, LEASE_WRITE); 875 error = VOP_OLD_REMOVE(dvp, vp, &cnp); 876 if (error == 0) { 877 cache_setunresolved(ncp); 878 cache_setvp(ncp, NULL); 879 } 880 } 881 if (vp) { 882 if (dvp == vp) 883 vrele(vp); 884 else 885 vput(vp); 886 } 887 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 888 VOP_UNLOCK(dvp, 0, td); 889 vrele(dvp); 890 return (error); 891 } 892 893 /* 894 * vop_compat_nrmdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION 895 * struct ucred *a_cred } 896 */ 897 int 898 vop_compat_nrmdir(struct vop_nrmdir_args *ap) 899 { 900 struct thread *td = curthread; 901 struct componentname cnp; 902 struct namecache *ncp; 903 struct vnode *dvp; 904 struct vnode *vp; 905 int error; 906 907 /* 908 * Sanity checks, get a locked directory vnode. 909 */ 910 ncp = ap->a_ncp; /* locked namecache node */ 911 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 912 return(EPERM); 913 if (ncp->nc_parent == NULL) 914 return(EPERM); 915 if ((dvp = ncp->nc_parent->nc_vp) == NULL) 916 return(EPERM); 917 918 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) { 919 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 920 ncp, ncp->nc_name); 921 return(EAGAIN); 922 } 923 924 /* 925 * Setup the cnp for a traditional vop_lookup() call. The lookup 926 * caches all information required to delete the entry in the 927 * directory inode. We expect a return code of 0 for the DELETE 928 * case (meaning that a vp has been found). The cnp must simulated 929 * a saved-name situation. 930 */ 931 bzero(&cnp, sizeof(cnp)); 932 cnp.cn_nameiop = NAMEI_DELETE; 933 cnp.cn_flags = CNP_LOCKPARENT; 934 cnp.cn_nameptr = ncp->nc_name; 935 cnp.cn_namelen = ncp->nc_nlen; 936 cnp.cn_cred = ap->a_cred; 937 cnp.cn_td = td; 938 939 /* 940 * The vnode must be a directory and must not represent the 941 * current directory. 942 */ 943 vp = NULL; 944 error = vop_lookup(ap->a_head.a_ops, dvp, &vp, &cnp); 945 if (error == 0 && vp->v_type != VDIR) 946 error = ENOTDIR; 947 if (error == 0 && vp == dvp) 948 error = EINVAL; 949 if (error == 0 && (vp->v_flag & VROOT)) 950 error = EBUSY; 951 if (error == 0) { 952 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0); 953 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE); 954 VOP_LEASE(vp, td, ap->a_cred, LEASE_WRITE); 955 error = VOP_OLD_RMDIR(dvp, vp, &cnp); 956 957 /* 958 * Note that this invalidation will cause any process 959 * currently CD'd into the directory being removed to be 960 * disconnected from the topology and not be able to ".." 961 * back out. 962 */ 963 if (error == 0) 964 cache_inval(ncp, CINV_DESTROY); 965 } 966 if (vp) { 967 if (dvp == vp) 968 vrele(vp); 969 else 970 vput(vp); 971 } 972 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0) 973 VOP_UNLOCK(dvp, 0, td); 974 vrele(dvp); 975 return (error); 976 } 977 978 /* 979 * vop_compat_nrename { struct namecache *a_fncp, XXX STOPGAP FUNCTION 980 * struct namecache *a_tncp, 981 * struct ucred *a_cred } 982 * 983 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that 984 * the source directory and vnode be unlocked and the target directory and 985 * vnode (if it exists) be locked. All arguments will be vrele'd and 986 * the targets will also be unlocked regardless of the return code. 987 */ 988 int 989 vop_compat_nrename(struct vop_nrename_args *ap) 990 { 991 struct thread *td = curthread; 992 struct componentname fcnp; 993 struct componentname tcnp; 994 struct namecache *fncp; 995 struct namecache *tncp; 996 struct vnode *fdvp, *fvp; 997 struct vnode *tdvp, *tvp; 998 int error; 999 1000 /* 1001 * Sanity checks, get referenced vnodes representing the source. 1002 */ 1003 fncp = ap->a_fncp; /* locked namecache node */ 1004 if (fncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 1005 return(EPERM); 1006 if (fncp->nc_parent == NULL) 1007 return(EPERM); 1008 if ((fdvp = fncp->nc_parent->nc_vp) == NULL) 1009 return(EPERM); 1010 1011 /* 1012 * Temporarily lock the source directory and lookup in DELETE mode to 1013 * check permissions. XXX delete permissions should have been 1014 * checked by nlookup(), we need to add NLC_DELETE for delete 1015 * checking. It is unclear whether VFS's require the directory setup 1016 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but 1017 * since it isn't locked and since UFS always does a relookup of 1018 * the source, it is believed that the only side effect that matters 1019 * is the permissions check. 1020 */ 1021 if ((error = vget(fdvp, LK_EXCLUSIVE, td)) != 0) { 1022 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 1023 fncp, fncp->nc_name); 1024 return(EAGAIN); 1025 } 1026 1027 bzero(&fcnp, sizeof(fcnp)); 1028 fcnp.cn_nameiop = NAMEI_DELETE; 1029 fcnp.cn_flags = CNP_LOCKPARENT; 1030 fcnp.cn_nameptr = fncp->nc_name; 1031 fcnp.cn_namelen = fncp->nc_nlen; 1032 fcnp.cn_cred = ap->a_cred; 1033 fcnp.cn_td = td; 1034 1035 /* 1036 * note: vop_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked 1037 * fvp. 1038 */ 1039 fvp = NULL; 1040 error = vop_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp); 1041 if (error == 0 && (fvp->v_flag & VROOT)) { 1042 vput(fvp); /* as if vop_lookup had failed */ 1043 error = EBUSY; 1044 } 1045 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) { 1046 fcnp.cn_flags |= CNP_PDIRUNLOCK; 1047 VOP_UNLOCK(fdvp, 0, td); 1048 } 1049 if (error) { 1050 vrele(fdvp); 1051 return (error); 1052 } 1053 VOP_UNLOCK(fvp, 0, td); 1054 1055 /* 1056 * fdvp and fvp are now referenced and unlocked. 1057 * 1058 * Get a locked directory vnode for the target and lookup the target 1059 * in CREATE mode so it places the required information in the 1060 * directory inode. 1061 */ 1062 tncp = ap->a_tncp; /* locked namecache node */ 1063 if (tncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */ 1064 error = EPERM; 1065 if (tncp->nc_parent == NULL) 1066 error = EPERM; 1067 if ((tdvp = tncp->nc_parent->nc_vp) == NULL) 1068 error = EPERM; 1069 if (error) { 1070 vrele(fdvp); 1071 vrele(fvp); 1072 return (error); 1073 } 1074 if ((error = vget(tdvp, LK_EXCLUSIVE, td)) != 0) { 1075 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n", 1076 tncp, tncp->nc_name); 1077 vrele(fdvp); 1078 vrele(fvp); 1079 return(EAGAIN); 1080 } 1081 1082 /* 1083 * Setup the cnp for a traditional vop_lookup() call. The lookup 1084 * caches all information required to create the entry in the 1085 * target directory inode. 1086 */ 1087 bzero(&tcnp, sizeof(tcnp)); 1088 tcnp.cn_nameiop = NAMEI_RENAME; 1089 tcnp.cn_flags = CNP_LOCKPARENT; 1090 tcnp.cn_nameptr = tncp->nc_name; 1091 tcnp.cn_namelen = tncp->nc_nlen; 1092 tcnp.cn_cred = ap->a_cred; 1093 tcnp.cn_td = td; 1094 1095 tvp = NULL; 1096 error = vop_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp); 1097 1098 if (error == EJUSTRETURN) { 1099 /* 1100 * Target does not exist. tvp should be NULL. 1101 */ 1102 KKASSERT(tvp == NULL); 1103 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1104 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1105 if (error == 0) { 1106 cache_rename(fncp, tncp); 1107 cache_setvp(tncp, fvp); 1108 } 1109 } else if (error == 0) { 1110 /* 1111 * Target exists. VOP_OLD_RENAME should correctly delete the 1112 * target. 1113 */ 1114 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0); 1115 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp); 1116 if (error == 0) { 1117 cache_rename(fncp, tncp); 1118 cache_setvp(tncp, fvp); 1119 } 1120 } else { 1121 vrele(fdvp); 1122 vrele(fvp); 1123 if (tcnp.cn_flags & CNP_PDIRUNLOCK) 1124 vrele(tdvp); 1125 else 1126 vput(tdvp); 1127 } 1128 return (error); 1129 } 1130 1131 static int 1132 vop_nolookup(ap) 1133 struct vop_lookup_args /* { 1134 struct vnode *a_dvp; 1135 struct vnode **a_vpp; 1136 struct componentname *a_cnp; 1137 } */ *ap; 1138 { 1139 1140 *ap->a_vpp = NULL; 1141 return (ENOTDIR); 1142 } 1143 1144 /* 1145 * vop_nostrategy: 1146 * 1147 * Strategy routine for VFS devices that have none. 1148 * 1149 * B_ERROR and B_INVAL must be cleared prior to calling any strategy 1150 * routine. Typically this is done for a B_READ strategy call. Typically 1151 * B_INVAL is assumed to already be clear prior to a write and should not 1152 * be cleared manually unless you just made the buffer invalid. B_ERROR 1153 * should be cleared either way. 1154 */ 1155 1156 static int 1157 vop_nostrategy (struct vop_strategy_args *ap) 1158 { 1159 printf("No strategy for buffer at %p\n", ap->a_bp); 1160 vprint("", ap->a_vp); 1161 vprint("", ap->a_bp->b_vp); 1162 ap->a_bp->b_flags |= B_ERROR; 1163 ap->a_bp->b_error = EOPNOTSUPP; 1164 biodone(ap->a_bp); 1165 return (EOPNOTSUPP); 1166 } 1167 1168 int 1169 vop_stdpathconf(ap) 1170 struct vop_pathconf_args /* { 1171 struct vnode *a_vp; 1172 int a_name; 1173 int *a_retval; 1174 } */ *ap; 1175 { 1176 1177 switch (ap->a_name) { 1178 case _PC_LINK_MAX: 1179 *ap->a_retval = LINK_MAX; 1180 return (0); 1181 case _PC_MAX_CANON: 1182 *ap->a_retval = MAX_CANON; 1183 return (0); 1184 case _PC_MAX_INPUT: 1185 *ap->a_retval = MAX_INPUT; 1186 return (0); 1187 case _PC_PIPE_BUF: 1188 *ap->a_retval = PIPE_BUF; 1189 return (0); 1190 case _PC_CHOWN_RESTRICTED: 1191 *ap->a_retval = 1; 1192 return (0); 1193 case _PC_VDISABLE: 1194 *ap->a_retval = _POSIX_VDISABLE; 1195 return (0); 1196 default: 1197 return (EINVAL); 1198 } 1199 /* NOTREACHED */ 1200 } 1201 1202 /* 1203 * Standard lock. The lock is recursive-capable only if the lock was 1204 * initialized with LK_CANRECURSE or that flag is passed in a_flags. 1205 */ 1206 int 1207 vop_stdlock(ap) 1208 struct vop_lock_args /* { 1209 struct vnode *a_vp; 1210 int a_flags; 1211 struct proc *a_p; 1212 } */ *ap; 1213 { 1214 int error; 1215 1216 #ifndef DEBUG_LOCKS 1217 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags, NULL, ap->a_td); 1218 #else 1219 error = debuglockmgr(&ap->a_vp->v_lock, ap->a_flags, 1220 NULL, ap->a_td, 1221 "vop_stdlock", ap->a_vp->filename, ap->a_vp->line); 1222 #endif 1223 return(error); 1224 } 1225 1226 int 1227 vop_stdunlock(ap) 1228 struct vop_unlock_args /* { 1229 struct vnode *a_vp; 1230 int a_flags; 1231 struct thread *a_td; 1232 } */ *ap; 1233 { 1234 int error; 1235 1236 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags | LK_RELEASE, 1237 NULL, ap->a_td); 1238 return(error); 1239 } 1240 1241 int 1242 vop_stdislocked(ap) 1243 struct vop_islocked_args /* { 1244 struct vnode *a_vp; 1245 struct thread *a_td; 1246 } */ *ap; 1247 { 1248 return (lockstatus(&ap->a_vp->v_lock, ap->a_td)); 1249 } 1250 1251 /* 1252 * Return true for select/poll. 1253 */ 1254 int 1255 vop_nopoll(ap) 1256 struct vop_poll_args /* { 1257 struct vnode *a_vp; 1258 int a_events; 1259 struct ucred *a_cred; 1260 struct proc *a_p; 1261 } */ *ap; 1262 { 1263 /* 1264 * Return true for read/write. If the user asked for something 1265 * special, return POLLNVAL, so that clients have a way of 1266 * determining reliably whether or not the extended 1267 * functionality is present without hard-coding knowledge 1268 * of specific filesystem implementations. 1269 */ 1270 if (ap->a_events & ~POLLSTANDARD) 1271 return (POLLNVAL); 1272 1273 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1274 } 1275 1276 /* 1277 * Implement poll for local filesystems that support it. 1278 */ 1279 int 1280 vop_stdpoll(ap) 1281 struct vop_poll_args /* { 1282 struct vnode *a_vp; 1283 int a_events; 1284 struct ucred *a_cred; 1285 struct thread *a_td; 1286 } */ *ap; 1287 { 1288 if (ap->a_events & ~POLLSTANDARD) 1289 return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 1290 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 1291 } 1292 1293 int 1294 vop_stdbwrite(ap) 1295 struct vop_bwrite_args *ap; 1296 { 1297 return (bwrite(ap->a_bp)); 1298 } 1299 1300 int 1301 vop_stdcreatevobject(ap) 1302 struct vop_createvobject_args /* { 1303 struct vnode *a_vp; 1304 struct proc *a_td; 1305 } */ *ap; 1306 { 1307 struct vnode *vp = ap->a_vp; 1308 struct thread *td = ap->a_td; 1309 struct vattr vat; 1310 vm_object_t object; 1311 int error = 0; 1312 1313 if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE) 1314 return (0); 1315 1316 retry: 1317 if ((object = vp->v_object) == NULL) { 1318 if (vp->v_type == VREG || vp->v_type == VDIR) { 1319 if ((error = VOP_GETATTR(vp, &vat, td)) != 0) 1320 goto retn; 1321 object = vnode_pager_alloc(vp, vat.va_size, 0, 0); 1322 } else if (vp->v_rdev && dev_is_good(vp->v_rdev)) { 1323 /* 1324 * XXX v_rdev uses NULL/non-NULL instead of NODEV 1325 * 1326 * This simply allocates the biggest object possible 1327 * for a disk vnode. This should be fixed, but doesn't 1328 * cause any problems (yet). 1329 */ 1330 object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0); 1331 } else { 1332 goto retn; 1333 } 1334 /* 1335 * Dereference the reference we just created. This assumes 1336 * that the object is associated with the vp. 1337 */ 1338 object->ref_count--; 1339 vp->v_usecount--; 1340 } else { 1341 if (object->flags & OBJ_DEAD) { 1342 VOP_UNLOCK(vp, 0, td); 1343 tsleep(object, 0, "vodead", 0); 1344 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1345 goto retry; 1346 } 1347 } 1348 1349 KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object")); 1350 vp->v_flag |= VOBJBUF; 1351 1352 retn: 1353 return (error); 1354 } 1355 1356 int 1357 vop_stddestroyvobject(ap) 1358 struct vop_destroyvobject_args /* { 1359 struct vnode *vp; 1360 } */ *ap; 1361 { 1362 struct vnode *vp = ap->a_vp; 1363 vm_object_t obj = vp->v_object; 1364 1365 if (vp->v_object == NULL) 1366 return (0); 1367 1368 if (obj->ref_count == 0) { 1369 /* 1370 * vclean() may be called twice. The first time 1371 * removes the primary reference to the object, 1372 * the second time goes one further and is a 1373 * special-case to terminate the object. 1374 * 1375 * don't double-terminate the object. 1376 */ 1377 if ((obj->flags & OBJ_DEAD) == 0) 1378 vm_object_terminate(obj); 1379 } else { 1380 /* 1381 * Woe to the process that tries to page now :-). 1382 */ 1383 vm_pager_deallocate(obj); 1384 } 1385 return (0); 1386 } 1387 1388 /* 1389 * Return the underlying VM object. This routine may be called with or 1390 * without the vnode interlock held. If called without, the returned 1391 * object is not guarenteed to be valid. The syncer typically gets the 1392 * object without holding the interlock in order to quickly test whether 1393 * it might be dirty before going heavy-weight. vm_object's use zalloc 1394 * and thus stable-storage, so this is safe. 1395 */ 1396 int 1397 vop_stdgetvobject(ap) 1398 struct vop_getvobject_args /* { 1399 struct vnode *vp; 1400 struct vm_object **objpp; 1401 } */ *ap; 1402 { 1403 struct vnode *vp = ap->a_vp; 1404 struct vm_object **objpp = ap->a_objpp; 1405 1406 if (objpp) 1407 *objpp = vp->v_object; 1408 return (vp->v_object ? 0 : EINVAL); 1409 } 1410 1411 /* 1412 * vfs default ops 1413 * used to fill the vfs fucntion table to get reasonable default return values. 1414 */ 1415 int 1416 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct thread *td) 1417 { 1418 return (0); 1419 } 1420 1421 int 1422 vfs_stdunmount(struct mount *mp, int mntflags, struct thread *td) 1423 { 1424 return (0); 1425 } 1426 1427 int 1428 vfs_stdroot(struct mount *mp, struct vnode **vpp) 1429 { 1430 return (EOPNOTSUPP); 1431 } 1432 1433 int 1434 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct thread *td) 1435 { 1436 return (EOPNOTSUPP); 1437 } 1438 1439 int 1440 vfs_stdvptofh(struct vnode *vp, struct fid *fhp) 1441 { 1442 return (EOPNOTSUPP); 1443 } 1444 1445 int 1446 vfs_stdstart(struct mount *mp, int flags, struct thread *td) 1447 { 1448 return (0); 1449 } 1450 1451 int 1452 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid, 1453 caddr_t arg, struct thread *td) 1454 { 1455 return (EOPNOTSUPP); 1456 } 1457 1458 int 1459 vfs_stdsync(struct mount *mp, int waitfor, struct thread *td) 1460 { 1461 return (0); 1462 } 1463 1464 int 1465 vfs_stdnosync(struct mount *mp, int waitfor, struct thread *td) 1466 { 1467 return (EOPNOTSUPP); 1468 } 1469 1470 int 1471 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp) 1472 { 1473 return (EOPNOTSUPP); 1474 } 1475 1476 int 1477 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1478 { 1479 return (EOPNOTSUPP); 1480 } 1481 1482 int 1483 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, 1484 struct ucred **credanonp) 1485 { 1486 return (EOPNOTSUPP); 1487 } 1488 1489 int 1490 vfs_stdinit(struct vfsconf *vfsp) 1491 { 1492 return (0); 1493 } 1494 1495 int 1496 vfs_stduninit(struct vfsconf *vfsp) 1497 { 1498 return(0); 1499 } 1500 1501 int 1502 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname, 1503 caddr_t arg, struct thread *td) 1504 { 1505 return(EOPNOTSUPP); 1506 } 1507 1508 /* end of vfs default ops */ 1509