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 <security/mac/mac_framework.h> 59 60#include <vm/vm.h> 61#include <vm/vm_object.h> 62#include <vm/vm_extern.h> 63#include <vm/pmap.h> 64#include <vm/vm_map.h> 65#include <vm/vm_page.h> 66#include <vm/vm_pager.h> 67#include <vm/vnode_pager.h> 68 69static int vop_nolookup(struct vop_lookup_args *); 70static int vop_norename(struct vop_rename_args *); 71static int vop_nostrategy(struct vop_strategy_args *); 72static int get_next_dirent(struct vnode *vp, struct dirent **dpp, 73 char *dirbuf, int dirbuflen, off_t *off, 74 char **cpos, int *len, int *eofflag, 75 struct thread *td); 76static int dirent_exists(struct vnode *vp, const char *dirname, 77 struct thread *td); 78 79#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) 80 81/* 82 * This vnode table stores what we want to do if the filesystem doesn't 83 * implement a particular VOP. 84 * 85 * If there is no specific entry here, we will return EOPNOTSUPP. 86 * 87 * Note that every filesystem has to implement either vop_access 88 * or vop_accessx; failing to do so will result in immediate crash 89 * due to stack overflow, as vop_stdaccess() calls vop_stdaccessx(), 90 * which calls vop_stdaccess() etc. 91 */ 92 93struct vop_vector default_vnodeops = { 94 .vop_default = NULL, 95 .vop_bypass = VOP_EOPNOTSUPP, 96 97 .vop_access = vop_stdaccess, 98 .vop_accessx = vop_stdaccessx, 99 .vop_advise = vop_stdadvise, 100 .vop_advlock = vop_stdadvlock, 101 .vop_advlockasync = vop_stdadvlockasync, 102 .vop_advlockpurge = vop_stdadvlockpurge, 103 .vop_allocate = vop_stdallocate, 104 .vop_bmap = vop_stdbmap, 105 .vop_close = VOP_NULL, 106 .vop_fsync = VOP_NULL, 107 .vop_getpages = vop_stdgetpages, 108 .vop_getwritemount = vop_stdgetwritemount, 109 .vop_inactive = VOP_NULL, 110 .vop_ioctl = VOP_ENOTTY, 111 .vop_kqfilter = vop_stdkqfilter, 112 .vop_islocked = vop_stdislocked, 113 .vop_lock1 = vop_stdlock, 114 .vop_lookup = vop_nolookup, 115 .vop_open = VOP_NULL, 116 .vop_pathconf = VOP_EINVAL, 117 .vop_poll = vop_nopoll, 118 .vop_putpages = vop_stdputpages, 119 .vop_readlink = VOP_EINVAL, 120 .vop_rename = vop_norename, 121 .vop_revoke = VOP_PANIC, 122 .vop_strategy = vop_nostrategy, 123 .vop_unlock = vop_stdunlock, 124 .vop_vptocnp = vop_stdvptocnp, 125 .vop_vptofh = vop_stdvptofh,
|
129}; 130 131/* 132 * Series of placeholder functions for various error returns for 133 * VOPs. 134 */ 135 136int 137vop_eopnotsupp(struct vop_generic_args *ap) 138{ 139 /* 140 printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name); 141 */ 142 143 return (EOPNOTSUPP); 144} 145 146int 147vop_ebadf(struct vop_generic_args *ap) 148{ 149 150 return (EBADF); 151} 152 153int 154vop_enotty(struct vop_generic_args *ap) 155{ 156 157 return (ENOTTY); 158} 159 160int 161vop_einval(struct vop_generic_args *ap) 162{ 163 164 return (EINVAL); 165} 166 167int 168vop_enoent(struct vop_generic_args *ap) 169{ 170 171 return (ENOENT); 172} 173 174int 175vop_null(struct vop_generic_args *ap) 176{ 177 178 return (0); 179} 180 181/* 182 * Helper function to panic on some bad VOPs in some filesystems. 183 */ 184int 185vop_panic(struct vop_generic_args *ap) 186{ 187 188 panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 189} 190 191/* 192 * vop_std<something> and vop_no<something> are default functions for use by 193 * filesystems that need the "default reasonable" implementation for a 194 * particular operation. 195 * 196 * The documentation for the operations they implement exists (if it exists) 197 * in the VOP_<SOMETHING>(9) manpage (all uppercase). 198 */ 199 200/* 201 * Default vop for filesystems that do not support name lookup 202 */ 203static int 204vop_nolookup(ap) 205 struct vop_lookup_args /* { 206 struct vnode *a_dvp; 207 struct vnode **a_vpp; 208 struct componentname *a_cnp; 209 } */ *ap; 210{ 211 212 *ap->a_vpp = NULL; 213 return (ENOTDIR); 214} 215 216/* 217 * vop_norename: 218 * 219 * Handle unlock and reference counting for arguments of vop_rename 220 * for filesystems that do not implement rename operation. 221 */ 222static int 223vop_norename(struct vop_rename_args *ap) 224{ 225 226 vop_rename_fail(ap); 227 return (EOPNOTSUPP); 228} 229 230/* 231 * vop_nostrategy: 232 * 233 * Strategy routine for VFS devices that have none. 234 * 235 * BIO_ERROR and B_INVAL must be cleared prior to calling any strategy 236 * routine. Typically this is done for a BIO_READ strategy call. 237 * Typically B_INVAL is assumed to already be clear prior to a write 238 * and should not be cleared manually unless you just made the buffer 239 * invalid. BIO_ERROR should be cleared either way. 240 */ 241 242static int 243vop_nostrategy (struct vop_strategy_args *ap) 244{ 245 printf("No strategy for buffer at %p\n", ap->a_bp); 246 vprint("vnode", ap->a_vp); 247 ap->a_bp->b_ioflags |= BIO_ERROR; 248 ap->a_bp->b_error = EOPNOTSUPP; 249 bufdone(ap->a_bp); 250 return (EOPNOTSUPP); 251} 252 253static int 254get_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, 255 int dirbuflen, off_t *off, char **cpos, int *len, 256 int *eofflag, struct thread *td) 257{ 258 int error, reclen; 259 struct uio uio; 260 struct iovec iov; 261 struct dirent *dp; 262 263 KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 264 KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 265 266 if (*len == 0) { 267 iov.iov_base = dirbuf; 268 iov.iov_len = dirbuflen; 269 270 uio.uio_iov = &iov; 271 uio.uio_iovcnt = 1; 272 uio.uio_offset = *off; 273 uio.uio_resid = dirbuflen; 274 uio.uio_segflg = UIO_SYSSPACE; 275 uio.uio_rw = UIO_READ; 276 uio.uio_td = td; 277 278 *eofflag = 0; 279 280#ifdef MAC 281 error = mac_vnode_check_readdir(td->td_ucred, vp); 282 if (error == 0) 283#endif 284 error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, 285 NULL, NULL); 286 if (error) 287 return (error); 288 289 *off = uio.uio_offset; 290 291 *cpos = dirbuf; 292 *len = (dirbuflen - uio.uio_resid); 293 294 if (*len == 0) 295 return (ENOENT); 296 } 297 298 dp = (struct dirent *)(*cpos); 299 reclen = dp->d_reclen; 300 *dpp = dp; 301 302 /* check for malformed directory.. */ 303 if (reclen < DIRENT_MINSIZE) 304 return (EINVAL); 305 306 *cpos += reclen; 307 *len -= reclen; 308 309 return (0); 310} 311 312/* 313 * Check if a named file exists in a given directory vnode. 314 */ 315static int 316dirent_exists(struct vnode *vp, const char *dirname, struct thread *td) 317{ 318 char *dirbuf, *cpos; 319 int error, eofflag, dirbuflen, len, found; 320 off_t off; 321 struct dirent *dp; 322 struct vattr va; 323 324 KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 325 KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 326 327 found = 0; 328 329 error = VOP_GETATTR(vp, &va, td->td_ucred); 330 if (error) 331 return (found); 332 333 dirbuflen = DEV_BSIZE; 334 if (dirbuflen < va.va_blocksize) 335 dirbuflen = va.va_blocksize; 336 dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 337 338 off = 0; 339 len = 0; 340 do { 341 error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, 342 &cpos, &len, &eofflag, td); 343 if (error) 344 goto out; 345 346 if ((dp->d_type != DT_WHT) && 347 !strcmp(dp->d_name, dirname)) { 348 found = 1; 349 goto out; 350 } 351 } while (len > 0 || !eofflag); 352 353out: 354 free(dirbuf, M_TEMP); 355 return (found); 356} 357 358int 359vop_stdaccess(struct vop_access_args *ap) 360{ 361 362 KASSERT((ap->a_accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | 363 VAPPEND)) == 0, ("invalid bit in accmode")); 364 365 return (VOP_ACCESSX(ap->a_vp, ap->a_accmode, ap->a_cred, ap->a_td)); 366} 367 368int 369vop_stdaccessx(struct vop_accessx_args *ap) 370{ 371 int error; 372 accmode_t accmode = ap->a_accmode; 373 374 error = vfs_unixify_accmode(&accmode); 375 if (error != 0) 376 return (error); 377 378 if (accmode == 0) 379 return (0); 380 381 return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td)); 382} 383 384/* 385 * Advisory record locking support 386 */ 387int 388vop_stdadvlock(struct vop_advlock_args *ap) 389{ 390 struct vnode *vp; 391 struct ucred *cred; 392 struct vattr vattr; 393 int error; 394 395 vp = ap->a_vp; 396 cred = curthread->td_ucred; 397 vn_lock(vp, LK_SHARED | LK_RETRY); 398 error = VOP_GETATTR(vp, &vattr, cred); 399 VOP_UNLOCK(vp, 0); 400 if (error) 401 return (error); 402 403 return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); 404} 405 406int 407vop_stdadvlockasync(struct vop_advlockasync_args *ap) 408{ 409 struct vnode *vp; 410 struct ucred *cred; 411 struct vattr vattr; 412 int error; 413 414 vp = ap->a_vp; 415 cred = curthread->td_ucred; 416 vn_lock(vp, LK_SHARED | LK_RETRY); 417 error = VOP_GETATTR(vp, &vattr, cred); 418 VOP_UNLOCK(vp, 0); 419 if (error) 420 return (error); 421 422 return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); 423} 424 425int 426vop_stdadvlockpurge(struct vop_advlockpurge_args *ap) 427{ 428 struct vnode *vp; 429 430 vp = ap->a_vp; 431 lf_purgelocks(vp, &vp->v_lockf); 432 return (0); 433} 434 435/* 436 * vop_stdpathconf: 437 * 438 * Standard implementation of POSIX pathconf, to get information about limits 439 * for a filesystem. 440 * Override per filesystem for the case where the filesystem has smaller 441 * limits. 442 */ 443int 444vop_stdpathconf(ap) 445 struct vop_pathconf_args /* { 446 struct vnode *a_vp; 447 int a_name; 448 int *a_retval; 449 } */ *ap; 450{ 451 452 switch (ap->a_name) { 453 case _PC_NAME_MAX: 454 *ap->a_retval = NAME_MAX; 455 return (0); 456 case _PC_PATH_MAX: 457 *ap->a_retval = PATH_MAX; 458 return (0); 459 case _PC_LINK_MAX: 460 *ap->a_retval = LINK_MAX; 461 return (0); 462 case _PC_MAX_CANON: 463 *ap->a_retval = MAX_CANON; 464 return (0); 465 case _PC_MAX_INPUT: 466 *ap->a_retval = MAX_INPUT; 467 return (0); 468 case _PC_PIPE_BUF: 469 *ap->a_retval = PIPE_BUF; 470 return (0); 471 case _PC_CHOWN_RESTRICTED: 472 *ap->a_retval = 1; 473 return (0); 474 case _PC_VDISABLE: 475 *ap->a_retval = _POSIX_VDISABLE; 476 return (0); 477 default: 478 return (EINVAL); 479 } 480 /* NOTREACHED */ 481} 482 483/* 484 * Standard lock, unlock and islocked functions. 485 */ 486int 487vop_stdlock(ap) 488 struct vop_lock1_args /* { 489 struct vnode *a_vp; 490 int a_flags; 491 char *file; 492 int line; 493 } */ *ap; 494{ 495 struct vnode *vp = ap->a_vp; 496 497 return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), 498 LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, 499 ap->a_line)); 500} 501 502/* See above. */ 503int 504vop_stdunlock(ap) 505 struct vop_unlock_args /* { 506 struct vnode *a_vp; 507 int a_flags; 508 } */ *ap; 509{ 510 struct vnode *vp = ap->a_vp; 511 512 return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); 513} 514 515/* See above. */ 516int 517vop_stdislocked(ap) 518 struct vop_islocked_args /* { 519 struct vnode *a_vp; 520 } */ *ap; 521{ 522 523 return (lockstatus(ap->a_vp->v_vnlock)); 524} 525 526/* 527 * Return true for select/poll. 528 */ 529int 530vop_nopoll(ap) 531 struct vop_poll_args /* { 532 struct vnode *a_vp; 533 int a_events; 534 struct ucred *a_cred; 535 struct thread *a_td; 536 } */ *ap; 537{ 538 539 return (poll_no_poll(ap->a_events)); 540} 541 542/* 543 * Implement poll for local filesystems that support it. 544 */ 545int 546vop_stdpoll(ap) 547 struct vop_poll_args /* { 548 struct vnode *a_vp; 549 int a_events; 550 struct ucred *a_cred; 551 struct thread *a_td; 552 } */ *ap; 553{ 554 if (ap->a_events & ~POLLSTANDARD) 555 return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 556 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 557} 558 559/* 560 * Return our mount point, as we will take charge of the writes. 561 */ 562int 563vop_stdgetwritemount(ap) 564 struct vop_getwritemount_args /* { 565 struct vnode *a_vp; 566 struct mount **a_mpp; 567 } */ *ap; 568{ 569 struct mount *mp; 570 571 /* 572 * XXX Since this is called unlocked we may be recycled while 573 * attempting to ref the mount. If this is the case or mountpoint 574 * will be set to NULL. We only have to prevent this call from 575 * returning with a ref to an incorrect mountpoint. It is not 576 * harmful to return with a ref to our previous mountpoint. 577 */ 578 mp = ap->a_vp->v_mount; 579 if (mp != NULL) { 580 vfs_ref(mp); 581 if (mp != ap->a_vp->v_mount) { 582 vfs_rel(mp); 583 mp = NULL; 584 } 585 } 586 *(ap->a_mpp) = mp; 587 return (0); 588} 589 590/* XXX Needs good comment and VOP_BMAP(9) manpage */ 591int 592vop_stdbmap(ap) 593 struct vop_bmap_args /* { 594 struct vnode *a_vp; 595 daddr_t a_bn; 596 struct bufobj **a_bop; 597 daddr_t *a_bnp; 598 int *a_runp; 599 int *a_runb; 600 } */ *ap; 601{ 602 603 if (ap->a_bop != NULL) 604 *ap->a_bop = &ap->a_vp->v_bufobj; 605 if (ap->a_bnp != NULL) 606 *ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize); 607 if (ap->a_runp != NULL) 608 *ap->a_runp = 0; 609 if (ap->a_runb != NULL) 610 *ap->a_runb = 0; 611 return (0); 612} 613 614int 615vop_stdfsync(ap) 616 struct vop_fsync_args /* { 617 struct vnode *a_vp; 618 struct ucred *a_cred; 619 int a_waitfor; 620 struct thread *a_td; 621 } */ *ap; 622{ 623 struct vnode *vp = ap->a_vp; 624 struct buf *bp; 625 struct bufobj *bo; 626 struct buf *nbp; 627 int error = 0; 628 int maxretry = 1000; /* large, arbitrarily chosen */ 629 630 bo = &vp->v_bufobj; 631 BO_LOCK(bo); 632loop1: 633 /* 634 * MARK/SCAN initialization to avoid infinite loops. 635 */ 636 TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { 637 bp->b_vflags &= ~BV_SCANNED; 638 bp->b_error = 0; 639 } 640 641 /* 642 * Flush all dirty buffers associated with a vnode. 643 */ 644loop2: 645 TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { 646 if ((bp->b_vflags & BV_SCANNED) != 0) 647 continue; 648 bp->b_vflags |= BV_SCANNED; 649 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) 650 continue; 651 BO_UNLOCK(bo); 652 KASSERT(bp->b_bufobj == bo, 653 ("bp %p wrong b_bufobj %p should be %p", 654 bp, bp->b_bufobj, bo)); 655 if ((bp->b_flags & B_DELWRI) == 0) 656 panic("fsync: not dirty"); 657 if ((vp->v_object != NULL) && (bp->b_flags & B_CLUSTEROK)) { 658 vfs_bio_awrite(bp); 659 } else { 660 bremfree(bp); 661 bawrite(bp); 662 } 663 BO_LOCK(bo); 664 goto loop2; 665 } 666 667 /* 668 * If synchronous the caller expects us to completely resolve all 669 * dirty buffers in the system. Wait for in-progress I/O to 670 * complete (which could include background bitmap writes), then 671 * retry if dirty blocks still exist. 672 */ 673 if (ap->a_waitfor == MNT_WAIT) { 674 bufobj_wwait(bo, 0, 0); 675 if (bo->bo_dirty.bv_cnt > 0) { 676 /* 677 * If we are unable to write any of these buffers 678 * then we fail now rather than trying endlessly 679 * to write them out. 680 */ 681 TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) 682 if ((error = bp->b_error) == 0) 683 continue; 684 if (error == 0 && --maxretry >= 0) 685 goto loop1; 686 error = EAGAIN; 687 } 688 } 689 BO_UNLOCK(bo); 690 if (error == EAGAIN) 691 vprint("fsync: giving up on dirty", vp); 692 693 return (error); 694} 695 696/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ 697int 698vop_stdgetpages(ap) 699 struct vop_getpages_args /* { 700 struct vnode *a_vp; 701 vm_page_t *a_m; 702 int a_count; 703 int a_reqpage; 704 vm_ooffset_t a_offset; 705 } */ *ap; 706{ 707 708 return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 709 ap->a_count, ap->a_reqpage); 710} 711 712int 713vop_stdkqfilter(struct vop_kqfilter_args *ap) 714{ 715 return vfs_kqfilter(ap); 716} 717 718/* XXX Needs good comment and more info in the manpage (VOP_PUTPAGES(9)). */ 719int 720vop_stdputpages(ap) 721 struct vop_putpages_args /* { 722 struct vnode *a_vp; 723 vm_page_t *a_m; 724 int a_count; 725 int a_sync; 726 int *a_rtvals; 727 vm_ooffset_t a_offset; 728 } */ *ap; 729{ 730 731 return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count, 732 ap->a_sync, ap->a_rtvals); 733} 734 735int 736vop_stdvptofh(struct vop_vptofh_args *ap) 737{ 738 return (EOPNOTSUPP); 739} 740 741int 742vop_stdvptocnp(struct vop_vptocnp_args *ap) 743{ 744 struct vnode *vp = ap->a_vp; 745 struct vnode **dvp = ap->a_vpp; 746 struct ucred *cred = ap->a_cred; 747 char *buf = ap->a_buf; 748 int *buflen = ap->a_buflen; 749 char *dirbuf, *cpos; 750 int i, error, eofflag, dirbuflen, flags, locked, len, covered; 751 off_t off; 752 ino_t fileno; 753 struct vattr va; 754 struct nameidata nd; 755 struct thread *td; 756 struct dirent *dp; 757 struct vnode *mvp; 758 759 i = *buflen; 760 error = 0; 761 covered = 0; 762 td = curthread; 763 764 if (vp->v_type != VDIR) 765 return (ENOENT); 766 767 error = VOP_GETATTR(vp, &va, cred); 768 if (error) 769 return (error); 770 771 VREF(vp); 772 locked = VOP_ISLOCKED(vp); 773 VOP_UNLOCK(vp, 0); 774 NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 775 "..", vp, td); 776 flags = FREAD; 777 error = vn_open_cred(&nd, &flags, 0, VN_OPEN_NOAUDIT, cred, NULL); 778 if (error) { 779 vn_lock(vp, locked | LK_RETRY); 780 return (error); 781 } 782 NDFREE(&nd, NDF_ONLY_PNBUF); 783 784 mvp = *dvp = nd.ni_vp; 785 786 if (vp->v_mount != (*dvp)->v_mount && 787 ((*dvp)->v_vflag & VV_ROOT) && 788 ((*dvp)->v_mount->mnt_flag & MNT_UNION)) { 789 *dvp = (*dvp)->v_mount->mnt_vnodecovered; 790 VREF(mvp); 791 VOP_UNLOCK(mvp, 0); 792 vn_close(mvp, FREAD, cred, td); 793 VREF(*dvp); 794 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 795 covered = 1; 796 } 797 798 fileno = va.va_fileid; 799 800 dirbuflen = DEV_BSIZE; 801 if (dirbuflen < va.va_blocksize) 802 dirbuflen = va.va_blocksize; 803 dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 804 805 if ((*dvp)->v_type != VDIR) { 806 error = ENOENT; 807 goto out; 808 } 809 810 off = 0; 811 len = 0; 812 do { 813 /* call VOP_READDIR of parent */ 814 error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, 815 &cpos, &len, &eofflag, td); 816 if (error) 817 goto out; 818 819 if ((dp->d_type != DT_WHT) && 820 (dp->d_fileno == fileno)) { 821 if (covered) { 822 VOP_UNLOCK(*dvp, 0); 823 vn_lock(mvp, LK_EXCLUSIVE | LK_RETRY); 824 if (dirent_exists(mvp, dp->d_name, td)) { 825 error = ENOENT; 826 VOP_UNLOCK(mvp, 0); 827 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 828 goto out; 829 } 830 VOP_UNLOCK(mvp, 0); 831 vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 832 } 833 i -= dp->d_namlen; 834 835 if (i < 0) { 836 error = ENOMEM; 837 goto out; 838 } 839 bcopy(dp->d_name, buf + i, dp->d_namlen); 840 error = 0; 841 goto out; 842 } 843 } while (len > 0 || !eofflag); 844 error = ENOENT; 845 846out: 847 free(dirbuf, M_TEMP); 848 if (!error) { 849 *buflen = i; 850 vref(*dvp); 851 } 852 if (covered) { 853 vput(*dvp); 854 vrele(mvp); 855 } else { 856 VOP_UNLOCK(mvp, 0); 857 vn_close(mvp, FREAD, cred, td); 858 } 859 vn_lock(vp, locked | LK_RETRY); 860 return (error); 861} 862 863int 864vop_stdallocate(struct vop_allocate_args *ap) 865{ 866#ifdef __notyet__ 867 struct statfs sfs; 868#endif 869 struct iovec aiov; 870 struct vattr vattr, *vap; 871 struct uio auio; 872 off_t fsize, len, cur, offset; 873 uint8_t *buf; 874 struct thread *td; 875 struct vnode *vp; 876 size_t iosize; 877 int error; 878 879 buf = NULL; 880 error = 0; 881 td = curthread; 882 vap = &vattr; 883 vp = ap->a_vp; 884 len = *ap->a_len; 885 offset = *ap->a_offset; 886 887 error = VOP_GETATTR(vp, vap, td->td_ucred); 888 if (error != 0) 889 goto out; 890 fsize = vap->va_size; 891 iosize = vap->va_blocksize; 892 if (iosize == 0) 893 iosize = BLKDEV_IOSIZE; 894 if (iosize > MAXPHYS) 895 iosize = MAXPHYS; 896 buf = malloc(iosize, M_TEMP, M_WAITOK); 897 898#ifdef __notyet__ 899 /* 900 * Check if the filesystem sets f_maxfilesize; if not use 901 * VOP_SETATTR to perform the check. 902 */ 903 error = VFS_STATFS(vp->v_mount, &sfs, td); 904 if (error != 0) 905 goto out; 906 if (sfs.f_maxfilesize) { 907 if (offset > sfs.f_maxfilesize || len > sfs.f_maxfilesize || 908 offset + len > sfs.f_maxfilesize) { 909 error = EFBIG; 910 goto out; 911 } 912 } else 913#endif 914 if (offset + len > vap->va_size) { 915 /* 916 * Test offset + len against the filesystem's maxfilesize. 917 */ 918 VATTR_NULL(vap); 919 vap->va_size = offset + len; 920 error = VOP_SETATTR(vp, vap, td->td_ucred); 921 if (error != 0) 922 goto out; 923 VATTR_NULL(vap); 924 vap->va_size = fsize; 925 error = VOP_SETATTR(vp, vap, td->td_ucred); 926 if (error != 0) 927 goto out; 928 } 929 930 for (;;) { 931 /* 932 * Read and write back anything below the nominal file 933 * size. There's currently no way outside the filesystem 934 * to know whether this area is sparse or not. 935 */ 936 cur = iosize; 937 if ((offset % iosize) != 0) 938 cur -= (offset % iosize); 939 if (cur > len) 940 cur = len; 941 if (offset < fsize) { 942 aiov.iov_base = buf; 943 aiov.iov_len = cur; 944 auio.uio_iov = &aiov; 945 auio.uio_iovcnt = 1; 946 auio.uio_offset = offset; 947 auio.uio_resid = cur; 948 auio.uio_segflg = UIO_SYSSPACE; 949 auio.uio_rw = UIO_READ; 950 auio.uio_td = td; 951 error = VOP_READ(vp, &auio, 0, td->td_ucred); 952 if (error != 0) 953 break; 954 if (auio.uio_resid > 0) { 955 bzero(buf + cur - auio.uio_resid, 956 auio.uio_resid); 957 } 958 } else { 959 bzero(buf, cur); 960 } 961 962 aiov.iov_base = buf; 963 aiov.iov_len = cur; 964 auio.uio_iov = &aiov; 965 auio.uio_iovcnt = 1; 966 auio.uio_offset = offset; 967 auio.uio_resid = cur; 968 auio.uio_segflg = UIO_SYSSPACE; 969 auio.uio_rw = UIO_WRITE; 970 auio.uio_td = td; 971 972 error = VOP_WRITE(vp, &auio, 0, td->td_ucred); 973 if (error != 0) 974 break; 975 976 len -= cur; 977 offset += cur; 978 if (len == 0) 979 break; 980 if (should_yield()) 981 break; 982 } 983 984 out: 985 *ap->a_len = len; 986 *ap->a_offset = offset; 987 free(buf, M_TEMP); 988 return (error); 989} 990 991int 992vop_stdadvise(struct vop_advise_args *ap) 993{ 994 struct vnode *vp; 995 off_t start, end; 996 int error, vfslocked; 997 998 vp = ap->a_vp; 999 switch (ap->a_advice) { 1000 case POSIX_FADV_WILLNEED: 1001 /* 1002 * Do nothing for now. Filesystems should provide a 1003 * custom method which starts an asynchronous read of 1004 * the requested region. 1005 */ 1006 error = 0; 1007 break; 1008 case POSIX_FADV_DONTNEED: 1009 /* 1010 * Flush any open FS buffers and then remove pages 1011 * from the backing VM object. Using vinvalbuf() here 1012 * is a bit heavy-handed as it flushes all buffers for 1013 * the given vnode, not just the buffers covering the 1014 * requested range. 1015 */ 1016 error = 0; 1017 vfslocked = VFS_LOCK_GIANT(vp->v_mount); 1018 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1019 if (vp->v_iflag & VI_DOOMED) { 1020 VOP_UNLOCK(vp, 0); 1021 VFS_UNLOCK_GIANT(vfslocked); 1022 break; 1023 } 1024 vinvalbuf(vp, V_CLEANONLY, 0, 0); 1025 if (vp->v_object != NULL) { 1026 start = trunc_page(ap->a_start); 1027 end = round_page(ap->a_end); 1028 VM_OBJECT_LOCK(vp->v_object); 1029 vm_object_page_cache(vp->v_object, OFF_TO_IDX(start), 1030 OFF_TO_IDX(end)); 1031 VM_OBJECT_UNLOCK(vp->v_object); 1032 } 1033 VOP_UNLOCK(vp, 0); 1034 VFS_UNLOCK_GIANT(vfslocked); 1035 break; 1036 default: 1037 error = EINVAL; 1038 break; 1039 } 1040 return (error); 1041} 1042
|