18329232eSGordon Ross /*
28329232eSGordon Ross  * CDDL HEADER START
38329232eSGordon Ross  *
48329232eSGordon Ross  * The contents of this file are subject to the terms of the
58329232eSGordon Ross  * Common Development and Distribution License (the "License").
68329232eSGordon Ross  * You may not use this file except in compliance with the License.
78329232eSGordon Ross  *
88329232eSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98329232eSGordon Ross  * or http://www.opensolaris.org/os/licensing.
108329232eSGordon Ross  * See the License for the specific language governing permissions
118329232eSGordon Ross  * and limitations under the License.
128329232eSGordon Ross  *
138329232eSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
148329232eSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158329232eSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
168329232eSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
178329232eSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
188329232eSGordon Ross  *
198329232eSGordon Ross  * CDDL HEADER END
208329232eSGordon Ross  */
218329232eSGordon Ross 
228329232eSGordon Ross /*
238329232eSGordon Ross  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
248329232eSGordon Ross  * Copyright 2017, Joyent, Inc.
258329232eSGordon Ross  * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
268329232eSGordon Ross  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
278329232eSGordon Ross  */
288329232eSGordon Ross 
298329232eSGordon Ross /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
308329232eSGordon Ross /*	  All Rights Reserved	*/
318329232eSGordon Ross 
328329232eSGordon Ross /*
338329232eSGordon Ross  * University Copyright- Copyright (c) 1982, 1986, 1988
348329232eSGordon Ross  * The Regents of the University of California
358329232eSGordon Ross  * All Rights Reserved
368329232eSGordon Ross  *
378329232eSGordon Ross  * University Acknowledgment- Portions of this document are derived from
388329232eSGordon Ross  * software developed by the University of California, Berkeley, and its
398329232eSGordon Ross  * contributors.
408329232eSGordon Ross  */
418329232eSGordon Ross 
428329232eSGordon Ross /*
438329232eSGordon Ross  * This file contains those functions from fs/vnode.c that can be
448329232eSGordon Ross  * used with relatively little change.  Functions that differ
458329232eSGordon Ross  * significantly from that are in other files.
468329232eSGordon Ross  */
478329232eSGordon Ross 
488329232eSGordon Ross #include <sys/types.h>
498329232eSGordon Ross #include <sys/param.h>
508329232eSGordon Ross #include <sys/t_lock.h>
518329232eSGordon Ross #include <sys/errno.h>
528329232eSGordon Ross #include <sys/cred.h>
538329232eSGordon Ross #include <sys/user.h>
548329232eSGordon Ross #include <sys/uio.h>
558329232eSGordon Ross #include <sys/file.h>
568329232eSGordon Ross #include <sys/pathname.h>
578329232eSGordon Ross #include <sys/vfs.h>
588329232eSGordon Ross #include <sys/vfs_opreg.h>
598329232eSGordon Ross #include <sys/vnode.h>
608329232eSGordon Ross #include <sys/rwstlock.h>
618329232eSGordon Ross #include <sys/fem.h>
628329232eSGordon Ross #include <sys/stat.h>
638329232eSGordon Ross #include <sys/mode.h>
648329232eSGordon Ross #include <sys/conf.h>
658329232eSGordon Ross #include <sys/sysmacros.h>
668329232eSGordon Ross #include <sys/cmn_err.h>
678329232eSGordon Ross #include <sys/systm.h>
688329232eSGordon Ross #include <sys/kmem.h>
698329232eSGordon Ross #include <sys/atomic.h>
708329232eSGordon Ross #include <sys/debug.h>
718329232eSGordon Ross #include <sys/acl.h>
728329232eSGordon Ross #include <sys/nbmlock.h>
738329232eSGordon Ross #include <sys/fcntl.h>
748329232eSGordon Ross #include <sys/time.h>
758329232eSGordon Ross #include <fs/fs_subr.h>
768329232eSGordon Ross #include <fs/fs_reparse.h>
778329232eSGordon Ross 
788329232eSGordon Ross #include <libfksmbfs.h>
798329232eSGordon Ross 
808329232eSGordon Ross /* Determine if this vnode is a file that is read-only */
818329232eSGordon Ross #define	ISROFILE(vp)	\
828329232eSGordon Ross 	((vp)->v_type != VCHR && (vp)->v_type != VBLK && \
838329232eSGordon Ross 	    (vp)->v_type != VFIFO && vn_is_readonly(vp))
848329232eSGordon Ross 
858329232eSGordon Ross #define	VOPSTATS_UPDATE(vp, counter) ((void)vp)
868329232eSGordon Ross #define	VOPSTATS_UPDATE_IO(vp, counter, bytecounter, bytesval) \
878329232eSGordon Ross 	((void)vp, (void)bytesval)
888329232eSGordon Ross #define	VOPXID_MAP_CR(vp, cr)	((void)vp)
898329232eSGordon Ross 
908329232eSGordon Ross /*
918329232eSGordon Ross  * Excerpts from fs/vnode.c
928329232eSGordon Ross  */
938329232eSGordon Ross 
948329232eSGordon Ross /* Global used for empty/invalid v_path */
958329232eSGordon Ross char *vn_vpath_empty = "";
968329232eSGordon Ross 
978329232eSGordon Ross static int fs_reparse_mark(char *target, vattr_t *vap, xvattr_t *xvattr);
988329232eSGordon Ross 
998329232eSGordon Ross /*
1008329232eSGordon Ross  * Convert stat(2) formats to vnode types and vice versa.  (Knows about
1018329232eSGordon Ross  * numerical order of S_IFMT and vnode types.)
1028329232eSGordon Ross  */
1038329232eSGordon Ross enum vtype iftovt_tab[] = {
1048329232eSGordon Ross 	VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
1058329232eSGordon Ross 	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
1068329232eSGordon Ross };
1078329232eSGordon Ross 
1088329232eSGordon Ross ushort_t vttoif_tab[] = {
1098329232eSGordon Ross 	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO,
1108329232eSGordon Ross 	S_IFDOOR, 0, S_IFSOCK, S_IFPORT, 0
1118329232eSGordon Ross };
1128329232eSGordon Ross 
1138329232eSGordon Ross /*
1148329232eSGordon Ross  * The system vnode cache.
1158329232eSGordon Ross  */
1168329232eSGordon Ross 
1178329232eSGordon Ross kmem_cache_t *vn_cache;
1188329232eSGordon Ross 
1198329232eSGordon Ross 
1208329232eSGordon Ross /*
1218329232eSGordon Ross  * Vnode operations vector.
1228329232eSGordon Ross  */
1238329232eSGordon Ross 
1248329232eSGordon Ross static const fs_operation_trans_def_t vn_ops_table[] = {
1258329232eSGordon Ross 	VOPNAME_OPEN, offsetof(struct vnodeops, vop_open),
1268329232eSGordon Ross 	    fs_nosys, fs_nosys,
1278329232eSGordon Ross 
1288329232eSGordon Ross 	VOPNAME_CLOSE, offsetof(struct vnodeops, vop_close),
1298329232eSGordon Ross 	    fs_nosys, fs_nosys,
1308329232eSGordon Ross 
1318329232eSGordon Ross 	VOPNAME_READ, offsetof(struct vnodeops, vop_read),
1328329232eSGordon Ross 	    fs_nosys, fs_nosys,
1338329232eSGordon Ross 
1348329232eSGordon Ross 	VOPNAME_WRITE, offsetof(struct vnodeops, vop_write),
1358329232eSGordon Ross 	    fs_nosys, fs_nosys,
1368329232eSGordon Ross 
1378329232eSGordon Ross 	VOPNAME_IOCTL, offsetof(struct vnodeops, vop_ioctl),
1388329232eSGordon Ross 	    fs_nosys, fs_nosys,
1398329232eSGordon Ross 
1408329232eSGordon Ross 	VOPNAME_SETFL, offsetof(struct vnodeops, vop_setfl),
1418329232eSGordon Ross 	    fs_setfl, fs_nosys,
1428329232eSGordon Ross 
1438329232eSGordon Ross 	VOPNAME_GETATTR, offsetof(struct vnodeops, vop_getattr),
1448329232eSGordon Ross 	    fs_nosys, fs_nosys,
1458329232eSGordon Ross 
1468329232eSGordon Ross 	VOPNAME_SETATTR, offsetof(struct vnodeops, vop_setattr),
1478329232eSGordon Ross 	    fs_nosys, fs_nosys,
1488329232eSGordon Ross 
1498329232eSGordon Ross 	VOPNAME_ACCESS, offsetof(struct vnodeops, vop_access),
1508329232eSGordon Ross 	    fs_nosys, fs_nosys,
1518329232eSGordon Ross 
1528329232eSGordon Ross 	VOPNAME_LOOKUP, offsetof(struct vnodeops, vop_lookup),
1538329232eSGordon Ross 	    fs_nosys, fs_nosys,
1548329232eSGordon Ross 
1558329232eSGordon Ross 	VOPNAME_CREATE, offsetof(struct vnodeops, vop_create),
1568329232eSGordon Ross 	    fs_nosys, fs_nosys,
1578329232eSGordon Ross 
1588329232eSGordon Ross 	VOPNAME_REMOVE, offsetof(struct vnodeops, vop_remove),
1598329232eSGordon Ross 	    fs_nosys, fs_nosys,
1608329232eSGordon Ross 
1618329232eSGordon Ross 	VOPNAME_LINK, offsetof(struct vnodeops, vop_link),
1628329232eSGordon Ross 	    fs_nosys, fs_nosys,
1638329232eSGordon Ross 
1648329232eSGordon Ross 	VOPNAME_RENAME, offsetof(struct vnodeops, vop_rename),
1658329232eSGordon Ross 	    fs_nosys, fs_nosys,
1668329232eSGordon Ross 
1678329232eSGordon Ross 	VOPNAME_MKDIR, offsetof(struct vnodeops, vop_mkdir),
1688329232eSGordon Ross 	    fs_nosys, fs_nosys,
1698329232eSGordon Ross 
1708329232eSGordon Ross 	VOPNAME_RMDIR, offsetof(struct vnodeops, vop_rmdir),
1718329232eSGordon Ross 	    fs_nosys, fs_nosys,
1728329232eSGordon Ross 
1738329232eSGordon Ross 	VOPNAME_READDIR, offsetof(struct vnodeops, vop_readdir),
1748329232eSGordon Ross 	    fs_nosys, fs_nosys,
1758329232eSGordon Ross 
1768329232eSGordon Ross 	VOPNAME_SYMLINK, offsetof(struct vnodeops, vop_symlink),
1778329232eSGordon Ross 	    fs_nosys, fs_nosys,
1788329232eSGordon Ross 
1798329232eSGordon Ross 	VOPNAME_READLINK, offsetof(struct vnodeops, vop_readlink),
1808329232eSGordon Ross 	    fs_nosys, fs_nosys,
1818329232eSGordon Ross 
1828329232eSGordon Ross 	VOPNAME_FSYNC, offsetof(struct vnodeops, vop_fsync),
1838329232eSGordon Ross 	    fs_nosys, fs_nosys,
1848329232eSGordon Ross 
1858329232eSGordon Ross 	VOPNAME_INACTIVE, offsetof(struct vnodeops, vop_inactive),
1868329232eSGordon Ross 	    fs_nosys, fs_nosys,
1878329232eSGordon Ross 
1888329232eSGordon Ross 	VOPNAME_FID, offsetof(struct vnodeops, vop_fid),
1898329232eSGordon Ross 	    fs_nosys, fs_nosys,
1908329232eSGordon Ross 
1918329232eSGordon Ross 	VOPNAME_RWLOCK, offsetof(struct vnodeops, vop_rwlock),
1928329232eSGordon Ross 	    fs_rwlock, fs_rwlock,
1938329232eSGordon Ross 
1948329232eSGordon Ross 	VOPNAME_RWUNLOCK, offsetof(struct vnodeops, vop_rwunlock),
195*8bbe90c1SToomas Soome 	    (fs_generic_func_p)(uintptr_t)fs_rwunlock,
196*8bbe90c1SToomas Soome 	    (fs_generic_func_p)(intptr_t)fs_rwunlock,	/* no errors allowed */
1978329232eSGordon Ross 
1988329232eSGordon Ross 	VOPNAME_SEEK, offsetof(struct vnodeops, vop_seek),
1998329232eSGordon Ross 	    fs_nosys, fs_nosys,
2008329232eSGordon Ross 
2018329232eSGordon Ross 	VOPNAME_CMP, offsetof(struct vnodeops, vop_cmp),
2028329232eSGordon Ross 	    fs_cmp, fs_cmp,		/* no errors allowed */
2038329232eSGordon Ross 
2048329232eSGordon Ross 	VOPNAME_FRLOCK, offsetof(struct vnodeops, vop_frlock),
2058329232eSGordon Ross 	    fs_frlock, fs_nosys,
2068329232eSGordon Ross 
2078329232eSGordon Ross 	VOPNAME_SPACE, offsetof(struct vnodeops, vop_space),
2088329232eSGordon Ross 	    fs_nosys, fs_nosys,
2098329232eSGordon Ross 
2108329232eSGordon Ross 	VOPNAME_REALVP, offsetof(struct vnodeops, vop_realvp),
2118329232eSGordon Ross 	    fs_nosys, fs_nosys,
2128329232eSGordon Ross 
2138329232eSGordon Ross 	VOPNAME_GETPAGE, offsetof(struct vnodeops, vop_getpage),
2148329232eSGordon Ross 	    fs_nosys, fs_nosys,
2158329232eSGordon Ross 
2168329232eSGordon Ross 	VOPNAME_PUTPAGE, offsetof(struct vnodeops, vop_putpage),
2178329232eSGordon Ross 	    fs_nosys, fs_nosys,
2188329232eSGordon Ross 
2198329232eSGordon Ross 	VOPNAME_MAP, offsetof(struct vnodeops, vop_map),
2208329232eSGordon Ross 	    (fs_generic_func_p) fs_nosys_map,
2218329232eSGordon Ross 	    (fs_generic_func_p) fs_nosys_map,
2228329232eSGordon Ross 
2238329232eSGordon Ross 	VOPNAME_ADDMAP, offsetof(struct vnodeops, vop_addmap),
2248329232eSGordon Ross 	    (fs_generic_func_p) fs_nosys_addmap,
2258329232eSGordon Ross 	    (fs_generic_func_p) fs_nosys_addmap,
2268329232eSGordon Ross 
2278329232eSGordon Ross 	VOPNAME_DELMAP, offsetof(struct vnodeops, vop_delmap),
2288329232eSGordon Ross 	    fs_nosys, fs_nosys,
2298329232eSGordon Ross 
2308329232eSGordon Ross 	VOPNAME_POLL, offsetof(struct vnodeops, vop_poll),
2318329232eSGordon Ross 	    (fs_generic_func_p) fs_poll, (fs_generic_func_p) fs_nosys_poll,
2328329232eSGordon Ross 
2338329232eSGordon Ross 	VOPNAME_DUMP, offsetof(struct vnodeops, vop_dump),
2348329232eSGordon Ross 	    fs_nosys, fs_nosys,
2358329232eSGordon Ross 
2368329232eSGordon Ross 	VOPNAME_PATHCONF, offsetof(struct vnodeops, vop_pathconf),
2378329232eSGordon Ross 	    fs_pathconf, fs_nosys,
2388329232eSGordon Ross 
2398329232eSGordon Ross 	VOPNAME_PAGEIO, offsetof(struct vnodeops, vop_pageio),
2408329232eSGordon Ross 	    fs_nosys, fs_nosys,
2418329232eSGordon Ross 
2428329232eSGordon Ross 	VOPNAME_DUMPCTL, offsetof(struct vnodeops, vop_dumpctl),
2438329232eSGordon Ross 	    fs_nosys, fs_nosys,
2448329232eSGordon Ross 
2458329232eSGordon Ross 	VOPNAME_DISPOSE, offsetof(struct vnodeops, vop_dispose),
246*8bbe90c1SToomas Soome 	    (fs_generic_func_p)(intptr_t)fs_dispose,
247*8bbe90c1SToomas Soome 	    (fs_generic_func_p)(intptr_t)fs_nodispose,
2488329232eSGordon Ross 
2498329232eSGordon Ross 	VOPNAME_SETSECATTR, offsetof(struct vnodeops, vop_setsecattr),
2508329232eSGordon Ross 	    fs_nosys, fs_nosys,
2518329232eSGordon Ross 
2528329232eSGordon Ross 	VOPNAME_GETSECATTR, offsetof(struct vnodeops, vop_getsecattr),
2538329232eSGordon Ross 	    fs_fab_acl, fs_nosys,
2548329232eSGordon Ross 
2558329232eSGordon Ross 	VOPNAME_SHRLOCK, offsetof(struct vnodeops, vop_shrlock),
2568329232eSGordon Ross 	    fs_shrlock, fs_nosys,
2578329232eSGordon Ross 
2588329232eSGordon Ross 	VOPNAME_VNEVENT, offsetof(struct vnodeops, vop_vnevent),
2598329232eSGordon Ross 	    (fs_generic_func_p) fs_vnevent_nosupport,
2608329232eSGordon Ross 	    (fs_generic_func_p) fs_vnevent_nosupport,
2618329232eSGordon Ross 
2628329232eSGordon Ross 	VOPNAME_REQZCBUF, offsetof(struct vnodeops, vop_reqzcbuf),
2638329232eSGordon Ross 	    fs_nosys, fs_nosys,
2648329232eSGordon Ross 
2658329232eSGordon Ross 	VOPNAME_RETZCBUF, offsetof(struct vnodeops, vop_retzcbuf),
2668329232eSGordon Ross 	    fs_nosys, fs_nosys,
2678329232eSGordon Ross 
2688329232eSGordon Ross 	NULL, 0, NULL, NULL
2698329232eSGordon Ross };
2708329232eSGordon Ross 
2718329232eSGordon Ross /* Extensible attribute (xva) routines. */
2728329232eSGordon Ross 
2738329232eSGordon Ross /*
2748329232eSGordon Ross  * Zero out the structure, set the size of the requested/returned bitmaps,
2758329232eSGordon Ross  * set AT_XVATTR in the embedded vattr_t's va_mask, and set up the pointer
2768329232eSGordon Ross  * to the returned attributes array.
2778329232eSGordon Ross  */
2788329232eSGordon Ross void
xva_init(xvattr_t * xvap)2798329232eSGordon Ross xva_init(xvattr_t *xvap)
2808329232eSGordon Ross {
2818329232eSGordon Ross 	bzero(xvap, sizeof (xvattr_t));
2828329232eSGordon Ross 	xvap->xva_mapsize = XVA_MAPSIZE;
2838329232eSGordon Ross 	xvap->xva_magic = XVA_MAGIC;
2848329232eSGordon Ross 	xvap->xva_vattr.va_mask = AT_XVATTR;
2858329232eSGordon Ross 	xvap->xva_rtnattrmapp = &(xvap->xva_rtnattrmap)[0];
2868329232eSGordon Ross }
2878329232eSGordon Ross 
2888329232eSGordon Ross /*
2898329232eSGordon Ross  * If AT_XVATTR is set, returns a pointer to the embedded xoptattr_t
2908329232eSGordon Ross  * structure.  Otherwise, returns NULL.
2918329232eSGordon Ross  */
2928329232eSGordon Ross xoptattr_t *
xva_getxoptattr(xvattr_t * xvap)2938329232eSGordon Ross xva_getxoptattr(xvattr_t *xvap)
2948329232eSGordon Ross {
2958329232eSGordon Ross 	xoptattr_t *xoap = NULL;
2968329232eSGordon Ross 	if (xvap->xva_vattr.va_mask & AT_XVATTR)
2978329232eSGordon Ross 		xoap = &xvap->xva_xoptattrs;
2988329232eSGordon Ross 	return (xoap);
2998329232eSGordon Ross }
3008329232eSGordon Ross 
3018329232eSGordon Ross // vska_compar
3028329232eSGordon Ross // create_vopstats_template
3038329232eSGordon Ross // new_vskstat
3048329232eSGordon Ross // vopstats_startup
3058329232eSGordon Ross // initialize_vopstats
3068329232eSGordon Ross // get_fstype_vopstats
3078329232eSGordon Ross // get_vskstat_anchor
3088329232eSGordon Ross // teardown_vopstats
3098329232eSGordon Ross 
3108329232eSGordon Ross /*
3118329232eSGordon Ross  * Read or write a vnode.  Called from kernel code.
3128329232eSGordon Ross  */
3138329232eSGordon Ross int
vn_rdwr(enum uio_rw rw,struct vnode * vp,caddr_t base,ssize_t len,offset_t offset,enum uio_seg seg,int ioflag,rlim64_t ulimit,cred_t * cr,ssize_t * residp)3148329232eSGordon Ross vn_rdwr(
3158329232eSGordon Ross 	enum uio_rw rw,
3168329232eSGordon Ross 	struct vnode *vp,
3178329232eSGordon Ross 	caddr_t base,
3188329232eSGordon Ross 	ssize_t len,
3198329232eSGordon Ross 	offset_t offset,
3208329232eSGordon Ross 	enum uio_seg seg,
3218329232eSGordon Ross 	int ioflag,
3228329232eSGordon Ross 	rlim64_t ulimit,	/* meaningful only if rw is UIO_WRITE */
3238329232eSGordon Ross 	cred_t *cr,
3248329232eSGordon Ross 	ssize_t *residp)
3258329232eSGordon Ross {
3268329232eSGordon Ross 	struct uio uio;
3278329232eSGordon Ross 	struct iovec iov;
3288329232eSGordon Ross 	int error;
3298329232eSGordon Ross 	int in_crit = 0;
3308329232eSGordon Ross 
3318329232eSGordon Ross 	if (rw == UIO_WRITE && ISROFILE(vp))
3328329232eSGordon Ross 		return (EROFS);
3338329232eSGordon Ross 
3348329232eSGordon Ross 	if (len < 0)
3358329232eSGordon Ross 		return (EIO);
3368329232eSGordon Ross 
3378329232eSGordon Ross 	VOPXID_MAP_CR(vp, cr);
3388329232eSGordon Ross 
3398329232eSGordon Ross 	iov.iov_base = base;
3408329232eSGordon Ross 	iov.iov_len = len;
3418329232eSGordon Ross 	uio.uio_iov = &iov;
3428329232eSGordon Ross 	uio.uio_iovcnt = 1;
3438329232eSGordon Ross 	uio.uio_loffset = offset;
3448329232eSGordon Ross 	uio.uio_segflg = (short)seg;
3458329232eSGordon Ross 	uio.uio_resid = len;
3468329232eSGordon Ross 	uio.uio_llimit = ulimit;
3478329232eSGordon Ross 
3488329232eSGordon Ross 	/*
3498329232eSGordon Ross 	 * We have to enter the critical region before calling VOP_RWLOCK
3508329232eSGordon Ross 	 * to avoid a deadlock with ufs.
3518329232eSGordon Ross 	 */
3528329232eSGordon Ross 	if (nbl_need_check(vp)) {
3538329232eSGordon Ross 		int svmand;
3548329232eSGordon Ross 
3558329232eSGordon Ross 		nbl_start_crit(vp, RW_READER);
3568329232eSGordon Ross 		in_crit = 1;
3578329232eSGordon Ross 		error = nbl_svmand(vp, cr, &svmand);
3588329232eSGordon Ross 		if (error != 0)
3598329232eSGordon Ross 			goto done;
3608329232eSGordon Ross 		if (nbl_conflict(vp, rw == UIO_WRITE ? NBL_WRITE : NBL_READ,
3618329232eSGordon Ross 		    uio.uio_offset, uio.uio_resid, svmand, NULL)) {
3628329232eSGordon Ross 			error = EACCES;
3638329232eSGordon Ross 			goto done;
3648329232eSGordon Ross 		}
3658329232eSGordon Ross 	}
3668329232eSGordon Ross 
3678329232eSGordon Ross 	(void) VOP_RWLOCK(vp,
3688329232eSGordon Ross 	    rw == UIO_WRITE ? V_WRITELOCK_TRUE : V_WRITELOCK_FALSE, NULL);
3698329232eSGordon Ross 	if (rw == UIO_WRITE) {
3708329232eSGordon Ross 		uio.uio_fmode = FWRITE;
3718329232eSGordon Ross 		uio.uio_extflg = UIO_COPY_DEFAULT;
3728329232eSGordon Ross 		error = VOP_WRITE(vp, &uio, ioflag, cr, NULL);
3738329232eSGordon Ross 	} else {
3748329232eSGordon Ross 		uio.uio_fmode = FREAD;
3758329232eSGordon Ross 		uio.uio_extflg = UIO_COPY_CACHED;
3768329232eSGordon Ross 		error = VOP_READ(vp, &uio, ioflag, cr, NULL);
3778329232eSGordon Ross 	}
3788329232eSGordon Ross 	VOP_RWUNLOCK(vp,
3798329232eSGordon Ross 	    rw == UIO_WRITE ? V_WRITELOCK_TRUE : V_WRITELOCK_FALSE, NULL);
3808329232eSGordon Ross 	if (residp)
3818329232eSGordon Ross 		*residp = uio.uio_resid;
3828329232eSGordon Ross 	else if (uio.uio_resid)
3838329232eSGordon Ross 		error = EIO;
3848329232eSGordon Ross 
3858329232eSGordon Ross done:
3868329232eSGordon Ross 	if (in_crit)
3878329232eSGordon Ross 		nbl_end_crit(vp);
3888329232eSGordon Ross 	return (error);
3898329232eSGordon Ross }
3908329232eSGordon Ross 
3918329232eSGordon Ross /*
3928329232eSGordon Ross  * Incremend the hold on a vnode
3938329232eSGordon Ross  * (Real kernel uses a macro)
3948329232eSGordon Ross  */
3958329232eSGordon Ross void
vn_hold(struct vnode * vp)3968329232eSGordon Ross vn_hold(struct vnode *vp)
3978329232eSGordon Ross {
3988329232eSGordon Ross 	mutex_enter(&vp->v_lock);
3998329232eSGordon Ross 	(vp)->v_count++;
4008329232eSGordon Ross 	mutex_exit(&vp->v_lock);
4018329232eSGordon Ross }
4028329232eSGordon Ross 
4038329232eSGordon Ross /*
4048329232eSGordon Ross  * Release a vnode.  Call VOP_INACTIVE on last reference or
4058329232eSGordon Ross  * decrement reference count...
4068329232eSGordon Ross  */
4078329232eSGordon Ross void
vn_rele(vnode_t * vp)4088329232eSGordon Ross vn_rele(vnode_t *vp)
4098329232eSGordon Ross {
4108329232eSGordon Ross 	VERIFY(vp->v_count > 0);
4118329232eSGordon Ross 	mutex_enter(&vp->v_lock);
4128329232eSGordon Ross 	if (vp->v_count == 1) {
4138329232eSGordon Ross 		mutex_exit(&vp->v_lock);
4148329232eSGordon Ross 		VOP_INACTIVE(vp, CRED(), NULL);
4158329232eSGordon Ross 		return;
4168329232eSGordon Ross 	}
4178329232eSGordon Ross 	VN_RELE_LOCKED(vp);
4188329232eSGordon Ross 	mutex_exit(&vp->v_lock);
4198329232eSGordon Ross }
4208329232eSGordon Ross 
4218329232eSGordon Ross // vn_rele_dnlc
4228329232eSGordon Ross // vn_rele_stream
4238329232eSGordon Ross // vn_rele_inactive
4248329232eSGordon Ross // vn_rele_async
4258329232eSGordon Ross // vn_open, vn_openat
4268329232eSGordon Ross // vn_open_upgrade
4278329232eSGordon Ross // vn_open_downgrade
4288329232eSGordon Ross // vn_create, vn_createat
4298329232eSGordon Ross // vn_link, vn_linkat
4308329232eSGordon Ross // vn_rename, vn_renameat
4318329232eSGordon Ross // vn_remove, vn_removeat
4328329232eSGordon Ross 
4338329232eSGordon Ross 
4348329232eSGordon Ross /*
4358329232eSGordon Ross  * Utility function to compare equality of vnodes.
4368329232eSGordon Ross  * Compare the underlying real vnodes, if there are underlying vnodes.
4378329232eSGordon Ross  * This is a more thorough comparison than the VN_CMP() macro provides.
4388329232eSGordon Ross  */
4398329232eSGordon Ross int
vn_compare(vnode_t * vp1,vnode_t * vp2)4408329232eSGordon Ross vn_compare(vnode_t *vp1, vnode_t *vp2)
4418329232eSGordon Ross {
4428329232eSGordon Ross 	vnode_t *realvp;
4438329232eSGordon Ross 
4448329232eSGordon Ross 	if (vp1 != NULL && VOP_REALVP(vp1, &realvp, NULL) == 0)
4458329232eSGordon Ross 		vp1 = realvp;
4468329232eSGordon Ross 	if (vp2 != NULL && VOP_REALVP(vp2, &realvp, NULL) == 0)
4478329232eSGordon Ross 		vp2 = realvp;
4488329232eSGordon Ross 	return (VN_CMP(vp1, vp2));
4498329232eSGordon Ross }
4508329232eSGordon Ross 
4518329232eSGordon Ross // vn_vfslocks_buckets
4528329232eSGordon Ross // vn_vfslocks_getlock
4538329232eSGordon Ross // vn_vfslocks_rele
4548329232eSGordon Ross 
4558329232eSGordon Ross static krwlock_t vfsentry_ve_lock;
4568329232eSGordon Ross 
4578329232eSGordon Ross /*
4588329232eSGordon Ross  * vn_vfswlock_wait is used to implement a lock which is logically a
4598329232eSGordon Ross  * writers lock protecting the v_vfsmountedhere field.
4608329232eSGordon Ross  * vn_vfswlock_wait has been modified to be similar to vn_vfswlock,
4618329232eSGordon Ross  * except that it blocks to acquire the lock VVFSLOCK.
4628329232eSGordon Ross  *
4638329232eSGordon Ross  * traverse() and routines re-implementing part of traverse (e.g. autofs)
4648329232eSGordon Ross  * need to hold this lock. mount(), vn_rename(), vn_remove() and so on
4658329232eSGordon Ross  * need the non-blocking version of the writers lock i.e. vn_vfswlock
4668329232eSGordon Ross  */
4678329232eSGordon Ross int
vn_vfswlock_wait(vnode_t * vp)4688329232eSGordon Ross vn_vfswlock_wait(vnode_t *vp)
4698329232eSGordon Ross {
4708329232eSGordon Ross 
4718329232eSGordon Ross 	ASSERT(vp != NULL);
4728329232eSGordon Ross 
4738329232eSGordon Ross 	rw_enter(&vfsentry_ve_lock, RW_WRITER);
4748329232eSGordon Ross 
4758329232eSGordon Ross 	return (0);
4768329232eSGordon Ross }
4778329232eSGordon Ross 
4788329232eSGordon Ross int
vn_vfsrlock_wait(vnode_t * vp)4798329232eSGordon Ross vn_vfsrlock_wait(vnode_t *vp)
4808329232eSGordon Ross {
4818329232eSGordon Ross 
4828329232eSGordon Ross 	ASSERT(vp != NULL);
4838329232eSGordon Ross 
4848329232eSGordon Ross 	rw_enter(&vfsentry_ve_lock, RW_READER);
4858329232eSGordon Ross 
4868329232eSGordon Ross 	return (0);
4878329232eSGordon Ross }
4888329232eSGordon Ross 
4898329232eSGordon Ross /*
4908329232eSGordon Ross  * vn_vfswlock is used to implement a lock which is logically a writers lock
4918329232eSGordon Ross  * protecting the v_vfsmountedhere field.
4928329232eSGordon Ross  */
4938329232eSGordon Ross int
vn_vfswlock(vnode_t * vp)4948329232eSGordon Ross vn_vfswlock(vnode_t *vp)
4958329232eSGordon Ross {
4968329232eSGordon Ross 
4978329232eSGordon Ross 	if (vp == NULL)
4988329232eSGordon Ross 		return (EBUSY);
4998329232eSGordon Ross 
5008329232eSGordon Ross 	if (rw_tryenter(&vfsentry_ve_lock, RW_WRITER))
5018329232eSGordon Ross 		return (0);
5028329232eSGordon Ross 
5038329232eSGordon Ross 	return (EBUSY);
5048329232eSGordon Ross }
5058329232eSGordon Ross 
5068329232eSGordon Ross int
vn_vfsrlock(vnode_t * vp)5078329232eSGordon Ross vn_vfsrlock(vnode_t *vp)
5088329232eSGordon Ross {
5098329232eSGordon Ross 
5108329232eSGordon Ross 	if (vp == NULL)
5118329232eSGordon Ross 		return (EBUSY);
5128329232eSGordon Ross 
5138329232eSGordon Ross 	if (rw_tryenter(&vfsentry_ve_lock, RW_READER))
5148329232eSGordon Ross 		return (0);
5158329232eSGordon Ross 
5168329232eSGordon Ross 	return (EBUSY);
5178329232eSGordon Ross }
5188329232eSGordon Ross 
5198329232eSGordon Ross void
vn_vfsunlock(vnode_t * vp)5208329232eSGordon Ross vn_vfsunlock(vnode_t *vp)
5218329232eSGordon Ross {
5228329232eSGordon Ross 
5238329232eSGordon Ross 	rw_exit(&vfsentry_ve_lock);
5248329232eSGordon Ross }
5258329232eSGordon Ross 
5268329232eSGordon Ross int
vn_vfswlock_held(vnode_t * vp)5278329232eSGordon Ross vn_vfswlock_held(vnode_t *vp)
5288329232eSGordon Ross {
5298329232eSGordon Ross 	int held;
5308329232eSGordon Ross 
5318329232eSGordon Ross 	ASSERT(vp != NULL);
5328329232eSGordon Ross 
5338329232eSGordon Ross 	held = rw_write_held(&vfsentry_ve_lock);
5348329232eSGordon Ross 
5358329232eSGordon Ross 	return (held);
5368329232eSGordon Ross }
5378329232eSGordon Ross 
5388329232eSGordon Ross 
5398329232eSGordon Ross int
vn_make_ops(const char * name,const fs_operation_def_t * templ,vnodeops_t ** actual)5408329232eSGordon Ross vn_make_ops(
5418329232eSGordon Ross 	const char *name,			/* Name of file system */
5428329232eSGordon Ross 	const fs_operation_def_t *templ,	/* Operation specification */
5438329232eSGordon Ross 	vnodeops_t **actual)			/* Return the vnodeops */
5448329232eSGordon Ross {
5458329232eSGordon Ross 	int unused_ops;
5468329232eSGordon Ross 	int error;
5478329232eSGordon Ross 
5488329232eSGordon Ross 	*actual = (vnodeops_t *)kmem_alloc(sizeof (vnodeops_t), KM_SLEEP);
5498329232eSGordon Ross 
5508329232eSGordon Ross 	(*actual)->vnop_name = name;
5518329232eSGordon Ross 
5528329232eSGordon Ross 	error = fs_build_vector(*actual, &unused_ops, vn_ops_table, templ);
5538329232eSGordon Ross 	if (error) {
5548329232eSGordon Ross 		kmem_free(*actual, sizeof (vnodeops_t));
5558329232eSGordon Ross 	}
5568329232eSGordon Ross 
5578329232eSGordon Ross #if DEBUG
5588329232eSGordon Ross 	if (unused_ops != 0)
5598329232eSGordon Ross 		cmn_err(CE_WARN, "vn_make_ops: %s: %d operations supplied "
5608329232eSGordon Ross 		    "but not used", name, unused_ops);
5618329232eSGordon Ross #endif
5628329232eSGordon Ross 
5638329232eSGordon Ross 	return (error);
5648329232eSGordon Ross }
5658329232eSGordon Ross 
5668329232eSGordon Ross /*
5678329232eSGordon Ross  * Free the vnodeops created as a result of vn_make_ops()
5688329232eSGordon Ross  */
5698329232eSGordon Ross void
vn_freevnodeops(vnodeops_t * vnops)5708329232eSGordon Ross vn_freevnodeops(vnodeops_t *vnops)
5718329232eSGordon Ross {
5728329232eSGordon Ross 	kmem_free(vnops, sizeof (vnodeops_t));
5738329232eSGordon Ross }
5748329232eSGordon Ross 
5758329232eSGordon Ross /*
5768329232eSGordon Ross  * Vnode cache.
5778329232eSGordon Ross  */
5788329232eSGordon Ross 
5798329232eSGordon Ross /* ARGSUSED */
5808329232eSGordon Ross static int
vn_cache_constructor(void * buf,void * cdrarg,int kmflags)5818329232eSGordon Ross vn_cache_constructor(void *buf, void *cdrarg, int kmflags)
5828329232eSGordon Ross {
5838329232eSGordon Ross 	struct vnode *vp = buf;
5848329232eSGordon Ross 
5858329232eSGordon Ross 	bzero(vp, sizeof (*vp));
5868329232eSGordon Ross 	mutex_init(&vp->v_lock, NULL, MUTEX_DEFAULT, NULL);
5878329232eSGordon Ross 	rw_init(&vp->v_nbllock, NULL, RW_DEFAULT, NULL);
5888329232eSGordon Ross 	vp->v_path = vn_vpath_empty;
5898329232eSGordon Ross 	vp->v_fd = -1;
5908329232eSGordon Ross 	vp->v_st_dev = NODEV;
5918329232eSGordon Ross 
5928329232eSGordon Ross 	return (0);
5938329232eSGordon Ross }
5948329232eSGordon Ross 
5958329232eSGordon Ross /* ARGSUSED */
5968329232eSGordon Ross static void
vn_cache_destructor(void * buf,void * cdrarg)5978329232eSGordon Ross vn_cache_destructor(void *buf, void *cdrarg)
5988329232eSGordon Ross {
5998329232eSGordon Ross 	struct vnode *vp;
6008329232eSGordon Ross 
6018329232eSGordon Ross 	vp = buf;
6028329232eSGordon Ross 
6038329232eSGordon Ross 	rw_destroy(&vp->v_nbllock);
6048329232eSGordon Ross 	mutex_destroy(&vp->v_lock);
6058329232eSGordon Ross }
6068329232eSGordon Ross 
6078329232eSGordon Ross void
vn_create_cache(void)6088329232eSGordon Ross vn_create_cache(void)
6098329232eSGordon Ross {
6108329232eSGordon Ross 	vn_cache = kmem_cache_create("vn_cache", sizeof (struct vnode),
6118329232eSGordon Ross 	    VNODE_ALIGN, vn_cache_constructor, vn_cache_destructor, NULL, NULL,
6128329232eSGordon Ross 	    NULL, 0);
6138329232eSGordon Ross }
6148329232eSGordon Ross 
6158329232eSGordon Ross void
vn_destroy_cache(void)6168329232eSGordon Ross vn_destroy_cache(void)
6178329232eSGordon Ross {
6188329232eSGordon Ross 	kmem_cache_destroy(vn_cache);
6198329232eSGordon Ross }
6208329232eSGordon Ross 
6218329232eSGordon Ross /*
6228329232eSGordon Ross  * Used by file systems when fs-specific nodes (e.g., ufs inodes) are
6238329232eSGordon Ross  * cached by the file system and vnodes remain associated.
6248329232eSGordon Ross  */
6258329232eSGordon Ross void
vn_recycle(vnode_t * vp)6268329232eSGordon Ross vn_recycle(vnode_t *vp)
6278329232eSGordon Ross {
6288329232eSGordon Ross 	VERIFY(vp->v_path != NULL);
6298329232eSGordon Ross 
6308329232eSGordon Ross 	/*
6318329232eSGordon Ross 	 * XXX - This really belongs in vn_reinit(), but we have some issues
6328329232eSGordon Ross 	 * with the counts.  Best to have it here for clean initialization.
6338329232eSGordon Ross 	 */
6348329232eSGordon Ross 	vp->v_rdcnt = 0;
6358329232eSGordon Ross 	vp->v_wrcnt = 0;
6368329232eSGordon Ross 
6378329232eSGordon Ross 	/*
6388329232eSGordon Ross 	 * If FEM was in use...
6398329232eSGordon Ross 	 */
6408329232eSGordon Ross 
6418329232eSGordon Ross 	if (vp->v_path != vn_vpath_empty) {
6428329232eSGordon Ross 		kmem_free(vp->v_path, strlen(vp->v_path) + 1);
6438329232eSGordon Ross 		vp->v_path = vn_vpath_empty;
6448329232eSGordon Ross 	}
6458329232eSGordon Ross 	// vsd_free(vp);
6468329232eSGordon Ross }
6478329232eSGordon Ross 
6488329232eSGordon Ross /*
6498329232eSGordon Ross  * Used to reset the vnode fields including those that are directly accessible
6508329232eSGordon Ross  * as well as those which require an accessor function.
6518329232eSGordon Ross  */
6528329232eSGordon Ross void
vn_reinit(vnode_t * vp)6538329232eSGordon Ross vn_reinit(vnode_t *vp)
6548329232eSGordon Ross {
6558329232eSGordon Ross 	vp->v_count = 1;
6568329232eSGordon Ross 	// vp->v_count_dnlc = 0;
6578329232eSGordon Ross 	vp->v_vfsp = NULL;
6588329232eSGordon Ross 	vp->v_stream = NULL;
6598329232eSGordon Ross 	vp->v_vfsmountedhere = NULL;
6608329232eSGordon Ross 	vp->v_flag = 0;
6618329232eSGordon Ross 	vp->v_type = VNON;
6628329232eSGordon Ross 	vp->v_rdev = NODEV;
6638329232eSGordon Ross 
6648329232eSGordon Ross 	vp->v_xattrdir = NULL;
6658329232eSGordon Ross 
6668329232eSGordon Ross 	/*
6678329232eSGordon Ross 	 * In a few specific instances, vn_reinit() is used to initialize
6688329232eSGordon Ross 	 * locally defined vnode_t instances.  Lacking the construction offered
6698329232eSGordon Ross 	 * by vn_alloc(), these vnodes require v_path initialization.
6708329232eSGordon Ross 	 */
6718329232eSGordon Ross 	if (vp->v_path == NULL) {
6728329232eSGordon Ross 		vp->v_path = vn_vpath_empty;
6738329232eSGordon Ross 	}
6748329232eSGordon Ross 
6758329232eSGordon Ross 	/* Handles v_femhead, v_path, and the r/w/map counts */
6768329232eSGordon Ross 	vn_recycle(vp);
6778329232eSGordon Ross }
6788329232eSGordon Ross 
6798329232eSGordon Ross vnode_t *
vn_alloc(int kmflag)6808329232eSGordon Ross vn_alloc(int kmflag)
6818329232eSGordon Ross {
6828329232eSGordon Ross 	vnode_t *vp;
6838329232eSGordon Ross 
6848329232eSGordon Ross 	vp = kmem_cache_alloc(vn_cache, kmflag);
6858329232eSGordon Ross 
6868329232eSGordon Ross 	if (vp != NULL) {
6878329232eSGordon Ross 		// vp->v_femhead = NULL; /* Must be done before vn_reinit() */
6888329232eSGordon Ross 		// vp->v_fopdata = NULL;
6898329232eSGordon Ross 		vn_reinit(vp);
6908329232eSGordon Ross 	}
6918329232eSGordon Ross 
6928329232eSGordon Ross 	return (vp);
6938329232eSGordon Ross }
6948329232eSGordon Ross 
6958329232eSGordon Ross void
vn_free(vnode_t * vp)6968329232eSGordon Ross vn_free(vnode_t *vp)
6978329232eSGordon Ross {
6988329232eSGordon Ross 	extern vnode_t *rootdir;
6998329232eSGordon Ross 	ASSERT(vp != rootdir);
7008329232eSGordon Ross 
7018329232eSGordon Ross 	/*
7028329232eSGordon Ross 	 * Some file systems call vn_free() with v_count of zero,
7038329232eSGordon Ross 	 * some with v_count of 1.  In any case, the value should
7048329232eSGordon Ross 	 * never be anything else.
7058329232eSGordon Ross 	 */
7068329232eSGordon Ross 	ASSERT((vp->v_count == 0) || (vp->v_count == 1));
7078329232eSGordon Ross 	VERIFY(vp->v_path != NULL);
7088329232eSGordon Ross 	if (vp->v_path != vn_vpath_empty) {
7098329232eSGordon Ross 		kmem_free(vp->v_path, strlen(vp->v_path) + 1);
7108329232eSGordon Ross 		vp->v_path = vn_vpath_empty;
7118329232eSGordon Ross 	}
7128329232eSGordon Ross 
7138329232eSGordon Ross 	/* If FEM was in use... */
7148329232eSGordon Ross 
7158329232eSGordon Ross 	// vsd_free(vp);
7168329232eSGordon Ross 	kmem_cache_free(vn_cache, vp);
7178329232eSGordon Ross }
7188329232eSGordon Ross 
7198329232eSGordon Ross /*
7208329232eSGordon Ross  * vnode status changes, should define better states than 1, 0.
7218329232eSGordon Ross  */
7228329232eSGordon Ross void
vn_reclaim(vnode_t * vp)7238329232eSGordon Ross vn_reclaim(vnode_t *vp)
7248329232eSGordon Ross {
7258329232eSGordon Ross 	vfs_t   *vfsp = vp->v_vfsp;
7268329232eSGordon Ross 
7278329232eSGordon Ross 	if (vfsp == NULL ||
7288329232eSGordon Ross 	    vfsp->vfs_implp == NULL || vfsp->vfs_femhead == NULL) {
7298329232eSGordon Ross 		return;
7308329232eSGordon Ross 	}
7318329232eSGordon Ross 	(void) VFS_VNSTATE(vfsp, vp, VNTRANS_RECLAIMED);
7328329232eSGordon Ross }
7338329232eSGordon Ross 
7348329232eSGordon Ross void
vn_idle(vnode_t * vp)7358329232eSGordon Ross vn_idle(vnode_t *vp)
7368329232eSGordon Ross {
7378329232eSGordon Ross 	vfs_t   *vfsp = vp->v_vfsp;
7388329232eSGordon Ross 
7398329232eSGordon Ross 	if (vfsp == NULL ||
7408329232eSGordon Ross 	    vfsp->vfs_implp == NULL || vfsp->vfs_femhead == NULL) {
7418329232eSGordon Ross 		return;
7428329232eSGordon Ross 	}
7438329232eSGordon Ross 	(void) VFS_VNSTATE(vfsp, vp, VNTRANS_IDLED);
7448329232eSGordon Ross }
7458329232eSGordon Ross void
vn_exists(vnode_t * vp)7468329232eSGordon Ross vn_exists(vnode_t *vp)
7478329232eSGordon Ross {
7488329232eSGordon Ross 	vfs_t   *vfsp = vp->v_vfsp;
7498329232eSGordon Ross 
7508329232eSGordon Ross 	if (vfsp == NULL ||
7518329232eSGordon Ross 	    vfsp->vfs_implp == NULL || vfsp->vfs_femhead == NULL) {
7528329232eSGordon Ross 		return;
7538329232eSGordon Ross 	}
7548329232eSGordon Ross 	(void) VFS_VNSTATE(vfsp, vp, VNTRANS_EXISTS);
7558329232eSGordon Ross }
7568329232eSGordon Ross 
7578329232eSGordon Ross void
vn_invalid(vnode_t * vp)7588329232eSGordon Ross vn_invalid(vnode_t *vp)
7598329232eSGordon Ross {
7608329232eSGordon Ross }
7618329232eSGordon Ross 
7628329232eSGordon Ross /* Vnode event notification */
7638329232eSGordon Ross // vnevent_support()
7648329232eSGordon Ross // vnevent_...
7658329232eSGordon Ross 
7668329232eSGordon Ross /*
7678329232eSGordon Ross  * Vnode accessors.
7688329232eSGordon Ross  */
7698329232eSGordon Ross 
7708329232eSGordon Ross int
vn_is_readonly(vnode_t * vp)7718329232eSGordon Ross vn_is_readonly(vnode_t *vp)
7728329232eSGordon Ross {
7738329232eSGordon Ross 	return (vp->v_vfsp->vfs_flag & VFS_RDONLY);
7748329232eSGordon Ross }
7758329232eSGordon Ross 
7768329232eSGordon Ross int
vn_has_flocks(vnode_t * vp)7778329232eSGordon Ross vn_has_flocks(vnode_t *vp)
7788329232eSGordon Ross {
7798329232eSGordon Ross 	return (0);
7808329232eSGordon Ross }
7818329232eSGordon Ross 
7828329232eSGordon Ross int
vn_has_mandatory_locks(vnode_t * vp,int mode)7838329232eSGordon Ross vn_has_mandatory_locks(vnode_t *vp, int mode)
7848329232eSGordon Ross {
7858329232eSGordon Ross 	return (0);
7868329232eSGordon Ross }
7878329232eSGordon Ross 
7888329232eSGordon Ross int
vn_has_cached_data(vnode_t * vp)7898329232eSGordon Ross vn_has_cached_data(vnode_t *vp)
7908329232eSGordon Ross {
7918329232eSGordon Ross 	return (0);
7928329232eSGordon Ross }
7938329232eSGordon Ross 
7948329232eSGordon Ross // vn_can_change_zones
7958329232eSGordon Ross 
7968329232eSGordon Ross /*
7978329232eSGordon Ross  * Return nonzero if the vnode is a mount point, zero if not.
7988329232eSGordon Ross  */
7998329232eSGordon Ross int
vn_ismntpt(vnode_t * vp)8008329232eSGordon Ross vn_ismntpt(vnode_t *vp)
8018329232eSGordon Ross {
8028329232eSGordon Ross 	return (vp->v_vfsmountedhere != NULL);
8038329232eSGordon Ross }
8048329232eSGordon Ross 
8058329232eSGordon Ross /* Retrieve the vfs (if any) mounted on this vnode */
8068329232eSGordon Ross vfs_t *
vn_mountedvfs(vnode_t * vp)8078329232eSGordon Ross vn_mountedvfs(vnode_t *vp)
8088329232eSGordon Ross {
8098329232eSGordon Ross 	return (vp->v_vfsmountedhere);
8108329232eSGordon Ross }
8118329232eSGordon Ross 
8128329232eSGordon Ross /*
8138329232eSGordon Ross  * Return nonzero if the vnode is referenced by the dnlc, zero if not.
8148329232eSGordon Ross  * (no DNLC here)
8158329232eSGordon Ross  */
8168329232eSGordon Ross int
vn_in_dnlc(vnode_t * vp)8178329232eSGordon Ross vn_in_dnlc(vnode_t *vp)
8188329232eSGordon Ross {
8198329232eSGordon Ross 	return (0);
8208329232eSGordon Ross }
8218329232eSGordon Ross 
8228329232eSGordon Ross 
8238329232eSGordon Ross /*
8248329232eSGordon Ross  * vn_has_other_opens() checks whether a particular file is opened by more than
8258329232eSGordon Ross  * just the caller and whether the open is for read and/or write.
8268329232eSGordon Ross  * This routine is for calling after the caller has already called VOP_OPEN()
8278329232eSGordon Ross  * and the caller wishes to know if they are the only one with it open for
8288329232eSGordon Ross  * the mode(s) specified.
8298329232eSGordon Ross  *
8308329232eSGordon Ross  * Vnode counts are only kept on regular files (v_type=VREG).
8318329232eSGordon Ross  */
8328329232eSGordon Ross int
vn_has_other_opens(vnode_t * vp,v_mode_t mode)8338329232eSGordon Ross vn_has_other_opens(
8348329232eSGordon Ross 	vnode_t *vp,
8358329232eSGordon Ross 	v_mode_t mode)
8368329232eSGordon Ross {
8378329232eSGordon Ross 
8388329232eSGordon Ross 	ASSERT(vp != NULL);