xref: /titanic_50/usr/src/uts/common/nfs/rnode4.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  *	Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  *	Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #ifndef	_NFS_RNODE4_H
31*7c478bd9Sstevel@tonic-gate #define	_NFS_RNODE4_H
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
36*7c478bd9Sstevel@tonic-gate extern "C" {
37*7c478bd9Sstevel@tonic-gate #endif
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate #include <nfs/rnode.h>		/* for symlink_cache, nfs_rwlock_t, etc. */
40*7c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
41*7c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/thread.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>	/* for offsetof */
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate typedef enum nfs4_access_type {
46*7c478bd9Sstevel@tonic-gate 	NFS4_ACCESS_UNKNOWN,
47*7c478bd9Sstevel@tonic-gate 	NFS4_ACCESS_ALLOWED,
48*7c478bd9Sstevel@tonic-gate 	NFS4_ACCESS_DENIED
49*7c478bd9Sstevel@tonic-gate } nfs4_access_type_t;
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * Access cache
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate typedef struct acache4_hash {
55*7c478bd9Sstevel@tonic-gate 	struct acache4 *next;
56*7c478bd9Sstevel@tonic-gate 	struct acache4 *prev;
57*7c478bd9Sstevel@tonic-gate 	krwlock_t lock;
58*7c478bd9Sstevel@tonic-gate } acache4_hash_t;
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate typedef struct acache4 {
61*7c478bd9Sstevel@tonic-gate 	struct acache4 *next;	/* next and prev must be first */
62*7c478bd9Sstevel@tonic-gate 	struct acache4 *prev;
63*7c478bd9Sstevel@tonic-gate 	uint32_t known;
64*7c478bd9Sstevel@tonic-gate 	uint32_t allowed;
65*7c478bd9Sstevel@tonic-gate 	struct rnode4 *rnode;
66*7c478bd9Sstevel@tonic-gate 	cred_t *cred;
67*7c478bd9Sstevel@tonic-gate 	struct acache4 *list;
68*7c478bd9Sstevel@tonic-gate 	struct acache4_hash *hashq;
69*7c478bd9Sstevel@tonic-gate } acache4_t;
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * Note on the different buffer sizes in rddir4_cache:
73*7c478bd9Sstevel@tonic-gate  * There seems to be some discrepancy between the intended and actual
74*7c478bd9Sstevel@tonic-gate  * use of entlen and buflen, which does not correspond to the comment below.
75*7c478bd9Sstevel@tonic-gate  *	entlen - nfsv2/3 used as both alloc'd size of entries buffer and
76*7c478bd9Sstevel@tonic-gate  *		as the actual size of the entries (XXX is this correct?).
77*7c478bd9Sstevel@tonic-gate  *		nfsv4 will use it only as the alloc'd size.
78*7c478bd9Sstevel@tonic-gate  *	buflen - used for calculations of readahead.
79*7c478bd9Sstevel@tonic-gate  *	actlen - added for nfsv4 to serve as the size of the useful
80*7c478bd9Sstevel@tonic-gate  *		portion of the entries buffer. That is because in
81*7c478bd9Sstevel@tonic-gate  *		nfsv4, the otw entries are converted to system entries,
82*7c478bd9Sstevel@tonic-gate  *		and may not be the same size - thus buffer may not be full.
83*7c478bd9Sstevel@tonic-gate  */
84*7c478bd9Sstevel@tonic-gate typedef struct rddir4_cache {
85*7c478bd9Sstevel@tonic-gate 	lloff_t _cookie;	/* cookie used to find this cache entry */
86*7c478bd9Sstevel@tonic-gate 	lloff_t _ncookie;	/* cookie used to find the next cache entry */
87*7c478bd9Sstevel@tonic-gate 	char *entries;		/* buffer containing dirent entries */
88*7c478bd9Sstevel@tonic-gate 	int eof;		/* EOF reached after this request */
89*7c478bd9Sstevel@tonic-gate 	int entlen;		/* size of dirent entries in buf */
90*7c478bd9Sstevel@tonic-gate 	int buflen;		/* size of the buffer used to store entries */
91*7c478bd9Sstevel@tonic-gate 	int actlen;		/* size of the actual entries (nfsv4 only) */
92*7c478bd9Sstevel@tonic-gate 	int flags;		/* control flags, see below */
93*7c478bd9Sstevel@tonic-gate 	kcondvar_t cv;		/* cv for blocking */
94*7c478bd9Sstevel@tonic-gate 	int error;		/* error from RPC operation */
95*7c478bd9Sstevel@tonic-gate 	void *data;		/* private data */
96*7c478bd9Sstevel@tonic-gate } rddir4_cache;
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate #define	nfs4_cookie	_cookie._f
99*7c478bd9Sstevel@tonic-gate #define	nfs4_ncookie	_ncookie._f
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate /*
102*7c478bd9Sstevel@tonic-gate  * Shadow vnode, v4 only.
103*7c478bd9Sstevel@tonic-gate  *
104*7c478bd9Sstevel@tonic-gate  * A file's shadow vnode list is protected by its hash bucket lock,
105*7c478bd9Sstevel@tonic-gate  * r_hashq->r_lock.
106*7c478bd9Sstevel@tonic-gate  *
107*7c478bd9Sstevel@tonic-gate  * sv_r_vnode is protected by the appropriate vnode locks.
108*7c478bd9Sstevel@tonic-gate  *
109*7c478bd9Sstevel@tonic-gate  * sv_dfh, sv_name, sv_dfileid, and sv_dfileid_valid are protected
110*7c478bd9Sstevel@tonic-gate  * by rp->r_svlock.
111*7c478bd9Sstevel@tonic-gate  */
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate typedef struct insq_link {
114*7c478bd9Sstevel@tonic-gate 	void	*forw;
115*7c478bd9Sstevel@tonic-gate 	void	*back;
116*7c478bd9Sstevel@tonic-gate } insq_link_t;
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate typedef struct svnode {
119*7c478bd9Sstevel@tonic-gate 	insq_link_t	sv_link;	/* must be first for insque */
120*7c478bd9Sstevel@tonic-gate 	vnode_t		*sv_r_vnode;	/* vnode for this shadow */
121*7c478bd9Sstevel@tonic-gate 	nfs4_fname_t	*sv_name;	/* component name */
122*7c478bd9Sstevel@tonic-gate 	nfs4_sharedfh_t	*sv_dfh;	/* directory file handle */
123*7c478bd9Sstevel@tonic-gate } svnode_t;
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate #define	sv_forw			sv_link.forw
126*7c478bd9Sstevel@tonic-gate #define	sv_back			sv_link.back
127*7c478bd9Sstevel@tonic-gate extern svnode_t			*vtosv(vnode_t *);
128*7c478bd9Sstevel@tonic-gate #define	VTOSV(vp)		vtosv(vp)
129*7c478bd9Sstevel@tonic-gate #define	SVTOV(svp)		(((svp)->sv_r_vnode))
130*7c478bd9Sstevel@tonic-gate #define	IS_SHADOW(vp, rp)	((vp) != (rp)->r_vnode)
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate /*
133*7c478bd9Sstevel@tonic-gate  * The format of the hash bucket used to lookup rnodes from a file handle.
134*7c478bd9Sstevel@tonic-gate  */
135*7c478bd9Sstevel@tonic-gate typedef struct r4hashq {
136*7c478bd9Sstevel@tonic-gate 	struct rnode4 *r_hashf;
137*7c478bd9Sstevel@tonic-gate 	struct rnode4 *r_hashb;
138*7c478bd9Sstevel@tonic-gate 	krwlock_t r_lock;
139*7c478bd9Sstevel@tonic-gate } r4hashq_t;
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate /*
142*7c478bd9Sstevel@tonic-gate  * Remote file information structure.
143*7c478bd9Sstevel@tonic-gate  *
144*7c478bd9Sstevel@tonic-gate  * The rnode is the "inode" for remote files.  It contains all the
145*7c478bd9Sstevel@tonic-gate  * information necessary to handle remote file on the client side.
146*7c478bd9Sstevel@tonic-gate  *
147*7c478bd9Sstevel@tonic-gate  * Note on file sizes:  we keep two file sizes in the rnode: the size
148*7c478bd9Sstevel@tonic-gate  * according to the client (r_size) and the size according to the server
149*7c478bd9Sstevel@tonic-gate  * (r_attr.va_size).  They can differ because we modify r_size during a
150*7c478bd9Sstevel@tonic-gate  * write system call (nfs_rdwr), before the write request goes over the
151*7c478bd9Sstevel@tonic-gate  * wire (before the file is actually modified on the server).  If an OTW
152*7c478bd9Sstevel@tonic-gate  * request occurs before the cached data is written to the server the file
153*7c478bd9Sstevel@tonic-gate  * size returned from the server (r_attr.va_size) may not match r_size.
154*7c478bd9Sstevel@tonic-gate  * r_size is the one we use, in general.  r_attr.va_size is only used to
155*7c478bd9Sstevel@tonic-gate  * determine whether or not our cached data is valid.
156*7c478bd9Sstevel@tonic-gate  *
157*7c478bd9Sstevel@tonic-gate  * Each rnode has 5 locks associated with it (not including the rnode
158*7c478bd9Sstevel@tonic-gate  * hash table and free list locks):
159*7c478bd9Sstevel@tonic-gate  *
160*7c478bd9Sstevel@tonic-gate  *	r_rwlock:	Serializes nfs_write and nfs_setattr requests
161*7c478bd9Sstevel@tonic-gate  *			and allows nfs_read requests to proceed in parallel.
162*7c478bd9Sstevel@tonic-gate  *			Serializes reads/updates to directories.
163*7c478bd9Sstevel@tonic-gate  *
164*7c478bd9Sstevel@tonic-gate  *	r_lkserlock:	Serializes lock requests with map, write, and
165*7c478bd9Sstevel@tonic-gate  *			readahead operations.
166*7c478bd9Sstevel@tonic-gate  *
167*7c478bd9Sstevel@tonic-gate  *	r_statelock:	Protects all fields in the rnode except for
168*7c478bd9Sstevel@tonic-gate  *			those listed below.  This lock is intented
169*7c478bd9Sstevel@tonic-gate  *			to be held for relatively short periods of
170*7c478bd9Sstevel@tonic-gate  *			time (not accross entire putpage operations,
171*7c478bd9Sstevel@tonic-gate  *			for example).
172*7c478bd9Sstevel@tonic-gate  *
173*7c478bd9Sstevel@tonic-gate  *	r_statev4_lock:	Protects the created_v4 flag, the lock_owners list,
174*7c478bd9Sstevel@tonic-gate  *			and all the delegation fields except r_deleg_list.
175*7c478bd9Sstevel@tonic-gate  *
176*7c478bd9Sstevel@tonic-gate  *	r_os_lock:	Protects r_open_streams.
177*7c478bd9Sstevel@tonic-gate  *
178*7c478bd9Sstevel@tonic-gate  *
179*7c478bd9Sstevel@tonic-gate  * The following members are protected by the mutex rp4freelist_lock:
180*7c478bd9Sstevel@tonic-gate  *	r_freef
181*7c478bd9Sstevel@tonic-gate  *	r_freeb
182*7c478bd9Sstevel@tonic-gate  *
183*7c478bd9Sstevel@tonic-gate  * The following members are protected by the hash bucket rwlock:
184*7c478bd9Sstevel@tonic-gate  *	r_hashf
185*7c478bd9Sstevel@tonic-gate  *	r_hashb
186*7c478bd9Sstevel@tonic-gate  *
187*7c478bd9Sstevel@tonic-gate  * r_fh is read-only except when an rnode is created (or recycled from the
188*7c478bd9Sstevel@tonic-gate  * free list).
189*7c478bd9Sstevel@tonic-gate  *
190*7c478bd9Sstevel@tonic-gate  * The following members are protected by nfs4_server_t::s_lock:
191*7c478bd9Sstevel@tonic-gate  *	r_deleg_list
192*7c478bd9Sstevel@tonic-gate  *
193*7c478bd9Sstevel@tonic-gate  * Note: r_modaddr is only accessed when the r_statelock mutex is held.
194*7c478bd9Sstevel@tonic-gate  *	Its value is also controlled via r_rwlock.  It is assumed that
195*7c478bd9Sstevel@tonic-gate  *	there will be only 1 writer active at a time, so it safe to
196*7c478bd9Sstevel@tonic-gate  *	set r_modaddr and release r_statelock as long as the r_rwlock
197*7c478bd9Sstevel@tonic-gate  *	writer lock is held.
198*7c478bd9Sstevel@tonic-gate  *
199*7c478bd9Sstevel@tonic-gate  * 64-bit offsets: the code formerly assumed that atomic reads of
200*7c478bd9Sstevel@tonic-gate  * r_size were safe and reliable; on 32-bit architectures, this is
201*7c478bd9Sstevel@tonic-gate  * not true since an intervening bus cycle from another processor
202*7c478bd9Sstevel@tonic-gate  * could update half of the size field.  The r_statelock must now
203*7c478bd9Sstevel@tonic-gate  * be held whenever any kind of access of r_size is made.
204*7c478bd9Sstevel@tonic-gate  *
205*7c478bd9Sstevel@tonic-gate  * Lock ordering:
206*7c478bd9Sstevel@tonic-gate  * 	r_rwlock > r_lkserlock > r_os_lock > r_statelock > r_statev4_lock
207*7c478bd9Sstevel@tonic-gate  *	vnode_t::v_lock > r_os_lock
208*7c478bd9Sstevel@tonic-gate  */
209*7c478bd9Sstevel@tonic-gate struct exportinfo;	/* defined in nfs/export.h */
210*7c478bd9Sstevel@tonic-gate struct servinfo4;	/* defined in nfs/nfs4_clnt.h */
211*7c478bd9Sstevel@tonic-gate struct failinfo;	/* defined in nfs/nfs_clnt.h */
212*7c478bd9Sstevel@tonic-gate struct mntinfo4;	/* defined in nfs/nfs4_clnt.h */
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate typedef struct rnode4 {
215*7c478bd9Sstevel@tonic-gate 	/* the hash fields must be first to match the rhashq_t */
216*7c478bd9Sstevel@tonic-gate 	struct rnode4	*r_hashf;	/* hash queue forward pointer */
217*7c478bd9Sstevel@tonic-gate 	struct rnode4	*r_hashb;	/* hash queue back pointer */
218*7c478bd9Sstevel@tonic-gate 	struct rnode4	*r_freef;	/* free list forward pointer */
219*7c478bd9Sstevel@tonic-gate 	struct rnode4	*r_freeb;	/* free list back pointer */
220*7c478bd9Sstevel@tonic-gate 	r4hashq_t	*r_hashq;	/* pointer to the hash bucket */
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	svnode_t	r_svnode;	/* "master" shadow vnode for file */
223*7c478bd9Sstevel@tonic-gate 	kmutex_t	r_svlock;	/* serializes access to svnode list */
224*7c478bd9Sstevel@tonic-gate 	nfs_rwlock_t	r_rwlock;	/* serializes write/setattr requests */
225*7c478bd9Sstevel@tonic-gate 	nfs_rwlock_t	r_lkserlock;	/* serialize lock with other ops */
226*7c478bd9Sstevel@tonic-gate 	kmutex_t	r_statelock;	/* protects (most of) rnode contents */
227*7c478bd9Sstevel@tonic-gate 	nfs4_sharedfh_t	*r_fh;		/* file handle */
228*7c478bd9Sstevel@tonic-gate 	struct servinfo4
229*7c478bd9Sstevel@tonic-gate 			*r_server;	/* current server */
230*7c478bd9Sstevel@tonic-gate 	u_offset_t	r_nextr;	/* next byte read offset (read-ahead) */
231*7c478bd9Sstevel@tonic-gate 	uint_t		r_flags;	/* flags, see below */
232*7c478bd9Sstevel@tonic-gate 	short		r_error;	/* async write error */
233*7c478bd9Sstevel@tonic-gate 	cred_t		*r_unlcred;	/* unlinked credentials */
234*7c478bd9Sstevel@tonic-gate 	char		*r_unlname;	/* unlinked file name */
235*7c478bd9Sstevel@tonic-gate 	vnode_t		*r_unldvp;	/* parent dir of unlinked file */
236*7c478bd9Sstevel@tonic-gate 	vnode_t		*r_xattr_dir;	/* cached xattr dir vnode */
237*7c478bd9Sstevel@tonic-gate 	len_t		r_size;		/* client's view of file size */
238*7c478bd9Sstevel@tonic-gate 	vattr_t		r_attr;		/* cached vnode attributes */
239*7c478bd9Sstevel@tonic-gate 	hrtime_t	r_time_attr_saved; /* time attributes were cached */
240*7c478bd9Sstevel@tonic-gate 	hrtime_t	r_time_attr_inval; /* time attributes become invalid */
241*7c478bd9Sstevel@tonic-gate 	hrtime_t	r_time_cache_inval; /* time caches become invalid */
242*7c478bd9Sstevel@tonic-gate 	time_t		r_delay_wait;	/* future time for DELAY handling */
243*7c478bd9Sstevel@tonic-gate 	int		r_delay_interval; /* Number of Secs of last DELAY */
244*7c478bd9Sstevel@tonic-gate 	time_t		r_last_recov;	/* time of last recovery operation */
245*7c478bd9Sstevel@tonic-gate 	nfs4_recov_t	r_recov_act;	/* action from last recovery op */
246*7c478bd9Sstevel@tonic-gate 	long		r_mapcnt;	/* count of mmapped pages */
247*7c478bd9Sstevel@tonic-gate 	uint_t		r_count;	/* # of refs not reflect in v_count */
248*7c478bd9Sstevel@tonic-gate 	uint_t		r_awcount;	/* # of outstanding async write */
249*7c478bd9Sstevel@tonic-gate 	uint_t		r_gcount;	/* getattrs waiting to flush pages */
250*7c478bd9Sstevel@tonic-gate 	kcondvar_t	r_cv;		/* condvar for blocked threads */
251*7c478bd9Sstevel@tonic-gate 	int		(*r_putapage)	/* address of putapage routine */
252*7c478bd9Sstevel@tonic-gate 		(vnode_t *, page_t *, u_offset_t *, size_t *, int, cred_t *);
253*7c478bd9Sstevel@tonic-gate 	void		*r_dir;		/* cache of readdir responses */
254*7c478bd9Sstevel@tonic-gate 	rddir4_cache	*r_direof;	/* pointer to the EOF entry */
255*7c478bd9Sstevel@tonic-gate 	symlink_cache	r_symlink;	/* cached readlink response */
256*7c478bd9Sstevel@tonic-gate 	verifier4	r_writeverf;	/* file data write verifier */
257*7c478bd9Sstevel@tonic-gate 	u_offset_t	r_modaddr;	/* address for page in writerp */
258*7c478bd9Sstevel@tonic-gate 	commit_t	r_commit;	/* commit information */
259*7c478bd9Sstevel@tonic-gate 	u_offset_t	r_truncaddr;	/* base for truncate operation */
260*7c478bd9Sstevel@tonic-gate 	vsecattr_t	*r_secattr;	/* cached security attributes (acls) */
261*7c478bd9Sstevel@tonic-gate 	verifier4	r_cookieverf4;	/* version 4 readdir cookie verifier */
262*7c478bd9Sstevel@tonic-gate 	nfs4_pathconf_info_t r_pathconf; /* cached pathconf info */
263*7c478bd9Sstevel@tonic-gate 	acache4_t	*r_acache;	/* list of access cache entries */
264*7c478bd9Sstevel@tonic-gate 	list_t		r_open_streams;	/* open streams list */
265*7c478bd9Sstevel@tonic-gate 	kmutex_t	r_os_lock;	/* protects r_open_streams */
266*7c478bd9Sstevel@tonic-gate 	nfs4_lock_owner_t
267*7c478bd9Sstevel@tonic-gate 			r_lo_head;	/* lock owners list head */
268*7c478bd9Sstevel@tonic-gate 	int		created_v4;	/* 1 if file has been created in v4 */
269*7c478bd9Sstevel@tonic-gate 	kmutex_t	r_statev4_lock;	/* protects created_v4, state4ptr */
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 	list_node_t	r_deleg_link;	/* linkage into list of */
272*7c478bd9Sstevel@tonic-gate 					/* delegated rnodes for this server */
273*7c478bd9Sstevel@tonic-gate 	open_delegation_type4
274*7c478bd9Sstevel@tonic-gate 			r_deleg_type;	/* type of delegation granted */
275*7c478bd9Sstevel@tonic-gate 	stateid4	r_deleg_stateid;
276*7c478bd9Sstevel@tonic-gate 					/* delegation state id */
277*7c478bd9Sstevel@tonic-gate 	nfs_space_limit4
278*7c478bd9Sstevel@tonic-gate 			r_deleg_limit;	/* file limits returned from */
279*7c478bd9Sstevel@tonic-gate 					/* server on delegated open */
280*7c478bd9Sstevel@tonic-gate 	nfsace4		r_deleg_perms;	/* file permissions returned from */
281*7c478bd9Sstevel@tonic-gate 					/* server on delegated open */
282*7c478bd9Sstevel@tonic-gate 	fattr4_change	r_deleg_change;	/* current deleg change attr */
283*7c478bd9Sstevel@tonic-gate 	fattr4_change	r_deleg_change_grant;
284*7c478bd9Sstevel@tonic-gate 					/* change @ write deleg grant */
285*7c478bd9Sstevel@tonic-gate 	cred_t		*r_deleg_cred;	/* credential in force when the */
286*7c478bd9Sstevel@tonic-gate 					/* delegation was granted */
287*7c478bd9Sstevel@tonic-gate 	open_delegation_type4
288*7c478bd9Sstevel@tonic-gate 			r_deleg_needs_recovery;
289*7c478bd9Sstevel@tonic-gate 					/* delegation needs recovery */
290*7c478bd9Sstevel@tonic-gate 					/* This contains the delegation type */
291*7c478bd9Sstevel@tonic-gate 					/* for use with CLAIM_PREVIOUS. */
292*7c478bd9Sstevel@tonic-gate 					/* OPEN_DELEGATE_NONE means recovery */
293*7c478bd9Sstevel@tonic-gate 					/* is not needed. */
294*7c478bd9Sstevel@tonic-gate 	unsigned	r_deleg_needs_recall:1;
295*7c478bd9Sstevel@tonic-gate 					/* delegation has been recalled by */
296*7c478bd9Sstevel@tonic-gate 					/* the server during open with */
297*7c478bd9Sstevel@tonic-gate 					/* CLAIM_PREVIOUS */
298*7c478bd9Sstevel@tonic-gate 	unsigned 	r_deleg_return_pending:1;
299*7c478bd9Sstevel@tonic-gate 					/* delegreturn is pending, don't use */
300*7c478bd9Sstevel@tonic-gate 					/* the delegation stateid, set in */
301*7c478bd9Sstevel@tonic-gate 					/* nfs4_dlistadd */
302*7c478bd9Sstevel@tonic-gate 	unsigned 	r_deleg_return_inprog:1;
303*7c478bd9Sstevel@tonic-gate 					/* delegreturn is in progress, may */
304*7c478bd9Sstevel@tonic-gate 					/* only be set by nfs4delegreturn. */
305*7c478bd9Sstevel@tonic-gate 	nfs_rwlock_t    r_deleg_recall_lock;
306*7c478bd9Sstevel@tonic-gate 					/* lock for synchronizing delegreturn */
307*7c478bd9Sstevel@tonic-gate 					/* with in other operations, acquired */
308*7c478bd9Sstevel@tonic-gate 					/* in read mode by nfs4_start_fop, */
309*7c478bd9Sstevel@tonic-gate 					/* acquired in write mode in */
310*7c478bd9Sstevel@tonic-gate 					/* nfs4delegreturn */
311*7c478bd9Sstevel@tonic-gate 	fattr4_change	r_change;	/* GETATTR4 change attr;  client  */
312*7c478bd9Sstevel@tonic-gate 					/* should always request change   */
313*7c478bd9Sstevel@tonic-gate 					/* when c/mtime requested to keep */
314*7c478bd9Sstevel@tonic-gate 					/* change and c/mtime in sync	  */
315*7c478bd9Sstevel@tonic-gate 	fattr4_fileid	r_mntd_fid;	/* mounted on fileid attr	  */
316*7c478bd9Sstevel@tonic-gate 	kthread_t	*r_serial;	/* attrcache validation thread */
317*7c478bd9Sstevel@tonic-gate 	kthread_t	*r_pgflush;	/* thread flushing page cache */
318*7c478bd9Sstevel@tonic-gate 	avl_node_t	r_fileid_map;	/* map fileids to extant rnodes */
319*7c478bd9Sstevel@tonic-gate 	list_t		r_indelmap;	/* list of delmap callers */
320*7c478bd9Sstevel@tonic-gate 	fattr4_fsid	r_srv_fsid;	/* fsid of srv fs containing object */
321*7c478bd9Sstevel@tonic-gate 					/* when rnode created; compare with */
322*7c478bd9Sstevel@tonic-gate 					/* sv_fsid (servinfo4_t) to see why */
323*7c478bd9Sstevel@tonic-gate 					/* R4SRVSTUB was set		    */
324*7c478bd9Sstevel@tonic-gate } rnode4_t;
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate #define	r_vnode	r_svnode.sv_r_vnode
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate /*
329*7c478bd9Sstevel@tonic-gate  * Flags
330*7c478bd9Sstevel@tonic-gate  */
331*7c478bd9Sstevel@tonic-gate #define	R4READDIRWATTR	0x1	/* Use READDIR with attributes */
332*7c478bd9Sstevel@tonic-gate #define	R4DIRTY		0x2	/* dirty pages from write operation */
333*7c478bd9Sstevel@tonic-gate #define	R4STALE		0x4	/* stale, don't even attempt to write */
334*7c478bd9Sstevel@tonic-gate #define	R4MODINPROGRESS	0x8	/* page modification happening */
335*7c478bd9Sstevel@tonic-gate #define	R4TRUNCATE	0x10	/* truncating, don't commit */
336*7c478bd9Sstevel@tonic-gate #define	R4HAVEVERF	0x20	/* have a write verifier to compare against */
337*7c478bd9Sstevel@tonic-gate #define	R4COMMIT	0x40	/* commit in progress */
338*7c478bd9Sstevel@tonic-gate #define	R4COMMITWAIT	0x80	/* someone is waiting to do a commit */
339*7c478bd9Sstevel@tonic-gate #define	R4HASHED	0x100	/* rnode is in hash queues */
340*7c478bd9Sstevel@tonic-gate #define	R4OUTOFSPACE	0x200	/* an out of space error has happened */
341*7c478bd9Sstevel@tonic-gate #define	R4LODANGLERS	0x400	/* rnode has dangling lock_owners to cleanup */
342*7c478bd9Sstevel@tonic-gate #define	R4WRITEMODIFIED	0x800	/* file data has been modified by write */
343*7c478bd9Sstevel@tonic-gate #define	R4DIRECTIO	0x1000	/* bypass the buffer cache */
344*7c478bd9Sstevel@tonic-gate #define	R4RECOVERR	0x2000	/* couldn't recover */
345*7c478bd9Sstevel@tonic-gate #define	R4RECEXPFH	0x4000	/* recovering expired filehandle */
346*7c478bd9Sstevel@tonic-gate #define	R4RECOVERRP	0x8000	/* R4RECOVERR pending, but not set (yet) */
347*7c478bd9Sstevel@tonic-gate #define	R4SRVSTUB	0x10000	/* server stub / fs mntpnt */
348*7c478bd9Sstevel@tonic-gate #define	R4ISXATTR	0x20000	/* rnode is a named attribute */
349*7c478bd9Sstevel@tonic-gate #define	R4DELMAPLIST	0x40000	/* delmap callers tracked for as callback */
350*7c478bd9Sstevel@tonic-gate #define	R4PGFLUSH	0x80000	/* page flush thread active */
351*7c478bd9Sstevel@tonic-gate #define	R4FILEIDMAP	0x100000 /* rnode is in fileid map */
352*7c478bd9Sstevel@tonic-gate #define	R4LOOKUP	0x200000 /* a lookup has been done in the directory */
353*7c478bd9Sstevel@tonic-gate /*
354*7c478bd9Sstevel@tonic-gate  * Convert between vnode and rnode
355*7c478bd9Sstevel@tonic-gate  */
356*7c478bd9Sstevel@tonic-gate #define	RTOV4(rp)	((rp)->r_vnode)
357*7c478bd9Sstevel@tonic-gate #define	VTOR4(vp)	((rnode4_t *)((vp)->v_data))
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate /*
360*7c478bd9Sstevel@tonic-gate  * Open file instances.
361*7c478bd9Sstevel@tonic-gate  */
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate typedef struct nfs4_opinst {
364*7c478bd9Sstevel@tonic-gate 	struct nfs4_opinst	*re_next; /* next in list */
365*7c478bd9Sstevel@tonic-gate 	vnode_t			*re_vp;	/* held reference */
366*7c478bd9Sstevel@tonic-gate 	uint32_t		re_numosp; /* number of valid open streams */
367*7c478bd9Sstevel@tonic-gate 	nfs4_open_stream_t	**re_osp; /* held reference */
368*7c478bd9Sstevel@tonic-gate } nfs4_opinst_t;
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL
371*7c478bd9Sstevel@tonic-gate 
372*7c478bd9Sstevel@tonic-gate extern long nrnode;
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate /* Used for r_delay_interval */
375*7c478bd9Sstevel@tonic-gate #define	NFS4_INITIAL_DELAY_INTERVAL	 1
376*7c478bd9Sstevel@tonic-gate #define	NFS4_MAX_DELAY_INTERVAL		20
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate extern rnode4_t	*r4find(r4hashq_t *, nfs4_sharedfh_t *, struct vfs *);
379*7c478bd9Sstevel@tonic-gate extern rnode4_t	*r4find_unlocked(nfs4_sharedfh_t *, struct vfs *);
380*7c478bd9Sstevel@tonic-gate extern void	r4flush(struct vfs *, cred_t *);
381*7c478bd9Sstevel@tonic-gate extern void	destroy_rtable4(struct vfs *, cred_t *);
382*7c478bd9Sstevel@tonic-gate extern int	check_rtable4(struct vfs *);
383*7c478bd9Sstevel@tonic-gate extern void	rp4_addfree(rnode4_t *, cred_t *);
384*7c478bd9Sstevel@tonic-gate extern void	rp4_addhash(rnode4_t *);
385*7c478bd9Sstevel@tonic-gate extern void	rp4_rmhash(rnode4_t *);
386*7c478bd9Sstevel@tonic-gate extern void	rp4_rmhash_locked(rnode4_t *);
387*7c478bd9Sstevel@tonic-gate extern int	rtable4hash(nfs4_sharedfh_t *);
388*7c478bd9Sstevel@tonic-gate extern void	rp4_fileid_map_init(avl_tree_t *);
389*7c478bd9Sstevel@tonic-gate extern void	rp4_fileid_map_remove(rnode4_t *);
390*7c478bd9Sstevel@tonic-gate extern void	destroy_fileid_map(struct vfs *);
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate extern vnode_t *makenfs4node(nfs4_sharedfh_t *, nfs4_ga_res_t *, struct vfs *,
393*7c478bd9Sstevel@tonic-gate 				hrtime_t, cred_t *, vnode_t *, nfs4_fname_t *);
394*7c478bd9Sstevel@tonic-gate extern vnode_t *makenfs4node_by_fh(nfs4_sharedfh_t *, nfs4_sharedfh_t *,
395*7c478bd9Sstevel@tonic-gate     nfs4_fname_t **, nfs4_ga_res_t *, mntinfo4_t *, cred_t *, hrtime_t);
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate extern nfs4_opinst_t *r4mkopenlist(struct mntinfo4 *);
398*7c478bd9Sstevel@tonic-gate extern void	r4releopenlist(nfs4_opinst_t *);
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate /* Access cache calls */
401*7c478bd9Sstevel@tonic-gate extern nfs4_access_type_t nfs4_access_check(rnode4_t *, uint32_t, cred_t *);
402*7c478bd9Sstevel@tonic-gate extern void	nfs4_access_cache(rnode4_t *rp, uint32_t, uint32_t, cred_t *);
403*7c478bd9Sstevel@tonic-gate extern int	nfs4_access_purge_rp(rnode4_t *);
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate extern int	nfs4_free_data_reclaim(rnode4_t *);
406*7c478bd9Sstevel@tonic-gate extern void	nfs4_rnode_invalidate(struct vfs *);
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate extern time_t	r2lease_time(rnode4_t *);
409*7c478bd9Sstevel@tonic-gate extern int	nfs4_directio(vnode_t *, int, cred_t *);
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate /* shadow vnode functions */
412*7c478bd9Sstevel@tonic-gate extern void	sv_activate(vnode_t **, vnode_t *, nfs4_fname_t **, int);
413*7c478bd9Sstevel@tonic-gate extern vnode_t	*sv_find(vnode_t *, vnode_t *, nfs4_fname_t **);
414*7c478bd9Sstevel@tonic-gate extern void	sv_update_path(vnode_t *, char *, char *);
415*7c478bd9Sstevel@tonic-gate extern void	sv_inactive(vnode_t *);
416*7c478bd9Sstevel@tonic-gate extern void	sv_exchange(vnode_t **);
417*7c478bd9Sstevel@tonic-gate extern void	sv_uninit(svnode_t *);
418*7c478bd9Sstevel@tonic-gate extern void	nfs4_clear_open_streams(rnode4_t *);
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate /*
421*7c478bd9Sstevel@tonic-gate  * Mark cached attributes as timed out
422*7c478bd9Sstevel@tonic-gate  *
423*7c478bd9Sstevel@tonic-gate  * The caller must not be holding the rnode r_statelock mutex.
424*7c478bd9Sstevel@tonic-gate  */
425*7c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE4_LOCKED(rp)				\
426*7c478bd9Sstevel@tonic-gate 	rp->r_time_attr_inval = gethrtime();			\
427*7c478bd9Sstevel@tonic-gate 	rp->r_time_attr_saved = rp->r_time_attr_inval;		\
428*7c478bd9Sstevel@tonic-gate 	rp->r_pathconf.pc4_xattr_valid = 0;			\
429*7c478bd9Sstevel@tonic-gate 	rp->r_pathconf.pc4_cache_valid = 0;
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate #define	PURGE_ATTRCACHE4(vp)	{				\
432*7c478bd9Sstevel@tonic-gate 	rnode4_t *rp = VTOR4(vp);				\
433*7c478bd9Sstevel@tonic-gate 	mutex_enter(&rp->r_statelock);				\
434*7c478bd9Sstevel@tonic-gate 	PURGE_ATTRCACHE4_LOCKED(rp);				\
435*7c478bd9Sstevel@tonic-gate 	mutex_exit(&rp->r_statelock);				\
436*7c478bd9Sstevel@tonic-gate }
437*7c478bd9Sstevel@tonic-gate 
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate extern void	nfs4_async_readdir(vnode_t *, rddir4_cache *,
440*7c478bd9Sstevel@tonic-gate 			cred_t *, int (*)(vnode_t *, rddir4_cache *, cred_t *));
441*7c478bd9Sstevel@tonic-gate extern char	*rnode4info(rnode4_t *rp);
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate extern int	writerp4(rnode4_t *, caddr_t, int, struct uio *, int);
444*7c478bd9Sstevel@tonic-gate extern void	nfs4_set_nonvattrs(rnode4_t *, struct nfs4attr_to_vattr *);
445*7c478bd9Sstevel@tonic-gate extern void	nfs4delegabandon(rnode4_t *);
446*7c478bd9Sstevel@tonic-gate extern stateid4 nfs4_get_w_stateid(cred_t *, rnode4_t *, pid_t, mntinfo4_t *,
447*7c478bd9Sstevel@tonic-gate 			nfs_opnum4, nfs4_stateid_types_t *);
448*7c478bd9Sstevel@tonic-gate extern stateid4 nfs4_get_stateid(cred_t *, rnode4_t *, pid_t, mntinfo4_t *,
449*7c478bd9Sstevel@tonic-gate 			nfs_opnum4, nfs4_stateid_types_t *, bool_t);
450*7c478bd9Sstevel@tonic-gate extern nfsstat4 nfs4_find_or_create_lock_owner(pid_t, rnode4_t *, cred_t *,
451*7c478bd9Sstevel@tonic-gate 			nfs4_open_owner_t **, nfs4_open_stream_t **,
452*7c478bd9Sstevel@tonic-gate 			nfs4_lock_owner_t **);
453*7c478bd9Sstevel@tonic-gate extern cred_t   *nfs4_get_otw_cred_by_osp(rnode4_t *, cred_t *,
454*7c478bd9Sstevel@tonic-gate 			nfs4_open_stream_t **, bool_t *, bool_t *);
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate 
457*7c478bd9Sstevel@tonic-gate /*
458*7c478bd9Sstevel@tonic-gate  * Defines for the flag argument of nfs4delegreturn
459*7c478bd9Sstevel@tonic-gate  */
460*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_FORCE	0x1	/* discard even if start_op fails */
461*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_PUSH	0x2	/* push modified data back to the server */
462*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_DISCARD	0x4	/* discard the delegation w/o delegreturn */
463*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_DID_OP	0x8	/* calling function did nfs4_start_op */
464*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_RECALL	0x10	/* delegreturn done in response to CB_RECALL */
465*7c478bd9Sstevel@tonic-gate #define	NFS4_DR_REOPEN	0x20	/* perform file reopens, if applicable */
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate extern int nfs4delegreturn(rnode4_t *, int);
468*7c478bd9Sstevel@tonic-gate extern void	nfs4_delegreturn_all(nfs4_server_t *);
469*7c478bd9Sstevel@tonic-gate extern void	nfs4delegreturn_cleanup(rnode4_t *, nfs4_server_t *);
470*7c478bd9Sstevel@tonic-gate extern void nfs4_delegation_accept(rnode4_t *, open_claim_type4, OPEN4res *,
471*7c478bd9Sstevel@tonic-gate 		nfs4_ga_res_t *, cred_t *);
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate extern void	nfs4_dlistclean(void);
474*7c478bd9Sstevel@tonic-gate extern void	nfs4_deleg_discard(mntinfo4_t *, nfs4_server_t *);
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate extern void	rddir4_cache_create(rnode4_t *);
477*7c478bd9Sstevel@tonic-gate extern void	rddir4_cache_purge(rnode4_t *);
478*7c478bd9Sstevel@tonic-gate extern void	rddir4_cache_destroy(rnode4_t *);
479*7c478bd9Sstevel@tonic-gate extern rddir4_cache *rddir4_cache_lookup(rnode4_t *, offset_t, int);
480*7c478bd9Sstevel@tonic-gate extern void	rddir4_cache_rele(rnode4_t *, rddir4_cache *);
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
483*7c478bd9Sstevel@tonic-gate extern char	*rddir4_cache_buf_alloc(size_t, int);
484*7c478bd9Sstevel@tonic-gate extern void	rddir4_cache_buf_free(void *, size_t);
485*7c478bd9Sstevel@tonic-gate #endif
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 
488*7c478bd9Sstevel@tonic-gate 
489*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
490*7c478bd9Sstevel@tonic-gate 
491*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
492*7c478bd9Sstevel@tonic-gate }
493*7c478bd9Sstevel@tonic-gate #endif
494*7c478bd9Sstevel@tonic-gate 
495*7c478bd9Sstevel@tonic-gate #endif	/* _NFS_RNODE4_H */
496