vfs_default.c revision 276192
1139804Simp/*- 230489Sphk * Copyright (c) 1989, 1993 330489Sphk * The Regents of the University of California. All rights reserved. 430489Sphk * 530489Sphk * This code is derived from software contributed 630489Sphk * to Berkeley by John Heidemann of the UCLA Ficus project. 730489Sphk * 830489Sphk * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project 930489Sphk * 1030489Sphk * Redistribution and use in source and binary forms, with or without 1130489Sphk * modification, are permitted provided that the following conditions 1230489Sphk * are met: 1330489Sphk * 1. Redistributions of source code must retain the above copyright 1430489Sphk * notice, this list of conditions and the following disclaimer. 1530489Sphk * 2. Redistributions in binary form must reproduce the above copyright 1630489Sphk * notice, this list of conditions and the following disclaimer in the 1730489Sphk * documentation and/or other materials provided with the distribution. 1830489Sphk * 4. Neither the name of the University nor the names of its contributors 1930489Sphk * may be used to endorse or promote products derived from this software 2030489Sphk * without specific prior written permission. 2130489Sphk * 2230489Sphk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2330489Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2430489Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2530489Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2630489Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2730489Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2830489Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2930489Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3030489Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3130489Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3230489Sphk * SUCH DAMAGE. 3330489Sphk */ 3430489Sphk 35116182Sobrien#include <sys/cdefs.h> 36116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/vfs_default.c 276192 2014-12-24 22:58:08Z rmacklem $"); 37116182Sobrien 3830489Sphk#include <sys/param.h> 3930489Sphk#include <sys/systm.h> 4060041Sphk#include <sys/bio.h> 4144272Sbde#include <sys/buf.h> 4265770Sbp#include <sys/conf.h> 43147198Sssouhlal#include <sys/event.h> 4430489Sphk#include <sys/kernel.h> 45114216Skan#include <sys/limits.h> 4631561Sbde#include <sys/lock.h> 47178243Skib#include <sys/lockf.h> 4830743Sphk#include <sys/malloc.h> 4951068Salfred#include <sys/mount.h> 50189539Smarcus#include <sys/namei.h> 51248084Sattilio#include <sys/rwlock.h> 52189539Smarcus#include <sys/fcntl.h> 5330492Sphk#include <sys/unistd.h> 5430489Sphk#include <sys/vnode.h> 55189539Smarcus#include <sys/dirent.h> 5630743Sphk#include <sys/poll.h> 5730489Sphk 58193508Srwatson#include <security/mac/mac_framework.h> 59193508Srwatson 6065770Sbp#include <vm/vm.h> 6165770Sbp#include <vm/vm_object.h> 6265770Sbp#include <vm/vm_extern.h> 6365770Sbp#include <vm/pmap.h> 6465770Sbp#include <vm/vm_map.h> 6565770Sbp#include <vm/vm_page.h> 6665770Sbp#include <vm/vm_pager.h> 6765770Sbp#include <vm/vnode_pager.h> 6865770Sbp 6992723Salfredstatic int vop_nolookup(struct vop_lookup_args *); 70206094Skibstatic int vop_norename(struct vop_rename_args *); 7192723Salfredstatic int vop_nostrategy(struct vop_strategy_args *); 72189539Smarcusstatic int get_next_dirent(struct vnode *vp, struct dirent **dpp, 73189539Smarcus char *dirbuf, int dirbuflen, off_t *off, 74189539Smarcus char **cpos, int *len, int *eofflag, 75189539Smarcus struct thread *td); 76189539Smarcusstatic int dirent_exists(struct vnode *vp, const char *dirname, 77189539Smarcus struct thread *td); 7830489Sphk 79189539Smarcus#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) 80189539Smarcus 81241025Skibstatic int vop_stdis_text(struct vop_is_text_args *ap); 82241025Skibstatic int vop_stdset_text(struct vop_set_text_args *ap); 83241025Skibstatic int vop_stdunset_text(struct vop_unset_text_args *ap); 84242476Skibstatic int vop_stdget_writecount(struct vop_get_writecount_args *ap); 85242476Skibstatic int vop_stdadd_writecount(struct vop_add_writecount_args *ap); 86274914Sglebiusstatic int vop_stdgetpages_async(struct vop_getpages_async_args *ap); 87241025Skib 8830489Sphk/* 8930489Sphk * This vnode table stores what we want to do if the filesystem doesn't 9030489Sphk * implement a particular VOP. 9130489Sphk * 9230489Sphk * If there is no specific entry here, we will return EOPNOTSUPP. 9330489Sphk * 94197680Strasz * Note that every filesystem has to implement either vop_access 95197680Strasz * or vop_accessx; failing to do so will result in immediate crash 96197680Strasz * due to stack overflow, as vop_stdaccess() calls vop_stdaccessx(), 97197680Strasz * which calls vop_stdaccess() etc. 9830489Sphk */ 9930489Sphk 100138290Sphkstruct vop_vector default_vnodeops = { 101138290Sphk .vop_default = NULL, 102138339Sphk .vop_bypass = VOP_EOPNOTSUPP, 103138339Sphk 104197680Strasz .vop_access = vop_stdaccess, 105193092Strasz .vop_accessx = vop_stdaccessx, 106227070Sjhb .vop_advise = vop_stdadvise, 107178243Skib .vop_advlock = vop_stdadvlock, 108178243Skib .vop_advlockasync = vop_stdadvlockasync, 109208003Szml .vop_advlockpurge = vop_stdadvlockpurge, 110220791Smdf .vop_allocate = vop_stdallocate, 111138290Sphk .vop_bmap = vop_stdbmap, 112138290Sphk .vop_close = VOP_NULL, 113138290Sphk .vop_fsync = VOP_NULL, 114138290Sphk .vop_getpages = vop_stdgetpages, 115274914Sglebius .vop_getpages_async = vop_stdgetpages_async, 116138290Sphk .vop_getwritemount = vop_stdgetwritemount, 117143494Sjeff .vop_inactive = VOP_NULL, 118138290Sphk .vop_ioctl = VOP_ENOTTY, 119147198Sssouhlal .vop_kqfilter = vop_stdkqfilter, 120138290Sphk .vop_islocked = vop_stdislocked, 121169671Skib .vop_lock1 = vop_stdlock, 122138290Sphk .vop_lookup = vop_nolookup, 123138290Sphk .vop_open = VOP_NULL, 124138290Sphk .vop_pathconf = VOP_EINVAL, 125138290Sphk .vop_poll = vop_nopoll, 126138290Sphk .vop_putpages = vop_stdputpages, 127138290Sphk .vop_readlink = VOP_EINVAL, 128206094Skib .vop_rename = vop_norename, 129138290Sphk .vop_revoke = VOP_PANIC, 130138290Sphk .vop_strategy = vop_nostrategy, 131138290Sphk .vop_unlock = vop_stdunlock, 132189539Smarcus .vop_vptocnp = vop_stdvptocnp, 133166774Spjd .vop_vptofh = vop_stdvptofh, 134232317Strociny .vop_unp_bind = vop_stdunp_bind, 135232317Strociny .vop_unp_connect = vop_stdunp_connect, 136232317Strociny .vop_unp_detach = vop_stdunp_detach, 137241025Skib .vop_is_text = vop_stdis_text, 138241025Skib .vop_set_text = vop_stdset_text, 139241025Skib .vop_unset_text = vop_stdunset_text, 140242476Skib .vop_get_writecount = vop_stdget_writecount, 141242476Skib .vop_add_writecount = vop_stdadd_writecount, 14230489Sphk}; 14330489Sphk 14491690Seivind/* 14591690Seivind * Series of placeholder functions for various error returns for 14691690Seivind * VOPs. 14791690Seivind */ 14891690Seivind 14930489Sphkint 15030492Sphkvop_eopnotsupp(struct vop_generic_args *ap) 15130489Sphk{ 15230489Sphk /* 15330492Sphk printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name); 15430489Sphk */ 15530489Sphk 15630489Sphk return (EOPNOTSUPP); 15730489Sphk} 15830489Sphk 15930489Sphkint 16030492Sphkvop_ebadf(struct vop_generic_args *ap) 16130489Sphk{ 16230489Sphk 16330492Sphk return (EBADF); 16430492Sphk} 16530492Sphk 16630492Sphkint 16730492Sphkvop_enotty(struct vop_generic_args *ap) 16830492Sphk{ 16930492Sphk 17030492Sphk return (ENOTTY); 17130492Sphk} 17230492Sphk 17330492Sphkint 17430492Sphkvop_einval(struct vop_generic_args *ap) 17530492Sphk{ 17630492Sphk 17730492Sphk return (EINVAL); 17830492Sphk} 17930492Sphk 18030492Sphkint 181185956Smarcusvop_enoent(struct vop_generic_args *ap) 182185956Smarcus{ 183185956Smarcus 184185956Smarcus return (ENOENT); 185185956Smarcus} 186185956Smarcus 187185956Smarcusint 18830492Sphkvop_null(struct vop_generic_args *ap) 18930492Sphk{ 19030492Sphk 19130492Sphk return (0); 19230492Sphk} 19330492Sphk 19491690Seivind/* 19591690Seivind * Helper function to panic on some bad VOPs in some filesystems. 19691690Seivind */ 19741056Speterint 19841056Spetervop_panic(struct vop_generic_args *ap) 19941056Speter{ 20041056Speter 20172594Sbde panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 20241056Speter} 20341056Speter 20491690Seivind/* 20591690Seivind * vop_std<something> and vop_no<something> are default functions for use by 20691690Seivind * filesystems that need the "default reasonable" implementation for a 20791690Seivind * particular operation. 20891690Seivind * 20991690Seivind * The documentation for the operations they implement exists (if it exists) 21091690Seivind * in the VOP_<SOMETHING>(9) manpage (all uppercase). 21191690Seivind */ 21291690Seivind 21391690Seivind/* 21491690Seivind * Default vop for filesystems that do not support name lookup 21591690Seivind */ 21672594Sbdestatic int 21772594Sbdevop_nolookup(ap) 21872594Sbde struct vop_lookup_args /* { 21972594Sbde struct vnode *a_dvp; 22072594Sbde struct vnode **a_vpp; 22172594Sbde struct componentname *a_cnp; 22272594Sbde } */ *ap; 22372594Sbde{ 22472594Sbde 22572594Sbde *ap->a_vpp = NULL; 22672594Sbde return (ENOTDIR); 22772594Sbde} 22872594Sbde 22946349Salc/* 230206094Skib * vop_norename: 231206094Skib * 232206094Skib * Handle unlock and reference counting for arguments of vop_rename 233206094Skib * for filesystems that do not implement rename operation. 234206094Skib */ 235206094Skibstatic int 236206094Skibvop_norename(struct vop_rename_args *ap) 237206094Skib{ 238206094Skib 239206094Skib vop_rename_fail(ap); 240206094Skib return (EOPNOTSUPP); 241206094Skib} 242206094Skib 243206094Skib/* 24446349Salc * vop_nostrategy: 24546349Salc * 24646349Salc * Strategy routine for VFS devices that have none. 24746349Salc * 24858934Sphk * BIO_ERROR and B_INVAL must be cleared prior to calling any strategy 24958345Sphk * routine. Typically this is done for a BIO_READ strategy call. 250112067Skan * Typically B_INVAL is assumed to already be clear prior to a write 25158345Sphk * and should not be cleared manually unless you just made the buffer 25258934Sphk * invalid. BIO_ERROR should be cleared either way. 25346349Salc */ 25446349Salc 25530489Sphkstatic int 25630489Sphkvop_nostrategy (struct vop_strategy_args *ap) 25730489Sphk{ 25830489Sphk printf("No strategy for buffer at %p\n", ap->a_bp); 259111842Snjl vprint("vnode", ap->a_vp); 26058934Sphk ap->a_bp->b_ioflags |= BIO_ERROR; 26130489Sphk ap->a_bp->b_error = EOPNOTSUPP; 26259249Sphk bufdone(ap->a_bp); 26330489Sphk return (EOPNOTSUPP); 26430489Sphk} 26530492Sphk 266189539Smarcusstatic int 267189539Smarcusget_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, 268189539Smarcus int dirbuflen, off_t *off, char **cpos, int *len, 269189539Smarcus int *eofflag, struct thread *td) 270189539Smarcus{ 271189539Smarcus int error, reclen; 272189539Smarcus struct uio uio; 273189539Smarcus struct iovec iov; 274189539Smarcus struct dirent *dp; 275189539Smarcus 276189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 277189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 278189539Smarcus 279189539Smarcus if (*len == 0) { 280189539Smarcus iov.iov_base = dirbuf; 281189539Smarcus iov.iov_len = dirbuflen; 282189539Smarcus 283189539Smarcus uio.uio_iov = &iov; 284189539Smarcus uio.uio_iovcnt = 1; 285189539Smarcus uio.uio_offset = *off; 286189539Smarcus uio.uio_resid = dirbuflen; 287189539Smarcus uio.uio_segflg = UIO_SYSSPACE; 288189539Smarcus uio.uio_rw = UIO_READ; 289189539Smarcus uio.uio_td = td; 290189539Smarcus 291189539Smarcus *eofflag = 0; 292189539Smarcus 293189539Smarcus#ifdef MAC 294189539Smarcus error = mac_vnode_check_readdir(td->td_ucred, vp); 295189539Smarcus if (error == 0) 296189539Smarcus#endif 297189539Smarcus error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, 298189539Smarcus NULL, NULL); 299189539Smarcus if (error) 300189539Smarcus return (error); 301189539Smarcus 302211818Sbrian *off = uio.uio_offset; 303211818Sbrian 304211684Sbrian *cpos = dirbuf; 305211818Sbrian *len = (dirbuflen - uio.uio_resid); 306211818Sbrian 307211818Sbrian if (*len == 0) 308211818Sbrian return (ENOENT); 309189539Smarcus } 310189539Smarcus 311189539Smarcus dp = (struct dirent *)(*cpos); 312189539Smarcus reclen = dp->d_reclen; 313189539Smarcus *dpp = dp; 314189539Smarcus 315189539Smarcus /* check for malformed directory.. */ 316189539Smarcus if (reclen < DIRENT_MINSIZE) 317189539Smarcus return (EINVAL); 318189539Smarcus 319189539Smarcus *cpos += reclen; 320189539Smarcus *len -= reclen; 321189539Smarcus 322189539Smarcus return (0); 323189539Smarcus} 324189539Smarcus 32591690Seivind/* 326189539Smarcus * Check if a named file exists in a given directory vnode. 327189539Smarcus */ 328189539Smarcusstatic int 329189539Smarcusdirent_exists(struct vnode *vp, const char *dirname, struct thread *td) 330189539Smarcus{ 331189539Smarcus char *dirbuf, *cpos; 332189539Smarcus int error, eofflag, dirbuflen, len, found; 333189539Smarcus off_t off; 334189539Smarcus struct dirent *dp; 335189539Smarcus struct vattr va; 336189539Smarcus 337189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 338189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 339189539Smarcus 340189539Smarcus found = 0; 341189539Smarcus 342189539Smarcus error = VOP_GETATTR(vp, &va, td->td_ucred); 343189539Smarcus if (error) 344189539Smarcus return (found); 345189539Smarcus 346189539Smarcus dirbuflen = DEV_BSIZE; 347189539Smarcus if (dirbuflen < va.va_blocksize) 348189539Smarcus dirbuflen = va.va_blocksize; 349189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 350189539Smarcus 351189539Smarcus off = 0; 352189539Smarcus len = 0; 353189539Smarcus do { 354189539Smarcus error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, 355189539Smarcus &cpos, &len, &eofflag, td); 356189539Smarcus if (error) 357189539Smarcus goto out; 358189539Smarcus 359235503Sgleb if (dp->d_type != DT_WHT && dp->d_fileno != 0 && 360235503Sgleb strcmp(dp->d_name, dirname) == 0) { 361189539Smarcus found = 1; 362189539Smarcus goto out; 363189539Smarcus } 364189539Smarcus } while (len > 0 || !eofflag); 365189539Smarcus 366189539Smarcusout: 367189539Smarcus free(dirbuf, M_TEMP); 368189539Smarcus return (found); 369189539Smarcus} 370189539Smarcus 371193092Straszint 372197680Straszvop_stdaccess(struct vop_access_args *ap) 373197680Strasz{ 374197680Strasz 375197680Strasz KASSERT((ap->a_accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | 376197680Strasz VAPPEND)) == 0, ("invalid bit in accmode")); 377197680Strasz 378197680Strasz return (VOP_ACCESSX(ap->a_vp, ap->a_accmode, ap->a_cred, ap->a_td)); 379197680Strasz} 380197680Strasz 381197680Straszint 382193092Straszvop_stdaccessx(struct vop_accessx_args *ap) 383193092Strasz{ 384193092Strasz int error; 385193092Strasz accmode_t accmode = ap->a_accmode; 386193092Strasz 387193092Strasz error = vfs_unixify_accmode(&accmode); 388193092Strasz if (error != 0) 389193092Strasz return (error); 390193092Strasz 391193092Strasz if (accmode == 0) 392193092Strasz return (0); 393193092Strasz 394193092Strasz return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td)); 395193092Strasz} 396193092Strasz 397189539Smarcus/* 398178243Skib * Advisory record locking support 399178243Skib */ 400178243Skibint 401178243Skibvop_stdadvlock(struct vop_advlock_args *ap) 402178243Skib{ 403182371Sattilio struct vnode *vp; 404178243Skib struct vattr vattr; 405178243Skib int error; 406178243Skib 407182371Sattilio vp = ap->a_vp; 408276192Srmacklem if (ap->a_fl->l_whence == SEEK_END) { 409276192Srmacklem /* 410276192Srmacklem * The NFSv4 server will LOR/deadlock if a vn_lock() call 411276192Srmacklem * is done on vp. Fortunately, vattr.va_size is only 412276192Srmacklem * needed for SEEK_END and the NFSv4 server only uses SEEK_SET. 413276192Srmacklem */ 414276192Srmacklem vn_lock(vp, LK_SHARED | LK_RETRY); 415276192Srmacklem error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 416276192Srmacklem VOP_UNLOCK(vp, 0); 417276192Srmacklem if (error) 418276192Srmacklem return (error); 419276192Srmacklem } else 420276192Srmacklem vattr.va_size = 0; 421178243Skib 422178243Skib return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); 423178243Skib} 424178243Skib 425178243Skibint 426178243Skibvop_stdadvlockasync(struct vop_advlockasync_args *ap) 427178243Skib{ 428182371Sattilio struct vnode *vp; 429178243Skib struct vattr vattr; 430178243Skib int error; 431178243Skib 432182371Sattilio vp = ap->a_vp; 433276192Srmacklem if (ap->a_fl->l_whence == SEEK_END) { 434276192Srmacklem /* The size argument is only needed for SEEK_END. */ 435276192Srmacklem vn_lock(vp, LK_SHARED | LK_RETRY); 436276192Srmacklem error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); 437276192Srmacklem VOP_UNLOCK(vp, 0); 438276192Srmacklem if (error) 439276192Srmacklem return (error); 440276192Srmacklem } else 441276192Srmacklem vattr.va_size = 0; 442178243Skib 443178243Skib return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); 444178243Skib} 445178243Skib 446208003Szmlint 447208003Szmlvop_stdadvlockpurge(struct vop_advlockpurge_args *ap) 448208003Szml{ 449208003Szml struct vnode *vp; 450208003Szml 451208003Szml vp = ap->a_vp; 452208003Szml lf_purgelocks(vp, &vp->v_lockf); 453208003Szml return (0); 454208003Szml} 455208003Szml 456178243Skib/* 45791690Seivind * vop_stdpathconf: 458112067Skan * 45991690Seivind * Standard implementation of POSIX pathconf, to get information about limits 46091690Seivind * for a filesystem. 46191690Seivind * Override per filesystem for the case where the filesystem has smaller 46291690Seivind * limits. 46391690Seivind */ 46430492Sphkint 46530492Sphkvop_stdpathconf(ap) 46630492Sphk struct vop_pathconf_args /* { 46730492Sphk struct vnode *a_vp; 46830492Sphk int a_name; 46930492Sphk int *a_retval; 47030492Sphk } */ *ap; 47130492Sphk{ 47230492Sphk 47330492Sphk switch (ap->a_name) { 474149175Sphk case _PC_NAME_MAX: 475149175Sphk *ap->a_retval = NAME_MAX; 476149175Sphk return (0); 477149175Sphk case _PC_PATH_MAX: 478149175Sphk *ap->a_retval = PATH_MAX; 479149175Sphk return (0); 48030492Sphk case _PC_LINK_MAX: 48130492Sphk *ap->a_retval = LINK_MAX; 48230492Sphk return (0); 48330492Sphk case _PC_MAX_CANON: 48430492Sphk *ap->a_retval = MAX_CANON; 48530492Sphk return (0); 48630492Sphk case _PC_MAX_INPUT: 48730492Sphk *ap->a_retval = MAX_INPUT; 48830492Sphk return (0); 48930492Sphk case _PC_PIPE_BUF: 49030492Sphk *ap->a_retval = PIPE_BUF; 49130492Sphk return (0); 49230492Sphk case _PC_CHOWN_RESTRICTED: 49330492Sphk *ap->a_retval = 1; 49430492Sphk return (0); 49530492Sphk case _PC_VDISABLE: 49630492Sphk *ap->a_retval = _POSIX_VDISABLE; 49730492Sphk return (0); 49830492Sphk default: 49930492Sphk return (EINVAL); 50030492Sphk } 50130492Sphk /* NOTREACHED */ 50230492Sphk} 50330513Sphk 50430513Sphk/* 50530513Sphk * Standard lock, unlock and islocked functions. 50630513Sphk */ 50730513Sphkint 50830513Sphkvop_stdlock(ap) 509169671Skib struct vop_lock1_args /* { 51030513Sphk struct vnode *a_vp; 51130513Sphk int a_flags; 512164248Skmacy char *file; 513164248Skmacy int line; 51430513Sphk } */ *ap; 515112067Skan{ 51666355Sbp struct vnode *vp = ap->a_vp; 51730513Sphk 518176320Sattilio return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), 519176320Sattilio LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, 520175635Sattilio ap->a_line)); 52130513Sphk} 52230513Sphk 52391690Seivind/* See above. */ 52430513Sphkint 52530513Sphkvop_stdunlock(ap) 52630513Sphk struct vop_unlock_args /* { 52730513Sphk struct vnode *a_vp; 52830513Sphk int a_flags; 52930513Sphk } */ *ap; 53030513Sphk{ 53166355Sbp struct vnode *vp = ap->a_vp; 53230513Sphk 533175635Sattilio return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); 53430513Sphk} 53530513Sphk 53691690Seivind/* See above. */ 53730513Sphkint 53830513Sphkvop_stdislocked(ap) 53930513Sphk struct vop_islocked_args /* { 54030513Sphk struct vnode *a_vp; 54130513Sphk } */ *ap; 54230513Sphk{ 54330513Sphk 544176559Sattilio return (lockstatus(ap->a_vp->v_vnlock)); 54530513Sphk} 54630513Sphk 54730743Sphk/* 54830743Sphk * Return true for select/poll. 54930743Sphk */ 55030743Sphkint 55130743Sphkvop_nopoll(ap) 55230743Sphk struct vop_poll_args /* { 55330743Sphk struct vnode *a_vp; 55430743Sphk int a_events; 55530743Sphk struct ucred *a_cred; 55683366Sjulian struct thread *a_td; 55730743Sphk } */ *ap; 55830743Sphk{ 55931727Swollman 560189450Skib return (poll_no_poll(ap->a_events)); 56130743Sphk} 56230743Sphk 56331727Swollman/* 56431727Swollman * Implement poll for local filesystems that support it. 56531727Swollman */ 56630743Sphkint 56731727Swollmanvop_stdpoll(ap) 56831727Swollman struct vop_poll_args /* { 56931727Swollman struct vnode *a_vp; 57031727Swollman int a_events; 57131727Swollman struct ucred *a_cred; 57283366Sjulian struct thread *a_td; 57331727Swollman } */ *ap; 57431727Swollman{ 57576578Sjlemon if (ap->a_events & ~POLLSTANDARD) 57683366Sjulian return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 57776578Sjlemon return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 57831727Swollman} 57931727Swollman 58030743Sphk/* 58162976Smckusick * Return our mount point, as we will take charge of the writes. 58262976Smckusick */ 58362976Smckusickint 58462976Smckusickvop_stdgetwritemount(ap) 58562976Smckusick struct vop_getwritemount_args /* { 58662976Smckusick struct vnode *a_vp; 58762976Smckusick struct mount **a_mpp; 58862976Smckusick } */ *ap; 58962976Smckusick{ 590157323Sjeff struct mount *mp; 59162976Smckusick 592157323Sjeff /* 593157323Sjeff * XXX Since this is called unlocked we may be recycled while 594157323Sjeff * attempting to ref the mount. If this is the case or mountpoint 595157323Sjeff * will be set to NULL. We only have to prevent this call from 596157323Sjeff * returning with a ref to an incorrect mountpoint. It is not 597157323Sjeff * harmful to return with a ref to our previous mountpoint. 598157323Sjeff */ 599157323Sjeff mp = ap->a_vp->v_mount; 600162455Stegge if (mp != NULL) { 601162455Stegge vfs_ref(mp); 602162455Stegge if (mp != ap->a_vp->v_mount) { 603162455Stegge vfs_rel(mp); 604162455Stegge mp = NULL; 605162455Stegge } 606157323Sjeff } 607157323Sjeff *(ap->a_mpp) = mp; 60862976Smckusick return (0); 60962976Smckusick} 61062976Smckusick 61191690Seivind/* XXX Needs good comment and VOP_BMAP(9) manpage */ 61276131Sphkint 61376131Sphkvop_stdbmap(ap) 614112067Skan struct vop_bmap_args /* { 61576131Sphk struct vnode *a_vp; 61676131Sphk daddr_t a_bn; 617137726Sphk struct bufobj **a_bop; 61876131Sphk daddr_t *a_bnp; 61976131Sphk int *a_runp; 62076131Sphk int *a_runb; 62176131Sphk } */ *ap; 62276131Sphk{ 62376131Sphk 624137726Sphk if (ap->a_bop != NULL) 625137726Sphk *ap->a_bop = &ap->a_vp->v_bufobj; 62676131Sphk if (ap->a_bnp != NULL) 62776131Sphk *ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize); 62876131Sphk if (ap->a_runp != NULL) 62976131Sphk *ap->a_runp = 0; 63076131Sphk if (ap->a_runb != NULL) 63176131Sphk *ap->a_runb = 0; 63276131Sphk return (0); 63376131Sphk} 63476131Sphk 635110584Sjeffint 636110584Sjeffvop_stdfsync(ap) 637110584Sjeff struct vop_fsync_args /* { 638110584Sjeff struct vnode *a_vp; 639110584Sjeff struct ucred *a_cred; 640110584Sjeff int a_waitfor; 641110584Sjeff struct thread *a_td; 642110584Sjeff } */ *ap; 643110584Sjeff{ 644110584Sjeff struct vnode *vp = ap->a_vp; 645110584Sjeff struct buf *bp; 646136751Sphk struct bufobj *bo; 647110584Sjeff struct buf *nbp; 648145732Sjeff int error = 0; 649144584Sjeff int maxretry = 1000; /* large, arbitrarily chosen */ 650110584Sjeff 651177493Sjeff bo = &vp->v_bufobj; 652177493Sjeff BO_LOCK(bo); 653110584Sjeffloop1: 654110584Sjeff /* 655110584Sjeff * MARK/SCAN initialization to avoid infinite loops. 656110584Sjeff */ 657177493Sjeff TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { 658110584Sjeff bp->b_vflags &= ~BV_SCANNED; 659110584Sjeff bp->b_error = 0; 660110584Sjeff } 661110584Sjeff 662110584Sjeff /* 663144584Sjeff * Flush all dirty buffers associated with a vnode. 664110584Sjeff */ 665110584Sjeffloop2: 666177493Sjeff TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { 667110584Sjeff if ((bp->b_vflags & BV_SCANNED) != 0) 668110584Sjeff continue; 669110584Sjeff bp->b_vflags |= BV_SCANNED; 670236825Smckusick if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { 671236825Smckusick if (ap->a_waitfor != MNT_WAIT) 672236825Smckusick continue; 673236825Smckusick if (BUF_LOCK(bp, 674236825Smckusick LK_EXCLUSIVE | LK_INTERLOCK | LK_SLEEPFAIL, 675251171Sjeff BO_LOCKPTR(bo)) != 0) { 676236825Smckusick BO_LOCK(bo); 677236825Smckusick goto loop1; 678236825Smckusick } 679236825Smckusick BO_LOCK(bo); 680236825Smckusick } 681177493Sjeff BO_UNLOCK(bo); 682177493Sjeff KASSERT(bp->b_bufobj == bo, 683147388Sjeff ("bp %p wrong b_bufobj %p should be %p", 684177493Sjeff bp, bp->b_bufobj, bo)); 685110584Sjeff if ((bp->b_flags & B_DELWRI) == 0) 686110588Sjeff panic("fsync: not dirty"); 687140734Sphk if ((vp->v_object != NULL) && (bp->b_flags & B_CLUSTEROK)) { 688110584Sjeff vfs_bio_awrite(bp); 689110584Sjeff } else { 690110584Sjeff bremfree(bp); 691110584Sjeff bawrite(bp); 692110584Sjeff } 693177493Sjeff BO_LOCK(bo); 694110584Sjeff goto loop2; 695110584Sjeff } 696110584Sjeff 697110584Sjeff /* 698110584Sjeff * If synchronous the caller expects us to completely resolve all 699110584Sjeff * dirty buffers in the system. Wait for in-progress I/O to 700110584Sjeff * complete (which could include background bitmap writes), then 701110584Sjeff * retry if dirty blocks still exist. 702110584Sjeff */ 703110584Sjeff if (ap->a_waitfor == MNT_WAIT) { 704136751Sphk bufobj_wwait(bo, 0, 0); 705136751Sphk if (bo->bo_dirty.bv_cnt > 0) { 706110584Sjeff /* 707110584Sjeff * If we are unable to write any of these buffers 708110584Sjeff * then we fail now rather than trying endlessly 709110584Sjeff * to write them out. 710110584Sjeff */ 711136751Sphk TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) 712110584Sjeff if ((error = bp->b_error) == 0) 713110584Sjeff continue; 714145732Sjeff if (error == 0 && --maxretry >= 0) 715110584Sjeff goto loop1; 716110584Sjeff error = EAGAIN; 717110584Sjeff } 718110584Sjeff } 719177493Sjeff BO_UNLOCK(bo); 720144584Sjeff if (error == EAGAIN) 721144584Sjeff vprint("fsync: giving up on dirty", vp); 722112067Skan 723110584Sjeff return (error); 724110584Sjeff} 725112067Skan 72691690Seivind/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ 72776167Sphkint 72876167Sphkvop_stdgetpages(ap) 72976167Sphk struct vop_getpages_args /* { 73076167Sphk struct vnode *a_vp; 73176167Sphk vm_page_t *a_m; 73276167Sphk int a_count; 73376167Sphk int a_reqpage; 73476167Sphk } */ *ap; 73576167Sphk{ 73676131Sphk 73776167Sphk return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 738274914Sglebius ap->a_count, ap->a_reqpage, NULL, NULL); 73976167Sphk} 74076167Sphk 741274914Sglebiusstatic int 742274914Sglebiusvop_stdgetpages_async(struct vop_getpages_async_args *ap) 743274914Sglebius{ 744274914Sglebius int error; 745274914Sglebius 746274914Sglebius error = VOP_GETPAGES(ap->a_vp, ap->a_m, ap->a_count, ap->a_reqpage); 747274914Sglebius ap->a_iodone(ap->a_arg, ap->a_m, ap->a_reqpage, error); 748274914Sglebius return (error); 749274914Sglebius} 750274914Sglebius 751147198Sssouhlalint 752147198Sssouhlalvop_stdkqfilter(struct vop_kqfilter_args *ap) 753147198Sssouhlal{ 754147198Sssouhlal return vfs_kqfilter(ap); 755147198Sssouhlal} 756147198Sssouhlal 75791690Seivind/* XXX Needs good comment and more info in the manpage (VOP_PUTPAGES(9)). */ 75876319Sphkint 75976167Sphkvop_stdputpages(ap) 76076167Sphk struct vop_putpages_args /* { 76176167Sphk struct vnode *a_vp; 76276167Sphk vm_page_t *a_m; 76376167Sphk int a_count; 76476167Sphk int a_sync; 76576167Sphk int *a_rtvals; 76676167Sphk } */ *ap; 76776167Sphk{ 76876167Sphk 76976319Sphk return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count, 77076167Sphk ap->a_sync, ap->a_rtvals); 77176167Sphk} 77276167Sphk 773166774Spjdint 774166774Spjdvop_stdvptofh(struct vop_vptofh_args *ap) 775166774Spjd{ 776166795Spjd return (EOPNOTSUPP); 777166774Spjd} 778166774Spjd 779189539Smarcusint 780189539Smarcusvop_stdvptocnp(struct vop_vptocnp_args *ap) 781189539Smarcus{ 782189539Smarcus struct vnode *vp = ap->a_vp; 783189539Smarcus struct vnode **dvp = ap->a_vpp; 784194601Skib struct ucred *cred = ap->a_cred; 785189539Smarcus char *buf = ap->a_buf; 786189539Smarcus int *buflen = ap->a_buflen; 787189539Smarcus char *dirbuf, *cpos; 788189539Smarcus int i, error, eofflag, dirbuflen, flags, locked, len, covered; 789189539Smarcus off_t off; 790189539Smarcus ino_t fileno; 791189539Smarcus struct vattr va; 792189539Smarcus struct nameidata nd; 793189539Smarcus struct thread *td; 794189539Smarcus struct dirent *dp; 795189539Smarcus struct vnode *mvp; 796189539Smarcus 797189539Smarcus i = *buflen; 798189539Smarcus error = 0; 799189539Smarcus covered = 0; 800189539Smarcus td = curthread; 801189539Smarcus 802189539Smarcus if (vp->v_type != VDIR) 803189539Smarcus return (ENOENT); 804189539Smarcus 805194601Skib error = VOP_GETATTR(vp, &va, cred); 806189539Smarcus if (error) 807189539Smarcus return (error); 808189539Smarcus 809189539Smarcus VREF(vp); 810189539Smarcus locked = VOP_ISLOCKED(vp); 811189539Smarcus VOP_UNLOCK(vp, 0); 812189539Smarcus NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 813189539Smarcus "..", vp, td); 814189539Smarcus flags = FREAD; 815194601Skib error = vn_open_cred(&nd, &flags, 0, VN_OPEN_NOAUDIT, cred, NULL); 816189539Smarcus if (error) { 817189539Smarcus vn_lock(vp, locked | LK_RETRY); 818189539Smarcus return (error); 819189539Smarcus } 820189539Smarcus NDFREE(&nd, NDF_ONLY_PNBUF); 821189539Smarcus 822189539Smarcus mvp = *dvp = nd.ni_vp; 823189539Smarcus 824189539Smarcus if (vp->v_mount != (*dvp)->v_mount && 825189539Smarcus ((*dvp)->v_vflag & VV_ROOT) && 826189539Smarcus ((*dvp)->v_mount->mnt_flag & MNT_UNION)) { 827189539Smarcus *dvp = (*dvp)->v_mount->mnt_vnodecovered; 828189539Smarcus VREF(mvp); 829189539Smarcus VOP_UNLOCK(mvp, 0); 830194601Skib vn_close(mvp, FREAD, cred, td); 831189539Smarcus VREF(*dvp); 832189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 833189539Smarcus covered = 1; 834189539Smarcus } 835189539Smarcus 836189539Smarcus fileno = va.va_fileid; 837189539Smarcus 838189539Smarcus dirbuflen = DEV_BSIZE; 839189539Smarcus if (dirbuflen < va.va_blocksize) 840189539Smarcus dirbuflen = va.va_blocksize; 841189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 842189539Smarcus 843189539Smarcus if ((*dvp)->v_type != VDIR) { 844189539Smarcus error = ENOENT; 845189539Smarcus goto out; 846189539Smarcus } 847189539Smarcus 848189539Smarcus off = 0; 849189539Smarcus len = 0; 850189539Smarcus do { 851189539Smarcus /* call VOP_READDIR of parent */ 852189539Smarcus error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, 853189539Smarcus &cpos, &len, &eofflag, td); 854189539Smarcus if (error) 855189539Smarcus goto out; 856189539Smarcus 857189539Smarcus if ((dp->d_type != DT_WHT) && 858189539Smarcus (dp->d_fileno == fileno)) { 859189539Smarcus if (covered) { 860189539Smarcus VOP_UNLOCK(*dvp, 0); 861189539Smarcus vn_lock(mvp, LK_EXCLUSIVE | LK_RETRY); 862189539Smarcus if (dirent_exists(mvp, dp->d_name, td)) { 863189539Smarcus error = ENOENT; 864189539Smarcus VOP_UNLOCK(mvp, 0); 865189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 866189539Smarcus goto out; 867189539Smarcus } 868189539Smarcus VOP_UNLOCK(mvp, 0); 869189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 870189539Smarcus } 871189539Smarcus i -= dp->d_namlen; 872189539Smarcus 873189539Smarcus if (i < 0) { 874189539Smarcus error = ENOMEM; 875189539Smarcus goto out; 876189539Smarcus } 877247560Skib if (dp->d_namlen == 1 && dp->d_name[0] == '.') { 878247560Skib error = ENOENT; 879247560Skib } else { 880247560Skib bcopy(dp->d_name, buf + i, dp->d_namlen); 881247560Skib error = 0; 882247560Skib } 883189539Smarcus goto out; 884189539Smarcus } 885189539Smarcus } while (len > 0 || !eofflag); 886189539Smarcus error = ENOENT; 887189539Smarcus 888189539Smarcusout: 889189539Smarcus free(dirbuf, M_TEMP); 890189539Smarcus if (!error) { 891189539Smarcus *buflen = i; 892227697Skib vref(*dvp); 893189539Smarcus } 894189539Smarcus if (covered) { 895189539Smarcus vput(*dvp); 896189539Smarcus vrele(mvp); 897189539Smarcus } else { 898189539Smarcus VOP_UNLOCK(mvp, 0); 899194601Skib vn_close(mvp, FREAD, cred, td); 900189539Smarcus } 901189539Smarcus vn_lock(vp, locked | LK_RETRY); 902189539Smarcus return (error); 903189539Smarcus} 904189539Smarcus 905220791Smdfint 906220791Smdfvop_stdallocate(struct vop_allocate_args *ap) 907220791Smdf{ 908220791Smdf#ifdef __notyet__ 909220791Smdf struct statfs sfs; 910220791Smdf#endif 911220791Smdf struct iovec aiov; 912220791Smdf struct vattr vattr, *vap; 913220791Smdf struct uio auio; 914220846Smdf off_t fsize, len, cur, offset; 915220791Smdf uint8_t *buf; 916220791Smdf struct thread *td; 917220791Smdf struct vnode *vp; 918220791Smdf size_t iosize; 919220846Smdf int error; 920220791Smdf 921220791Smdf buf = NULL; 922220791Smdf error = 0; 923220791Smdf td = curthread; 924220791Smdf vap = &vattr; 925220791Smdf vp = ap->a_vp; 926220846Smdf len = *ap->a_len; 927220846Smdf offset = *ap->a_offset; 928220791Smdf 929220791Smdf error = VOP_GETATTR(vp, vap, td->td_ucred); 930220791Smdf if (error != 0) 931220791Smdf goto out; 932220846Smdf fsize = vap->va_size; 933220791Smdf iosize = vap->va_blocksize; 934220791Smdf if (iosize == 0) 935220791Smdf iosize = BLKDEV_IOSIZE; 936220791Smdf if (iosize > MAXPHYS) 937220791Smdf iosize = MAXPHYS; 938220791Smdf buf = malloc(iosize, M_TEMP, M_WAITOK); 939220791Smdf 940220791Smdf#ifdef __notyet__ 941220791Smdf /* 942220791Smdf * Check if the filesystem sets f_maxfilesize; if not use 943220791Smdf * VOP_SETATTR to perform the check. 944220791Smdf */ 945220791Smdf error = VFS_STATFS(vp->v_mount, &sfs, td); 946220791Smdf if (error != 0) 947220791Smdf goto out; 948220791Smdf if (sfs.f_maxfilesize) { 949220791Smdf if (offset > sfs.f_maxfilesize || len > sfs.f_maxfilesize || 950220791Smdf offset + len > sfs.f_maxfilesize) { 951220791Smdf error = EFBIG; 952220791Smdf goto out; 953220791Smdf } 954220791Smdf } else 955220791Smdf#endif 956220791Smdf if (offset + len > vap->va_size) { 957220846Smdf /* 958220846Smdf * Test offset + len against the filesystem's maxfilesize. 959220846Smdf */ 960220791Smdf VATTR_NULL(vap); 961220791Smdf vap->va_size = offset + len; 962220791Smdf error = VOP_SETATTR(vp, vap, td->td_ucred); 963220791Smdf if (error != 0) 964220791Smdf goto out; 965220846Smdf VATTR_NULL(vap); 966220846Smdf vap->va_size = fsize; 967220846Smdf error = VOP_SETATTR(vp, vap, td->td_ucred); 968220846Smdf if (error != 0) 969220846Smdf goto out; 970220791Smdf } 971220791Smdf 972220846Smdf for (;;) { 973220791Smdf /* 974220791Smdf * Read and write back anything below the nominal file 975220791Smdf * size. There's currently no way outside the filesystem 976220791Smdf * to know whether this area is sparse or not. 977220791Smdf */ 978220791Smdf cur = iosize; 979220791Smdf if ((offset % iosize) != 0) 980220791Smdf cur -= (offset % iosize); 981220791Smdf if (cur > len) 982220791Smdf cur = len; 983220846Smdf if (offset < fsize) { 984220791Smdf aiov.iov_base = buf; 985220791Smdf aiov.iov_len = cur; 986220791Smdf auio.uio_iov = &aiov; 987220791Smdf auio.uio_iovcnt = 1; 988220791Smdf auio.uio_offset = offset; 989220791Smdf auio.uio_resid = cur; 990220791Smdf auio.uio_segflg = UIO_SYSSPACE; 991220791Smdf auio.uio_rw = UIO_READ; 992220791Smdf auio.uio_td = td; 993220791Smdf error = VOP_READ(vp, &auio, 0, td->td_ucred); 994220791Smdf if (error != 0) 995220791Smdf break; 996220791Smdf if (auio.uio_resid > 0) { 997220791Smdf bzero(buf + cur - auio.uio_resid, 998220791Smdf auio.uio_resid); 999220791Smdf } 1000220791Smdf } else { 1001220791Smdf bzero(buf, cur); 1002220791Smdf } 1003220791Smdf 1004220791Smdf aiov.iov_base = buf; 1005220791Smdf aiov.iov_len = cur; 1006220791Smdf auio.uio_iov = &aiov; 1007220791Smdf auio.uio_iovcnt = 1; 1008220791Smdf auio.uio_offset = offset; 1009220791Smdf auio.uio_resid = cur; 1010220791Smdf auio.uio_segflg = UIO_SYSSPACE; 1011220791Smdf auio.uio_rw = UIO_WRITE; 1012220791Smdf auio.uio_td = td; 1013220791Smdf 1014220791Smdf error = VOP_WRITE(vp, &auio, 0, td->td_ucred); 1015220791Smdf if (error != 0) 1016220791Smdf break; 1017220791Smdf 1018220791Smdf len -= cur; 1019220791Smdf offset += cur; 1020220846Smdf if (len == 0) 1021220846Smdf break; 1022220846Smdf if (should_yield()) 1023220846Smdf break; 1024220791Smdf } 1025220791Smdf 1026220791Smdf out: 1027220846Smdf *ap->a_len = len; 1028220846Smdf *ap->a_offset = offset; 1029220791Smdf free(buf, M_TEMP); 1030220791Smdf return (error); 1031220791Smdf} 1032220791Smdf 1033227070Sjhbint 1034227070Sjhbvop_stdadvise(struct vop_advise_args *ap) 1035227070Sjhb{ 1036227070Sjhb struct vnode *vp; 1037227070Sjhb off_t start, end; 1038241896Skib int error; 1039227070Sjhb 1040227070Sjhb vp = ap->a_vp; 1041227070Sjhb switch (ap->a_advice) { 1042227070Sjhb case POSIX_FADV_WILLNEED: 1043227070Sjhb /* 1044227070Sjhb * Do nothing for now. Filesystems should provide a 1045227070Sjhb * custom method which starts an asynchronous read of 1046227070Sjhb * the requested region. 1047227070Sjhb */ 1048227070Sjhb error = 0; 1049227070Sjhb break; 1050227070Sjhb case POSIX_FADV_DONTNEED: 1051227070Sjhb /* 1052227070Sjhb * Flush any open FS buffers and then remove pages 1053227070Sjhb * from the backing VM object. Using vinvalbuf() here 1054227070Sjhb * is a bit heavy-handed as it flushes all buffers for 1055227070Sjhb * the given vnode, not just the buffers covering the 1056227070Sjhb * requested range. 1057227070Sjhb */ 1058227070Sjhb error = 0; 1059227070Sjhb vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1060227070Sjhb if (vp->v_iflag & VI_DOOMED) { 1061227070Sjhb VOP_UNLOCK(vp, 0); 1062227070Sjhb break; 1063227070Sjhb } 1064227070Sjhb vinvalbuf(vp, V_CLEANONLY, 0, 0); 1065227070Sjhb if (vp->v_object != NULL) { 1066227070Sjhb start = trunc_page(ap->a_start); 1067227070Sjhb end = round_page(ap->a_end); 1068248084Sattilio VM_OBJECT_WLOCK(vp->v_object); 1069227070Sjhb vm_object_page_cache(vp->v_object, OFF_TO_IDX(start), 1070227070Sjhb OFF_TO_IDX(end)); 1071248084Sattilio VM_OBJECT_WUNLOCK(vp->v_object); 1072227070Sjhb } 1073227070Sjhb VOP_UNLOCK(vp, 0); 1074227070Sjhb break; 1075227070Sjhb default: 1076227070Sjhb error = EINVAL; 1077227070Sjhb break; 1078227070Sjhb } 1079227070Sjhb return (error); 1080227070Sjhb} 1081227070Sjhb 1082232317Strocinyint 1083232317Strocinyvop_stdunp_bind(struct vop_unp_bind_args *ap) 1084232317Strociny{ 1085232317Strociny 1086232317Strociny ap->a_vp->v_socket = ap->a_socket; 1087232317Strociny return (0); 1088232317Strociny} 1089232317Strociny 1090232317Strocinyint 1091232317Strocinyvop_stdunp_connect(struct vop_unp_connect_args *ap) 1092232317Strociny{ 1093232317Strociny 1094232317Strociny *ap->a_socket = ap->a_vp->v_socket; 1095232317Strociny return (0); 1096232317Strociny} 1097232317Strociny 1098232317Strocinyint 1099232317Strocinyvop_stdunp_detach(struct vop_unp_detach_args *ap) 1100232317Strociny{ 1101232317Strociny 1102232317Strociny ap->a_vp->v_socket = NULL; 1103232317Strociny return (0); 1104232317Strociny} 1105232317Strociny 1106241025Skibstatic int 1107241025Skibvop_stdis_text(struct vop_is_text_args *ap) 1108241025Skib{ 1109241025Skib 1110241025Skib return ((ap->a_vp->v_vflag & VV_TEXT) != 0); 1111241025Skib} 1112241025Skib 1113241025Skibstatic int 1114241025Skibvop_stdset_text(struct vop_set_text_args *ap) 1115241025Skib{ 1116241025Skib 1117241025Skib ap->a_vp->v_vflag |= VV_TEXT; 1118241025Skib return (0); 1119241025Skib} 1120241025Skib 1121241025Skibstatic int 1122241025Skibvop_stdunset_text(struct vop_unset_text_args *ap) 1123241025Skib{ 1124241025Skib 1125241025Skib ap->a_vp->v_vflag &= ~VV_TEXT; 1126241025Skib return (0); 1127241025Skib} 1128241025Skib 1129242476Skibstatic int 1130242476Skibvop_stdget_writecount(struct vop_get_writecount_args *ap) 1131242476Skib{ 1132242476Skib 1133242476Skib *ap->a_writecount = ap->a_vp->v_writecount; 1134242476Skib return (0); 1135242476Skib} 1136242476Skib 1137242476Skibstatic int 1138242476Skibvop_stdadd_writecount(struct vop_add_writecount_args *ap) 1139242476Skib{ 1140242476Skib 1141242476Skib ap->a_vp->v_writecount += ap->a_inc; 1142242476Skib return (0); 1143242476Skib} 1144242476Skib 1145112067Skan/* 114651068Salfred * vfs default ops 114791690Seivind * used to fill the vfs function table to get reasonable default return values. 114851068Salfred */ 114991690Seivindint 1150191990Sattiliovfs_stdroot (mp, flags, vpp) 115151068Salfred struct mount *mp; 1152144054Sjeff int flags; 115351068Salfred struct vnode **vpp; 115451068Salfred{ 1155131734Salfred 115651068Salfred return (EOPNOTSUPP); 115751068Salfred} 115851068Salfred 115991690Seivindint 1160191990Sattiliovfs_stdstatfs (mp, sbp) 116151068Salfred struct mount *mp; 116251068Salfred struct statfs *sbp; 116351068Salfred{ 1164131734Salfred 116551068Salfred return (EOPNOTSUPP); 116651068Salfred} 116751068Salfred 116851068Salfredint 1169191990Sattiliovfs_stdquotactl (mp, cmds, uid, arg) 117051068Salfred struct mount *mp; 117151068Salfred int cmds; 117251068Salfred uid_t uid; 1173153400Sdes void *arg; 117451068Salfred{ 1175131734Salfred 117651068Salfred return (EOPNOTSUPP); 117751068Salfred} 117851068Salfred 1179112067Skanint 1180191990Sattiliovfs_stdsync(mp, waitfor) 118151068Salfred struct mount *mp; 118251068Salfred int waitfor; 118351068Salfred{ 1184154152Stegge struct vnode *vp, *mvp; 1185191990Sattilio struct thread *td; 1186112119Skan int error, lockreq, allerror = 0; 1187112119Skan 1188191990Sattilio td = curthread; 1189112119Skan lockreq = LK_EXCLUSIVE | LK_INTERLOCK; 1190112119Skan if (waitfor != MNT_WAIT) 1191112119Skan lockreq |= LK_NOWAIT; 1192112119Skan /* 1193112119Skan * Force stale buffer cache information to be flushed. 1194112119Skan */ 1195112119Skanloop: 1196234386Smckusick MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { 1197234386Smckusick if (vp->v_bufobj.bo_dirty.bv_cnt == 0) { 1198234386Smckusick VI_UNLOCK(vp); 1199177493Sjeff continue; 1200234386Smckusick } 1201112119Skan if ((error = vget(vp, lockreq, td)) != 0) { 1202154152Stegge if (error == ENOENT) { 1203234386Smckusick MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); 1204112119Skan goto loop; 1205154152Stegge } 1206112119Skan continue; 1207112119Skan } 1208140048Sphk error = VOP_FSYNC(vp, waitfor, td); 1209112119Skan if (error) 1210112119Skan allerror = error; 1211204065Spjd vput(vp); 1212112119Skan } 1213112119Skan return (allerror); 1214112119Skan} 1215112119Skan 1216112119Skanint 1217191990Sattiliovfs_stdnosync (mp, waitfor) 1218112119Skan struct mount *mp; 1219112119Skan int waitfor; 1220112119Skan{ 1221131734Salfred 122251068Salfred return (0); 122351068Salfred} 122451068Salfred 1225112067Skanint 122692462Smckusickvfs_stdvget (mp, ino, flags, vpp) 122751068Salfred struct mount *mp; 122851068Salfred ino_t ino; 122992462Smckusick int flags; 123051068Salfred struct vnode **vpp; 123151068Salfred{ 1232131734Salfred 123351068Salfred return (EOPNOTSUPP); 123451068Salfred} 123551068Salfred 1236112067Skanint 1237222167Srmacklemvfs_stdfhtovp (mp, fhp, flags, vpp) 123851068Salfred struct mount *mp; 123951068Salfred struct fid *fhp; 1240222167Srmacklem int flags; 124151138Salfred struct vnode **vpp; 124251138Salfred{ 1243131734Salfred 124451138Salfred return (EOPNOTSUPP); 124551138Salfred} 124651138Salfred 124751068Salfredint 1248112067Skanvfs_stdinit (vfsp) 124951068Salfred struct vfsconf *vfsp; 125051068Salfred{ 1251131734Salfred 125251068Salfred return (0); 125351068Salfred} 125451068Salfred 125551068Salfredint 125651068Salfredvfs_stduninit (vfsp) 125751068Salfred struct vfsconf *vfsp; 125851068Salfred{ 1259131734Salfred 126051068Salfred return(0); 126151068Salfred} 126251068Salfred 126354803Srwatsonint 1264191990Sattiliovfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname) 126554803Srwatson struct mount *mp; 126654803Srwatson int cmd; 126774273Srwatson struct vnode *filename_vp; 126874437Srwatson int attrnamespace; 126956272Srwatson const char *attrname; 127054803Srwatson{ 1271131734Salfred 1272101786Sphk if (filename_vp != NULL) 1273175294Sattilio VOP_UNLOCK(filename_vp, 0); 1274131734Salfred return (EOPNOTSUPP); 127554803Srwatson} 127654803Srwatson 1277131733Salfredint 1278131733Salfredvfs_stdsysctl(mp, op, req) 1279131733Salfred struct mount *mp; 1280131733Salfred fsctlop_t op; 1281131733Salfred struct sysctl_req *req; 1282131733Salfred{ 1283131733Salfred 1284131733Salfred return (EOPNOTSUPP); 1285131733Salfred} 1286131733Salfred 128751068Salfred/* end of vfs default ops */ 1288