vfs_default.c revision 191990
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 191990 2009-05-11 15:33:26Z attilio $"); 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 5865770Sbp#include <vm/vm.h> 5965770Sbp#include <vm/vm_object.h> 6065770Sbp#include <vm/vm_extern.h> 6165770Sbp#include <vm/pmap.h> 6265770Sbp#include <vm/vm_map.h> 6365770Sbp#include <vm/vm_page.h> 6465770Sbp#include <vm/vm_pager.h> 6565770Sbp#include <vm/vnode_pager.h> 6665770Sbp 6792723Salfredstatic int vop_nolookup(struct vop_lookup_args *); 6892723Salfredstatic int vop_nostrategy(struct vop_strategy_args *); 69189539Smarcusstatic int get_next_dirent(struct vnode *vp, struct dirent **dpp, 70189539Smarcus char *dirbuf, int dirbuflen, off_t *off, 71189539Smarcus char **cpos, int *len, int *eofflag, 72189539Smarcus struct thread *td); 73189539Smarcusstatic int dirent_exists(struct vnode *vp, const char *dirname, 74189539Smarcus struct thread *td); 7530489Sphk 76189539Smarcus#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) 77189539Smarcus 7830489Sphk/* 7930489Sphk * This vnode table stores what we want to do if the filesystem doesn't 8030489Sphk * implement a particular VOP. 8130489Sphk * 8230489Sphk * If there is no specific entry here, we will return EOPNOTSUPP. 8330489Sphk * 8430489Sphk */ 8530489Sphk 86138290Sphkstruct vop_vector default_vnodeops = { 87138290Sphk .vop_default = NULL, 88138339Sphk .vop_bypass = VOP_EOPNOTSUPP, 89138339Sphk 90178243Skib .vop_advlock = vop_stdadvlock, 91178243Skib .vop_advlockasync = vop_stdadvlockasync, 92138290Sphk .vop_bmap = vop_stdbmap, 93138290Sphk .vop_close = VOP_NULL, 94138290Sphk .vop_fsync = VOP_NULL, 95138290Sphk .vop_getpages = vop_stdgetpages, 96138290Sphk .vop_getwritemount = vop_stdgetwritemount, 97143494Sjeff .vop_inactive = VOP_NULL, 98138290Sphk .vop_ioctl = VOP_ENOTTY, 99147198Sssouhlal .vop_kqfilter = vop_stdkqfilter, 100138290Sphk .vop_islocked = vop_stdislocked, 101169671Skib .vop_lock1 = vop_stdlock, 102138290Sphk .vop_lookup = vop_nolookup, 103138290Sphk .vop_open = VOP_NULL, 104138290Sphk .vop_pathconf = VOP_EINVAL, 105138290Sphk .vop_poll = vop_nopoll, 106138290Sphk .vop_putpages = vop_stdputpages, 107138290Sphk .vop_readlink = VOP_EINVAL, 108138290Sphk .vop_revoke = VOP_PANIC, 109138290Sphk .vop_strategy = vop_nostrategy, 110138290Sphk .vop_unlock = vop_stdunlock, 111189539Smarcus .vop_vptocnp = vop_stdvptocnp, 112166774Spjd .vop_vptofh = vop_stdvptofh, 11330489Sphk}; 11430489Sphk 11591690Seivind/* 11691690Seivind * Series of placeholder functions for various error returns for 11791690Seivind * VOPs. 11891690Seivind */ 11991690Seivind 12030489Sphkint 12130492Sphkvop_eopnotsupp(struct vop_generic_args *ap) 12230489Sphk{ 12330489Sphk /* 12430492Sphk printf("vop_notsupp[%s]\n", ap->a_desc->vdesc_name); 12530489Sphk */ 12630489Sphk 12730489Sphk return (EOPNOTSUPP); 12830489Sphk} 12930489Sphk 13030489Sphkint 13130492Sphkvop_ebadf(struct vop_generic_args *ap) 13230489Sphk{ 13330489Sphk 13430492Sphk return (EBADF); 13530492Sphk} 13630492Sphk 13730492Sphkint 13830492Sphkvop_enotty(struct vop_generic_args *ap) 13930492Sphk{ 14030492Sphk 14130492Sphk return (ENOTTY); 14230492Sphk} 14330492Sphk 14430492Sphkint 14530492Sphkvop_einval(struct vop_generic_args *ap) 14630492Sphk{ 14730492Sphk 14830492Sphk return (EINVAL); 14930492Sphk} 15030492Sphk 15130492Sphkint 152185956Smarcusvop_enoent(struct vop_generic_args *ap) 153185956Smarcus{ 154185956Smarcus 155185956Smarcus return (ENOENT); 156185956Smarcus} 157185956Smarcus 158185956Smarcusint 15930492Sphkvop_null(struct vop_generic_args *ap) 16030492Sphk{ 16130492Sphk 16230492Sphk return (0); 16330492Sphk} 16430492Sphk 16591690Seivind/* 16691690Seivind * Helper function to panic on some bad VOPs in some filesystems. 16791690Seivind */ 16841056Speterint 16941056Spetervop_panic(struct vop_generic_args *ap) 17041056Speter{ 17141056Speter 17272594Sbde panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name); 17341056Speter} 17441056Speter 17591690Seivind/* 17691690Seivind * vop_std<something> and vop_no<something> are default functions for use by 17791690Seivind * filesystems that need the "default reasonable" implementation for a 17891690Seivind * particular operation. 17991690Seivind * 18091690Seivind * The documentation for the operations they implement exists (if it exists) 18191690Seivind * in the VOP_<SOMETHING>(9) manpage (all uppercase). 18291690Seivind */ 18391690Seivind 18491690Seivind/* 18591690Seivind * Default vop for filesystems that do not support name lookup 18691690Seivind */ 18772594Sbdestatic int 18872594Sbdevop_nolookup(ap) 18972594Sbde struct vop_lookup_args /* { 19072594Sbde struct vnode *a_dvp; 19172594Sbde struct vnode **a_vpp; 19272594Sbde struct componentname *a_cnp; 19372594Sbde } */ *ap; 19472594Sbde{ 19572594Sbde 19672594Sbde *ap->a_vpp = NULL; 19772594Sbde return (ENOTDIR); 19872594Sbde} 19972594Sbde 20046349Salc/* 20146349Salc * vop_nostrategy: 20246349Salc * 20346349Salc * Strategy routine for VFS devices that have none. 20446349Salc * 20558934Sphk * BIO_ERROR and B_INVAL must be cleared prior to calling any strategy 20658345Sphk * routine. Typically this is done for a BIO_READ strategy call. 207112067Skan * Typically B_INVAL is assumed to already be clear prior to a write 20858345Sphk * and should not be cleared manually unless you just made the buffer 20958934Sphk * invalid. BIO_ERROR should be cleared either way. 21046349Salc */ 21146349Salc 21230489Sphkstatic int 21330489Sphkvop_nostrategy (struct vop_strategy_args *ap) 21430489Sphk{ 21530489Sphk printf("No strategy for buffer at %p\n", ap->a_bp); 216111842Snjl vprint("vnode", ap->a_vp); 21758934Sphk ap->a_bp->b_ioflags |= BIO_ERROR; 21830489Sphk ap->a_bp->b_error = EOPNOTSUPP; 21959249Sphk bufdone(ap->a_bp); 22030489Sphk return (EOPNOTSUPP); 22130489Sphk} 22230492Sphk 223189539Smarcusstatic int 224189539Smarcusget_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, 225189539Smarcus int dirbuflen, off_t *off, char **cpos, int *len, 226189539Smarcus int *eofflag, struct thread *td) 227189539Smarcus{ 228189539Smarcus int error, reclen; 229189539Smarcus struct uio uio; 230189539Smarcus struct iovec iov; 231189539Smarcus struct dirent *dp; 232189539Smarcus 233189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 234189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 235189539Smarcus 236189539Smarcus if (*len == 0) { 237189539Smarcus iov.iov_base = dirbuf; 238189539Smarcus iov.iov_len = dirbuflen; 239189539Smarcus 240189539Smarcus uio.uio_iov = &iov; 241189539Smarcus uio.uio_iovcnt = 1; 242189539Smarcus uio.uio_offset = *off; 243189539Smarcus uio.uio_resid = dirbuflen; 244189539Smarcus uio.uio_segflg = UIO_SYSSPACE; 245189539Smarcus uio.uio_rw = UIO_READ; 246189539Smarcus uio.uio_td = td; 247189539Smarcus 248189539Smarcus *eofflag = 0; 249189539Smarcus 250189539Smarcus#ifdef MAC 251189539Smarcus error = mac_vnode_check_readdir(td->td_ucred, vp); 252189539Smarcus if (error == 0) 253189539Smarcus#endif 254189539Smarcus error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, 255189539Smarcus NULL, NULL); 256189539Smarcus if (error) 257189539Smarcus return (error); 258189539Smarcus 259189539Smarcus *off = uio.uio_offset; 260189539Smarcus 261189539Smarcus *cpos = dirbuf; 262189539Smarcus *len = (dirbuflen - uio.uio_resid); 263189539Smarcus } 264189539Smarcus 265189539Smarcus dp = (struct dirent *)(*cpos); 266189539Smarcus reclen = dp->d_reclen; 267189539Smarcus *dpp = dp; 268189539Smarcus 269189539Smarcus /* check for malformed directory.. */ 270189539Smarcus if (reclen < DIRENT_MINSIZE) 271189539Smarcus return (EINVAL); 272189539Smarcus 273189539Smarcus *cpos += reclen; 274189539Smarcus *len -= reclen; 275189539Smarcus 276189539Smarcus return (0); 277189539Smarcus} 278189539Smarcus 27991690Seivind/* 280189539Smarcus * Check if a named file exists in a given directory vnode. 281189539Smarcus */ 282189539Smarcusstatic int 283189539Smarcusdirent_exists(struct vnode *vp, const char *dirname, struct thread *td) 284189539Smarcus{ 285189539Smarcus char *dirbuf, *cpos; 286189539Smarcus int error, eofflag, dirbuflen, len, found; 287189539Smarcus off_t off; 288189539Smarcus struct dirent *dp; 289189539Smarcus struct vattr va; 290189539Smarcus 291189539Smarcus KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); 292189539Smarcus KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); 293189539Smarcus 294189539Smarcus found = 0; 295189539Smarcus 296189539Smarcus error = VOP_GETATTR(vp, &va, td->td_ucred); 297189539Smarcus if (error) 298189539Smarcus return (found); 299189539Smarcus 300189539Smarcus dirbuflen = DEV_BSIZE; 301189539Smarcus if (dirbuflen < va.va_blocksize) 302189539Smarcus dirbuflen = va.va_blocksize; 303189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 304189539Smarcus 305189539Smarcus off = 0; 306189539Smarcus len = 0; 307189539Smarcus do { 308189539Smarcus error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, 309189539Smarcus &cpos, &len, &eofflag, td); 310189539Smarcus if (error) 311189539Smarcus goto out; 312189539Smarcus 313189539Smarcus if ((dp->d_type != DT_WHT) && 314189539Smarcus !strcmp(dp->d_name, dirname)) { 315189539Smarcus found = 1; 316189539Smarcus goto out; 317189539Smarcus } 318189539Smarcus } while (len > 0 || !eofflag); 319189539Smarcus 320189539Smarcusout: 321189539Smarcus free(dirbuf, M_TEMP); 322189539Smarcus return (found); 323189539Smarcus} 324189539Smarcus 325189539Smarcus/* 326178243Skib * Advisory record locking support 327178243Skib */ 328178243Skibint 329178243Skibvop_stdadvlock(struct vop_advlock_args *ap) 330178243Skib{ 331182371Sattilio struct vnode *vp; 332182371Sattilio struct ucred *cred; 333178243Skib struct vattr vattr; 334178243Skib int error; 335178243Skib 336182371Sattilio vp = ap->a_vp; 337182371Sattilio cred = curthread->td_ucred; 338178243Skib vn_lock(vp, LK_SHARED | LK_RETRY); 339182371Sattilio error = VOP_GETATTR(vp, &vattr, cred); 340178243Skib VOP_UNLOCK(vp, 0); 341178243Skib if (error) 342178243Skib return (error); 343178243Skib 344178243Skib return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); 345178243Skib} 346178243Skib 347178243Skibint 348178243Skibvop_stdadvlockasync(struct vop_advlockasync_args *ap) 349178243Skib{ 350182371Sattilio struct vnode *vp; 351182371Sattilio struct ucred *cred; 352178243Skib struct vattr vattr; 353178243Skib int error; 354178243Skib 355182371Sattilio vp = ap->a_vp; 356182371Sattilio cred = curthread->td_ucred; 357178243Skib vn_lock(vp, LK_SHARED | LK_RETRY); 358182371Sattilio error = VOP_GETATTR(vp, &vattr, cred); 359178243Skib VOP_UNLOCK(vp, 0); 360178243Skib if (error) 361178243Skib return (error); 362178243Skib 363178243Skib return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); 364178243Skib} 365178243Skib 366178243Skib/* 36791690Seivind * vop_stdpathconf: 368112067Skan * 36991690Seivind * Standard implementation of POSIX pathconf, to get information about limits 37091690Seivind * for a filesystem. 37191690Seivind * Override per filesystem for the case where the filesystem has smaller 37291690Seivind * limits. 37391690Seivind */ 37430492Sphkint 37530492Sphkvop_stdpathconf(ap) 37630492Sphk struct vop_pathconf_args /* { 37730492Sphk struct vnode *a_vp; 37830492Sphk int a_name; 37930492Sphk int *a_retval; 38030492Sphk } */ *ap; 38130492Sphk{ 38230492Sphk 38330492Sphk switch (ap->a_name) { 384149175Sphk case _PC_NAME_MAX: 385149175Sphk *ap->a_retval = NAME_MAX; 386149175Sphk return (0); 387149175Sphk case _PC_PATH_MAX: 388149175Sphk *ap->a_retval = PATH_MAX; 389149175Sphk return (0); 39030492Sphk case _PC_LINK_MAX: 39130492Sphk *ap->a_retval = LINK_MAX; 39230492Sphk return (0); 39330492Sphk case _PC_MAX_CANON: 39430492Sphk *ap->a_retval = MAX_CANON; 39530492Sphk return (0); 39630492Sphk case _PC_MAX_INPUT: 39730492Sphk *ap->a_retval = MAX_INPUT; 39830492Sphk return (0); 39930492Sphk case _PC_PIPE_BUF: 40030492Sphk *ap->a_retval = PIPE_BUF; 40130492Sphk return (0); 40230492Sphk case _PC_CHOWN_RESTRICTED: 40330492Sphk *ap->a_retval = 1; 40430492Sphk return (0); 40530492Sphk case _PC_VDISABLE: 40630492Sphk *ap->a_retval = _POSIX_VDISABLE; 40730492Sphk return (0); 40830492Sphk default: 40930492Sphk return (EINVAL); 41030492Sphk } 41130492Sphk /* NOTREACHED */ 41230492Sphk} 41330513Sphk 41430513Sphk/* 41530513Sphk * Standard lock, unlock and islocked functions. 41630513Sphk */ 41730513Sphkint 41830513Sphkvop_stdlock(ap) 419169671Skib struct vop_lock1_args /* { 42030513Sphk struct vnode *a_vp; 42130513Sphk int a_flags; 422164248Skmacy char *file; 423164248Skmacy int line; 42430513Sphk } */ *ap; 425112067Skan{ 42666355Sbp struct vnode *vp = ap->a_vp; 42730513Sphk 428176320Sattilio return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), 429176320Sattilio LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, 430175635Sattilio ap->a_line)); 43130513Sphk} 43230513Sphk 43391690Seivind/* See above. */ 43430513Sphkint 43530513Sphkvop_stdunlock(ap) 43630513Sphk struct vop_unlock_args /* { 43730513Sphk struct vnode *a_vp; 43830513Sphk int a_flags; 43930513Sphk } */ *ap; 44030513Sphk{ 44166355Sbp struct vnode *vp = ap->a_vp; 44230513Sphk 443175635Sattilio return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); 44430513Sphk} 44530513Sphk 44691690Seivind/* See above. */ 44730513Sphkint 44830513Sphkvop_stdislocked(ap) 44930513Sphk struct vop_islocked_args /* { 45030513Sphk struct vnode *a_vp; 45130513Sphk } */ *ap; 45230513Sphk{ 45330513Sphk 454176559Sattilio return (lockstatus(ap->a_vp->v_vnlock)); 45530513Sphk} 45630513Sphk 45730743Sphk/* 45830743Sphk * Return true for select/poll. 45930743Sphk */ 46030743Sphkint 46130743Sphkvop_nopoll(ap) 46230743Sphk struct vop_poll_args /* { 46330743Sphk struct vnode *a_vp; 46430743Sphk int a_events; 46530743Sphk struct ucred *a_cred; 46683366Sjulian struct thread *a_td; 46730743Sphk } */ *ap; 46830743Sphk{ 46931727Swollman 470189450Skib return (poll_no_poll(ap->a_events)); 47130743Sphk} 47230743Sphk 47331727Swollman/* 47431727Swollman * Implement poll for local filesystems that support it. 47531727Swollman */ 47630743Sphkint 47731727Swollmanvop_stdpoll(ap) 47831727Swollman struct vop_poll_args /* { 47931727Swollman struct vnode *a_vp; 48031727Swollman int a_events; 48131727Swollman struct ucred *a_cred; 48283366Sjulian struct thread *a_td; 48331727Swollman } */ *ap; 48431727Swollman{ 48576578Sjlemon if (ap->a_events & ~POLLSTANDARD) 48683366Sjulian return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events)); 48776578Sjlemon return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 48831727Swollman} 48931727Swollman 49030743Sphk/* 49162976Smckusick * Return our mount point, as we will take charge of the writes. 49262976Smckusick */ 49362976Smckusickint 49462976Smckusickvop_stdgetwritemount(ap) 49562976Smckusick struct vop_getwritemount_args /* { 49662976Smckusick struct vnode *a_vp; 49762976Smckusick struct mount **a_mpp; 49862976Smckusick } */ *ap; 49962976Smckusick{ 500157323Sjeff struct mount *mp; 50162976Smckusick 502157323Sjeff /* 503157323Sjeff * XXX Since this is called unlocked we may be recycled while 504157323Sjeff * attempting to ref the mount. If this is the case or mountpoint 505157323Sjeff * will be set to NULL. We only have to prevent this call from 506157323Sjeff * returning with a ref to an incorrect mountpoint. It is not 507157323Sjeff * harmful to return with a ref to our previous mountpoint. 508157323Sjeff */ 509157323Sjeff mp = ap->a_vp->v_mount; 510162455Stegge if (mp != NULL) { 511162455Stegge vfs_ref(mp); 512162455Stegge if (mp != ap->a_vp->v_mount) { 513162455Stegge vfs_rel(mp); 514162455Stegge mp = NULL; 515162455Stegge } 516157323Sjeff } 517157323Sjeff *(ap->a_mpp) = mp; 51862976Smckusick return (0); 51962976Smckusick} 52062976Smckusick 52191690Seivind/* XXX Needs good comment and VOP_BMAP(9) manpage */ 52276131Sphkint 52376131Sphkvop_stdbmap(ap) 524112067Skan struct vop_bmap_args /* { 52576131Sphk struct vnode *a_vp; 52676131Sphk daddr_t a_bn; 527137726Sphk struct bufobj **a_bop; 52876131Sphk daddr_t *a_bnp; 52976131Sphk int *a_runp; 53076131Sphk int *a_runb; 53176131Sphk } */ *ap; 53276131Sphk{ 53376131Sphk 534137726Sphk if (ap->a_bop != NULL) 535137726Sphk *ap->a_bop = &ap->a_vp->v_bufobj; 53676131Sphk if (ap->a_bnp != NULL) 53776131Sphk *ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize); 53876131Sphk if (ap->a_runp != NULL) 53976131Sphk *ap->a_runp = 0; 54076131Sphk if (ap->a_runb != NULL) 54176131Sphk *ap->a_runb = 0; 54276131Sphk return (0); 54376131Sphk} 54476131Sphk 545110584Sjeffint 546110584Sjeffvop_stdfsync(ap) 547110584Sjeff struct vop_fsync_args /* { 548110584Sjeff struct vnode *a_vp; 549110584Sjeff struct ucred *a_cred; 550110584Sjeff int a_waitfor; 551110584Sjeff struct thread *a_td; 552110584Sjeff } */ *ap; 553110584Sjeff{ 554110584Sjeff struct vnode *vp = ap->a_vp; 555110584Sjeff struct buf *bp; 556136751Sphk struct bufobj *bo; 557110584Sjeff struct buf *nbp; 558145732Sjeff int error = 0; 559144584Sjeff int maxretry = 1000; /* large, arbitrarily chosen */ 560110584Sjeff 561177493Sjeff bo = &vp->v_bufobj; 562177493Sjeff BO_LOCK(bo); 563110584Sjeffloop1: 564110584Sjeff /* 565110584Sjeff * MARK/SCAN initialization to avoid infinite loops. 566110584Sjeff */ 567177493Sjeff TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { 568110584Sjeff bp->b_vflags &= ~BV_SCANNED; 569110584Sjeff bp->b_error = 0; 570110584Sjeff } 571110584Sjeff 572110584Sjeff /* 573144584Sjeff * Flush all dirty buffers associated with a vnode. 574110584Sjeff */ 575110584Sjeffloop2: 576177493Sjeff TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { 577110584Sjeff if ((bp->b_vflags & BV_SCANNED) != 0) 578110584Sjeff continue; 579110584Sjeff bp->b_vflags |= BV_SCANNED; 580111463Sjeff if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) 581110584Sjeff continue; 582177493Sjeff BO_UNLOCK(bo); 583177493Sjeff KASSERT(bp->b_bufobj == bo, 584147388Sjeff ("bp %p wrong b_bufobj %p should be %p", 585177493Sjeff bp, bp->b_bufobj, bo)); 586110584Sjeff if ((bp->b_flags & B_DELWRI) == 0) 587110588Sjeff panic("fsync: not dirty"); 588140734Sphk if ((vp->v_object != NULL) && (bp->b_flags & B_CLUSTEROK)) { 589110584Sjeff vfs_bio_awrite(bp); 590110584Sjeff } else { 591110584Sjeff bremfree(bp); 592110584Sjeff bawrite(bp); 593110584Sjeff } 594177493Sjeff BO_LOCK(bo); 595110584Sjeff goto loop2; 596110584Sjeff } 597110584Sjeff 598110584Sjeff /* 599110584Sjeff * If synchronous the caller expects us to completely resolve all 600110584Sjeff * dirty buffers in the system. Wait for in-progress I/O to 601110584Sjeff * complete (which could include background bitmap writes), then 602110584Sjeff * retry if dirty blocks still exist. 603110584Sjeff */ 604110584Sjeff if (ap->a_waitfor == MNT_WAIT) { 605136751Sphk bufobj_wwait(bo, 0, 0); 606136751Sphk if (bo->bo_dirty.bv_cnt > 0) { 607110584Sjeff /* 608110584Sjeff * If we are unable to write any of these buffers 609110584Sjeff * then we fail now rather than trying endlessly 610110584Sjeff * to write them out. 611110584Sjeff */ 612136751Sphk TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) 613110584Sjeff if ((error = bp->b_error) == 0) 614110584Sjeff continue; 615145732Sjeff if (error == 0 && --maxretry >= 0) 616110584Sjeff goto loop1; 617110584Sjeff error = EAGAIN; 618110584Sjeff } 619110584Sjeff } 620177493Sjeff BO_UNLOCK(bo); 621144584Sjeff if (error == EAGAIN) 622144584Sjeff vprint("fsync: giving up on dirty", vp); 623112067Skan 624110584Sjeff return (error); 625110584Sjeff} 626112067Skan 62791690Seivind/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ 62876167Sphkint 62976167Sphkvop_stdgetpages(ap) 63076167Sphk struct vop_getpages_args /* { 63176167Sphk struct vnode *a_vp; 63276167Sphk vm_page_t *a_m; 63376167Sphk int a_count; 63476167Sphk int a_reqpage; 63576167Sphk vm_ooffset_t a_offset; 63676167Sphk } */ *ap; 63776167Sphk{ 63876131Sphk 63976167Sphk return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 64076167Sphk ap->a_count, ap->a_reqpage); 64176167Sphk} 64276167Sphk 643147198Sssouhlalint 644147198Sssouhlalvop_stdkqfilter(struct vop_kqfilter_args *ap) 645147198Sssouhlal{ 646147198Sssouhlal return vfs_kqfilter(ap); 647147198Sssouhlal} 648147198Sssouhlal 64991690Seivind/* XXX Needs good comment and more info in the manpage (VOP_PUTPAGES(9)). */ 65076319Sphkint 65176167Sphkvop_stdputpages(ap) 65276167Sphk struct vop_putpages_args /* { 65376167Sphk struct vnode *a_vp; 65476167Sphk vm_page_t *a_m; 65576167Sphk int a_count; 65676167Sphk int a_sync; 65776167Sphk int *a_rtvals; 65876167Sphk vm_ooffset_t a_offset; 65976167Sphk } */ *ap; 66076167Sphk{ 66176167Sphk 66276319Sphk return vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count, 66376167Sphk ap->a_sync, ap->a_rtvals); 66476167Sphk} 66576167Sphk 666166774Spjdint 667166774Spjdvop_stdvptofh(struct vop_vptofh_args *ap) 668166774Spjd{ 669166795Spjd return (EOPNOTSUPP); 670166774Spjd} 671166774Spjd 672189539Smarcusint 673189539Smarcusvop_stdvptocnp(struct vop_vptocnp_args *ap) 674189539Smarcus{ 675189539Smarcus struct vnode *vp = ap->a_vp; 676189539Smarcus struct vnode **dvp = ap->a_vpp; 677189539Smarcus char *buf = ap->a_buf; 678189539Smarcus int *buflen = ap->a_buflen; 679189539Smarcus char *dirbuf, *cpos; 680189539Smarcus int i, error, eofflag, dirbuflen, flags, locked, len, covered; 681189539Smarcus off_t off; 682189539Smarcus ino_t fileno; 683189539Smarcus struct vattr va; 684189539Smarcus struct nameidata nd; 685189539Smarcus struct thread *td; 686189539Smarcus struct dirent *dp; 687189539Smarcus struct vnode *mvp; 688189539Smarcus 689189539Smarcus i = *buflen; 690189539Smarcus error = 0; 691189539Smarcus covered = 0; 692189539Smarcus td = curthread; 693189539Smarcus 694189539Smarcus if (vp->v_type != VDIR) 695189539Smarcus return (ENOENT); 696189539Smarcus 697189539Smarcus error = VOP_GETATTR(vp, &va, td->td_ucred); 698189539Smarcus if (error) 699189539Smarcus return (error); 700189539Smarcus 701189539Smarcus VREF(vp); 702189539Smarcus locked = VOP_ISLOCKED(vp); 703189539Smarcus VOP_UNLOCK(vp, 0); 704189539Smarcus NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 705189539Smarcus "..", vp, td); 706189539Smarcus flags = FREAD; 707189539Smarcus error = vn_open(&nd, &flags, 0, NULL); 708189539Smarcus if (error) { 709189539Smarcus vn_lock(vp, locked | LK_RETRY); 710189539Smarcus return (error); 711189539Smarcus } 712189539Smarcus NDFREE(&nd, NDF_ONLY_PNBUF); 713189539Smarcus 714189539Smarcus mvp = *dvp = nd.ni_vp; 715189539Smarcus 716189539Smarcus if (vp->v_mount != (*dvp)->v_mount && 717189539Smarcus ((*dvp)->v_vflag & VV_ROOT) && 718189539Smarcus ((*dvp)->v_mount->mnt_flag & MNT_UNION)) { 719189539Smarcus *dvp = (*dvp)->v_mount->mnt_vnodecovered; 720189539Smarcus VREF(mvp); 721189539Smarcus VOP_UNLOCK(mvp, 0); 722189539Smarcus vn_close(mvp, FREAD, td->td_ucred, td); 723189539Smarcus VREF(*dvp); 724189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 725189539Smarcus covered = 1; 726189539Smarcus } 727189539Smarcus 728189539Smarcus fileno = va.va_fileid; 729189539Smarcus 730189539Smarcus dirbuflen = DEV_BSIZE; 731189539Smarcus if (dirbuflen < va.va_blocksize) 732189539Smarcus dirbuflen = va.va_blocksize; 733189539Smarcus dirbuf = (char *)malloc(dirbuflen, M_TEMP, M_WAITOK); 734189539Smarcus 735189539Smarcus if ((*dvp)->v_type != VDIR) { 736189539Smarcus error = ENOENT; 737189539Smarcus goto out; 738189539Smarcus } 739189539Smarcus 740189539Smarcus off = 0; 741189539Smarcus len = 0; 742189539Smarcus do { 743189539Smarcus /* call VOP_READDIR of parent */ 744189539Smarcus error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, 745189539Smarcus &cpos, &len, &eofflag, td); 746189539Smarcus if (error) 747189539Smarcus goto out; 748189539Smarcus 749189539Smarcus if ((dp->d_type != DT_WHT) && 750189539Smarcus (dp->d_fileno == fileno)) { 751189539Smarcus if (covered) { 752189539Smarcus VOP_UNLOCK(*dvp, 0); 753189539Smarcus vn_lock(mvp, LK_EXCLUSIVE | LK_RETRY); 754189539Smarcus if (dirent_exists(mvp, dp->d_name, td)) { 755189539Smarcus error = ENOENT; 756189539Smarcus VOP_UNLOCK(mvp, 0); 757189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 758189539Smarcus goto out; 759189539Smarcus } 760189539Smarcus VOP_UNLOCK(mvp, 0); 761189539Smarcus vn_lock(*dvp, LK_EXCLUSIVE | LK_RETRY); 762189539Smarcus } 763189539Smarcus i -= dp->d_namlen; 764189539Smarcus 765189539Smarcus if (i < 0) { 766189539Smarcus error = ENOMEM; 767189539Smarcus goto out; 768189539Smarcus } 769189539Smarcus bcopy(dp->d_name, buf + i, dp->d_namlen); 770189539Smarcus error = 0; 771189539Smarcus goto out; 772189539Smarcus } 773189539Smarcus } while (len > 0 || !eofflag); 774189539Smarcus error = ENOENT; 775189539Smarcus 776189539Smarcusout: 777189539Smarcus free(dirbuf, M_TEMP); 778189539Smarcus if (!error) { 779189539Smarcus *buflen = i; 780189539Smarcus vhold(*dvp); 781189539Smarcus } 782189539Smarcus if (covered) { 783189539Smarcus vput(*dvp); 784189539Smarcus vrele(mvp); 785189539Smarcus } else { 786189539Smarcus VOP_UNLOCK(mvp, 0); 787189539Smarcus vn_close(mvp, FREAD, td->td_ucred, td); 788189539Smarcus } 789189539Smarcus vn_lock(vp, locked | LK_RETRY); 790189539Smarcus return (error); 791189539Smarcus} 792189539Smarcus 793112067Skan/* 79451068Salfred * vfs default ops 79591690Seivind * used to fill the vfs function table to get reasonable default return values. 79651068Salfred */ 79791690Seivindint 798191990Sattiliovfs_stdroot (mp, flags, vpp) 79951068Salfred struct mount *mp; 800144054Sjeff int flags; 80151068Salfred struct vnode **vpp; 80251068Salfred{ 803131734Salfred 80451068Salfred return (EOPNOTSUPP); 80551068Salfred} 80651068Salfred 80791690Seivindint 808191990Sattiliovfs_stdstatfs (mp, sbp) 80951068Salfred struct mount *mp; 81051068Salfred struct statfs *sbp; 81151068Salfred{ 812131734Salfred 81351068Salfred return (EOPNOTSUPP); 81451068Salfred} 81551068Salfred 81651068Salfredint 817191990Sattiliovfs_stdquotactl (mp, cmds, uid, arg) 81851068Salfred struct mount *mp; 81951068Salfred int cmds; 82051068Salfred uid_t uid; 821153400Sdes void *arg; 82251068Salfred{ 823131734Salfred 82451068Salfred return (EOPNOTSUPP); 82551068Salfred} 82651068Salfred 827112067Skanint 828191990Sattiliovfs_stdsync(mp, waitfor) 82951068Salfred struct mount *mp; 83051068Salfred int waitfor; 83151068Salfred{ 832154152Stegge struct vnode *vp, *mvp; 833191990Sattilio struct thread *td; 834112119Skan int error, lockreq, allerror = 0; 835112119Skan 836191990Sattilio td = curthread; 837112119Skan lockreq = LK_EXCLUSIVE | LK_INTERLOCK; 838112119Skan if (waitfor != MNT_WAIT) 839112119Skan lockreq |= LK_NOWAIT; 840112119Skan /* 841112119Skan * Force stale buffer cache information to be flushed. 842112119Skan */ 843122091Skan MNT_ILOCK(mp); 844112119Skanloop: 845154152Stegge MNT_VNODE_FOREACH(vp, mp, mvp) { 846177493Sjeff /* bv_cnt is an acceptable race here. */ 847177493Sjeff if (vp->v_bufobj.bo_dirty.bv_cnt == 0) 848177493Sjeff continue; 849112119Skan VI_LOCK(vp); 850122091Skan MNT_IUNLOCK(mp); 851112119Skan if ((error = vget(vp, lockreq, td)) != 0) { 852122091Skan MNT_ILOCK(mp); 853154152Stegge if (error == ENOENT) { 854154152Stegge MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); 855112119Skan goto loop; 856154152Stegge } 857112119Skan continue; 858112119Skan } 859140048Sphk error = VOP_FSYNC(vp, waitfor, td); 860112119Skan if (error) 861112119Skan allerror = error; 862112119Skan 863155032Sjeff /* Do not turn this into vput. td is not always curthread. */ 864175294Sattilio VOP_UNLOCK(vp, 0); 865121874Skan vrele(vp); 866122091Skan MNT_ILOCK(mp); 867112119Skan } 868122091Skan MNT_IUNLOCK(mp); 869112119Skan return (allerror); 870112119Skan} 871112119Skan 872112119Skanint 873191990Sattiliovfs_stdnosync (mp, waitfor) 874112119Skan struct mount *mp; 875112119Skan int waitfor; 876112119Skan{ 877131734Salfred 87851068Salfred return (0); 87951068Salfred} 88051068Salfred 881112067Skanint 88292462Smckusickvfs_stdvget (mp, ino, flags, vpp) 88351068Salfred struct mount *mp; 88451068Salfred ino_t ino; 88592462Smckusick int flags; 88651068Salfred struct vnode **vpp; 88751068Salfred{ 888131734Salfred 88951068Salfred return (EOPNOTSUPP); 89051068Salfred} 89151068Salfred 892112067Skanint 89351138Salfredvfs_stdfhtovp (mp, fhp, vpp) 89451068Salfred struct mount *mp; 89551068Salfred struct fid *fhp; 89651138Salfred struct vnode **vpp; 89751138Salfred{ 898131734Salfred 89951138Salfred return (EOPNOTSUPP); 90051138Salfred} 90151138Salfred 90251068Salfredint 903112067Skanvfs_stdinit (vfsp) 90451068Salfred struct vfsconf *vfsp; 90551068Salfred{ 906131734Salfred 90751068Salfred return (0); 90851068Salfred} 90951068Salfred 91051068Salfredint 91151068Salfredvfs_stduninit (vfsp) 91251068Salfred struct vfsconf *vfsp; 91351068Salfred{ 914131734Salfred 91551068Salfred return(0); 91651068Salfred} 91751068Salfred 91854803Srwatsonint 919191990Sattiliovfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname) 92054803Srwatson struct mount *mp; 92154803Srwatson int cmd; 92274273Srwatson struct vnode *filename_vp; 92374437Srwatson int attrnamespace; 92456272Srwatson const char *attrname; 92554803Srwatson{ 926131734Salfred 927101786Sphk if (filename_vp != NULL) 928175294Sattilio VOP_UNLOCK(filename_vp, 0); 929131734Salfred return (EOPNOTSUPP); 93054803Srwatson} 93154803Srwatson 932131733Salfredint 933131733Salfredvfs_stdsysctl(mp, op, req) 934131733Salfred struct mount *mp; 935131733Salfred fsctlop_t op; 936131733Salfred struct sysctl_req *req; 937131733Salfred{ 938131733Salfred 939131733Salfred return (EOPNOTSUPP); 940131733Salfred} 941131733Salfred 94251068Salfred/* end of vfs default ops */ 943