18329232Gordon Ross/*
28329232Gordon Ross * CDDL HEADER START
38329232Gordon Ross *
48329232Gordon Ross * The contents of this file are subject to the terms of the
58329232Gordon Ross * Common Development and Distribution License (the "License").
68329232Gordon Ross * You may not use this file except in compliance with the License.
78329232Gordon Ross *
88329232Gordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98329232Gordon Ross * or http://www.opensolaris.org/os/licensing.
108329232Gordon Ross * See the License for the specific language governing permissions
118329232Gordon Ross * and limitations under the License.
128329232Gordon Ross *
138329232Gordon Ross * When distributing Covered Code, include this CDDL HEADER in each
148329232Gordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158329232Gordon Ross * If applicable, add the following below this CDDL HEADER, with the
168329232Gordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
178329232Gordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
188329232Gordon Ross *
198329232Gordon Ross * CDDL HEADER END
208329232Gordon Ross */
218329232Gordon Ross
228329232Gordon Ross/*
238329232Gordon Ross * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
248329232Gordon Ross * Copyright (c) 2013, Joyent, Inc. All rights reserved.
258329232Gordon Ross * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
268329232Gordon Ross */
278329232Gordon Ross
288329232Gordon Ross/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
298329232Gordon Ross/*	  All Rights Reserved	*/
308329232Gordon Ross
318329232Gordon Ross/*
328329232Gordon Ross * University Copyright- Copyright (c) 1982, 1986, 1988
338329232Gordon Ross * The Regents of the University of California
348329232Gordon Ross * All Rights Reserved
358329232Gordon Ross *
368329232Gordon Ross * University Acknowledgment- Portions of this document are derived from
378329232Gordon Ross * software developed by the University of California, Berkeley, and its
388329232Gordon Ross * contributors.
398329232Gordon Ross */
408329232Gordon Ross
418329232Gordon Ross#ifndef _SYS_VNODE_H
428329232Gordon Ross#define	_SYS_VNODE_H
438329232Gordon Ross
448329232Gordon Ross#include <sys/types.h>
458329232Gordon Ross#include <sys/t_lock.h>
468329232Gordon Ross#include <sys/time_impl.h>
478329232Gordon Ross#include <sys/cred.h>
488329232Gordon Ross#include <sys/uio.h>
498329232Gordon Ross#include <sys/resource.h>
508329232Gordon Ross#include <vm/seg_enum.h>
518329232Gordon Ross#include <sys/kstat.h>
528329232Gordon Ross#include <sys/kmem.h>
538329232Gordon Ross#include <sys/list.h>
548329232Gordon Ross#include <sys/avl.h>
558329232Gordon Ross#ifdef	_KERNEL
568329232Gordon Ross#include <sys/rwstlock.h>
578329232Gordon Ross#include <sys/buf.h>
588329232Gordon Ross#endif	/* _KERNEL */
598329232Gordon Ross
608329232Gordon Ross#ifdef	__cplusplus
618329232Gordon Rossextern "C" {
628329232Gordon Ross#endif
638329232Gordon Ross
648329232Gordon Ross#if defined(_KERNEL) || defined(_FAKE_KERNEL)
658329232Gordon Ross
668329232Gordon Ross/*
678329232Gordon Ross * Statistics for all vnode operations.
688329232Gordon Ross * All operations record number of ops (since boot/mount/zero'ed).
698329232Gordon Ross * Certain I/O operations (read, write, readdir) also record number
708329232Gordon Ross * of bytes transferred.
718329232Gordon Ross * This appears in two places in the system: one is embedded in each
728329232Gordon Ross * vfs_t.  There is also an array of vopstats_t structures allocated
738329232Gordon Ross * on a per-fstype basis.
748329232Gordon Ross */
758329232Gordon Ross
768329232Gordon Ross#define	VOPSTATS_STR	"vopstats_"	/* Initial string for vopstat kstats */
778329232Gordon Ross
788329232Gordon Rosstypedef struct vopstats {
798329232Gordon Ross	kstat_named_t	nopen;		/* VOP_OPEN */
808329232Gordon Ross	kstat_named_t	nclose;		/* VOP_CLOSE */
818329232Gordon Ross	kstat_named_t	nread;		/* VOP_READ */
828329232Gordon Ross	kstat_named_t	read_bytes;
838329232Gordon Ross	kstat_named_t	nwrite;		/* VOP_WRITE */
848329232Gordon Ross	kstat_named_t	write_bytes;
858329232Gordon Ross	kstat_named_t	nioctl;		/* VOP_IOCTL */
868329232Gordon Ross	kstat_named_t	nsetfl;		/* VOP_SETFL */
878329232Gordon Ross	kstat_named_t	ngetattr;	/* VOP_GETATTR */
888329232Gordon Ross	kstat_named_t	nsetattr;	/* VOP_SETATTR */
898329232Gordon Ross	kstat_named_t	naccess;	/* VOP_ACCESS */
908329232Gordon Ross	kstat_named_t	nlookup;	/* VOP_LOOKUP */
918329232Gordon Ross	kstat_named_t	ncreate;	/* VOP_CREATE */
928329232Gordon Ross	kstat_named_t	nremove;	/* VOP_REMOVE */
938329232Gordon Ross	kstat_named_t	nlink;		/* VOP_LINK */
948329232Gordon Ross	kstat_named_t	nrename;	/* VOP_RENAME */
958329232Gordon Ross	kstat_named_t	nmkdir;		/* VOP_MKDIR */
968329232Gordon Ross	kstat_named_t	nrmdir;		/* VOP_RMDIR */
978329232Gordon Ross	kstat_named_t	nreaddir;	/* VOP_READDIR */
988329232Gordon Ross	kstat_named_t	readdir_bytes;
998329232Gordon Ross	kstat_named_t	nsymlink;	/* VOP_SYMLINK */
1008329232Gordon Ross	kstat_named_t	nreadlink;	/* VOP_READLINK */
1018329232Gordon Ross	kstat_named_t	nfsync;		/* VOP_FSYNC */
1028329232Gordon Ross	kstat_named_t	ninactive;	/* VOP_INACTIVE */
1038329232Gordon Ross	kstat_named_t	nfid;		/* VOP_FID */
1048329232Gordon Ross	kstat_named_t	nrwlock;	/* VOP_RWLOCK */
1058329232Gordon Ross	kstat_named_t	nrwunlock;	/* VOP_RWUNLOCK */
1068329232Gordon Ross	kstat_named_t	nseek;		/* VOP_SEEK */
1078329232Gordon Ross	kstat_named_t	ncmp;		/* VOP_CMP */
1088329232Gordon Ross	kstat_named_t	nfrlock;	/* VOP_FRLOCK */
1098329232Gordon Ross	kstat_named_t	nspace;		/* VOP_SPACE */
1108329232Gordon Ross	kstat_named_t	nrealvp;	/* VOP_REALVP */
1118329232Gordon Ross	kstat_named_t	ngetpage;	/* VOP_GETPAGE */
1128329232Gordon Ross	kstat_named_t	nputpage;	/* VOP_PUTPAGE */
1138329232Gordon Ross	kstat_named_t	nmap;		/* VOP_MAP */
1148329232Gordon Ross	kstat_named_t	naddmap;	/* VOP_ADDMAP */
1158329232Gordon Ross	kstat_named_t	ndelmap;	/* VOP_DELMAP */
1168329232Gordon Ross	kstat_named_t	npoll;		/* VOP_POLL */
1178329232Gordon Ross	kstat_named_t	ndump;		/* VOP_DUMP */
1188329232Gordon Ross	kstat_named_t	npathconf;	/* VOP_PATHCONF */
1198329232Gordon Ross	kstat_named_t	npageio;	/* VOP_PAGEIO */
1208329232Gordon Ross	kstat_named_t	ndumpctl;	/* VOP_DUMPCTL */
1218329232Gordon Ross	kstat_named_t	ndispose;	/* VOP_DISPOSE */
1228329232Gordon Ross	kstat_named_t	nsetsecattr;	/* VOP_SETSECATTR */
1238329232Gordon Ross	kstat_named_t	ngetsecattr;	/* VOP_GETSECATTR */
1248329232Gordon Ross	kstat_named_t	nshrlock;	/* VOP_SHRLOCK */
1258329232Gordon Ross	kstat_named_t	nvnevent;	/* VOP_VNEVENT */
1268329232Gordon Ross	kstat_named_t	nreqzcbuf;	/* VOP_REQZCBUF */
1278329232Gordon Ross	kstat_named_t	nretzcbuf;	/* VOP_RETZCBUF */
1288329232Gordon Ross} vopstats_t;
1298329232Gordon Ross#endif // defined(_KERNEL) || defined(_FAKE_KERNEL)
1308329232Gordon Ross
1318329232Gordon Ross/*
1328329232Gordon Ross * The vnode is the focus of all file activity in UNIX.
1338329232Gordon Ross * A vnode is allocated for each active file, each current
1348329232Gordon Ross * directory, each mounted-on file, and the root.
1358329232Gordon Ross *
1368329232Gordon Ross * Each vnode is usually associated with a file-system-specific node (for
1378329232Gordon Ross * UFS, this is the in-memory inode).  Generally, a vnode and an fs-node
1388329232Gordon Ross * should be created and destroyed together as a pair.
1398329232Gordon Ross *
1408329232Gordon Ross * If a vnode is reused for a new file, it should be reinitialized by calling
1418329232Gordon Ross * either vn_reinit() or vn_recycle().
1428329232Gordon Ross *
1438329232Gordon Ross * vn_reinit() resets the entire vnode as if it was returned by vn_alloc().
1448329232Gordon Ross * The caller is responsible for setting up the entire vnode after calling
1458329232Gordon Ross * vn_reinit().  This is important when using kmem caching where the vnode is
1468329232Gordon Ross * allocated by a constructor, for instance.
1478329232Gordon Ross *
1488329232Gordon Ross * vn_recycle() is used when the file system keeps some state around in both
1498329232Gordon Ross * the vnode and the associated FS-node.  In UFS, for example, the inode of
1508329232Gordon Ross * a deleted file can be reused immediately.  The v_data, v_vfsp, v_op, etc.
1518329232Gordon Ross * remains the same but certain fields related to the previous instance need
1528329232Gordon Ross * to be reset.  In particular:
1538329232Gordon Ross *	v_femhead
1548329232Gordon Ross *	v_path
1558329232Gordon Ross *	v_rdcnt, v_wrcnt
1568329232Gordon Ross *	v_mmap_read, v_mmap_write
1578329232Gordon Ross */
1588329232Gordon Ross
1598329232Gordon Ross/*
1608329232Gordon Ross * vnode types.  VNON means no type.  These values are unrelated to
1618329232Gordon Ross * values in on-disk inodes.
1628329232Gordon Ross */
1638329232Gordon Rosstypedef enum vtype {
1648329232Gordon Ross	VNON	= 0,
1658329232Gordon Ross	VREG	= 1,
1668329232Gordon Ross	VDIR	= 2,
1678329232Gordon Ross	VBLK	= 3,
1688329232Gordon Ross	VCHR	= 4,
1698329232Gordon Ross	VLNK	= 5,
1708329232Gordon Ross	VFIFO	= 6,
1718329232Gordon Ross	VDOOR	= 7,
1728329232Gordon Ross	VPROC	= 8,
1738329232Gordon Ross	VSOCK	= 9,
1748329232Gordon Ross	VPORT	= 10,
1758329232Gordon Ross	VBAD	= 11
1768329232Gordon Ross} vtype_t;
1778329232Gordon Ross
1788329232Gordon Ross#if defined(_KERNEL) || defined(_FAKE_KERNEL)
1798329232Gordon Ross
1808329232Gordon Ross/*
1818329232Gordon Ross * VSD - Vnode Specific Data
1828329232Gordon Ross * Used to associate additional private data with a vnode.
1838329232Gordon Ross */
1848329232Gordon Rossstruct vsd_node {
1858329232Gordon Ross	list_node_t vs_nodes;		/* list of all VSD nodes */
1868329232Gordon Ross	uint_t vs_nkeys;		/* entries in value array */
1878329232Gordon Ross	void **vs_value;		/* array of value/key */
1888329232Gordon Ross};
1898329232Gordon Ross
1908329232Gordon Ross/*
1918329232Gordon Ross * Many of the fields in the vnode are read-only once they are initialized
1928329232Gordon Ross * at vnode creation time.  Other fields are protected by locks.
1938329232Gordon Ross *
1948329232Gordon Ross * IMPORTANT: vnodes should be created ONLY by calls to vn_alloc().  They
1958329232Gordon Ross * may not be embedded into the file-system specific node (inode).  The
1968329232Gordon Ross * size of vnodes may change.
1978329232Gordon Ross *
1988329232Gordon Ross * The v_lock protects:
1998329232Gordon Ross *   v_flag
2008329232Gordon Ross *   v_stream
2018329232Gordon Ross *   v_count
2028329232Gordon Ross *   v_shrlocks
2038329232Gordon Ross *   v_path
2048329232Gordon Ross *   v_vsd
2058329232Gordon Ross *   v_xattrdir
2068329232Gordon Ross *
2078329232Gordon Ross * A special lock (implemented by vn_vfswlock in vnode.c) protects:
2088329232Gordon Ross *   v_vfsmountedhere
2098329232Gordon Ross *
2108329232Gordon Ross * The global flock_lock mutex (in flock.c) protects:
2118329232Gordon Ross *   v_filocks
2128329232Gordon Ross *
2138329232Gordon Ross * IMPORTANT NOTE:
2148329232Gordon Ross *
2158329232Gordon Ross *   The following vnode fields are considered public and may safely be
2168329232Gordon Ross *   accessed by file systems or other consumers:
2178329232Gordon Ross *
2188329232Gordon Ross *     v_lock
2198329232Gordon Ross *     v_flag
2208329232Gordon Ross *     v_count
2218329232Gordon Ross *     v_data
2228329232Gordon Ross *     v_vfsp
2238329232Gordon Ross *     v_stream
2248329232Gordon Ross *     v_type
2258329232Gordon Ross *     v_rdev
2268329232Gordon Ross *
2278329232Gordon Ross * ALL OTHER FIELDS SHOULD BE ACCESSED ONLY BY THE OWNER OF THAT FIELD.
2288329232Gordon Ross * In particular, file systems should not access other fields; they may
2298329232Gordon Ross * change or even be removed.  The functionality which was once provided
2308329232Gordon Ross * by these fields is available through vn_* functions.
2318329232Gordon Ross */
2328329232Gordon Ross
2338329232Gordon Rossstruct fem_head;	/* from fem.h */
2348329232Gordon Ross
2358329232Gordon Rosstypedef struct vnode {
2368329232Gordon Ross	kmutex_t	v_lock;		/* protects vnode fields */
2378329232Gordon Ross	uint_t		v_flag;		/* vnode flags (see below) */
2388329232Gordon Ross	uint_t		v_count;	/* reference count */
2398329232Gordon Ross	void		*v_data;	/* private data for fs */
2408329232Gordon Ross	struct vfs	*v_vfsp;	/* ptr to containing VFS */
2418329232Gordon Ross	struct stdata	*v_stream;	/* associated stream */
2428329232Gordon Ross	enum vtype	v_type;		/* vnode type */
2438329232Gordon Ross	dev_t		v_rdev;		/* device (VCHR, VBLK) */
2448329232Gordon Ross
2458329232Gordon Ross	/* PRIVATE FIELDS BELOW - DO NOT USE */
2468329232Gordon Ross
2478329232Gordon Ross	struct vfs	*v_vfsmountedhere; /* ptr to vfs mounted here */
2488329232Gordon Ross	struct vnodeops	*v_op;		/* vnode operations */
2498329232Gordon Ross	krwlock_t	v_nbllock;	/* sync for NBMAND locks */
2508329232Gordon Ross	char		*v_path;	/* cached path */
2518329232Gordon Ross	uint_t		v_rdcnt;	/* open for read count  (VREG only) */
2528329232Gordon Ross	uint_t		v_wrcnt;	/* open for write count (VREG only) */
2538329232Gordon Ross	struct vnode	*v_xattrdir;	/* unnamed extended attr dir (GFS) */
2548329232Gordon Ross
2558329232Gordon Ross	/* Private to the fake vnode impl. */
2568329232Gordon Ross
2578329232Gordon Ross	int		v_fd;
2588329232Gordon Ross	dev_t		v_st_dev;
2598329232Gordon Ross	ino_t		v_st_ino;
2608329232Gordon Ross	avl_node_t	v_avl_node;
2618329232Gordon Ross	int		v_vfsrlocks;
2628329232Gordon Ross} vnode_t;
2638329232Gordon Ross
2648329232Gordon Ross#define	IS_DEVVP(vp)	\
2658329232Gordon Ross	((vp)->v_type == VCHR || (vp)->v_type == VBLK || (vp)->v_type == VFIFO)
2668329232Gordon Ross
2678329232Gordon Ross#define	VNODE_ALIGN	16
2688329232Gordon Ross
2698329232Gordon Ross/*
2708329232Gordon Ross * vnode flags.
2718329232Gordon Ross */
2728329232Gordon Ross#define	VROOT		0x01	/* root of its file system */
2738329232Gordon Ross#define	VNOCACHE	0x02	/* don't keep cache pages on vnode */
2748329232Gordon Ross#define	VNOMAP		0x04	/* file cannot be mapped/faulted */
2758329232Gordon Ross#define	VDUP		0x08	/* file should be dup'ed rather then opened */
2768329232Gordon Ross#define	VNOSWAP		0x10	/* file cannot be used as virtual swap device */
2778329232Gordon Ross#define	VNOMOUNT	0x20	/* file cannot be covered by mount */
2788329232Gordon Ross#define	VISSWAP		0x40	/* vnode is being used for swap */
2798329232Gordon Ross#define	VSWAPLIKE	0x80	/* vnode acts like swap (but may not be) */
2808329232Gordon Ross
2818329232Gordon Ross#define	IS_SWAPVP(vp)	(((vp)->v_flag & (VISSWAP | VSWAPLIKE)) != 0)
2828329232Gordon Ross
2838329232Gordon Ross#else // defined(_KERNEL) || defined(_FAKE_KERNEL)
2848329232Gordon Rosstypedef struct vnode vnode_t;
2858329232Gordon Ross#endif // defined(_KERNEL) || defined(_FAKE_KERNEL)
2868329232Gordon Ross
2878329232Gordon Ross#if defined(_KERNEL)
2888329232Gordon Rosstypedef struct vn_vfslocks_entry {
2898329232Gordon Ross	rwstlock_t ve_lock;
2908329232Gordon Ross	void *ve_vpvfs;
2918329232Gordon Ross	struct vn_vfslocks_entry *ve_next;
2928329232Gordon Ross	uint32_t ve_refcnt;
2938329232Gordon Ross	char pad[64 - sizeof (rwstlock_t) - 2 * sizeof (void *) - \
2948329232Gordon Ross	    sizeof (uint32_t)];
2958329232Gordon Ross} vn_vfslocks_entry_t;
2968329232Gordon Ross#endif	/* _KERNEL */
2978329232Gordon Ross
2988329232Gordon Ross/*
2998329232Gordon Ross * The following two flags are used to lock the v_vfsmountedhere field
3008329232Gordon Ross */
3018329232Gordon Ross#define	VVFSLOCK	0x100
3028329232Gordon Ross#define	VVFSWAIT	0x200
3038329232Gordon Ross
3048329232Gordon Ross/*
3058329232Gordon Ross * Used to serialize VM operations on a vnode
3068329232Gordon Ross */
3078329232Gordon Ross#define	VVMLOCK		0x400
3088329232Gordon Ross
3098329232Gordon Ross/*
3108329232Gordon Ross * Tell vn_open() not to fail a directory open for writing but
3118329232Gordon Ross * to go ahead and call VOP_OPEN() to let the filesystem check.
3128329232Gordon Ross */
3138329232Gordon Ross#define	VDIROPEN	0x800
3148329232Gordon Ross
3158329232Gordon Ross/*
3168329232Gordon Ross * Flag to let the VM system know that this file is most likely a binary
3178329232Gordon Ross * or shared library since it has been mmap()ed EXEC at some time.
3188329232Gordon Ross */
3198329232Gordon Ross#define	VVMEXEC		0x1000
3208329232Gordon Ross
3218329232Gordon Ross#define	VPXFS		0x2000  /* clustering: global fs proxy vnode */
3228329232Gordon Ross
3238329232Gordon Ross#define	IS_PXFSVP(vp)	((vp)->v_flag & VPXFS)
3248329232Gordon Ross
3258329232Gordon Ross#define	V_XATTRDIR	0x4000	/* attribute unnamed directory */
3268329232Gordon Ross
3278329232Gordon Ross#define	IS_XATTRDIR(vp)	((vp)->v_flag & V_XATTRDIR)
3288329232Gordon Ross
3298329232Gordon Ross#define	V_LOCALITY	0x8000	/* whether locality aware */
3308329232Gordon Ross
3318329232Gordon Ross/*
3328329232Gordon Ross * Flag that indicates the VM should maintain the v_pages list with all modified
3338329232Gordon Ross * pages on one end and unmodified pages at the other. This makes finding dirty
3348329232Gordon Ross * pages to write back to disk much faster at the expense of taking a minor
3358329232Gordon Ross * fault on the first store instruction which touches a writable page.
3368329232Gordon Ross */
3378329232Gordon Ross#define	VMODSORT	(0x10000)
3388329232Gordon Ross#define	IS_VMODSORT(vp) \
3398329232Gordon Ross	(pvn_vmodsort_supported != 0 && ((vp)->v_flag  & VMODSORT) != 0)
3408329232Gordon Ross
3418329232Gordon Ross#define	VISSWAPFS	0x20000	/* vnode is being used for swapfs */
3428329232Gordon Ross
3438329232Gordon Ross/*
3448329232Gordon Ross * The mdb memstat command assumes that IS_SWAPFSVP only uses the
3458329232Gordon Ross * vnode's v_flag field.  If this changes, cache the additional
3468329232Gordon Ross * fields in mdb; see vn_get in mdb/common/modules/genunix/memory.c
3478329232Gordon Ross */
3488329232Gordon Ross#define	IS_SWAPFSVP(vp)	(((vp)->v_flag & VISSWAPFS) != 0)
3498329232Gordon Ross
3508329232Gordon Ross#define	V_SYSATTR	0x40000	/* vnode is a GFS system attribute */
3518329232Gordon Ross
3528329232Gordon Ross/*
3538329232Gordon Ross * Vnode attributes.  A bit-mask is supplied as part of the
3548329232Gordon Ross * structure to indicate the attributes the caller wants to
3558329232Gordon Ross * set (setattr) or extract (getattr).
3568329232Gordon Ross */
3578329232Gordon Ross
3588329232Gordon Ross/*
3598329232Gordon Ross * Note that va_nodeid and va_nblocks are 64bit data type.
3608329232Gordon Ross * We support large files over NFSV3. With Solaris client and
3618329232Gordon Ross * Server that generates 64bit ino's and sizes these fields
3628329232Gordon Ross * will overflow if they are 32 bit sizes.
3638329232Gordon Ross */
3648329232Gordon Ross
3658329232Gordon Rosstypedef struct vattr {
3668329232Gordon Ross	uint_t		va_mask;	/* bit-mask of attributes */
3678329232Gordon Ross	vtype_t		va_type;	/* vnode type (for create) */
3688329232Gordon Ross	mode_t		va_mode;	/* file access mode */
3698329232Gordon Ross	uid_t		va_uid;		/* owner user id */
3708329232Gordon Ross	gid_t		va_gid;		/* owner group id */
3718329232Gordon Ross	dev_t		va_fsid;	/* file system id (dev for now) */
3728329232Gordon Ross	u_longlong_t	va_nodeid;	/* node id */
3738329232Gordon Ross	nlink_t		va_nlink;	/* number of references to file */
3748329232Gordon Ross	u_offset_t	va_size;	/* file size in bytes */
3758329232Gordon Ross	timestruc_t	va_atime;	/* time of last access */
3768329232Gordon Ross	timestruc_t	va_mtime;	/* time of last modification */
3778329232Gordon Ross	timestruc_t	va_ctime;	/* time of last status change */
3788329232Gordon Ross	dev_t		va_rdev;	/* device the file represents */
3798329232Gordon Ross	uint_t		va_blksize;	/* fundamental block size */
3808329232Gordon Ross	u_longlong_t	va_nblocks;	/* # of blocks allocated */
3818329232Gordon Ross	uint_t		va_seq;		/* sequence number */
3828329232Gordon Ross} vattr_t;
3838329232Gordon Ross
3848329232Gordon Ross#define	AV_SCANSTAMP_SZ	32		/* length of anti-virus scanstamp */
3858329232Gordon Ross
3868329232Gordon Ross/*
3878329232Gordon Ross * Structure of all optional attributes.
3888329232Gordon Ross */
3898329232Gordon Rosstypedef struct xoptattr {
3908329232Gordon Ross	timestruc_t	xoa_createtime;	/* Create time of file */
3918329232Gordon Ross	uint8_t		xoa_archive;
3928329232Gordon Ross	uint8_t		xoa_system;
3938329232Gordon Ross	uint8_t		xoa_readonly;
3948329232Gordon Ross	uint8_t		xoa_hidden;
3958329232Gordon Ross	uint8_t		xoa_nounlink;
3968329232Gordon Ross	uint8_t		xoa_immutable;
3978329232Gordon Ross	uint8_t		xoa_appendonly;
3988329232Gordon Ross	uint8_t		xoa_nodump;
3998329232Gordon Ross	uint8_t		xoa_opaque;
4008329232Gordon Ross	uint8_t		xoa_av_quarantined;
4018329232Gordon Ross	uint8_t		xoa_av_modified;
4028329232Gordon Ross	uint8_t		xoa_av_scanstamp[AV_SCANSTAMP_SZ];
4038329232Gordon Ross	uint8_t		xoa_reparse;
4048329232Gordon Ross	uint64_t	xoa_generation;
4058329232Gordon Ross	uint8_t		xoa_offline;
4068329232Gordon Ross	uint8_t		xoa_sparse;
4078329232Gordon Ross} xoptattr_t;
4088329232Gordon Ross
4098329232Gordon Ross/*
4108329232Gordon Ross * The xvattr structure is really a variable length structure that
4118329232Gordon Ross * is made up of:
4128329232Gordon Ross * - The classic vattr_t (xva_vattr)
4138329232Gordon Ross * - a 32 bit quantity (xva_mapsize) that specifies the size of the
4148329232Gordon Ross *   attribute bitmaps in 32 bit words.
4158329232Gordon Ross * - A pointer to the returned attribute bitmap (needed because the
4168329232Gordon Ross *   previous element, the requested attribute bitmap) is variable lenth.
4178329232Gordon Ross * - The requested attribute bitmap, which is an array of 32 bit words.
4188329232Gordon Ross *   Callers use the XVA_SET_REQ() macro to set the bits corresponding to
4198329232Gordon Ross *   the attributes that are being requested.
4208329232Gordon Ross * - The returned attribute bitmap, which is an array of 32 bit words.
4218329232Gordon Ross *   File systems that support optional attributes use the XVA_SET_RTN()
4228329232Gordon Ross *   macro to set the bits corresponding to the attributes that are being
4238329232Gordon Ross *   returned.
4248329232Gordon Ross * - The xoptattr_t structure which contains the attribute values
4258329232Gordon Ross *
4268329232Gordon Ross * xva_mapsize determines how many words in the attribute bitmaps.
4278329232Gordon Ross * Immediately following the attribute bitmaps is the xoptattr_t.
4288329232Gordon Ross * xva_getxoptattr() is used to get the pointer to the xoptattr_t
4298329232Gordon Ross * section.
4308329232Gordon Ross */
4318329232Gordon Ross
4328329232Gordon Ross#define	XVA_MAPSIZE	3		/* Size of attr bitmaps */
4338329232Gordon Ross#define	XVA_MAGIC	0x78766174	/* Magic # for verification */
4348329232Gordon Ross
4358329232Gordon Ross/*
4368329232Gordon Ross * The xvattr structure is an extensible structure which permits optional
4378329232Gordon Ross * attributes to be requested/returned.  File systems may or may not support
4388329232Gordon Ross * optional attributes.  They do so at their own discretion but if they do
4398329232Gordon Ross * support optional attributes, they must register the VFSFT_XVATTR feature
4408329232Gordon Ross * so that the optional attributes can be set/retrived.
4418329232Gordon Ross *
4428329232Gordon Ross * The fields of the xvattr structure are:
4438329232Gordon Ross *
4448329232Gordon Ross * xva_vattr - The first element of an xvattr is a legacy vattr structure
4458329232Gordon Ross * which includes the common attributes.  If AT_XVATTR is set in the va_mask
4468329232Gordon Ross * then the entire structure is treated as an xvattr.  If AT_XVATTR is not
4478329232Gordon Ross * set, then only the xva_vattr structure can be used.
4488329232Gordon Ross *
4498329232Gordon Ross * xva_magic - 0x78766174 (hex for "xvat"). Magic number for verification.
4508329232Gordon Ross *
4518329232Gordon Ross * xva_mapsize - Size of requested and returned attribute bitmaps.
4528329232Gordon Ross *
4538329232Gordon Ross * xva_rtnattrmapp - Pointer to xva_rtnattrmap[].  We need this since the
4548329232Gordon Ross * size of the array before it, xva_reqattrmap[], could change which means
4558329232Gordon Ross * the location of xva_rtnattrmap[] could change.  This will allow unbundled
4568329232Gordon Ross * file systems to find the location of xva_rtnattrmap[] when the sizes change.
4578329232Gordon Ross *
4588329232Gordon Ross * xva_reqattrmap[] - Array of requested attributes.  Attributes are
4598329232Gordon Ross * represented by a specific bit in a specific element of the attribute
4608329232Gordon Ross * map array.  Callers set the bits corresponding to the attributes
4618329232Gordon Ross * that the caller wants to get/set.
4628329232Gordon Ross *
4638329232Gordon Ross * xva_rtnattrmap[] - Array of attributes that the file system was able to
4648329232Gordon Ross * process.  Not all file systems support all optional attributes.  This map
4658329232Gordon Ross * informs the caller which attributes the underlying file system was able
4668329232Gordon Ross * to set/get.  (Same structure as the requested attributes array in terms
4678329232Gordon Ross * of each attribute  corresponding to specific bits and array elements.)
4688329232Gordon Ross *
4698329232Gordon Ross * xva_xoptattrs - Structure containing values of optional attributes.
4708329232Gordon Ross * These values are only valid if the corresponding bits in xva_reqattrmap
4718329232Gordon Ross * are set and the underlying file system supports those attributes.
4728329232Gordon Ross */
4738329232Gordon Rosstypedef struct xvattr {
4748329232Gordon Ross	vattr_t		xva_vattr;	/* Embedded vattr structure */
4758329232Gordon Ross	uint32_t	xva_magic;	/* Magic Number */
4768329232Gordon Ross	uint32_t	xva_mapsize;	/* Size of attr bitmap (32-bit words) */
4778329232Gordon Ross	uint32_t	*xva_rtnattrmapp;	/* Ptr to xva_rtnattrmap[] */
4788329232Gordon Ross	uint32_t	xva_reqattrmap[XVA_MAPSIZE];	/* Requested attrs */
4798329232Gordon Ross	uint32_t	xva_rtnattrmap[XVA_MAPSIZE];	/* Returned attrs */
4808329232Gordon Ross	xoptattr_t	xva_xoptattrs;	/* Optional attributes */
4818329232Gordon Ross} xvattr_t;
4828329232Gordon Ross
4838329232Gordon Ross#ifdef _SYSCALL32
4848329232Gordon Ross/*
4858329232Gordon Ross * For bigtypes time_t changed to 64 bit on the 64-bit kernel.
4868329232Gordon Ross * Define an old version for user/kernel interface
4878329232Gordon Ross */
4888329232Gordon Ross
4898329232Gordon Ross#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
4908329232Gordon Ross#pragma pack(4)
4918329232Gordon Ross#endif
4928329232Gordon Ross
4938329232Gordon Rosstypedef struct vattr32 {
4948329232Gordon Ross	uint32_t	va_mask;	/* bit-mask of attributes */
4958329232Gordon Ross	vtype_t		va_type;	/* vnode type (for create) */
4968329232Gordon Ross	mode32_t	va_mode;	/* file access mode */
4978329232Gordon Ross	uid32_t		va_uid;		/* owner user id */
4988329232Gordon Ross	gid32_t		va_gid;		/* owner group id */
4998329232Gordon Ross	dev32_t		va_fsid;	/* file system id (dev for now) */
5008329232Gordon Ross	u_longlong_t	va_nodeid;	/* node id */
5018329232Gordon Ross	nlink_t		va_nlink;	/* number of references to file */
5028329232Gordon Ross	u_offset_t	va_size;	/* file size in bytes */
5038329232Gordon Ross	timestruc32_t	va_atime;	/* time of last access */
5048329232Gordon Ross	timestruc32_t	va_mtime;	/* time of last modification */
5058329232Gordon Ross	timestruc32_t	va_ctime;	/* time of last status change */
5068329232Gordon Ross	dev32_t		va_rdev;	/* device the file represents */
5078329232Gordon Ross	uint32_t	va_blksize;	/* fundamental block size */
5088329232Gordon Ross	u_longlong_t	va_nblocks;	/* # of blocks allocated */
5098329232Gordon Ross	uint32_t	va_seq;		/* sequence number */
5108329232Gordon Ross} vattr32_t;
5118329232Gordon Ross
5128329232Gordon Ross#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
5138329232Gordon Ross#pragma pack()
5148329232Gordon Ross#endif
5158329232Gordon Ross
5168329232Gordon Ross#else  /* not _SYSCALL32 */
5178329232Gordon Ross#define	vattr32		vattr
5188329232Gordon Rosstypedef vattr_t		vattr32_t;
5198329232Gordon Ross#endif /* _SYSCALL32 */
5208329232Gordon Ross
5218329232Gordon Ross/*
5228329232Gordon Ross * Attributes of interest to the caller of setattr or getattr.
5238329232Gordon Ross */
5248329232Gordon Ross#define	AT_TYPE		0x00001
5258329232Gordon Ross#define	AT_MODE		0x00002
5268329232Gordon Ross#define	AT_UID		0x00004
5278329232Gordon Ross#define	AT_GID		0x00008
5288329232Gordon Ross#define	AT_FSID		0x00010
5298329232Gordon Ross#define	AT_NODEID	0x00020
5308329232Gordon Ross#define	AT_NLINK	0x00040
5318329232Gordon Ross#define	AT_SIZE		0x00080
5328329232Gordon Ross#define	AT_ATIME	0x00100
5338329232Gordon Ross#define	AT_MTIME	0x00200
5348329232Gordon Ross#define	AT_CTIME	0x00400
5358329232Gordon Ross#define	AT_RDEV		0x00800
5368329232Gordon Ross#define	AT_BLKSIZE	0x01000
5378329232Gordon Ross#define	AT_NBLOCKS	0x02000
5388329232Gordon Ross/*			0x04000 */	/* unused */
5398329232Gordon Ross#define	AT_SEQ		0x08000
5408329232Gordon Ross/*
5418329232Gordon Ross * If AT_XVATTR is set then there are additional bits to process in
5428329232Gordon Ross * the xvattr_t's attribute bitmap.  If this is not set then the bitmap
5438329232Gordon Ross * MUST be ignored.  Note that this bit must be set/cleared explicitly.
5448329232Gordon Ross * That is, setting AT_ALL will NOT set AT_XVATTR.
5458329232Gordon Ross */
5468329232Gordon Ross#define	AT_XVATTR	0x10000
5478329232Gordon Ross
5488329232Gordon Ross#define	AT_ALL		(AT_TYPE|AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|\
5498329232Gordon Ross			AT_NLINK|AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|\
5508329232Gordon Ross			AT_RDEV|AT_BLKSIZE|AT_NBLOCKS|AT_SEQ)
5518329232Gordon Ross
5528329232Gordon Ross#define	AT_STAT		(AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|AT_NLINK|\
5538329232Gordon Ross			AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|AT_RDEV|AT_TYPE)
5548329232Gordon Ross
5558329232Gordon Ross#define	AT_TIMES	(AT_ATIME|AT_MTIME|AT_CTIME)
5568329232Gordon Ross
5578329232Gordon Ross#define	AT_NOSET	(AT_NLINK|AT_RDEV|AT_FSID|AT_NODEID|AT_TYPE|\
5588329232Gordon Ross			AT_BLKSIZE|AT_NBLOCKS|AT_SEQ)
5598329232Gordon Ross
5608329232Gordon Ross/*
5618329232Gordon Ross * Attribute bits used in the extensible attribute's (xva's) attribute
5628329232Gordon Ross * bitmaps.  Note that the bitmaps are made up of a variable length number
5638329232Gordon Ross * of 32-bit words.  The convention is to use XAT{n}_{attrname} where "n"
5648329232Gordon Ross * is the element in the bitmap (starting at 1).  This convention is for
5658329232Gordon Ross * the convenience of the maintainer to keep track of which element each
5668329232Gordon Ross * attribute belongs to.
5678329232Gordon Ross *
5688329232Gordon Ross * NOTE THAT CONSUMERS MUST *NOT* USE THE XATn_* DEFINES DIRECTLY.  CONSUMERS
5698329232Gordon Ross * MUST USE THE XAT_* DEFINES.
5708329232Gordon Ross */
5718329232Gordon Ross#define	XAT0_INDEX	0LL		/* Index into bitmap for XAT0 attrs */
5728329232Gordon Ross#define	XAT0_CREATETIME	0x00000001	/* Create time of file */
5738329232Gordon Ross#define	XAT0_ARCHIVE	0x00000002	/* Archive */
5748329232Gordon Ross#define	XAT0_SYSTEM	0x00000004	/* System */
5758329232Gordon Ross#define	XAT0_READONLY	0x00000008	/* Readonly */
5768329232Gordon Ross#define	XAT0_HIDDEN	0x00000010	/* Hidden */
5778329232Gordon Ross#define	XAT0_NOUNLINK	0x00000020	/* Nounlink */
5788329232Gordon Ross#define	XAT0_IMMUTABLE	0x00000040	/* immutable */
5798329232Gordon Ross#define	XAT0_APPENDONLY	0x00000080	/* appendonly */
5808329232Gordon Ross#define	XAT0_NODUMP	0x00000100	/* nodump */
5818329232Gordon Ross#define	XAT0_OPAQUE	0x00000200	/* opaque */
5828329232Gordon Ross#define	XAT0_AV_QUARANTINED	0x00000400	/* anti-virus quarantine */
5838329232Gordon Ross#define	XAT0_AV_MODIFIED	0x00000800	/* anti-virus modified */
5848329232Gordon Ross#define	XAT0_AV_SCANSTAMP	0x00001000	/* anti-virus scanstamp */
5858329232Gordon Ross#define	XAT0_REPARSE	0x00002000	/* FS reparse point */
5868329232Gordon Ross#define	XAT0_GEN	0x00004000	/* object generation number */
5878329232Gordon Ross#define	XAT0_OFFLINE	0x00008000	/* offline */
5888329232Gordon Ross#define	XAT0_SPARSE	0x00010000	/* sparse */
5898329232Gordon Ross
5908329232Gordon Ross#define	XAT0_ALL_ATTRS	(XAT0_CREATETIME|XAT0_ARCHIVE|XAT0_SYSTEM| \
5918329232Gordon Ross    XAT0_READONLY|XAT0_HIDDEN|XAT0_NOUNLINK|XAT0_IMMUTABLE|XAT0_APPENDONLY| \
5928329232Gordon Ross    XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED|  XAT0_AV_MODIFIED| \
5938329232Gordon Ross    XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE)
5948329232Gordon Ross
5958329232Gordon Ross/* Support for XAT_* optional attributes */
5968329232Gordon Ross#define	XVA_MASK		0xffffffff	/* Used to mask off 32 bits */
5978329232Gordon Ross#define	XVA_SHFT		32		/* Used to shift index */
5988329232Gordon Ross
5998329232Gordon Ross/*
6008329232Gordon Ross * Used to pry out the index and attribute bits from the XAT_* attributes
6018329232Gordon Ross * defined below.  Note that we're masking things down to 32 bits then
6028329232Gordon Ross * casting to uint32_t.
6038329232Gordon Ross */
6048329232Gordon Ross#define	XVA_INDEX(attr)		((uint32_t)(((attr) >> XVA_SHFT) & XVA_MASK))
6058329232Gordon Ross#define	XVA_ATTRBIT(attr)	((uint32_t)((attr) & XVA_MASK))
6068329232Gordon Ross
6078329232Gordon Ross/*
6088329232Gordon Ross * The following defines present a "flat namespace" so that consumers don't
6098329232Gordon Ross * need to keep track of which element belongs to which bitmap entry.
6108329232Gordon Ross *
6118329232Gordon Ross * NOTE THAT THESE MUST NEVER BE OR-ed TOGETHER
6128329232Gordon Ross */
6138329232Gordon Ross#define	XAT_CREATETIME		((XAT0_INDEX << XVA_SHFT) | XAT0_CREATETIME)
6148329232Gordon Ross#define	XAT_ARCHIVE		((XAT0_INDEX << XVA_SHFT) | XAT0_ARCHIVE)
6158329232Gordon Ross#define	XAT_SYSTEM		((XAT0_INDEX << XVA_SHFT) | XAT0_SYSTEM)
6168329232Gordon Ross#define	XAT_READONLY		((XAT0_INDEX << XVA_SHFT) | XAT0_READONLY)
6178329232Gordon Ross#define	XAT_HIDDEN		((XAT0_INDEX << XVA_SHFT) | XAT0_HIDDEN)
6188329232Gordon Ross#define	XAT_NOUNLINK		((XAT0_INDEX << XVA_SHFT) | XAT0_NOUNLINK)
6198329232Gordon Ross#define	XAT_IMMUTABLE		((XAT0_INDEX << XVA_SHFT) | XAT0_IMMUTABLE)
6208329232Gordon Ross#define	XAT_APPENDONLY		((XAT0_INDEX << XVA_SHFT) | XAT0_APPENDONLY)
6218329232Gordon Ross#define	XAT_NODUMP		((XAT0_INDEX << XVA_SHFT) | XAT0_NODUMP)
6228329232Gordon Ross#define	XAT_OPAQUE		((XAT0_INDEX << XVA_SHFT) | XAT0_OPAQUE)
6238329232Gordon Ross#define	XAT_AV_QUARANTINED	((XAT0_INDEX << XVA_SHFT) | XAT0_AV_QUARANTINED)
6248329232Gordon Ross#define	XAT_AV_MODIFIED		((XAT0_INDEX << XVA_SHFT) | XAT0_AV_MODIFIED)
6258329232Gordon Ross#define	XAT_AV_SCANSTAMP	((XAT0_INDEX << XVA_SHFT) | XAT0_AV_SCANSTAMP)
6268329232Gordon Ross#define	XAT_REPARSE		((XAT0_INDEX << XVA_SHFT) | XAT0_REPARSE)
6278329232Gordon Ross#define	XAT_GEN			((XAT0_INDEX << XVA_SHFT) | XAT0_GEN)
6288329232Gordon Ross#define	XAT_OFFLINE		((XAT0_INDEX << XVA_SHFT) | XAT0_OFFLINE)
6298329232Gordon Ross#define	XAT_SPARSE		((XAT0_INDEX << XVA_SHFT) | XAT0_SPARSE)
6308329232Gordon Ross
6318329232Gordon Ross/*
6328329232Gordon Ross * The returned attribute map array (xva_rtnattrmap[]) is located past the
6338329232Gordon Ross * requested attribute map array (xva_reqattrmap[]).  Its location changes
6348329232Gordon Ross * when the array sizes change.  We use a separate pointer in a known location
6358329232Gordon Ross * (xva_rtnattrmapp) to hold the location of xva_rtnattrmap[].  This is
6368329232Gordon Ross * set in xva_init()
6378329232Gordon Ross */
6388329232Gordon Ross#define	XVA_RTNATTRMAP(xvap)	((xvap)->xva_rtnattrmapp)
6398329232Gordon Ross
6408329232Gordon Ross/*
6418329232Gordon Ross * XVA_SET_REQ() sets an attribute bit in the proper element in the bitmap
6428329232Gordon Ross * of requested attributes (xva_reqattrmap[]).
6438329232Gordon Ross */
6448329232Gordon Ross#define	XVA_SET_REQ(xvap, attr)					\
6458329232Gordon Ross	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
6468329232Gordon Ross	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
6478329232Gordon Ross	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
6488329232Gordon Ross/*
6498329232Gordon Ross * XVA_CLR_REQ() clears an attribute bit in the proper element in the bitmap
6508329232Gordon Ross * of requested attributes (xva_reqattrmap[]).
6518329232Gordon Ross */
6528329232Gordon Ross#define	XVA_CLR_REQ(xvap, attr)					\
6538329232Gordon Ross	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
6548329232Gordon Ross	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
6558329232Gordon Ross	(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
6568329232Gordon Ross
6578329232Gordon Ross/*
6588329232Gordon Ross * XVA_SET_RTN() sets an attribute bit in the proper element in the bitmap
6598329232Gordon Ross * of returned attributes (xva_rtnattrmap[]).
6608329232Gordon Ross */
6618329232Gordon Ross#define	XVA_SET_RTN(xvap, attr)					\
6628329232Gordon Ross	ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR);		\
6638329232Gordon Ross	ASSERT((xvap)->xva_magic == XVA_MAGIC);			\
6648329232Gordon Ross	(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
6658329232Gordon Ross
6668329232Gordon Ross/*
6678329232Gordon Ross * XVA_ISSET_REQ() checks the requested attribute bitmap (xva_reqattrmap[])
6688329232Gordon Ross * to see of the corresponding attribute bit is set.  If so, returns non-zero.
6698329232Gordon Ross */
6708329232Gordon Ross#define	XVA_ISSET_REQ(xvap, attr)					\
6718329232Gordon Ross	((((xvap)->xva_vattr.va_mask | AT_XVATTR) &&			\
6728329232Gordon Ross		((xvap)->xva_magic == XVA_MAGIC) &&			\
6738329232Gordon Ross		((xvap)->xva_mapsize > XVA_INDEX(attr))) ?		\
6748329232Gordon Ross	((xvap)->xva_reqattrmap[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) :	0)
6758329232Gordon Ross
6768329232Gordon Ross/*
6778329232Gordon Ross * XVA_ISSET_RTN() checks the returned attribute bitmap (xva_rtnattrmap[])
6788329232Gordon Ross * to see of the corresponding attribute bit is set.  If so, returns non-zero.
6798329232Gordon Ross */
6808329232Gordon Ross#define	XVA_ISSET_RTN(xvap, attr)					\
6818329232Gordon Ross	((((xvap)->xva_vattr.va_mask | AT_XVATTR) &&			\
6828329232Gordon Ross		((xvap)->xva_magic == XVA_MAGIC) &&			\
6838329232Gordon Ross		((xvap)->xva_mapsize > XVA_INDEX(attr))) ?		\
6848329232Gordon Ross	((XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
6858329232Gordon Ross
6868329232Gordon Ross/*
6878329232Gordon Ross *  Modes.  Some values same as S_xxx entries from stat.h for convenience.
6888329232Gordon Ross */
6898329232Gordon Ross#define	VSUID		04000		/* set user id on execution */
6908329232Gordon Ross#define	VSGID		02000		/* set group id on execution */
6918329232Gordon Ross#define	VSVTX		01000		/* save swapped text even after use */
6928329232Gordon Ross
6938329232Gordon Ross/*
6948329232Gordon Ross * Permissions.
6958329232Gordon Ross */
6968329232Gordon Ross#define	VREAD		00400
6978329232Gordon Ross#define	VWRITE		00200
6988329232Gordon Ross#define	VEXEC		00100
6998329232Gordon Ross
7008329232Gordon Ross#define	MODEMASK	07777		/* mode bits plus permission bits */
7018329232Gordon Ross#define	PERMMASK	00777		/* permission bits */
7028329232Gordon Ross
7038329232Gordon Ross/*
7048329232Gordon Ross * VOP_ACCESS flags
7058329232Gordon Ross */
7068329232Gordon Ross#define	V_ACE_MASK	0x1	/* mask represents  NFSv4 ACE permissions */
7078329232Gordon Ross#define	V_APPEND	0x2	/* want to do append only check */
7088329232Gordon Ross
7098329232Gordon Ross/*
7108329232Gordon Ross * Check whether mandatory file locking is enabled.
7118329232Gordon Ross */
7128329232Gordon Ross
7138329232Gordon Ross#define	MANDMODE(mode)		(((mode) & (VSGID|(VEXEC>>3))) == VSGID)
7148329232Gordon Ross#define	MANDLOCK(vp, mode)	((vp)->v_type == VREG && MANDMODE(mode))
7158329232Gordon Ross
7168329232Gordon Ross/*
7178329232Gordon Ross * Flags for vnode operations.
7188329232Gordon Ross */
7198329232Gordon Rossenum rm		{ RMFILE, RMDIRECTORY };	/* rm or rmdir (remove) */
7208329232Gordon Rossenum symfollow	{ NO_FOLLOW, FOLLOW };		/* follow symlinks (or not) */
7218329232Gordon Rossenum vcexcl	{ NONEXCL, EXCL };		/* (non)excl create */
7228329232Gordon Rossenum create	{ CRCREAT, CRMKNOD, CRMKDIR };	/* reason for create */
7238329232Gordon Ross
7248329232Gordon Rosstypedef enum rm		rm_t;
7258329232Gordon Rosstypedef enum symfollow	symfollow_t;
7268329232Gordon Rosstypedef enum vcexcl	vcexcl_t;
7278329232Gordon Rosstypedef enum create	create_t;
7288329232Gordon Ross
7298329232Gordon Ross/* Vnode Events - Used by VOP_VNEVENT */
7308329232Gordon Rosstypedef enum vnevent	{
7318329232Gordon Ross	VE_SUPPORT	= 0,	/* Query */
7328329232Gordon Ross	VE_RENAME_SRC	= 1,	/* Rename, with vnode as source */
7338329232Gordon Ross	VE_RENAME_DEST	= 2,	/* Rename, with vnode as target/destination */
7348329232Gordon Ross	VE_REMOVE	= 3,	/* Remove of vnode's name */
7358329232Gordon Ross	VE_RMDIR	= 4,	/* Remove of directory vnode's name */
7368329232Gordon Ross	VE_CREATE	= 5,	/* Create with vnode's name which exists */
7378329232Gordon Ross	VE_LINK		= 6,	/* Link with vnode's name as source */
7388329232Gordon Ross	VE_RENAME_DEST_DIR	= 7,	/* Rename with vnode as target dir */
7398329232Gordon Ross	VE_MOUNTEDOVER	= 8,	/* File or Filesystem got mounted over vnode */
7408329232Gordon Ross	VE_TRUNCATE = 9		/* Truncate */
7418329232Gordon Ross} vnevent_t;
7428329232Gordon Ross
7438329232Gordon Ross/*
7448329232Gordon Ross * Values for checking vnode open and map counts
7458329232Gordon Ross */
7468329232Gordon Rossenum v_mode { V_READ, V_WRITE, V_RDORWR, V_RDANDWR };
7478329232Gordon Ross
7488329232Gordon Rosstypedef enum v_mode v_mode_t;
7498329232Gordon Ross
7508329232Gordon Ross#define	V_TRUE	1
7518329232Gordon Ross#define	V_FALSE	0
7528329232Gordon Ross
7538329232Gordon Ross/*
7548329232Gordon Ross * Structure used on VOP_GETSECATTR and VOP_SETSECATTR operations
7558329232Gordon Ross */
7568329232Gordon Ross
7578329232Gordon Rosstypedef struct vsecattr {
7588329232Gordon Ross	uint_t		vsa_mask;	/* See below */
7598329232Gordon Ross	int		vsa_aclcnt;	/* ACL entry count */
7608329232Gordon Ross	void		*vsa_aclentp;	/* pointer to ACL entries */
7618329232Gordon Ross	int		vsa_dfaclcnt;	/* default ACL entry count */
7628329232Gordon Ross	void		*vsa_dfaclentp;	/* pointer to default ACL entries */
7638329232Gordon Ross	size_t		vsa_aclentsz;	/* ACE size in bytes of vsa_aclentp */
7648329232Gordon Ross	uint_t		vsa_aclflags;	/* ACE ACL flags */
7658329232Gordon Ross} vsecattr_t;
7668329232Gordon Ross
7678329232Gordon Ross/* vsa_mask values */
7688329232Gordon Ross#define	VSA_ACL			0x0001
7698329232Gordon Ross#define	VSA_ACLCNT		0x0002
7708329232Gordon Ross#define	VSA_DFACL		0x0004
7718329232Gordon Ross#define	VSA_DFACLCNT		0x0008
7728329232Gordon Ross#define	VSA_ACE			0x0010
7738329232Gordon Ross#define	VSA_ACECNT		0x0020
7748329232Gordon Ross#define	VSA_ACE_ALLTYPES	0x0040
7758329232Gordon Ross#define	VSA_ACE_ACLFLAGS	0x0080	/* get/set ACE ACL flags */
7768329232Gordon Ross
7778329232Gordon Ross/*
7788329232Gordon Ross * Structure used by various vnode operations to determine
7798329232Gordon Ross * the context (pid, host, identity) of a caller.
7808329232Gordon Ross *
7818329232Gordon Ross * The cc_caller_id is used to identify one or more callers who invoke
7828329232Gordon Ross * operations, possibly on behalf of others.  For example, the NFS
7838329232Gordon Ross * server could have it's own cc_caller_id which can be detected by
7848329232Gordon Ross * vnode/vfs operations or (FEM) monitors on those operations.  New
7858329232Gordon Ross * caller IDs are generated by fs_new_caller_id().
7868329232Gordon Ross */
7878329232Gordon Rosstypedef struct caller_context {
7888329232Gordon Ross	pid_t		cc_pid;		/* Process ID of the caller */
7898329232Gordon Ross	int		cc_sysid;	/* System ID, used for remote calls */
7908329232Gordon Ross	u_longlong_t	cc_caller_id;	/* Identifier for (set of) caller(s) */
7918329232Gordon Ross	ulong_t		cc_flags;
7928329232Gordon Ross} caller_context_t;
7938329232Gordon Ross
7948329232Gordon Ross/*
7958329232Gordon Ross * Flags for caller context.  The caller sets CC_DONTBLOCK if it does not
7968329232Gordon Ross * want to block inside of a FEM monitor.  The monitor will set CC_WOULDBLOCK
7978329232Gordon Ross * and return EAGAIN if the operation would have blocked.
7988329232Gordon Ross */
7998329232Gordon Ross#define	CC_WOULDBLOCK	0x01
8008329232Gordon Ross#define	CC_DONTBLOCK	0x02
8018329232Gordon Ross
8028329232Gordon Ross/*
8038329232Gordon Ross * Structure tags for function prototypes, defined elsewhere.
8048329232Gordon Ross */
8058329232Gordon Rossstruct pathname;
8068329232Gordon Rossstruct fid;
8078329232Gordon Rossstruct flock64;
8088329232Gordon Rossstruct flk_callback;
8098329232Gordon Rossstruct shrlock;
8108329232Gordon Rossstruct page;
8118329232Gordon Rossstruct seg;
8128329232Gordon Rossstruct as;
8138329232Gordon Rossstruct pollhead;
8148329232Gordon Rossstruct taskq;
8158329232Gordon Ross
8168329232Gordon Ross#if defined(_KERNEL) || defined(_FAKE_KERNEL)
8178329232Gordon Ross
8188329232Gordon Ross/*
8198329232Gordon Ross * VNODE_OPS defines all the vnode operations.  It is used to define
8208329232Gordon Ross * the vnodeops structure (below) and the fs_func_p union (vfs_opreg.h).
8218329232Gordon Ross */
8228329232Gordon Ross#define	VNODE_OPS							\
8238329232Gordon Ross	int	(*vop_open)(vnode_t **, int, cred_t *,			\
8248329232Gordon Ross				caller_context_t *);			\
8258329232Gordon Ross	int	(*vop_close)(vnode_t *, int, int, offset_t, cred_t *,	\
8268329232Gordon Ross				caller_context_t *);			\
8278329232Gordon Ross	int	(*vop_read)(vnode_t *, uio_t *, int, cred_t *,		\
8288329232Gordon Ross				caller_context_t *);			\
8298329232Gordon Ross	int	(*vop_write)(vnode_t *, uio_t *, int, cred_t *,		\
8308329232Gordon Ross				caller_context_t *);			\
8318329232Gordon Ross	int	(*vop_ioctl)(vnode_t *, int, intptr_t, int, cred_t *,	\
8328329232Gordon Ross				int *, caller_context_t *);		\
8338329232Gordon Ross	int	(*vop_setfl)(vnode_t *, int, int, cred_t *,		\
8348329232Gordon Ross				caller_context_t *);			\
8358329232Gordon Ross	int	(*vop_getattr)(vnode_t *, vattr_t *, int, cred_t *,	\
8368329232Gordon Ross				caller_context_t *);			\
8378329232Gordon Ross	int	(*vop_setattr)(vnode_t *, vattr_t *, int, cred_t *,	\
8388329232Gordon Ross				caller_context_t *);			\
8398329232Gordon Ross	int	(*vop_access)(vnode_t *, int, int, cred_t *,		\
8408329232Gordon Ross				caller_context_t *);			\
8418329232Gordon Ross	int	(*vop_lookup)(vnode_t *, char *, vnode_t **,		\
8428329232Gordon Ross				struct pathname *,			\
8438329232Gordon Ross				int, vnode_t *, cred_t *,		\
8448329232Gordon Ross				caller_context_t *, int *,		\
8458329232Gordon Ross				struct pathname *);			\
8468329232Gordon Ross	int	(*vop_create)(vnode_t *, char *, vattr_t *, vcexcl_t,	\
8478329232Gordon Ross				int, vnode_t **, cred_t *, int,		\
8488329232Gordon Ross				caller_context_t *, vsecattr_t *);	\
8498329232Gordon Ross	int	(*vop_remove)(vnode_t *, char *, cred_t *,		\
8508329232Gordon Ross				caller_context_t *, int);		\
8518329232Gordon Ross	int	(*vop_link)(vnode_t *, vnode_t *, char *, cred_t *,	\
8528329232Gordon Ross				caller_context_t *, int);		\
8538329232Gordon Ross	int	(*vop_rename)(vnode_t *, char *, vnode_t *, char *,	\
8548329232Gordon Ross				cred_t *, caller_context_t *, int);	\
8558329232Gordon Ross	int	(*vop_mkdir)(vnode_t *, char *, vattr_t *, vnode_t **,	\
8568329232Gordon Ross				cred_t *, caller_context_t *, int,	\
8578329232Gordon Ross				vsecattr_t *);				\
8588329232Gordon Ross	int	(*vop_rmdir)(vnode_t *, char *, vnode_t *, cred_t *,	\
8598329232Gordon Ross				caller_context_t *, int);		\
8608329232Gordon Ross	int	(*vop_readdir)(vnode_t *, uio_t *, cred_t *, int *,	\
8618329232Gordon Ross				caller_context_t *, int);		\
8628329232Gordon Ross	int	(*vop_symlink)(vnode_t *, char *, vattr_t *, char *,	\
8638329232Gordon Ross				cred_t *, caller_context_t *, int);	\
8648329232Gordon Ross	int	(*vop_readlink)(vnode_t *, uio_t *, cred_t *,		\
8658329232Gordon Ross				caller_context_t *);			\
8668329232Gordon Ross	int	(*vop_fsync)(vnode_t *, int, cred_t *,			\
8678329232Gordon Ross				caller_context_t *);			\
8688329232Gordon Ross	void	(*vop_inactive)(vnode_t *, cred_t *,			\
8698329232Gordon Ross				caller_context_t *);			\
8708329232Gordon Ross	int	(*vop_fid)(vnode_t *, struct fid *,			\
8718329232Gordon Ross				caller_context_t *);			\
8728329232Gordon Ross	int	(*vop_rwlock)(vnode_t *, int, caller_context_t *);	\
8738329232Gordon Ross	void	(*vop_rwunlock)(vnode_t *, int, caller_context_t *);	\
8748329232Gordon Ross	int	(*vop_seek)(vnode_t *, offset_t, offset_t *,		\
8758329232Gordon Ross				caller_context_t *);			\
8768329232Gordon Ross	int	(*vop_cmp)(vnode_t *, vnode_t *, caller_context_t *);	\
8778329232Gordon Ross	int	(*vop_frlock)(vnode_t *, int, struct flock64 *,		\
8788329232Gordon Ross				int, offset_t,				\
8798329232Gordon Ross				struct flk_callback *, cred_t *,	\
8808329232Gordon Ross				caller_context_t *);			\
8818329232Gordon Ross	int	(*vop_space)(vnode_t *, int, struct flock64 *,		\
8828329232Gordon Ross				int, offset_t,				\
8838329232Gordon Ross				cred_t *, caller_context_t *);		\
8848329232Gordon Ross	int	(*vop_realvp)(vnode_t *, vnode_t **,			\
8858329232Gordon Ross				caller_context_t *);			\
8868329232Gordon Ross	int	(*vop_getpage)(vnode_t *, offset_t, size_t, uint_t *,	\
8878329232Gordon Ross				struct page **, size_t, struct seg *,	\
8888329232Gordon Ross				caddr_t, enum seg_rw, cred_t *,		\
8898329232Gordon Ross				caller_context_t *);			\
8908329232Gordon Ross	int	(*vop_putpage)(vnode_t *, offset_t, size_t,		\
8918329232Gordon Ross				int, cred_t *, caller_context_t *);	\
8928329232Gordon Ross	int	(*vop_map)(vnode_t *, offset_t, struct as *,		\
8938329232Gordon Ross				caddr_t *, size_t,			\
8948329232Gordon Ross				uchar_t, uchar_t, uint_t, cred_t *,	\
8958329232Gordon Ross				caller_context_t *);			\
8968329232Gordon Ross	int	(*vop_addmap)(vnode_t *, offset_t, struct as *,		\
8978329232Gordon Ross				caddr_t, size_t,			\
8988329232Gordon Ross				uchar_t, uchar_t, uint_t, cred_t *,	\
8998329232Gordon Ross				caller_context_t *);			\
9008329232Gordon Ross	int	(*vop_delmap)(vnode_t *, offset_t, struct as *,		\
9018329232Gordon Ross				caddr_t, size_t,			\
9028329232Gordon Ross				uint_t, uint_t, uint_t, cred_t *,	\
9038329232Gordon Ross				caller_context_t *);			\
9048329232Gordon Ross	int	(*vop_poll)(vnode_t *, short, int, short *,		\
9058329232Gordon Ross				struct pollhead **,			\
9068329232Gordon Ross				caller_context_t *);			\
9078329232Gordon Ross	int	(*vop_dump)(vnode_t *, caddr_t, offset_t, offset_t,	\
9088329232Gordon Ross				caller_context_t *);			\
9098329232Gordon Ross	int	(*vop_pathconf)(vnode_t *, int, ulong_t *, cred_t *,	\
9108329232Gordon Ross				caller_context_t *);			\
9118329232Gordon Ross	int	(*vop_pageio)(vnode_t *, struct page *,			\
9128329232Gordon Ross				u_offset_t, size_t, int, cred_t *,	\
9138329232Gordon Ross				caller_context_t *);			\
9148329232Gordon Ross	int	(*vop_dumpctl)(vnode_t *, int, offset_t *,		\
9158329232Gordon Ross				caller_context_t *);			\
9168329232Gordon Ross	void	(*vop_dispose)(vnode_t *, struct page *,		\
9178329232Gordon Ross				int, int, cred_t *,			\
9188329232Gordon Ross				caller_context_t *);			\
9198329232Gordon Ross	int	(*vop_setsecattr)(vnode_t *, vsecattr_t *,		\
9208329232Gordon Ross				int, cred_t *, caller_context_t *);	\
9218329232Gordon Ross	int	(*vop_getsecattr)(vnode_t *, vsecattr_t *,		\
9228329232Gordon Ross				int, cred_t *, caller_context_t *);	\
9238329232Gordon Ross	int	(*vop_shrlock)(vnode_t *, int, struct shrlock *,	\
9248329232Gordon Ross				int, cred_t *, caller_context_t *);	\
9258329232Gordon Ross	int	(*vop_vnevent)(vnode_t *, vnevent_t, vnode_t *,		\
9268329232Gordon Ross				char *, caller_context_t *);		\
9278329232Gordon Ross	int	(*vop_reqzcbuf)(vnode_t *, enum uio_rw, xuio_t *,	\
9288329232Gordon Ross				cred_t *, caller_context_t *);		\
9298329232Gordon Ross	int	(*vop_retzcbuf)(vnode_t *, xuio_t *, cred_t *,		\
9308329232Gordon Ross				caller_context_t *)
9318329232Gordon Ross	/* NB: No ";" */
9328329232Gordon Ross
9338329232Gordon Ross/*
9348329232Gordon Ross * Operations on vnodes.  Note: File systems must never operate directly
9358329232Gordon Ross * on a 'vnodeops' structure -- it WILL change in future releases!  They
9368329232Gordon Ross * must use vn_make_ops() to create the structure.
9378329232Gordon Ross */
9388329232Gordon Rosstypedef struct vnodeops {
9398329232Gordon Ross	const char *vnop_name;
9408329232Gordon Ross	VNODE_OPS;	/* Signatures of all vnode operations (vops) */
9418329232Gordon Ross} vnodeops_t;
9428329232Gordon Ross
9438329232Gordon Rosstypedef int (*fs_generic_func_p) ();	/* Generic vop/vfsop/femop/fsemop ptr */
9448329232Gordon Ross
9458329232Gordon Rossextern int	fop_open(vnode_t **, int, cred_t *, caller_context_t *);
9468329232Gordon Rossextern int	fop_close(vnode_t *, int, int, offset_t, cred_t *,
9478329232Gordon Ross				caller_context_t *);
9488329232Gordon Rossextern int	fop_read(vnode_t *, uio_t *, int, cred_t *, caller_context_t *);
9498329232Gordon Rossextern int	fop_write(vnode_t *, uio_t *, int, cred_t *,
9508329232Gordon Ross				caller_context_t *);
9518329232Gordon Rossextern int	fop_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
9528329232Gordon Ross				caller_context_t *);
9538329232Gordon Rossextern int	fop_setfl(vnode_t *, int, int, cred_t *, caller_context_t *);
9548329232Gordon Rossextern int	fop_getattr(vnode_t *, vattr_t *, int, cred_t *,
9558329232Gordon Ross				caller_context_t *);
9568329232Gordon Rossextern int	fop_setattr(vnode_t *, vattr_t *, int, cred_t *,
9578329232Gordon Ross				caller_context_t *);
9588329232Gordon Rossextern int	fop_access(vnode_t *, int, int, cred_t *, caller_context_t *);
9598329232Gordon Rossextern int	fop_lookup(vnode_t *, char *, vnode_t **, struct pathname *,
9608329232Gordon Ross				int, vnode_t *, cred_t *, caller_context_t *,
9618329232Gordon Ross				int *, struct pathname *);
9628329232Gordon Rossextern int	fop_create(vnode_t *, char *, vattr_t *, vcexcl_t, int,
9638329232Gordon Ross				vnode_t **, cred_t *, int, caller_context_t *,
9648329232Gordon Ross				vsecattr_t *);
9658329232Gordon Rossextern int	fop_remove(vnode_t *vp, char *, cred_t *, caller_context_t *,
9668329232Gordon Ross				int);
9678329232Gordon Rossextern int	fop_link(vnode_t *, vnode_t *, char *, cred_t *,
9688329232Gordon Ross				caller_context_t *, int);
9698329232Gordon Rossextern int	fop_rename(vnode_t *, char *, vnode_t *, char *, cred_t *,
9708329232Gordon Ross				caller_context_t *, int);
9718329232Gordon Rossextern int	fop_mkdir(vnode_t *, char *, vattr_t *, vnode_t **, cred_t *,
9728329232Gordon Ross				caller_context_t *, int, vsecattr_t *);
9738329232Gordon Rossextern int	fop_rmdir(vnode_t *, char *, vnode_t *, cred_t *,
9748329232Gordon Ross				caller_context_t *, int);
9758329232Gordon Rossextern int	fop_readdir(vnode_t *, uio_t *, cred_t *, int *,
9768329232Gordon Ross				caller_context_t *, int);
9778329232Gordon Rossextern int	fop_symlink(vnode_t *, char *, vattr_t *, char *, cred_t *,
9788329232Gordon Ross				caller_context_t *, int);
9798329232Gordon Rossextern int	fop_readlink(vnode_t *, uio_t *, cred_t *, caller_context_t *);
9808329232Gordon Rossextern int	fop_fsync(vnode_t *, int, cred_t *, caller_context_t *);
9818329232Gordon Rossextern void	fop_inactive(vnode_t *, cred_t *, caller_context_t *);
9828329232Gordon Rossextern int	fop_fid(vnode_t *, struct fid *, caller_context_t *);
9838329232Gordon Rossextern int	fop_rwlock(vnode_t *, int, caller_context_t *);
9848329232Gordon Rossextern void	fop_rwunlock(vnode_t *, int, caller_context_t *);
9858329232Gordon Rossextern int	fop_seek(vnode_t *, offset_t, offset_t *, caller_context_t *);
9868329232Gordon Rossextern int	fop_cmp(vnode_t *, vnode_t *, caller_context_t *);
9878329232Gordon Rossextern int	fop_frlock(vnode_t *, int, struct flock64 *, int, offset_t,
9888329232Gordon Ross				struct flk_callback *, cred_t *,
9898329232Gordon Ross				caller_context_t *);
9908329232Gordon Rossextern int	fop_space(vnode_t *, int, struct flock64 *, int, offset_t,
9918329232Gordon Ross				cred_t *, caller_context_t *);
9928329232Gordon Rossextern int	fop_realvp(vnode_t *, vnode_t **, caller_context_t *);
9938329232Gordon Rossextern int	fop_getpage(vnode_t *, offset_t, size_t, uint_t *,
9948329232Gordon Ross				struct page **, size_t, struct seg *,
9958329232Gordon Ross				caddr_t, enum seg_rw, cred_t *,
9968329232Gordon Ross				caller_context_t *);
9978329232Gordon Rossextern int	fop_putpage(vnode_t *, offset_t, size_t, int, cred_t *,
9988329232Gordon Ross				caller_context_t *);
9998329232Gordon Rossextern int	fop_map(vnode_t *, offset_t, struct as *, caddr_t *, size_t,
10008329232Gordon Ross				uchar_t, uchar_t, uint_t, cred_t *cr,
10018329232Gordon Ross				caller_context_t *);
10028329232Gordon Rossextern int	fop_addmap(vnode_t *, offset_t, struct as *, caddr_t, size_t,
10038329232Gordon Ross				uchar_t, uchar_t, uint_t, cred_t *,
10048329232Gordon Ross				caller_context_t *);
10058329232Gordon Rossextern int	fop_delmap(vnode_t *, offset_t, struct as *, caddr_t, size_t,
10068329232Gordon Ross				uint_t, uint_t, uint_t, cred_t *,
10078329232Gordon Ross				caller_context_t *);
10088329232Gordon Rossextern int	fop_poll(vnode_t *, short, int, short *, struct pollhead **,
10098329232Gordon Ross				caller_context_t *);
10108329232Gordon Rossextern int	fop_dump(vnode_t *, caddr_t, offset_t, offset_t,
10118329232Gordon Ross    caller_context_t *);
10128329232Gordon Rossextern int	fop_pathconf(vnode_t *, int, ulong_t *, cred_t *,
10138329232Gordon Ross				caller_context_t *);
10148329232Gordon Rossextern int	fop_pageio(vnode_t *, struct page *, u_offset_t, size_t, int,
10158329232Gordon Ross				cred_t *, caller_context_t *);
10168329232Gordon Rossextern int	fop_dumpctl(vnode_t *, int, offset_t *, caller_context_t *);
10178329232Gordon Rossextern void	fop_dispose(vnode_t *, struct page *, int, int, cred_t *,
10188329232Gordon Ross				caller_context_t *);
10198329232