vfs_default.c revision 191990
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 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> 36__FBSDID("$FreeBSD: head/sys/kern/vfs_default.c 191990 2009-05-11 15:33:26Z attilio $"); 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/bio.h> 41#include <sys/buf.h> 42#include <sys/conf.h> 43#include <sys/event.h> 44#include <sys/kernel.h> 45#include <sys/limits.h> 46#include <sys/lock.h> 47#include <sys/lockf.h> 48#include <sys/malloc.h> 49#include <sys/mount.h> 50#include <sys/mutex.h> 51#include <sys/namei.h> 52#include <sys/fcntl.h> 53#include <sys/unistd.h> 54#include <sys/vnode.h> 55#include <sys/dirent.h> 56#include <sys/poll.h> 57 58#include <vm/vm.h> 59#include <vm/vm_object.h> 60#include <vm/vm_extern.h> 61#include <vm/pmap.h> 62#include <vm/vm_map.h> 63#include <vm/vm_page.h> 64#include <vm/vm_pager.h> 65#include <vm/vnode_pager.h> 66 67static int vop_nolookup(struct vop_lookup_args *); 68static int vop_nostrategy(struct vop_strategy_args *); 69static int get_next_dirent(struct vnode *vp, struct dirent **dpp, 70 char *dirbuf, int dirbuflen, off_t *off, 71 char **cpos, int *len, int *eofflag, 72 struct thread *td); 73static int dirent_exists(struct vnode *vp, const char *dirname, 74 struct thread *td); 75 76#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) 77 78/* 79 * This vnode table stores what we want to do if the filesystem doesn't 80 * implement a particular VOP. 81 * 82 * If there is no specific entry here, we will return EOPNOTSUPP. 83 * 84 */ 85 86struct vop_vector default_vnodeops = { 87 .vop_default = NULL, 88 .vop_bypass = VOP_EOPNOTSUPP, 89 90 .vop_advlock = vop_stdadvlock, 91 .vop_advlockasync = vop_stdadvlockasync, 92 .vop_bmap = vop_stdbmap, 93 .vop_close = VOP_NULL, 94 .vop_fsync = VOP_NULL, 95 .vop_getpages = vop_stdgetpages, 96 .vop_getwritemount = vop_stdgetwritemount, 97 .vop_inactive = VOP_NULL, 98 .vop_ioctl = VOP_ENOTTY, 99 .vop_kqfilter = vop_stdkqfilter, 100 .vop_islocked = vop_stdislocked, 101 .vop_lock1 = vop_stdlock, 102 .vop_lookup = vop_nolookup, 103 .vop_open = VOP_NULL, 104 .vop_pathconf = VOP_EINVAL, 105 .vop_poll = vop_nopoll, 106 .vop_putpages = vop_stdputpages, 107 .vop_readlink = VOP_EINVAL, 108 .vop_revoke = VOP_PANIC, 109 .vop_strategy = vop_nostrategy, 110 .vop_unlock = vop_stdunlock, 111 .vop_vptocnp = vop_stdvptocnp, 112 .vop_vptofh = vop_stdvptofh, 113}; 114 115/* 116 * Series of placeholder functions for various error returns for 117 * VOPs. 118 */ 119 120int 121vop_eopnotsupp(struct vop_generic_args *ap) 122{ 123 /* 124 printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name); 125 */ 126 127 return (EOPNOTSUPP); 128} 129 130int 131vop_ebadf(struct vop_generic_args *ap) 132{ 133 134 return (EBADF); 135} 136 137int 138vop_enotty(struct vop_generic_args *ap) 139{ 140 141 return (ENOTTY); 142} 143 144int 145vop_einval(struct vop_generic_args *ap) 146{ 147 148 return (EINVAL); 149} 150 151int 152vop_enoent(struct vop_generic_args *ap) 153{ 154 155 return (ENOENT); 156} 157 158int 159vop_null(struct vop_generic_args *ap) 160{ 161 162 return (0); 163} 164 165/* 166 * Helper function to panic on some bad VOPs in some filesystems. 167 */ 168int 169vop_panic(struct vop_generic_args *ap) 170{ 171 172 panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 173} 174 175/* 176 * vop_std<something> and vop_no<something> are default functions for use by 177 * filesystems that need the "default reasonable" implementation for a 178 * particular operation. 179 * 180 * The documentation for the operations they implement exists (if it exists) 181 * in the VOP_<SOMETHING>(9) manpage (all uppercase). 182 */ 183 184/* 185 * Default vop for filesystems that do not support name lookup 186 */ 187static int 188vop_nolookup(ap) 189 struct vop_lookup_args /* { 190 struct vnode *a_dvp; 191 struct vnode **a_vpp; 192 struct componentname *a_cnp; 193 } */ *ap; 194{ 195 196 *ap->a_vpp = NULL; 197 return (ENOTDIR); 198} 199 200/* 201 * vop_nostrategy: 202 * 203 * Strategy routine for VFS devices that have none. 204 * 205 * BIO_ERROR and B_INVAL must be cleared prior to calling any strategy 206 * routine. Typically this is done for a BIO_READ strategy call. 207 * Typically B_INVAL is assumed to already be clear prior to a write 208 * and should not be cleared manually unless you just made the buffer 209 * invalid. BIO_ERROR should be cleared either way. 210 */ 211 212static int 213vop_nostrategy (struct vop_strategy_args *ap) 214{ 215 printf("No strategy for buffer at %p\n", ap->a_bp); 216 vprint("vnode", ap->a_vp); 217 ap->a_bp->b_ioflags |= BIO_ERROR; 218 ap->a_bp->b_error = EOPNOTSUPP; 219 bufdone(ap->a_bp); 220 return (EOPNOTSUPP); 221} 222 223static int 224get_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, 225 int dirbuflen, off_t *off, char **cpos, int *len, 226 int *eofflag, struct thread *td) 227{ 228 int error, reclen; 229 struct uio uio; 230 struct iovec iov; 231 struct dirent *dp; 232 233 KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 234 KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 235 236 if (*len == 0) { 237 iov.iov_base = dirbuf; 238 iov.iov_len = dirbuflen; 239 240 uio.uio_iov = &iov; 241 uio.uio_iovcnt = 1; 242 uio.uio_offset = *off; 243 uio.uio_resid = dirbuflen; 244 uio.uio_segflg = UIO_SYSSPACE; 245 uio.uio_rw = UIO_READ; 246 uio.uio_td = td; 247 248 *eofflag = 0; 249 250#ifdef MAC 251 error = mac_vnode_check_readdir(td->td_ucred, vp); 252 if (error == 0) 253#endif 254 error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, 255 NULL, NULL); 256 if (error) 257 return (error); 258 259 *off = uio.uio_offset; 260 261 *cpos = dirbuf; 262 *len = (dirbuflen - uio.uio_resid); 263 } 264 265 dp = (struct dirent *)(*cpos); 266 reclen = dp->d_reclen; 267 *dpp = dp; 268 269 /* check for malformed directory.. */ 270 if (reclen < DIRENT_MINSIZE) 271 return (EINVAL); 272 273 *cpos += reclen; 274 *len -= reclen; 275 276 return (0); 277} 278 279/* 280 * Check if a named file exists in a given directory vnode. 281 */ 282static int 283dirent_exists(struct vnode *vp, const char *dirname, struct thread *td) 284{ 285 char *dirbuf, *cpos; 286 int error, eofflag, dirbuflen, len, found; 287 off_t off; 288 struct dirent *dp; 289 struct vattr va; 290 291 KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 292 KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 293 294 found = 0; 295 296 error = VOP_GETATTR(vp, &va, td->td_ucred); 297 if (error) 298 return (found); 299 300 dirbuflen = DEV_BSIZE; 301 if (dirbuflen < va.va_blocksize) 302 dirbuflen = va.va_blocksize; 303 dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 304 305 off = 0; 306 len = 0; 307 do { 308 error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, 309 &cpos, &len, &eofflag, td); 310 if (error) 311 goto out; 312 313 if ((dp->d_type != DT_WHT) && 314 !strcmp(dp->d_name, dirname)) { 315 found = 1; 316 goto out; 317 } 318 } while (len > 0 || !eofflag); 319 320out: 321 free(dirbuf, M_TEMP); 322 return (found); 323} 324 325/* 326 * Advisory record locking support 327 */ 328int 329vop_stdadvlock(struct vop_advlock_args *ap) 330{ 331 struct vnode *vp; 332 struct ucred *cred; 333 struct vattr vattr; 334 int error; 335 336 vp = ap->a_vp; 337 cred = curthread->td_ucred; 338 vn_lock(vp, LK_SHARED | LK_RETRY); 339 error = VOP_GETATTR(vp, &vattr, cred); 340 VOP_UNLOCK(vp, 0); 341 if (error) 342 return (error); 343 344 return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); 345} 346 347int 348vop_stdadvlockasync(struct vop_advlockasync_args *ap) 349{ 350 struct vnode *vp; 351 struct ucred *cred; 352 struct vattr vattr; 353 int error; 354 355 vp = ap->a_vp; 356 cred = curthread->td_ucred; 357 vn_lock(vp, LK_SHARED | LK_RETRY); 358 error = VOP_GETATTR(vp, &vattr, cred); 359 VOP_UNLOCK(vp, 0); 360 if (error) 361 return (error); 362 363 return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); 364} 365 366/* 367 * vop_stdpathconf: 368 * 369 * Standard implementation of POSIX pathconf, to get information about limits 370 * for a filesystem. 371 * Override per filesystem for the case where the filesystem has smaller 372 * limits. 373 */ 374int 375vop_stdpathconf(ap) 376 struct vop_pathconf_args /* { 377 struct vnode *a_vp; 378 int a_name; 379 int *a_retval; 380 } */ *ap; 381{ 382 383 switch (ap->a_name) { 384 case _PC_NAME_MAX: 385 *ap->a_retval = NAME_MAX; 386 return (0); 387 case _PC_PATH_MAX: 388 *ap->a_retval = PATH_MAX; 389 return (0); 390 case _PC_LINK_MAX: 391 *ap->a_retval = LINK_MAX; 392 return (0); 393 case _PC_MAX_CANON: 394 *ap->a_retval = MAX_CANON; 395 return (0); 396 case _PC_MAX_INPUT: 397 *ap->a_retval = MAX_INPUT; 398 return (0); 399 case _PC_PIPE_BUF: 400 *ap->a_retval = PIPE_BUF; 401 return (0); 402 case _PC_CHOWN_RESTRICTED: 403 *ap->a_retval = 1; 404 return (0); 405 case _PC_VDISABLE: 406 *ap->a_retval = _POSIX_VDISABLE; 407 return (0); 408 default: 409 return (EINVAL); 410 } 411 /* NOTREACHED */ 412} 413 414/* 415 * Standard lock, unlock and islocked functions. 416 */ 417int 418vop_stdlock(ap) 419 struct vop_lock1_args /* { 420 struct vnode *a_vp; 421 int a_flags; 422 char *file; 423 int line; 424 } */ *ap; 425{ 426 struct vnode *vp = ap->a_vp; 427 428 return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), 429 LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, 430 ap->a_line)); 431} 432 433/* See above. */ 434int 435vop_stdunlock(ap) 436 struct vop_unlock_args /* { 437 struct vnode *a_vp; 438 int a_flags; 439 } */ *ap; 440{ 441 struct vnode *vp = ap->a_vp; 442 443 return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); 444} 445 446/* See above. */ 447int 448vop_stdislocked(ap) 449 struct vop_islocked_args /* { 450 struct vnode *a_vp; 451 } */ *ap; 452{ 453 454 return (lockstatus(ap->a_vp->v_vnlock)); 455} 456 457/* 458 * Return true for select/poll. 459 */ 460int 461vop_nopoll(ap) 462 struct vop_poll_args /* { 463 struct vnode *a_vp; 464 int a_events; 465 struct ucred *a_cred; 466 struct thread *a_td; 467 } */ *ap; 468{ 469 470 return (poll_no_poll(ap->a_events)); 471} 472 473/* 474 * Implement poll for local filesystems that support it. 475 */ 476int 477vop_stdpoll(ap) 478 struct vop_poll_args /* { 479 struct vnode *a_vp; 480 int a_events; 481 struct ucred *a_cred; 482 struct thread *a_td; 483 } */ *ap; 484{ 485 if (ap->a_events & ~POLLSTANDARD) 486 return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 487 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 488} 489 490/* 491 * Return our mount point, as we will take charge of the writes. 492 */ 493int 494vop_stdgetwritemount(ap) 495 struct vop_getwritemount_args /* { 496 struct vnode *a_vp; 497 struct mount **a_mpp; 498 } */ *ap; 499{ 500 struct mount *mp; 501 502 /* 503 * XXX Since this is called unlocked we may be recycled while 504 * attempting to ref the mount. If this is the case or mountpoint 505 * will be set to NULL. We only have to prevent this call from 506 * returning with a ref to an incorrect mountpoint. It is not 507 * harmful to return with a ref to our previous mountpoint. 508 */ 509 mp = ap->a_vp->v_mount; 510 if (mp != NULL) { 511 vfs_ref(mp); 512 if (mp != ap->a_vp->v_mount) { 513 vfs_rel(mp); 514 mp = NULL; 515 } 516 } 517 *(ap->a_mpp) = mp; 518 return (0); 519} 520 521/* XXX Needs good comment and VOP_BMAP(9) manpage */ 522int 523vop_stdbmap(ap) 524 struct vop_bmap_args /* { 525 struct vnode *a_vp; 526 daddr_t a_bn; 527 struct bufobj **a_bop; 528 daddr_t *a_bnp; 529 int *a_runp; 530 int *a_runb; 531 } */ *ap; 532{ 533 534 if (ap->a_bop != NULL) 535 *ap->a_bop = &ap->a_vp->v_bufobj; 536 if (ap->a_bnp != NULL) 537 *ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize); 538 if (ap->a_runp != NULL) 539 *ap->a_runp = 0; 540 if (ap->a_runb != NULL) 541 *ap->a_runb = 0; 542 return (0); 543} 544 545int 546vop_stdfsync(ap) 547 struct vop_fsync_args /* { 548 struct vnode *a_vp; 549 struct ucred *a_cred; 550 int a_waitfor; 551 struct thread *a_td; 552 } */ *ap; 553{ 554 struct vnode *vp = ap->a_vp; 555 struct buf *bp; 556 struct bufobj *bo; 557 struct buf *nbp; 558 int error = 0; 559 int maxretry = 1000; /* large, arbitrarily chosen */ 560 561 bo = &vp->v_bufobj; 562 BO_LOCK(bo); 563loop1: 564 /* 565 * MARK/SCAN initialization to avoid infinite loops. 566 */ 567 TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { 568 bp->b_vflags &= ~BV_SCANNED; 569 bp->b_error = 0; 570 } 571 572 /* 573 * Flush all dirty buffers associated with a vnode. 574 */ 575loop2: 576 TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { 577 if ((bp->b_vflags & BV_SCANNED) != 0) 578 continue; 579 bp->b_vflags |= BV_SCANNED; 580 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) 581 continue; 582 BO_UNLOCK(bo); 583 KASSERT(bp->b_bufobj == bo, 584 ("bp %p wrong b_bufobj %p should be %p", 585 bp, bp->b_bufobj, bo)); 586 if ((bp->b_flags & B_DELWRI) == 0) 587 panic("fsync: not dirty"); 588 if ((vp->v_object != NULL) && (bp->b_flags & B_CLUSTEROK)) { 589 vfs_bio_awrite(bp); 590 } else { 591 bremfree(bp); 592 bawrite(bp); 593 } 594 BO_LOCK(bo); 595 goto loop2; 596 } 597 598 /* 599 * If synchronous the caller expects us to completely resolve all 600 * dirty buffers in the system. Wait for in-progress I/O to 601 * complete (which could include background bitmap writes), then 602 * retry if dirty blocks still exist. 603 */ 604 if (ap->a_waitfor == MNT_WAIT) { 605 bufobj_wwait(bo, 0, 0); 606 if (bo->bo_dirty.bv_cnt > 0) { 607 /* 608 * If we are unable to write any of these buffers 609 * then we fail now rather than trying endlessly 610 * to write them out. 611 */ 612 TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) 613 if ((error = bp->b_error) == 0) 614 continue; 615 if (error == 0 && --maxretry >= 0) 616 goto loop1; 617 error = EAGAIN; 618 } 619 } 620 BO_UNLOCK(bo); 621 if (error == EAGAIN) 622 vprint("fsync: giving up on dirty", vp); 623 624 return (error); 625} 626 627/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ 628int 629vop_stdgetpages(ap) 630 struct vop_getpages_args /* { 631 struct vnode *a_vp; 632 vm_page_t *a_m; 633 int a_count; 634 int a_reqpage; 635 vm_ooffset_t a_offset; 636 } */ *ap; 637{ 638 639 return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 640 ap->a_count, ap->a_reqpage); 641} 642 643int 644vop_stdkqfilter(struct vop_kqfilter_args *ap) 645{ 646 return vfs_kqfilter(ap); 647} 648 649/* XXX Needs good comment and more info in the manpage (VOP_PUTPAGES(9)). */ 650int 651vop_stdputpages(ap) 652 struct vop_putpages_args /* { 653 struct vnode *a_vp; 654 vm_page_t *a_m; 655 int a_count; 656 int a_sync; 657 int *a_rtvals; 658 vm_ooffset_t a_offset; 659 } */ *ap; 660{ 661 662 return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count, 663 ap->a_sync, ap->a_rtvals); 664} 665 666int 667vop_stdvptofh(struct vop_vptofh_args *ap) 668{ 669 return (EOPNOTSUPP); 670} 671 672int 673vop_stdvptocnp(struct vop_vptocnp_args *ap) 674{ 675 struct vnode *vp = ap->a_vp; 676 struct vnode **dvp = ap->a_vpp; 677 char *buf = ap->a_buf; 678 int *buflen = ap->a_buflen; 679 char *dirbuf, *cpos; 680 int i, error, eofflag, dirbuflen, flags, locked, len, covered; 681 off_t off; 682 ino_t fileno; 683 struct vattr va; 684 struct nameidata nd; 685 struct thread *td; 686 struct dirent *dp; 687 struct vnode *mvp; 688 689 i = *buflen; 690 error = 0; 691 covered = 0; 692 td = curthread; 693 694 if (vp->v_type != VDIR) 695 return (ENOENT); 696 697 error = VOP_GETATTR(vp, &va, td->td_ucred); 698 if (error) 699 return (error); 700 701 VREF(vp); 702 locked = VOP_ISLOCKED(vp); 703 VOP_UNLOCK(vp, 0); 704 NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 705 "..", vp, td); 706 flags = FREAD; 707 error = vn_open(&nd, &flags, 0, NULL); 708 if (error) { 709 vn_lock(vp, locked | LK_RETRY); 710 return (error); 711 } 712 NDFREE(&nd, NDF_ONLY_PNBUF); 713 714 mvp = *dvp = nd.ni_vp; 715 716 if (vp->v_mount != (*dvp)->v_mount && 717 ((*dvp)->v_vflag & VV_ROOT) && 718 ((*dvp)->v_mount->mnt_flag & MNT_UNION)) { 719 *dvp = (*dvp)->v_mount->mnt_vnodecovered; 720 VREF(mvp); 721 VOP_UNLOCK(mvp, 0); 722 vn_close(mvp, FREAD, td->td_ucred, td); 723 VREF(*dvp); 724 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 725 covered = 1; 726 } 727 728 fileno = va.va_fileid; 729 730 dirbuflen = DEV_BSIZE; 731 if (dirbuflen < va.va_blocksize) 732 dirbuflen = va.va_blocksize; 733 dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 734 735 if ((*dvp)->v_type != VDIR) { 736 error = ENOENT; 737 goto out; 738 } 739 740 off = 0; 741 len = 0; 742 do { 743 /* call VOP_READDIR of parent */ 744 error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, 745 &cpos, &len, &eofflag, td); 746 if (error) 747 goto out; 748 749 if ((dp->d_type != DT_WHT) && 750 (dp->d_fileno == fileno)) { 751 if (covered) { 752 VOP_UNLOCK(*dvp, 0); 753 vn_lock(mvp, LK_EXCLUSIVE | LK_RETRY); 754 if (dirent_exists(mvp, dp->d_name, td)) { 755 error = ENOENT; 756 VOP_UNLOCK(mvp, 0); 757 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 758 goto out; 759 } 760 VOP_UNLOCK(mvp, 0); 761 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 762 } 763 i -= dp->d_namlen; 764 765 if (i < 0) { 766 error = ENOMEM; 767 goto out; 768 } 769 bcopy(dp->d_name, buf + i, dp->d_namlen); 770 error = 0; 771 goto out; 772 } 773 } while (len > 0 || !eofflag); 774 error = ENOENT; 775 776out: 777 free(dirbuf, M_TEMP); 778 if (!error) { 779 *buflen = i; 780 vhold(*dvp); 781 } 782 if (covered) { 783 vput(*dvp); 784 vrele(mvp); 785 } else { 786 VOP_UNLOCK(mvp, 0); 787 vn_close(mvp, FREAD, td->td_ucred, td); 788 } 789 vn_lock(vp, locked | LK_RETRY); 790 return (error); 791} 792 793/* 794 * vfs default ops 795 * used to fill the vfs function table to get reasonable default return values. 796 */ 797int 798vfs_stdroot (mp, flags, vpp) 799 struct mount *mp; 800 int flags; 801 struct vnode **vpp; 802{ 803 804 return (EOPNOTSUPP); 805} 806 807int 808vfs_stdstatfs (mp, sbp) 809 struct mount *mp; 810 struct statfs *sbp; 811{ 812 813 return (EOPNOTSUPP); 814} 815 816int 817vfs_stdquotactl (mp, cmds, uid, arg) 818 struct mount *mp; 819 int cmds; 820 uid_t uid; 821 void *arg; 822{ 823 824 return (EOPNOTSUPP); 825} 826 827int 828vfs_stdsync(mp, waitfor) 829 struct mount *mp; 830 int waitfor; 831{ 832 struct vnode *vp, *mvp; 833 struct thread *td; 834 int error, lockreq, allerror = 0; 835 836 td = curthread; 837 lockreq = LK_EXCLUSIVE | LK_INTERLOCK; 838 if (waitfor != MNT_WAIT) 839 lockreq |= LK_NOWAIT; 840 /* 841 * Force stale buffer cache information to be flushed. 842 */ 843 MNT_ILOCK(mp); 844loop: 845 MNT_VNODE_FOREACH(vp, mp, mvp) { 846 /* bv_cnt is an acceptable race here. */ 847 if (vp->v_bufobj.bo_dirty.bv_cnt == 0) 848 continue; 849 VI_LOCK(vp); 850 MNT_IUNLOCK(mp); 851 if ((error = vget(vp, lockreq, td)) != 0) { 852 MNT_ILOCK(mp); 853 if (error == ENOENT) { 854 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); 855 goto loop; 856 } 857 continue; 858 } 859 error = VOP_FSYNC(vp, waitfor, td); 860 if (error) 861 allerror = error; 862 863 /* Do not turn this into vput. td is not always curthread. */ 864 VOP_UNLOCK(vp, 0); 865 vrele(vp); 866 MNT_ILOCK(mp); 867 } 868 MNT_IUNLOCK(mp); 869 return (allerror); 870} 871 872int 873vfs_stdnosync (mp, waitfor) 874 struct mount *mp; 875 int waitfor; 876{ 877 878 return (0); 879} 880 881int 882vfs_stdvget (mp, ino, flags, vpp) 883 struct mount *mp; 884 ino_t ino; 885 int flags; 886 struct vnode **vpp; 887{ 888 889 return (EOPNOTSUPP); 890} 891 892int 893vfs_stdfhtovp (mp, fhp, vpp) 894 struct mount *mp; 895 struct fid *fhp; 896 struct vnode **vpp; 897{ 898 899 return (EOPNOTSUPP); 900} 901 902int 903vfs_stdinit (vfsp) 904 struct vfsconf *vfsp; 905{ 906 907 return (0); 908} 909 910int 911vfs_stduninit (vfsp) 912 struct vfsconf *vfsp; 913{ 914 915 return(0); 916} 917 918int 919vfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname) 920 struct mount *mp; 921 int cmd; 922 struct vnode *filename_vp; 923 int attrnamespace; 924 const char *attrname; 925{ 926 927 if (filename_vp != NULL) 928 VOP_UNLOCK(filename_vp, 0); 929 return (EOPNOTSUPP); 930} 931 932int 933vfs_stdsysctl(mp, op, req) 934 struct mount *mp; 935 fsctlop_t op; 936 struct sysctl_req *req; 937{ 938 939 return (EOPNOTSUPP); 940} 941 942/* end of vfs default ops */ 943