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$"); 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> 5067365Sjhb#include <sys/mutex.h> 51189539Smarcus#include <sys/namei.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 81244658Skibstatic int vop_stdis_text(struct vop_is_text_args *ap); 82244658Skibstatic int vop_stdset_text(struct vop_set_text_args *ap); 83244658Skibstatic int vop_stdunset_text(struct vop_unset_text_args *ap); 84244660Skibstatic int vop_stdget_writecount(struct vop_get_writecount_args *ap); 85244660Skibstatic int vop_stdadd_writecount(struct vop_add_writecount_args *ap); 86244658Skib 8730489Sphk/* 8830489Sphk * This vnode table stores what we want to do if the filesystem doesn't 8930489Sphk * implement a particular VOP. 9030489Sphk * 9130489Sphk * If there is no specific entry here, we will return EOPNOTSUPP. 9230489Sphk * 93197680Strasz * Note that every filesystem has to implement either vop_access 94197680Strasz * or vop_accessx; failing to do so will result in immediate crash 95197680Strasz * due to stack overflow, as vop_stdaccess() calls vop_stdaccessx(), 96197680Strasz * which calls vop_stdaccess() etc. 9730489Sphk */ 9830489Sphk 99138290Sphkstruct vop_vector default_vnodeops = { 100138290Sphk .vop_default = NULL, 101138339Sphk .vop_bypass = VOP_EOPNOTSUPP, 102138339Sphk 103197680Strasz .vop_access = vop_stdaccess, 104193092Strasz .vop_accessx = vop_stdaccessx, 105229723Sjhb .vop_advise = vop_stdadvise, 106178243Skib .vop_advlock = vop_stdadvlock, 107178243Skib .vop_advlockasync = vop_stdadvlockasync, 108208003Szml .vop_advlockpurge = vop_stdadvlockpurge, 109220791Smdf .vop_allocate = vop_stdallocate, 110138290Sphk .vop_bmap = vop_stdbmap, 111138290Sphk .vop_close = VOP_NULL, 112138290Sphk .vop_fsync = VOP_NULL, 113138290Sphk .vop_getpages = vop_stdgetpages, 114138290Sphk .vop_getwritemount = vop_stdgetwritemount, 115143494Sjeff .vop_inactive = VOP_NULL, 116138290Sphk .vop_ioctl = VOP_ENOTTY, 117147198Sssouhlal .vop_kqfilter = vop_stdkqfilter, 118138290Sphk .vop_islocked = vop_stdislocked, 119169671Skib .vop_lock1 = vop_stdlock, 120138290Sphk .vop_lookup = vop_nolookup, 121138290Sphk .vop_open = VOP_NULL, 122138290Sphk .vop_pathconf = VOP_EINVAL, 123138290Sphk .vop_poll = vop_nopoll, 124138290Sphk .vop_putpages = vop_stdputpages, 125138290Sphk .vop_readlink = VOP_EINVAL, 126206094Skib .vop_rename = vop_norename, 127138290Sphk .vop_revoke = VOP_PANIC, 128138290Sphk .vop_strategy = vop_nostrategy, 129138290Sphk .vop_unlock = vop_stdunlock, 130189539Smarcus .vop_vptocnp = vop_stdvptocnp, 131166774Spjd .vop_vptofh = vop_stdvptofh, 132234660Strociny .vop_unp_bind = vop_stdunp_bind, 133234660Strociny .vop_unp_connect = vop_stdunp_connect, 134234660Strociny .vop_unp_detach = vop_stdunp_detach, 135244658Skib .vop_is_text = vop_stdis_text, 136244658Skib .vop_set_text = vop_stdset_text, 137244658Skib .vop_unset_text = vop_stdunset_text, 138244660Skib .vop_get_writecount = vop_stdget_writecount, 139244660Skib .vop_add_writecount = vop_stdadd_writecount, 14030489Sphk}; 14130489Sphk 14291690Seivind/* 14391690Seivind * Series of placeholder functions for various error returns for 14491690Seivind * VOPs. 14591690Seivind */ 14691690Seivind 14730489Sphkint 14830492Sphkvop_eopnotsupp(struct vop_generic_args *ap) 14930489Sphk{ 15030489Sphk /* 15130492Sphk printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name); 15230489Sphk */ 15330489Sphk 15430489Sphk return (EOPNOTSUPP); 15530489Sphk} 15630489Sphk 15730489Sphkint 15830492Sphkvop_ebadf(struct vop_generic_args *ap) 15930489Sphk{ 16030489Sphk 16130492Sphk return (EBADF); 16230492Sphk} 16330492Sphk 16430492Sphkint 16530492Sphkvop_enotty(struct vop_generic_args *ap) 16630492Sphk{ 16730492Sphk 16830492Sphk return (ENOTTY); 16930492Sphk} 17030492Sphk 17130492Sphkint 17230492Sphkvop_einval(struct vop_generic_args *ap) 17330492Sphk{ 17430492Sphk 17530492Sphk return (EINVAL); 17630492Sphk} 17730492Sphk 17830492Sphkint 179185956Smarcusvop_enoent(struct vop_generic_args *ap) 180185956Smarcus{ 181185956Smarcus 182185956Smarcus return (ENOENT); 183185956Smarcus} 184185956Smarcus 185185956Smarcusint 18630492Sphkvop_null(struct vop_generic_args *ap) 18730492Sphk{ 18830492Sphk 18930492Sphk return (0); 19030492Sphk} 19130492Sphk 19291690Seivind/* 19391690Seivind * Helper function to panic on some bad VOPs in some filesystems. 19491690Seivind */ 19541056Speterint 19641056Spetervop_panic(struct vop_generic_args *ap) 19741056Speter{ 19841056Speter 19972594Sbde panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 20041056Speter} 20141056Speter 20291690Seivind/* 20391690Seivind * vop_std<something> and vop_no<something> are default functions for use by 20491690Seivind * filesystems that need the "default reasonable" implementation for a 20591690Seivind * particular operation. 20691690Seivind * 20791690Seivind * The documentation for the operations they implement exists (if it exists) 20891690Seivind * in the VOP_<SOMETHING>(9) manpage (all uppercase). 20991690Seivind */ 21091690Seivind 21191690Seivind/* 21291690Seivind * Default vop for filesystems that do not support name lookup 21391690Seivind */ 21472594Sbdestatic int 21572594Sbdevop_nolookup(ap) 21672594Sbde struct vop_lookup_args /* { 21772594Sbde struct vnode *a_dvp; 21872594Sbde struct vnode **a_vpp; 21972594Sbde struct componentname *a_cnp; 22072594Sbde } */ *ap; 22172594Sbde{ 22272594Sbde 22372594Sbde *ap->a_vpp = NULL; 22472594Sbde return (ENOTDIR); 22572594Sbde} 22672594Sbde 22746349Salc/* 228206094Skib * vop_norename: 229206094Skib * 230206094Skib * Handle unlock and reference counting for arguments of vop_rename 231206094Skib * for filesystems that do not implement rename operation. 232206094Skib */ 233206094Skibstatic int 234206094Skibvop_norename(struct vop_rename_args *ap) 235206094Skib{ 236206094Skib 237206094Skib vop_rename_fail(ap); 238206094Skib return (EOPNOTSUPP); 239206094Skib} 240206094Skib 241206094Skib/* 24246349Salc * vop_nostrategy: 24346349Salc * 24446349Salc * Strategy routine for VFS devices that have none. 24546349Salc * 24658934Sphk * BIO_ERROR and B_INVAL must be cleared prior to calling any strategy 24758345Sphk * routine. Typically this is done for a BIO_READ strategy call. 248112067Skan * Typically B_INVAL is assumed to already be clear prior to a write 24958345Sphk * and should not be cleared manually unless you just made the buffer 25058934Sphk * invalid. BIO_ERROR should be cleared either way. 25146349Salc */ 25246349Salc 25330489Sphkstatic int 25430489Sphkvop_nostrategy (struct vop_strategy_args *ap) 25530489Sphk{ 25630489Sphk printf("No strategy for buffer at %p\n", ap->a_bp); 257111842Snjl vprint("vnode", ap->a_vp); 25858934Sphk ap->a_bp->b_ioflags |= BIO_ERROR; 25930489Sphk ap->a_bp->b_error = EOPNOTSUPP; 26059249Sphk bufdone(ap->a_bp); 26130489Sphk return (EOPNOTSUPP); 26230489Sphk} 26330492Sphk 264189539Smarcusstatic int 265189539Smarcusget_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, 266189539Smarcus int dirbuflen, off_t *off, char **cpos, int *len, 267189539Smarcus int *eofflag, struct thread *td) 268189539Smarcus{ 269189539Smarcus int error, reclen; 270189539Smarcus struct uio uio; 271189539Smarcus struct iovec iov; 272189539Smarcus struct dirent *dp; 273189539Smarcus 274189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 275189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 276189539Smarcus 277189539Smarcus if (*len == 0) { 278189539Smarcus iov.iov_base = dirbuf; 279189539Smarcus iov.iov_len = dirbuflen; 280189539Smarcus 281189539Smarcus uio.uio_iov = &iov; 282189539Smarcus uio.uio_iovcnt = 1; 283189539Smarcus uio.uio_offset = *off; 284189539Smarcus uio.uio_resid = dirbuflen; 285189539Smarcus uio.uio_segflg = UIO_SYSSPACE; 286189539Smarcus uio.uio_rw = UIO_READ; 287189539Smarcus uio.uio_td = td; 288189539Smarcus 289189539Smarcus *eofflag = 0; 290189539Smarcus 291189539Smarcus#ifdef MAC 292189539Smarcus error = mac_vnode_check_readdir(td->td_ucred, vp); 293189539Smarcus if (error == 0) 294189539Smarcus#endif 295189539Smarcus error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, 296189539Smarcus NULL, NULL); 297189539Smarcus if (error) 298189539Smarcus return (error); 299189539Smarcus 300211818Sbrian *off = uio.uio_offset; 301211818Sbrian 302211684Sbrian *cpos = dirbuf; 303211818Sbrian *len = (dirbuflen - uio.uio_resid); 304211818Sbrian 305211818Sbrian if (*len == 0) 306211818Sbrian return (ENOENT); 307189539Smarcus } 308189539Smarcus 309189539Smarcus dp = (struct dirent *)(*cpos); 310189539Smarcus reclen = dp->d_reclen; 311189539Smarcus *dpp = dp; 312189539Smarcus 313189539Smarcus /* check for malformed directory.. */ 314189539Smarcus if (reclen < DIRENT_MINSIZE) 315189539Smarcus return (EINVAL); 316189539Smarcus 317189539Smarcus *cpos += reclen; 318189539Smarcus *len -= reclen; 319189539Smarcus 320189539Smarcus return (0); 321189539Smarcus} 322189539Smarcus 32391690Seivind/* 324189539Smarcus * Check if a named file exists in a given directory vnode. 325189539Smarcus */ 326189539Smarcusstatic int 327189539Smarcusdirent_exists(struct vnode *vp, const char *dirname, struct thread *td) 328189539Smarcus{ 329189539Smarcus char *dirbuf, *cpos; 330189539Smarcus int error, eofflag, dirbuflen, len, found; 331189539Smarcus off_t off; 332189539Smarcus struct dirent *dp; 333189539Smarcus struct vattr va; 334189539Smarcus 335189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 336189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 337189539Smarcus 338189539Smarcus found = 0; 339189539Smarcus 340189539Smarcus error = VOP_GETATTR(vp, &va, td->td_ucred); 341189539Smarcus if (error) 342189539Smarcus return (found); 343189539Smarcus 344189539Smarcus dirbuflen = DEV_BSIZE; 345189539Smarcus if (dirbuflen < va.va_blocksize) 346189539Smarcus dirbuflen = va.va_blocksize; 347189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 348189539Smarcus 349189539Smarcus off = 0; 350189539Smarcus len = 0; 351189539Smarcus do { 352189539Smarcus error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, 353189539Smarcus &cpos, &len, &eofflag, td); 354189539Smarcus if (error) 355189539Smarcus goto out; 356189539Smarcus 357189539Smarcus if ((dp->d_type != DT_WHT) && 358189539Smarcus !strcmp(dp->d_name, dirname)) { 359189539Smarcus found = 1; 360189539Smarcus goto out; 361189539Smarcus } 362189539Smarcus } while (len > 0 || !eofflag); 363189539Smarcus 364189539Smarcusout: 365189539Smarcus free(dirbuf, M_TEMP); 366189539Smarcus return (found); 367189539Smarcus} 368189539Smarcus 369193092Straszint 370197680Straszvop_stdaccess(struct vop_access_args *ap) 371197680Strasz{ 372197680Strasz 373197680Strasz KASSERT((ap->a_accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | 374197680Strasz VAPPEND)) == 0, ("invalid bit in accmode")); 375197680Strasz 376197680Strasz return (VOP_ACCESSX(ap->a_vp, ap->a_accmode, ap->a_cred, ap->a_td)); 377197680Strasz} 378197680Strasz 379197680Straszint 380193092Straszvop_stdaccessx(struct vop_accessx_args *ap) 381193092Strasz{ 382193092Strasz int error; 383193092Strasz accmode_t accmode = ap->a_accmode; 384193092Strasz 385193092Strasz error = vfs_unixify_accmode(&accmode); 386193092Strasz if (error != 0) 387193092Strasz return (error); 388193092Strasz 389193092Strasz if (accmode == 0) 390193092Strasz return (0); 391193092Strasz 392193092Strasz return (VOP_ACCESS(ap->a_vp, accmode, ap->a_cred, ap->a_td)); 393193092Strasz} 394193092Strasz 395189539Smarcus/* 396178243Skib * Advisory record locking support 397178243Skib */ 398178243Skibint 399178243Skibvop_stdadvlock(struct vop_advlock_args *ap) 400178243Skib{ 401182371Sattilio struct vnode *vp; 402182371Sattilio struct ucred *cred; 403178243Skib struct vattr vattr; 404178243Skib int error; 405178243Skib 406182371Sattilio vp = ap->a_vp; 407182371Sattilio cred = curthread->td_ucred; 408178243Skib vn_lock(vp, LK_SHARED | LK_RETRY); 409182371Sattilio error = VOP_GETATTR(vp, &vattr, cred); 410178243Skib VOP_UNLOCK(vp, 0); 411178243Skib if (error) 412178243Skib return (error); 413178243Skib 414178243Skib return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); 415178243Skib} 416178243Skib 417178243Skibint 418178243Skibvop_stdadvlockasync(struct vop_advlockasync_args *ap) 419178243Skib{ 420182371Sattilio struct vnode *vp; 421182371Sattilio struct ucred *cred; 422178243Skib struct vattr vattr; 423178243Skib int error; 424178243Skib 425182371Sattilio vp = ap->a_vp; 426182371Sattilio cred = curthread->td_ucred; 427178243Skib vn_lock(vp, LK_SHARED | LK_RETRY); 428182371Sattilio error = VOP_GETATTR(vp, &vattr, cred); 429178243Skib VOP_UNLOCK(vp, 0); 430178243Skib if (error) 431178243Skib return (error); 432178243Skib 433178243Skib return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); 434178243Skib} 435178243Skib 436208003Szmlint 437208003Szmlvop_stdadvlockpurge(struct vop_advlockpurge_args *ap) 438208003Szml{ 439208003Szml struct vnode *vp; 440208003Szml 441208003Szml vp = ap->a_vp; 442208003Szml lf_purgelocks(vp, &vp->v_lockf); 443208003Szml return (0); 444208003Szml} 445208003Szml 446178243Skib/* 44791690Seivind * vop_stdpathconf: 448112067Skan * 44991690Seivind * Standard implementation of POSIX pathconf, to get information about limits 45091690Seivind * for a filesystem. 45191690Seivind * Override per filesystem for the case where the filesystem has smaller 45291690Seivind * limits. 45391690Seivind */ 45430492Sphkint 45530492Sphkvop_stdpathconf(ap) 45630492Sphk struct vop_pathconf_args /* { 45730492Sphk struct vnode *a_vp; 45830492Sphk int a_name; 45930492Sphk int *a_retval; 46030492Sphk } */ *ap; 46130492Sphk{ 46230492Sphk 46330492Sphk switch (ap->a_name) { 464149175Sphk case _PC_NAME_MAX: 465149175Sphk *ap->a_retval = NAME_MAX; 466149175Sphk return (0); 467149175Sphk case _PC_PATH_MAX: 468149175Sphk *ap->a_retval = PATH_MAX; 469149175Sphk return (0); 47030492Sphk case _PC_LINK_MAX: 47130492Sphk *ap->a_retval = LINK_MAX; 47230492Sphk return (0); 47330492Sphk case _PC_MAX_CANON: 47430492Sphk *ap->a_retval = MAX_CANON; 47530492Sphk return (0); 47630492Sphk case _PC_MAX_INPUT: 47730492Sphk *ap->a_retval = MAX_INPUT; 47830492Sphk return (0); 47930492Sphk case _PC_PIPE_BUF: 48030492Sphk *ap->a_retval = PIPE_BUF; 48130492Sphk return (0); 48230492Sphk case _PC_CHOWN_RESTRICTED: 48330492Sphk *ap->a_retval = 1; 48430492Sphk return (0); 48530492Sphk case _PC_VDISABLE: 48630492Sphk *ap->a_retval = _POSIX_VDISABLE; 48730492Sphk return (0); 48830492Sphk default: 48930492Sphk return (EINVAL); 49030492Sphk } 49130492Sphk /* NOTREACHED */ 49230492Sphk} 49330513Sphk 49430513Sphk/* 49530513Sphk * Standard lock, unlock and islocked functions. 49630513Sphk */ 49730513Sphkint 49830513Sphkvop_stdlock(ap) 499169671Skib struct vop_lock1_args /* { 50030513Sphk struct vnode *a_vp; 50130513Sphk int a_flags; 502164248Skmacy char *file; 503164248Skmacy int line; 50430513Sphk } */ *ap; 505112067Skan{ 50666355Sbp struct vnode *vp = ap->a_vp; 50730513Sphk 508176320Sattilio return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), 509176320Sattilio LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, 510175635Sattilio ap->a_line)); 51130513Sphk} 51230513Sphk 51391690Seivind/* See above. */ 51430513Sphkint 51530513Sphkvop_stdunlock(ap) 51630513Sphk struct vop_unlock_args /* { 51730513Sphk struct vnode *a_vp; 51830513Sphk int a_flags; 51930513Sphk } */ *ap; 52030513Sphk{ 52166355Sbp struct vnode *vp = ap->a_vp; 52230513Sphk 523175635Sattilio return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); 52430513Sphk} 52530513Sphk 52691690Seivind/* See above. */ 52730513Sphkint 52830513Sphkvop_stdislocked(ap) 52930513Sphk struct vop_islocked_args /* { 53030513Sphk struct vnode *a_vp; 53130513Sphk } */ *ap; 53230513Sphk{ 53330513Sphk 534176559Sattilio return (lockstatus(ap->a_vp->v_vnlock)); 53530513Sphk} 53630513Sphk 53730743Sphk/* 53830743Sphk * Return true for select/poll. 53930743Sphk */ 54030743Sphkint 54130743Sphkvop_nopoll(ap) 54230743Sphk struct vop_poll_args /* { 54330743Sphk struct vnode *a_vp; 54430743Sphk int a_events; 54530743Sphk struct ucred *a_cred; 54683366Sjulian struct thread *a_td; 54730743Sphk } */ *ap; 54830743Sphk{ 54931727Swollman 550189450Skib return (poll_no_poll(ap->a_events)); 55130743Sphk} 55230743Sphk 55331727Swollman/* 55431727Swollman * Implement poll for local filesystems that support it. 55531727Swollman */ 55630743Sphkint 55731727Swollmanvop_stdpoll(ap) 55831727Swollman struct vop_poll_args /* { 55931727Swollman struct vnode *a_vp; 56031727Swollman int a_events; 56131727Swollman struct ucred *a_cred; 56283366Sjulian struct thread *a_td; 56331727Swollman } */ *ap; 56431727Swollman{ 56576578Sjlemon if (ap->a_events & ~POLLSTANDARD) 56683366Sjulian return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 56776578Sjlemon return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 56831727Swollman} 56931727Swollman 57030743Sphk/* 57162976Smckusick * Return our mount point, as we will take charge of the writes. 57262976Smckusick */ 57362976Smckusickint 57462976Smckusickvop_stdgetwritemount(ap) 57562976Smckusick struct vop_getwritemount_args /* { 57662976Smckusick struct vnode *a_vp; 57762976Smckusick struct mount **a_mpp; 57862976Smckusick } */ *ap; 57962976Smckusick{ 580157323Sjeff struct mount *mp; 58162976Smckusick 582157323Sjeff /* 583157323Sjeff * XXX Since this is called unlocked we may be recycled while 584157323Sjeff * attempting to ref the mount. If this is the case or mountpoint 585157323Sjeff * will be set to NULL. We only have to prevent this call from 586157323Sjeff * returning with a ref to an incorrect mountpoint. It is not 587157323Sjeff * harmful to return with a ref to our previous mountpoint. 588157323Sjeff */ 589157323Sjeff mp = ap->a_vp->v_mount; 590162455Stegge if (mp != NULL) { 591162455Stegge vfs_ref(mp); 592162455Stegge if (mp != ap->a_vp->v_mount) { 593162455Stegge vfs_rel(mp); 594162455Stegge mp = NULL; 595162455Stegge } 596157323Sjeff } 597157323Sjeff *(ap->a_mpp) = mp; 59862976Smckusick return (0); 59962976Smckusick} 60062976Smckusick 60191690Seivind/* XXX Needs good comment and VOP_BMAP(9) manpage */ 60276131Sphkint 60376131Sphkvop_stdbmap(ap) 604112067Skan struct vop_bmap_args /* { 60576131Sphk struct vnode *a_vp; 60676131Sphk daddr_t a_bn; 607137726Sphk struct bufobj **a_bop; 60876131Sphk daddr_t *a_bnp; 60976131Sphk int *a_runp; 61076131Sphk int *a_runb; 61176131Sphk } */ *ap; 61276131Sphk{ 61376131Sphk 614137726Sphk if (ap->a_bop != NULL) 615137726Sphk *ap->a_bop = &ap->a_vp->v_bufobj; 61676131Sphk if (ap->a_bnp != NULL) 61776131Sphk *ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize); 61876131Sphk if (ap->a_runp != NULL) 61976131Sphk *ap->a_runp = 0; 62076131Sphk if (ap->a_runb != NULL) 62176131Sphk *ap->a_runb = 0; 62276131Sphk return (0); 62376131Sphk} 62476131Sphk 625110584Sjeffint 626110584Sjeffvop_stdfsync(ap) 627110584Sjeff struct vop_fsync_args /* { 628110584Sjeff struct vnode *a_vp; 629110584Sjeff struct ucred *a_cred; 630110584Sjeff int a_waitfor; 631110584Sjeff struct thread *a_td; 632110584Sjeff } */ *ap; 633110584Sjeff{ 634110584Sjeff struct vnode *vp = ap->a_vp; 635110584Sjeff struct buf *bp; 636136751Sphk struct bufobj *bo; 637110584Sjeff struct buf *nbp; 638145732Sjeff int error = 0; 639144584Sjeff int maxretry = 1000; /* large, arbitrarily chosen */ 640110584Sjeff 641177493Sjeff bo = &vp->v_bufobj; 642177493Sjeff BO_LOCK(bo); 643110584Sjeffloop1: 644110584Sjeff /* 645110584Sjeff * MARK/SCAN initialization to avoid infinite loops. 646110584Sjeff */ 647177493Sjeff TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { 648110584Sjeff bp->b_vflags &= ~BV_SCANNED; 649110584Sjeff bp->b_error = 0; 650110584Sjeff } 651110584Sjeff 652110584Sjeff /* 653144584Sjeff * Flush all dirty buffers associated with a vnode. 654110584Sjeff */ 655110584Sjeffloop2: 656177493Sjeff TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { 657110584Sjeff if ((bp->b_vflags & BV_SCANNED) != 0) 658110584Sjeff continue; 659110584Sjeff bp->b_vflags |= BV_SCANNED; 660237351Smckusick if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { 661237351Smckusick if (ap->a_waitfor != MNT_WAIT) 662237351Smckusick continue; 663237351Smckusick if (BUF_LOCK(bp, 664237351Smckusick LK_EXCLUSIVE | LK_INTERLOCK | LK_SLEEPFAIL, 665237351Smckusick BO_MTX(bo)) != 0) { 666237351Smckusick BO_LOCK(bo); 667237351Smckusick goto loop1; 668237351Smckusick } 669237351Smckusick BO_LOCK(bo); 670237351Smckusick } 671177493Sjeff BO_UNLOCK(bo); 672177493Sjeff KASSERT(bp->b_bufobj == bo, 673147388Sjeff ("bp %p wrong b_bufobj %p should be %p", 674177493Sjeff bp, bp->b_bufobj, bo)); 675110584Sjeff if ((bp->b_flags & B_DELWRI) == 0) 676110588Sjeff panic("fsync: not dirty"); 677140734Sphk if ((vp->v_object != NULL) && (bp->b_flags & B_CLUSTEROK)) { 678110584Sjeff vfs_bio_awrite(bp); 679110584Sjeff } else { 680110584Sjeff bremfree(bp); 681110584Sjeff bawrite(bp); 682110584Sjeff } 683177493Sjeff BO_LOCK(bo); 684110584Sjeff goto loop2; 685110584Sjeff } 686110584Sjeff 687110584Sjeff /* 688110584Sjeff * If synchronous the caller expects us to completely resolve all 689110584Sjeff * dirty buffers in the system. Wait for in-progress I/O to 690110584Sjeff * complete (which could include background bitmap writes), then 691110584Sjeff * retry if dirty blocks still exist. 692110584Sjeff */ 693110584Sjeff if (ap->a_waitfor == MNT_WAIT) { 694136751Sphk bufobj_wwait(bo, 0, 0); 695136751Sphk if (bo->bo_dirty.bv_cnt > 0) { 696110584Sjeff /* 697110584Sjeff * If we are unable to write any of these buffers 698110584Sjeff * then we fail now rather than trying endlessly 699110584Sjeff * to write them out. 700110584Sjeff */ 701136751Sphk TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) 702110584Sjeff if ((error = bp->b_error) == 0) 703110584Sjeff continue; 704145732Sjeff if (error == 0 && --maxretry >= 0) 705110584Sjeff goto loop1; 706110584Sjeff error = EAGAIN; 707110584Sjeff } 708110584Sjeff } 709177493Sjeff BO_UNLOCK(bo); 710144584Sjeff if (error == EAGAIN) 711144584Sjeff vprint("fsync: giving up on dirty", vp); 712112067Skan 713110584Sjeff return (error); 714110584Sjeff} 715112067Skan 71691690Seivind/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ 71776167Sphkint 71876167Sphkvop_stdgetpages(ap) 71976167Sphk struct vop_getpages_args /* { 72076167Sphk struct vnode *a_vp; 72176167Sphk vm_page_t *a_m; 72276167Sphk int a_count; 72376167Sphk int a_reqpage; 72476167Sphk vm_ooffset_t a_offset; 72576167Sphk } */ *ap; 72676167Sphk{ 72776131Sphk 72876167Sphk return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 72976167Sphk ap->a_count, ap->a_reqpage); 73076167Sphk} 73176167Sphk 732147198Sssouhlalint 733147198Sssouhlalvop_stdkqfilter(struct vop_kqfilter_args *ap) 734147198Sssouhlal{ 735147198Sssouhlal return vfs_kqfilter(ap); 736147198Sssouhlal} 737147198Sssouhlal 73891690Seivind/* XXX Needs good comment and more info in the manpage (VOP_PUTPAGES(9)). */ 73976319Sphkint 74076167Sphkvop_stdputpages(ap) 74176167Sphk struct vop_putpages_args /* { 74276167Sphk struct vnode *a_vp; 74376167Sphk vm_page_t *a_m; 74476167Sphk int a_count; 74576167Sphk int a_sync; 74676167Sphk int *a_rtvals; 74776167Sphk vm_ooffset_t a_offset; 74876167Sphk } */ *ap; 74976167Sphk{ 75076167Sphk 75176319Sphk return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count, 75276167Sphk ap->a_sync, ap->a_rtvals); 75376167Sphk} 75476167Sphk 755166774Spjdint 756166774Spjdvop_stdvptofh(struct vop_vptofh_args *ap) 757166774Spjd{ 758166795Spjd return (EOPNOTSUPP); 759166774Spjd} 760166774Spjd 761189539Smarcusint 762189539Smarcusvop_stdvptocnp(struct vop_vptocnp_args *ap) 763189539Smarcus{ 764189539Smarcus struct vnode *vp = ap->a_vp; 765189539Smarcus struct vnode **dvp = ap->a_vpp; 766194601Skib struct ucred *cred = ap->a_cred; 767189539Smarcus char *buf = ap->a_buf; 768189539Smarcus int *buflen = ap->a_buflen; 769189539Smarcus char *dirbuf, *cpos; 770189539Smarcus int i, error, eofflag, dirbuflen, flags, locked, len, covered; 771189539Smarcus off_t off; 772189539Smarcus ino_t fileno; 773189539Smarcus struct vattr va; 774189539Smarcus struct nameidata nd; 775189539Smarcus struct thread *td; 776189539Smarcus struct dirent *dp; 777189539Smarcus struct vnode *mvp; 778189539Smarcus 779189539Smarcus i = *buflen; 780189539Smarcus error = 0; 781189539Smarcus covered = 0; 782189539Smarcus td = curthread; 783189539Smarcus 784189539Smarcus if (vp->v_type != VDIR) 785189539Smarcus return (ENOENT); 786189539Smarcus 787194601Skib error = VOP_GETATTR(vp, &va, cred); 788189539Smarcus if (error) 789189539Smarcus return (error); 790189539Smarcus 791189539Smarcus VREF(vp); 792189539Smarcus locked = VOP_ISLOCKED(vp); 793189539Smarcus VOP_UNLOCK(vp, 0); 794189539Smarcus NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 795189539Smarcus "..", vp, td); 796189539Smarcus flags = FREAD; 797194601Skib error = vn_open_cred(&nd, &flags, 0, VN_OPEN_NOAUDIT, cred, NULL); 798189539Smarcus if (error) { 799189539Smarcus vn_lock(vp, locked | LK_RETRY); 800189539Smarcus return (error); 801189539Smarcus } 802189539Smarcus NDFREE(&nd, NDF_ONLY_PNBUF); 803189539Smarcus 804189539Smarcus mvp = *dvp = nd.ni_vp; 805189539Smarcus 806189539Smarcus if (vp->v_mount != (*dvp)->v_mount && 807189539Smarcus ((*dvp)->v_vflag & VV_ROOT) && 808189539Smarcus ((*dvp)->v_mount->mnt_flag & MNT_UNION)) { 809189539Smarcus *dvp = (*dvp)->v_mount->mnt_vnodecovered; 810189539Smarcus VREF(mvp); 811189539Smarcus VOP_UNLOCK(mvp, 0); 812194601Skib vn_close(mvp, FREAD, cred, td); 813189539Smarcus VREF(*dvp); 814189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 815189539Smarcus covered = 1; 816189539Smarcus } 817189539Smarcus 818189539Smarcus fileno = va.va_fileid; 819189539Smarcus 820189539Smarcus dirbuflen = DEV_BSIZE; 821189539Smarcus if (dirbuflen < va.va_blocksize) 822189539Smarcus dirbuflen = va.va_blocksize; 823189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 824189539Smarcus 825189539Smarcus if ((*dvp)->v_type != VDIR) { 826189539Smarcus error = ENOENT; 827189539Smarcus goto out; 828189539Smarcus } 829189539Smarcus 830189539Smarcus off = 0; 831189539Smarcus len = 0; 832189539Smarcus do { 833189539Smarcus /* call VOP_READDIR of parent */ 834189539Smarcus error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, 835189539Smarcus &cpos, &len, &eofflag, td); 836189539Smarcus if (error) 837189539Smarcus goto out; 838189539Smarcus 839189539Smarcus if ((dp->d_type != DT_WHT) && 840189539Smarcus (dp->d_fileno == fileno)) { 841189539Smarcus if (covered) { 842189539Smarcus VOP_UNLOCK(*dvp, 0); 843189539Smarcus vn_lock(mvp, LK_EXCLUSIVE | LK_RETRY); 844189539Smarcus if (dirent_exists(mvp, dp->d_name, td)) { 845189539Smarcus error = ENOENT; 846189539Smarcus VOP_UNLOCK(mvp, 0); 847189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 848189539Smarcus goto out; 849189539Smarcus } 850189539Smarcus VOP_UNLOCK(mvp, 0); 851189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 852189539Smarcus } 853189539Smarcus i -= dp->d_namlen; 854189539Smarcus 855189539Smarcus if (i < 0) { 856189539Smarcus error = ENOMEM; 857189539Smarcus goto out; 858189539Smarcus } 859248029Skib if (dp->d_namlen == 1 && dp->d_name[0] == '.') { 860248029Skib error = ENOENT; 861248029Skib } else { 862248029Skib bcopy(dp->d_name, buf + i, dp->d_namlen); 863248029Skib error = 0; 864248029Skib } 865189539Smarcus goto out; 866189539Smarcus } 867189539Smarcus } while (len > 0 || !eofflag); 868189539Smarcus error = ENOENT; 869189539Smarcus 870189539Smarcusout: 871189539Smarcus free(dirbuf, M_TEMP); 872189539Smarcus if (!error) { 873189539Smarcus *buflen = i; 874229703Skib vref(*dvp); 875189539Smarcus } 876189539Smarcus if (covered) { 877189539Smarcus vput(*dvp); 878189539Smarcus vrele(mvp); 879189539Smarcus } else { 880189539Smarcus VOP_UNLOCK(mvp, 0); 881194601Skib vn_close(mvp, FREAD, cred, td); 882189539Smarcus } 883189539Smarcus vn_lock(vp, locked | LK_RETRY); 884189539Smarcus return (error); 885189539Smarcus} 886189539Smarcus 887220791Smdfint 888220791Smdfvop_stdallocate(struct vop_allocate_args *ap) 889220791Smdf{ 890220791Smdf#ifdef __notyet__ 891220791Smdf struct statfs sfs; 892220791Smdf#endif 893220791Smdf struct iovec aiov; 894220791Smdf struct vattr vattr, *vap; 895220791Smdf struct uio auio; 896220846Smdf off_t fsize, len, cur, offset; 897220791Smdf uint8_t *buf; 898220791Smdf struct thread *td; 899220791Smdf struct vnode *vp; 900220791Smdf size_t iosize; 901220846Smdf int error; 902220791Smdf 903220791Smdf buf = NULL; 904220791Smdf error = 0; 905220791Smdf td = curthread; 906220791Smdf vap = &vattr; 907220791Smdf vp = ap->a_vp; 908220846Smdf len = *ap->a_len; 909220846Smdf offset = *ap->a_offset; 910220791Smdf 911220791Smdf error = VOP_GETATTR(vp, vap, td->td_ucred); 912220791Smdf if (error != 0) 913220791Smdf goto out; 914220846Smdf fsize = vap->va_size; 915220791Smdf iosize = vap->va_blocksize; 916220791Smdf if (iosize == 0) 917220791Smdf iosize = BLKDEV_IOSIZE; 918220791Smdf if (iosize > MAXPHYS) 919220791Smdf iosize = MAXPHYS; 920220791Smdf buf = malloc(iosize, M_TEMP, M_WAITOK); 921220791Smdf 922220791Smdf#ifdef __notyet__ 923220791Smdf /* 924220791Smdf * Check if the filesystem sets f_maxfilesize; if not use 925220791Smdf * VOP_SETATTR to perform the check. 926220791Smdf */ 927220791Smdf error = VFS_STATFS(vp->v_mount, &sfs, td); 928220791Smdf if (error != 0) 929220791Smdf goto out; 930220791Smdf if (sfs.f_maxfilesize) { 931220791Smdf if (offset > sfs.f_maxfilesize || len > sfs.f_maxfilesize || 932220791Smdf offset + len > sfs.f_maxfilesize) { 933220791Smdf error = EFBIG; 934220791Smdf goto out; 935220791Smdf } 936220791Smdf } else 937220791Smdf#endif 938220791Smdf if (offset + len > vap->va_size) { 939220846Smdf /* 940220846Smdf * Test offset + len against the filesystem's maxfilesize. 941220846Smdf */ 942220791Smdf VATTR_NULL(vap); 943220791Smdf vap->va_size = offset + len; 944220791Smdf error = VOP_SETATTR(vp, vap, td->td_ucred); 945220791Smdf if (error != 0) 946220791Smdf goto out; 947220846Smdf VATTR_NULL(vap); 948220846Smdf vap->va_size = fsize; 949220846Smdf error = VOP_SETATTR(vp, vap, td->td_ucred); 950220846Smdf if (error != 0) 951220846Smdf goto out; 952220791Smdf } 953220791Smdf 954220846Smdf for (;;) { 955220791Smdf /* 956220791Smdf * Read and write back anything below the nominal file 957220791Smdf * size. There's currently no way outside the filesystem 958220791Smdf * to know whether this area is sparse or not. 959220791Smdf */ 960220791Smdf cur = iosize; 961220791Smdf if ((offset % iosize) != 0) 962220791Smdf cur -= (offset % iosize); 963220791Smdf if (cur > len) 964220791Smdf cur = len; 965220846Smdf if (offset < fsize) { 966220791Smdf aiov.iov_base = buf; 967220791Smdf aiov.iov_len = cur; 968220791Smdf auio.uio_iov = &aiov; 969220791Smdf auio.uio_iovcnt = 1; 970220791Smdf auio.uio_offset = offset; 971220791Smdf auio.uio_resid = cur; 972220791Smdf auio.uio_segflg = UIO_SYSSPACE; 973220791Smdf auio.uio_rw = UIO_READ; 974220791Smdf auio.uio_td = td; 975220791Smdf error = VOP_READ(vp, &auio, 0, td->td_ucred); 976220791Smdf if (error != 0) 977220791Smdf break; 978220791Smdf if (auio.uio_resid > 0) { 979220791Smdf bzero(buf + cur - auio.uio_resid, 980220791Smdf auio.uio_resid); 981220791Smdf } 982220791Smdf } else { 983220791Smdf bzero(buf, cur); 984220791Smdf } 985220791Smdf 986220791Smdf aiov.iov_base = buf; 987220791Smdf aiov.iov_len = cur; 988220791Smdf auio.uio_iov = &aiov; 989220791Smdf auio.uio_iovcnt = 1; 990220791Smdf auio.uio_offset = offset; 991220791Smdf auio.uio_resid = cur; 992220791Smdf auio.uio_segflg = UIO_SYSSPACE; 993220791Smdf auio.uio_rw = UIO_WRITE; 994220791Smdf auio.uio_td = td; 995220791Smdf 996220791Smdf error = VOP_WRITE(vp, &auio, 0, td->td_ucred); 997220791Smdf if (error != 0) 998220791Smdf break; 999220791Smdf 1000220791Smdf len -= cur; 1001220791Smdf offset += cur; 1002220846Smdf if (len == 0) 1003220846Smdf break; 1004220846Smdf if (should_yield()) 1005220846Smdf break; 1006220791Smdf } 1007220791Smdf 1008220791Smdf out: 1009220846Smdf *ap->a_len = len; 1010220846Smdf *ap->a_offset = offset; 1011220791Smdf free(buf, M_TEMP); 1012220791Smdf return (error); 1013220791Smdf} 1014220791Smdf 1015229723Sjhbint 1016229723Sjhbvop_stdadvise(struct vop_advise_args *ap) 1017229723Sjhb{ 1018229723Sjhb struct vnode *vp; 1019229723Sjhb off_t start, end; 1020229723Sjhb int error, vfslocked; 1021229723Sjhb 1022229723Sjhb vp = ap->a_vp; 1023229723Sjhb switch (ap->a_advice) { 1024229723Sjhb case POSIX_FADV_WILLNEED: 1025229723Sjhb /* 1026229723Sjhb * Do nothing for now. Filesystems should provide a 1027229723Sjhb * custom method which starts an asynchronous read of 1028229723Sjhb * the requested region. 1029229723Sjhb */ 1030229723Sjhb error = 0; 1031229723Sjhb break; 1032229723Sjhb case POSIX_FADV_DONTNEED: 1033229723Sjhb /* 1034229723Sjhb * Flush any open FS buffers and then remove pages 1035229723Sjhb * from the backing VM object. Using vinvalbuf() here 1036229723Sjhb * is a bit heavy-handed as it flushes all buffers for 1037229723Sjhb * the given vnode, not just the buffers covering the 1038229723Sjhb * requested range. 1039229723Sjhb */ 1040229723Sjhb error = 0; 1041229723Sjhb vfslocked = VFS_LOCK_GIANT(vp->v_mount); 1042229723Sjhb vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 1043229723Sjhb if (vp->v_iflag & VI_DOOMED) { 1044229723Sjhb VOP_UNLOCK(vp, 0); 1045229723Sjhb VFS_UNLOCK_GIANT(vfslocked); 1046229723Sjhb break; 1047229723Sjhb } 1048229723Sjhb vinvalbuf(vp, V_CLEANONLY, 0, 0); 1049229723Sjhb if (vp->v_object != NULL) { 1050229723Sjhb start = trunc_page(ap->a_start); 1051229723Sjhb end = round_page(ap->a_end); 1052229723Sjhb VM_OBJECT_LOCK(vp->v_object); 1053229723Sjhb vm_object_page_cache(vp->v_object, OFF_TO_IDX(start), 1054229723Sjhb OFF_TO_IDX(end)); 1055229723Sjhb VM_OBJECT_UNLOCK(vp->v_object); 1056229723Sjhb } 1057229723Sjhb VOP_UNLOCK(vp, 0); 1058229723Sjhb VFS_UNLOCK_GIANT(vfslocked); 1059229723Sjhb break; 1060229723Sjhb default: 1061229723Sjhb error = EINVAL; 1062229723Sjhb break; 1063229723Sjhb } 1064229723Sjhb return (error); 1065229723Sjhb} 1066229723Sjhb 1067234660Strocinyint 1068234660Strocinyvop_stdunp_bind(struct vop_unp_bind_args *ap) 1069234660Strociny{ 1070234660Strociny 1071234660Strociny ap->a_vp->v_socket = ap->a_socket; 1072234660Strociny return (0); 1073234660Strociny} 1074234660Strociny 1075234660Strocinyint 1076234660Strocinyvop_stdunp_connect(struct vop_unp_connect_args *ap) 1077234660Strociny{ 1078234660Strociny 1079234660Strociny *ap->a_socket = ap->a_vp->v_socket; 1080234660Strociny return (0); 1081234660Strociny} 1082234660Strociny 1083234660Strocinyint 1084234660Strocinyvop_stdunp_detach(struct vop_unp_detach_args *ap) 1085234660Strociny{ 1086234660Strociny 1087234660Strociny ap->a_vp->v_socket = NULL; 1088234660Strociny return (0); 1089234660Strociny} 1090234660Strociny 1091244658Skibstatic int 1092244658Skibvop_stdis_text(struct vop_is_text_args *ap) 1093244658Skib{ 1094244658Skib 1095244658Skib return ((ap->a_vp->v_vflag & VV_TEXT) != 0); 1096244658Skib} 1097244658Skib 1098244658Skibstatic int 1099244658Skibvop_stdset_text(struct vop_set_text_args *ap) 1100244658Skib{ 1101244658Skib 1102244658Skib ap->a_vp->v_vflag |= VV_TEXT; 1103244658Skib return (0); 1104244658Skib} 1105244658Skib 1106244658Skibstatic int 1107244658Skibvop_stdunset_text(struct vop_unset_text_args *ap) 1108244658Skib{ 1109244658Skib 1110244658Skib ap->a_vp->v_vflag &= ~VV_TEXT; 1111244658Skib return (0); 1112244658Skib} 1113244658Skib 1114244660Skibstatic int 1115244660Skibvop_stdget_writecount(struct vop_get_writecount_args *ap) 1116244660Skib{ 1117244660Skib 1118244660Skib *ap->a_writecount = ap->a_vp->v_writecount; 1119244660Skib return (0); 1120244660Skib} 1121244660Skib 1122244660Skibstatic int 1123244660Skibvop_stdadd_writecount(struct vop_add_writecount_args *ap) 1124244660Skib{ 1125244660Skib 1126244660Skib ap->a_vp->v_writecount += ap->a_inc; 1127244660Skib return (0); 1128244660Skib} 1129244660Skib 1130112067Skan/* 113151068Salfred * vfs default ops 113291690Seivind * used to fill the vfs function table to get reasonable default return values. 113351068Salfred */ 113491690Seivindint 1135191990Sattiliovfs_stdroot (mp, flags, vpp) 113651068Salfred struct mount *mp; 1137144054Sjeff int flags; 113851068Salfred struct vnode **vpp; 113951068Salfred{ 1140131734Salfred 114151068Salfred return (EOPNOTSUPP); 114251068Salfred} 114351068Salfred 114491690Seivindint 1145191990Sattiliovfs_stdstatfs (mp, sbp) 114651068Salfred struct mount *mp; 114751068Salfred struct statfs *sbp; 114851068Salfred{ 1149131734Salfred 115051068Salfred return (EOPNOTSUPP); 115151068Salfred} 115251068Salfred 115351068Salfredint 1154191990Sattiliovfs_stdquotactl (mp, cmds, uid, arg) 115551068Salfred struct mount *mp; 115651068Salfred int cmds; 115751068Salfred uid_t uid; 1158153400Sdes void *arg; 115951068Salfred{ 1160131734Salfred 116151068Salfred return (EOPNOTSUPP); 116251068Salfred} 116351068Salfred 1164112067Skanint 1165191990Sattiliovfs_stdsync(mp, waitfor) 116651068Salfred struct mount *mp; 116751068Salfred int waitfor; 116851068Salfred{ 1169154152Stegge struct vnode *vp, *mvp; 1170191990Sattilio struct thread *td; 1171112119Skan int error, lockreq, allerror = 0; 1172112119Skan 1173191990Sattilio td = curthread; 1174112119Skan lockreq = LK_EXCLUSIVE | LK_INTERLOCK; 1175112119Skan if (waitfor != MNT_WAIT) 1176112119Skan lockreq |= LK_NOWAIT; 1177112119Skan /* 1178112119Skan * Force stale buffer cache information to be flushed. 1179112119Skan */ 1180112119Skanloop: 1181235626Smckusick MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { 1182235626Smckusick if (vp->v_bufobj.bo_dirty.bv_cnt == 0) { 1183235626Smckusick VI_UNLOCK(vp); 1184177493Sjeff continue; 1185235626Smckusick } 1186112119Skan if ((error = vget(vp, lockreq, td)) != 0) { 1187154152Stegge if (error == ENOENT) { 1188235626Smckusick MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); 1189112119Skan goto loop; 1190154152Stegge } 1191112119Skan continue; 1192112119Skan } 1193140048Sphk error = VOP_FSYNC(vp, waitfor, td); 1194112119Skan if (error) 1195112119Skan allerror = error; 1196204065Spjd vput(vp); 1197112119Skan } 1198112119Skan return (allerror); 1199112119Skan} 1200112119Skan 1201112119Skanint 1202191990Sattiliovfs_stdnosync (mp, waitfor) 1203112119Skan struct mount *mp; 1204112119Skan int waitfor; 1205112119Skan{ 1206131734Salfred 120751068Salfred return (0); 120851068Salfred} 120951068Salfred 1210112067Skanint 121192462Smckusickvfs_stdvget (mp, ino, flags, vpp) 121251068Salfred struct mount *mp; 121351068Salfred ino_t ino; 121492462Smckusick int flags; 121551068Salfred struct vnode **vpp; 121651068Salfred{ 1217131734Salfred 121851068Salfred return (EOPNOTSUPP); 121951068Salfred} 122051068Salfred 1221112067Skanint 1222222167Srmacklemvfs_stdfhtovp (mp, fhp, flags, vpp) 122351068Salfred struct mount *mp; 122451068Salfred struct fid *fhp; 1225222167Srmacklem int flags; 122651138Salfred struct vnode **vpp; 122751138Salfred{ 1228131734Salfred 122951138Salfred return (EOPNOTSUPP); 123051138Salfred} 123151138Salfred 123251068Salfredint 1233112067Skanvfs_stdinit (vfsp) 123451068Salfred struct vfsconf *vfsp; 123551068Salfred{ 1236131734Salfred 123751068Salfred return (0); 123851068Salfred} 123951068Salfred 124051068Salfredint 124151068Salfredvfs_stduninit (vfsp) 124251068Salfred struct vfsconf *vfsp; 124351068Salfred{ 1244131734Salfred 124551068Salfred return(0); 124651068Salfred} 124751068Salfred 124854803Srwatsonint 1249191990Sattiliovfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname) 125054803Srwatson struct mount *mp; 125154803Srwatson int cmd; 125274273Srwatson struct vnode *filename_vp; 125374437Srwatson int attrnamespace; 125456272Srwatson const char *attrname; 125554803Srwatson{ 1256131734Salfred 1257101786Sphk if (filename_vp != NULL) 1258175294Sattilio VOP_UNLOCK(filename_vp, 0); 1259131734Salfred return (EOPNOTSUPP); 126054803Srwatson} 126154803Srwatson 1262131733Salfredint 1263131733Salfredvfs_stdsysctl(mp, op, req) 1264131733Salfred struct mount *mp; 1265131733Salfred fsctlop_t op; 1266131733Salfred struct sysctl_req *req; 1267131733Salfred{ 1268131733Salfred 1269131733Salfred return (EOPNOTSUPP); 1270131733Salfred} 1271131733Salfred 127251068Salfred/* end of vfs default ops */ 1273