author | thurlow |
Mon, 13 Mar 2006 17:10:47 -0800 | |
changeset 1610 | 3436e82414c8 |
parent 1232 | 1a9b1651d839 |
child 2035 | a29bc457bcb9 |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1610
3436e82414c8
6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents:
1232
diff
changeset
|
5 |
* Common Development and Distribution License (the "License"). |
3436e82414c8
6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents:
1232
diff
changeset
|
6 |
* You may not use this file except in compliance with the License. |
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
21 |
/* |
|
1232 | 22 |
* Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
0 | 23 |
* Use is subject to license terms. |
24 |
*/ |
|
25 |
||
26 |
#ifndef _NFS4_H |
|
27 |
#define _NFS4_H |
|
28 |
||
29 |
#pragma ident "%Z%%M% %I% %E% SMI" |
|
30 |
||
31 |
#include <sys/types.h> |
|
32 |
#include <sys/vnode.h> |
|
33 |
#include <sys/fem.h> |
|
34 |
#include <rpc/rpc.h> |
|
35 |
#include <nfs/nfs.h> |
|
36 |
||
37 |
#ifdef _KERNEL |
|
38 |
#include <nfs/nfs4_kprot.h> |
|
39 |
#else |
|
40 |
#include <rpcsvc/nfs4_prot.h> |
|
41 |
#endif |
|
42 |
#include <nfs/nfs4_attr.h> |
|
43 |
#include <sys/acl.h> |
|
44 |
||
45 |
#ifdef __cplusplus |
|
46 |
extern "C" { |
|
47 |
#endif |
|
48 |
||
49 |
#define NFS4_MAX_UTF8STRING 65536 |
|
50 |
#define NFS4_MAX_PATHNAME4 65536 |
|
51 |
#define NFS4_MAX_SECOID4 65536 |
|
52 |
||
53 |
#ifdef _KERNEL |
|
54 |
||
55 |
typedef struct nfs4_fhandle { |
|
56 |
int fh_len; |
|
57 |
char fh_buf[NFS4_FHSIZE]; |
|
58 |
} nfs4_fhandle_t; |
|
59 |
||
60 |
#define NFS4_MINORVERSION 0 |
|
61 |
#define CB4_MINORVERSION 0 |
|
62 |
||
63 |
/* |
|
64 |
* Set the fattr4_change variable using a time struct. Note that change |
|
65 |
* is 64 bits, but timestruc_t is 128 bits in a 64-bit kernel. |
|
66 |
*/ |
|
67 |
#define NFS4_SET_FATTR4_CHANGE(change, ts) \ |
|
68 |
{ \ |
|
69 |
change = (ts).tv_sec; \ |
|
70 |
change <<= 32; \ |
|
71 |
change |= (uint32_t)((ts).tv_nsec); \ |
|
72 |
} |
|
73 |
||
74 |
/* |
|
75 |
* Server lease period. Value is in seconds; Also used for grace period |
|
76 |
*/ |
|
77 |
extern time_t rfs4_lease_time; |
|
78 |
||
79 |
/* |
|
80 |
* This set of typedefs and interfaces represent the core or base set |
|
81 |
* of functionality that backs the NFSv4 server's state related data |
|
82 |
* structures. Since the NFSv4 server needs inter-RPC state to be |
|
83 |
* available that is unrelated to the filesystem (in other words, |
|
84 |
* soft-state), this functionality is needed to maintain that and is |
|
85 |
* written to be somewhat flexible to adapt to the various types of |
|
86 |
* data structures contained within the server. |
|
87 |
* |
|
88 |
* The basic structure at this level is that the server maintains a |
|
89 |
* global "database" which consists of a set of tables. Each table |
|
90 |
* contains a set of like data structures. Each table is indexed by |
|
91 |
* at least one hash function and in most cases two hashes. Each |
|
92 |
* table's characteristics is set when it is created at run-time via |
|
93 |
* rfs4_table_create(). All table creation and related functions are |
|
94 |
* located in nfs4_state.c. The generic database functionality is |
|
95 |
* located in nfs4_db.c. |
|
96 |
*/ |
|
97 |
||
98 |
typedef struct rfs4_dbe rfs4_dbe_t; /* basic opaque db entry */ |
|
99 |
typedef struct rfs4_table rfs4_table_t; /* basic table type */ |
|
100 |
typedef struct rfs4_index rfs4_index_t; /* index */ |
|
101 |
typedef struct rfs4_database rfs4_database_t; /* and database */ |
|
102 |
||
103 |
typedef struct { /* opaque entry type for later use */ |
|
104 |
rfs4_dbe_t *dbe; |
|
105 |
} *rfs4_entry_t; |
|
106 |
||
107 |
extern rfs4_table_t *rfs4_client_tab; |
|
108 |
||
109 |
/* database, table, index creation entry points */ |
|
110 |
extern rfs4_database_t *rfs4_database_create(uint32_t); |
|
111 |
extern void rfs4_database_shutdown(rfs4_database_t *); |
|
112 |
extern void rfs4_database_destroy(rfs4_database_t *); |
|
113 |
||
114 |
extern void rfs4_database_destroy(rfs4_database_t *); |
|
115 |
||
116 |
extern rfs4_table_t *rfs4_table_create(rfs4_database_t *, char *, |
|
117 |
time_t, uint32_t, |
|
118 |
bool_t (*create)(rfs4_entry_t, void *), |
|
119 |
void (*destroy)(rfs4_entry_t), |
|
120 |
bool_t (*expiry)(rfs4_entry_t), |
|
121 |
uint32_t, uint32_t, uint32_t, id_t); |
|
122 |
extern void rfs4_table_destroy(rfs4_database_t *, rfs4_table_t *); |
|
123 |
extern rfs4_index_t *rfs4_index_create(rfs4_table_t *, char *, |
|
124 |
uint32_t (*hash)(void *), |
|
125 |
bool_t (compare)(rfs4_entry_t, void *), |
|
126 |
void *(*mkkey)(rfs4_entry_t), bool_t); |
|
127 |
extern void rfs4_index_destroy(rfs4_index_t *); |
|
128 |
||
129 |
/* Type used to direct rfs4_dbsearch() in what types of records to inspect */ |
|
130 |
typedef enum {RFS4_DBS_VALID, RFS4_DBS_INVALID} rfs4_dbsearch_type_t; |
|
131 |
/* search and db entry manipulation entry points */ |
|
132 |
extern rfs4_entry_t rfs4_dbsearch(rfs4_index_t *, void *, |
|
133 |
bool_t *, void *, rfs4_dbsearch_type_t); |
|
134 |
extern void rfs4_dbe_lock(rfs4_dbe_t *); |
|
135 |
extern void rfs4_dbe_unlock(rfs4_dbe_t *); |
|
136 |
extern clock_t rfs4_dbe_twait(rfs4_dbe_t *, clock_t); |
|
137 |
extern void rfs4_dbe_cv_broadcast(rfs4_dbe_t *); |
|
138 |
extern void rfs4_dbe_hold(rfs4_dbe_t *); |
|
139 |
extern void rfs4_dbe_hold_nolock(rfs4_dbe_t *); |
|
140 |
extern void rfs4_dbe_rele_nolock(rfs4_dbe_t *); |
|
141 |
extern void rfs4_dbe_rele(rfs4_dbe_t *); |
|
142 |
extern uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *); |
|
143 |
extern id_t rfs4_dbe_getid(rfs4_dbe_t *); |
|
144 |
extern void rfs4_dbe_invalidate(rfs4_dbe_t *); |
|
145 |
extern bool_t rfs4_dbe_is_invalid(rfs4_dbe_t *); |
|
146 |
extern time_t rfs4_dbe_get_timerele(rfs4_dbe_t *); |
|
147 |
extern void rfs4_dbe_hide(rfs4_dbe_t *); |
|
148 |
extern void rfs4_dbe_unhide(rfs4_dbe_t *); |
|
149 |
#ifdef DEBUG |
|
150 |
extern bool_t rfs4_dbe_islocked(rfs4_dbe_t *); |
|
151 |
#endif |
|
152 |
extern void rfs4_dbe_walk(rfs4_table_t *, |
|
153 |
void (*callout)(rfs4_entry_t, void *), void *); |
|
154 |
||
155 |
/* |
|
156 |
* Minimal server stable storage. |
|
157 |
* |
|
158 |
* Currently the NFSv4 server will only save the client |
|
159 |
* ID (the long version) so that it will be able to |
|
160 |
* grant possible reclaim requests during the infamous |
|
161 |
* grace_period. |
|
162 |
*/ |
|
163 |
||
164 |
#define RFS4_SS_DIRSIZE 64 * 1024 |
|
165 |
#define NFS4_SS_VERSION 1 |
|
166 |
||
167 |
/* handy pathname structure */ |
|
168 |
typedef struct ss_pn { |
|
169 |
char *leaf; |
|
170 |
char pn[MAXPATHLEN]; |
|
171 |
} rfs4_ss_pn_t; |
|
172 |
||
173 |
/* |
|
174 |
* The server will build this link list on startup. It represents the |
|
175 |
* clients that have had valid state on the server in a prior instance. |
|
176 |
* |
|
177 |
*/ |
|
178 |
typedef struct rfs4_oldstate { |
|
179 |
struct rfs4_oldstate *next; |
|
180 |
struct rfs4_oldstate *prev; |
|
181 |
rfs4_ss_pn_t *ss_pn; |
|
182 |
nfs_client_id4 cl_id4; |
|
183 |
} rfs4_oldstate_t; |
|
184 |
||
185 |
/* |
|
186 |
* This union is used to overlay the server's internal treatment of |
|
187 |
* the protocols stateid4 datatype. Therefore, "bits" must not exceed |
|
188 |
* the size of stateid4 and more importantly should match the size of |
|
189 |
* stateid4. The chgseq field must the first entry since it overlays |
|
190 |
* stateid4.seqid. |
|
191 |
*/ |
|
192 |
typedef union { |
|
193 |
stateid4 stateid; |
|
194 |
struct { |
|
195 |
uint32_t chgseq; /* State changes / protocol's seqid */ |
|
196 |
uint32_t boottime; /* boot time */ |
|
197 |
uint32_t type:2; /* stateid_type_t as define below */ |
|
198 |
uint32_t clnodeid:8; /* cluster server nodeid */ |
|
199 |
uint32_t ident:22; /* 2^22-1 openowner x fhs */ |
|
200 |
pid_t pid; /* pid of corresponding lock owner */ |
|
201 |
} bits; |
|
202 |
} stateid_t; |
|
203 |
/* |
|
204 |
* Note that the way the type field above is defined, this enum must |
|
205 |
* not have more than 4 members. |
|
206 |
*/ |
|
207 |
typedef enum {OPENID, LOCKID, DELEGID} stateid_type_t; |
|
208 |
||
209 |
||
210 |
/* |
|
211 |
* Set of RPC credentials used for a particular operation. |
|
212 |
* Used for operations like SETCLIENTID_CONFIRM where the |
|
213 |
* credentials needs to match those used at SETCLIENTID. |
|
214 |
*/ |
|
215 |
typedef void *cred_set_t; /* For now XXX */ |
|
216 |
||
217 |
/* |
|
218 |
* "wait" struct for use in the open open and lock owner state |
|
219 |
* structures to provide serialization between server threads that are |
|
220 |
* handling requests for the same open owner or lock stateid. This |
|
221 |
* way only one thread will be updating things like sequence ids, |
|
222 |
* replay cache and stateid at a time. |
|
223 |
*/ |
|
224 |
typedef struct rfs4_state_wait { |
|
225 |
uint32_t sw_active; |
|
226 |
uint32_t sw_wait_count; |
|
227 |
kmutex_t sw_cv_lock[1]; |
|
228 |
kcondvar_t sw_cv[1]; |
|
229 |
} rfs4_state_wait_t; |
|
230 |
||
231 |
extern void rfs4_sw_enter(rfs4_state_wait_t *); |
|
232 |
extern void rfs4_sw_exit(rfs4_state_wait_t *); |
|
233 |
||
234 |
/* |
|
235 |
* This enum and the following rfs4_cbinfo_t struct are used to |
|
236 |
* maintain information about the callback path used from the server |
|
237 |
* to client for operations like CB_GETATTR and CB_RECALL. The |
|
238 |
* rfs4_cbinfo_t struct is meant to be encompassed in the client |
|
239 |
* struct and managed within that structure's locking scheme. |
|
240 |
* |
|
241 |
* The various states of the callback path are used by the server to |
|
242 |
* determine if delegations should initially be provided to a client |
|
243 |
* and then later on if connectivity has been lost and delegations |
|
244 |
* should be revoked. |
|
245 |
*/ |
|
246 |
||
247 |
/* |
|
248 |
* CB_NOCHANGE - Special value used for interfaces within the delegation |
|
249 |
* code to signify that "no change" has occurred to the |
|
250 |
* callback path |
|
251 |
* CB_UNINIT - No callback info provided by the client |
|
252 |
* CB_NONE - Callback info provided but CB_NULL call |
|
253 |
* has yet to be attempted |
|
254 |
* CB_OK - Callback path tested with CB_NULL with success |
|
255 |
* CB_INPROG - Callback path currently being tested with CB_NULL |
|
256 |
* CB_FAILED - Callback path was == CB_OK but has failed |
|
257 |
* with timeout/rpc error |
|
258 |
* CB_BAD - Callback info provided but CB_NULL failed |
|
259 |
*/ |
|
260 |
typedef enum { |
|
261 |
CB_NOCHANGE = 0, |
|
262 |
CB_UNINIT = 1, |
|
263 |
CB_NONE = 2, |
|
264 |
CB_OK = 3, |
|
265 |
CB_INPROG = 4, |
|
266 |
CB_FAILED = 5, |
|
267 |
CB_BAD = 6 |
|
268 |
} rfs4_cbstate_t; |
|
269 |
||
270 |
#define RFS4_CBCH_MAX 10 /* size callback client handle cache */ |
|
271 |
/* |
|
272 |
* Callback info for a client. |
|
273 |
* Client only provides: cb_client4 and cb_ident |
|
274 |
* The rest of the information is used to track callback path status |
|
275 |
* and usage. |
|
276 |
* |
|
277 |
* cb_state - used as comments for the rfs4_cbstate_t enum indicate |
|
278 |
* cb_notified_of_cb_path_down - if the callback path was once CB_OK and |
|
279 |
* has hence CB_FAILED, the client needs to be notified via RENEW. |
|
280 |
* cb_timefailed - current time when cb_state transitioned from |
|
281 |
* CB_OK -> CB_FAILED. Meant for observability. When did that happen? |
|
282 |
* cb_chc_free/cb_chc - cache of client handles for the callback path |
|
283 |
* cb_ident - SETCLIENTID provided callback_ident value |
|
284 |
* callback - SETCLIENTID provided cb_client4 value |
|
285 |
* cb_refcnt - current number of users of this structure's content |
|
286 |
* protected by cb_lock |
|
287 |
* cb_badbehavior - how many times did a client do something we didn't like? |
|
288 |
* cb_lock - lock for contents of cbinfo |
|
289 |
* cb_cv - used to allow threads to wait on CB_NULL completion |
|
290 |
* cb_nullcaller - is there a thread currently taking care of |
|
291 |
* new callback information? |
|
292 |
* cb_cv_nullcaller - used by the thread doing CB_NULL to wait on |
|
293 |
* threads that may be using client handles of the current |
|
294 |
* client handle cache. |
|
295 |
* newer - new callback info provided by a client and awaiting |
|
296 |
* CB_NULL testing and move to regular cbinfo. |
|
297 |
*/ |
|
298 |
typedef struct { |
|
299 |
rfs4_cbstate_t cb_state; |
|
300 |
unsigned cb_notified_of_cb_path_down:1; |
|
301 |
time_t cb_timefailed; |
|
302 |
int cb_chc_free; |
|
303 |
CLIENT *cb_chc[RFS4_CBCH_MAX]; |
|
304 |
uint32_t cb_ident; |
|
305 |
cb_client4 cb_callback; |
|
306 |
uint32_t cb_refcnt; |
|
307 |
uint32_t cb_badbehavior; |
|
308 |
kmutex_t cb_lock[1]; |
|
309 |
kcondvar_t cb_cv[1]; |
|
310 |
bool_t cb_nullcaller; |
|
311 |
kcondvar_t cb_cv_nullcaller[1]; |
|
312 |
struct { |
|
313 |
bool_t cb_new; |
|
314 |
bool_t cb_confirmed; |
|
315 |
uint32_t cb_ident; |
|
316 |
cb_client4 cb_callback; |
|
317 |
} cb_newer; |
|
318 |
} rfs4_cbinfo_t; |
|
319 |
||
320 |
/* |
|
321 |
* A server instance. We can associate sets of clients - via a pointer in |
|
322 |
* rfs4_client_t - with a given server instance, allowing us to treat clients |
|
323 |
* in the set differently to clients in other sets. |
|
324 |
* |
|
325 |
* Currently used only for Sun Cluster HA-NFS support, to group clients |
|
326 |
* on NFS resource failover so each set of clients gets its own dedicated |
|
327 |
* grace period. |
|
328 |
*/ |
|
329 |
typedef struct rfs4_servinst { |
|
330 |
krwlock_t rwlock; |
|
331 |
time_t start_time; |
|
332 |
time_t grace_period; |
|
333 |
struct rfs4_servinst *next; |
|
334 |
struct rfs4_servinst *prev; |
|
335 |
} rfs4_servinst_t; |
|
336 |
||
337 |
/* |
|
338 |
* List declarations (suitable for insque/remque) used to link the |
|
339 |
* various datastructs listed below. |
|
340 |
*/ |
|
341 |
typedef struct rfs4_state_list { |
|
342 |
struct rfs4_state_list *next; |
|
343 |
struct rfs4_state_list *prev; |
|
344 |
struct rfs4_state *sp; |
|
345 |
} rfs4_state_list_t; |
|
346 |
||
347 |
typedef struct rfs4_lo_state_list { |
|
348 |
struct rfs4_lo_state_list *next; |
|
349 |
struct rfs4_lo_state_list *prev; |
|
350 |
struct rfs4_lo_state *lsp; |
|
351 |
} rfs4_lo_state_list_t; |
|
352 |
||
353 |
typedef struct rfs4_openowner_list { |
|
354 |
struct rfs4_openowner_list *next; |
|
355 |
struct rfs4_openowner_list *prev; |
|
356 |
struct rfs4_openowner *oop; |
|
357 |
} rfs4_openowner_list_t; |
|
358 |
||
359 |
typedef struct rfs4_deleg_list { |
|
360 |
struct rfs4_deleg_list *next; |
|
361 |
struct rfs4_deleg_list *prev; |
|
362 |
struct rfs4_deleg_state *dsp; |
|
363 |
} rfs4_deleg_list_t; |
|
364 |
||
365 |
/* |
|
366 |
* The server maintains a set of state on a per client basis that |
|
367 |
* matches that of the protocol requirements. A client's state is |
|
368 |
* rooted with the rfs4_client_t struct of which there is one per |
|
369 |
* client and is created when SETCLIENTID/SETCLIENTID_CONFIRM are |
|
370 |
* received. From there, the server then creates rfs4_openowner_t |
|
371 |
* structs for each new open owner from that client and are initiated |
|
372 |
* at OPEN/OPEN_CONFIRM (when the open owner is new to the server). |
|
373 |
* At OPEN, at least two other structures are created, and potentially a |
|
374 |
* third. rfs4_state_t is created to track the association between an |
|
375 |
* open owner and a particular file. An rfs4_file_t struct may be |
|
376 |
* created (if the file is not already open) at OPEN as well. The |
|
377 |
* rfs4_file_t struct is the only one that is per server and not per |
|
378 |
* client. The rfs4_deleg_state_t struct is created in the |
|
379 |
* instance that the server is going to provide a delegation for the |
|
380 |
* file being OPENed. Finally, the rfs4_lockowner_t is created at the |
|
381 |
* first use of a lock owner at the server and is a result of the LOCK |
|
382 |
* operation. The rfs4_lo_state_t struct is then created to represent |
|
383 |
* the relation between the lock owner and the file. |
|
384 |
* |
|
385 |
*/ |
|
386 |
/* |
|
387 |
* The following ascii art represents each of these data structs and |
|
388 |
* their references to each other. Note: "<-(x)->" represents the |
|
389 |
* doubly link lists defined above. |
|
390 |
* |
|
391 |
* ____________________ |
|
392 |
* | | |
|
393 |
* | rfs4_client_t | |
|
394 |
* ->| (1),(2) |<- |
|
395 |
* / |____________________| \ |
|
396 |
* / ^ \ |
|
397 |
* / | \ |
|
398 |
* ____________________ ____________________ ____________________ |
|
399 |
* | | | | | | |
|
400 |
* | rfs4_lockowner_t | | rfs4_openowner_t | | rfs4_deleg_state_t | |
|
401 |
* | | | (3) <-(1)-> | | <-(2)-> | |
|
402 |
* |____________________| |____________________| |____________________| |
|
403 |
* ^ ^ | |
|
404 |
* | | V |
|
405 |
* ____________________ ____________________ ____________________ |
|
406 |
* | | | | | | |
|
407 |
* | rfs4_lo_state_t |->| rfs4_state_t |->| rfs4_file_t | |
|
408 |
* | <-(4)-> | | (4) <-(3)-> | | | |
|
409 |
* |____________________| |____________________| |____________________| |
|
410 |
*/ |
|
411 |
/* |
|
412 |
* Each of these data types are kept in a separate rfs4_table_t and is |
|
413 |
* actually encapsulated within a rfs4_dbe_t struct. The various |
|
414 |
* tables and their construction is done in nfs4_state.c but |
|
415 |
* documented here to completeness. |
|
416 |
* |
|
417 |
* Table Data struct stored Indexed by |
|
418 |
* ----- ------------------ ---------- |
|
419 |
* rfs4_client_tab rfs4_client_t nfs_client_id4 |
|
420 |
* clientid4 |
|
421 |
* |
|
422 |
* rfs4_openowner_tab rfs4_openowner_t open_owner4 |
|
423 |
* |
|
424 |
* rfs4_state_tab rfs4_state_t open_owner4 | file |
|
425 |
* stateid |
|
426 |
* |
|
427 |
* rfs4_lo_state_tab rfs4_lo_state_t lockowner | stateid |
|
428 |
* lock_stateid |
|
429 |
* |
|
430 |
* rfs4_lockowner_tab rfs4_lockowner_t lockowner |
|
431 |
* pid |
|
432 |
* |
|
433 |
* rfs4_file_tab rfs4_file_t filehandle |
|
434 |
* |
|
435 |
* rfs4_deleg_state_tab rfs4_deleg_state_t clientid4 | file |
|
436 |
* deleg_stateid |
|
437 |
*/ |
|
438 |
||
439 |
/* |
|
440 |
* The client struct, it is the root of all state for a particular |
|
441 |
* client. The client is identified by the nfs_client_id4 via |
|
442 |
* SETCLIENTID and the server returns the clientid4 as short hand reference |
|
443 |
*/ |
|
444 |
/* |
|
445 |
* Client struct - as mentioned above it is the root of all state for |
|
446 |
* a single client as identified by the client supplied nfs_client_id4 |
|
447 |
* |
|
448 |
* dbe - encapsulation struct |
|
449 |
* clientid - server assigned short hand reference to client |
|
450 |
* nfs_client - client supplied identifier for itself |
|
451 |
* confirm_verf - the value provided to the client for SETCLIENTID_CONFIRM |
|
452 |
* need_confirm - does this client need to be SETCLIENTID_CONFIRMed? |
|
453 |
* |
|
454 |
* unlksys_completed - has an F_UNLKSYS been done for this client which |
|
455 |
* says that the use of cleanlocks() on individual files |
|
456 |
* is not required? |
|
457 |
* can_reclaim - indicates if client is allowed to reclaim after server |
|
458 |
* start-up (client had previous state at server) |
|
459 |
* ss_remove - indicates that the rfs4_client_destroy function should |
|
460 |
* clean up stable storage file. |
|
461 |
* forced_expire - set if the sysadmin has used clear_locks for this client. |
|
462 |
* deleg_revoked - how many delegations have been revoked for this client? |
|
463 |
* |
|
464 |
* cp_confirmed - this refers to a confirmed client struct that has |
|
465 |
* the same nfs_client_id4 as this client struct. When/if this client |
|
466 |
* struct is confirmed via SETCLINETID_CONFIRM, the previously |
|
467 |
* confirmed client struct will be "closed" and hence this reference. |
|
468 |
* |
|
469 |
* last_access - used to determine if the client has let its lease expire |
|
470 |
* cbinfo - struct containing all callback related information |
|
471 |
* cr_set - credentials used for the SETCLIENTID/SETCLIENTID_CONFIRM pair |
|
472 |
* sysid - the lock manager sysid allocated for this client's file locks |
|
473 |
* openownerlist - root of openowners list associated with this client |
|
474 |
* clientdeleglist - root of delegations list provided to this client |
|
475 |
* ss_pn - Pathname to the stable storage file. |
|
476 |
* cl_addr - Clients network address. |
|
477 |
* server_instance - pointer to the currently associated server instance |
|
478 |
*/ |
|
479 |
typedef struct rfs4_client { |
|
480 |
rfs4_dbe_t *dbe; |
|
481 |
clientid4 clientid; |
|
482 |
nfs_client_id4 nfs_client; |
|
483 |
verifier4 confirm_verf; |
|
484 |
unsigned need_confirm:1; |
|
485 |
unsigned unlksys_completed:1; |
|
486 |
unsigned can_reclaim:1; |
|
487 |
unsigned ss_remove:1; |
|
488 |
unsigned forced_expire:1; |
|
489 |
uint_t deleg_revoked; |
|
490 |
struct rfs4_client *cp_confirmed; |
|
491 |
time_t last_access; |
|
492 |
rfs4_cbinfo_t cbinfo; |
|
493 |
cred_set_t cr_set; |
|
494 |
sysid_t sysidt; |
|
495 |
rfs4_openowner_list_t openownerlist; |
|
496 |
rfs4_deleg_list_t clientdeleglist; |
|
497 |
rfs4_ss_pn_t *ss_pn; |
|
498 |
struct sockaddr_storage cl_addr; |
|
499 |
rfs4_servinst_t *server_instance; |
|
500 |
} rfs4_client_t; |
|
501 |
||
502 |
/* |
|
503 |
* The openowner contains the client supplied open_owner4 as well as |
|
504 |
* the matching sequence id and is used to track the client's usage of |
|
505 |
* the open_owner4. Note that a reply is saved here as well for |
|
506 |
* processing of retransmissions. |
|
507 |
* |
|
508 |
* dbe - encapsulation struct |
|
509 |
* client - reference to rfs4_client_t for this openowner |
|
510 |
* owner - actual client supplied open_owner4 |
|
511 |
* need_confirm - does this openowner need to be OPEN_CONFIRMed |
|
512 |
* postpone_confirm - set if error received on first use of open_owner |
|
513 |
* state2confirm - what stateid4 should be used on the OPEN_CONFIRM |
|
514 |
* open_seqid - what is the next open_seqid expected for this openowner |
|
515 |
* oo_sw - used to serialize access to the open seqid/reply handling |
|
516 |
* cr_set - credential used for the OPEN |
|
517 |
* ownerstateids - root of state struct list associated with this openowner |
|
518 |
* openownerlist - list of openowners for a client struct |
|
519 |
* reply_fh - open replay processing needs the filehandle so that it is |
|
520 |
* able to reset the current filehandle for appropriate compound |
|
521 |
* processing and reply. |
|
522 |
* reply - last reply sent in relation to this openowner |
|
523 |
*/ |
|
524 |
typedef struct rfs4_openowner { |
|
525 |
rfs4_dbe_t *dbe; |
|
526 |
rfs4_client_t *client; |
|
527 |
open_owner4 owner; |
|
528 |
unsigned need_confirm:1; |
|
529 |
unsigned postpone_confirm:1; |
|
530 |
seqid4 open_seqid; |
|
531 |
rfs4_state_wait_t oo_sw; |
|
532 |
cred_set_t cr_set; |
|
533 |
rfs4_state_list_t ownerstateids; |
|
534 |
rfs4_openowner_list_t openownerlist; |
|
535 |
nfs_fh4 reply_fh; |
|
536 |
nfs_resop4 reply[1]; |
|
537 |
} rfs4_openowner_t; |
|
538 |
||
539 |
/* |
|
540 |
* This state struct represents the association between an openowner |
|
541 |
* and a file that has been OPENed by that openowner. |
|
542 |
* |
|
543 |
* dbe - encapsulation struct |
|
544 |
* stateid - server provided stateid |
|
545 |
* owner - reference back to the openowner for this state |
|
546 |
* finfo - reference to the open file for this state |
|
547 |
* share_access - how did the openowner OPEN the file (access) |
|
548 |
* share_deny - how did the openowner OPEN the file (deny) |
|
549 |
* closed - has this file been closed? |
|
550 |
* lockownerlist - root of list of lockowners associated with this state/file |
|
551 |
* ownerstateids - list of state structs for an openowner |
|
552 |
*/ |
|
553 |
typedef struct rfs4_state { |
|
554 |
rfs4_dbe_t *dbe; |
|
555 |
stateid_t stateid; |
|
556 |
rfs4_openowner_t *owner; |
|
557 |
struct rfs4_file *finfo; |
|
558 |
uint32_t share_access; |
|
559 |
uint32_t share_deny; |
|
560 |
unsigned closed:1; |
|
561 |
rfs4_lo_state_list_t lockownerlist; |
|
562 |
rfs4_state_list_t ownerstateids; |
|
563 |
} rfs4_state_t; |
|
564 |
||
565 |
/* |
|
566 |
* Lockowner - track the lockowner and its related info |
|
567 |
* |
|
568 |
* dbe - encapsulation struct |
|
569 |
* client - reference to the client |
|
570 |
* owner - lockowner supplied by the client |
|
571 |
* pid - local identifier used for file locking |
|
572 |
*/ |
|
573 |
typedef struct rfs4_lockowner { |
|
574 |
rfs4_dbe_t *dbe; |
|
575 |
rfs4_client_t *client; |
|
576 |
lock_owner4 owner; |
|
577 |
pid_t pid; |
|
578 |
} rfs4_lockowner_t; |
|
579 |
||
580 |
/* |
|
581 |
* Lockowner_state associated with a state struct and lockowner |
|
582 |
* |
|
583 |
* dbe - encapsulation struct |
|
584 |
* state - reference back to state struct for open file |
|
585 |
* lockid - stateid for this lockowner/state |
|
586 |
* locker - reference to lockowner |
|
587 |
* seqid - sequence id for this lockowner/state |
|
588 |
* skip_seqid_check - used on initialization of struct |
|
589 |
* locks_cleaned - have all locks been released for this lockowner/file? |
|
590 |
* lock_completed - successful LOCK with lockowner/file? |
|
591 |
* ls_sw - used to serialize update seqid/reply/stateid handling |
|
592 |
* lockownerlist - list of lockowners for a state struct |
|
593 |
* reply - last reply sent in relation to this lockowner/state |
|
594 |
*/ |
|
595 |
typedef struct rfs4_lo_state { |
|
596 |
rfs4_dbe_t *dbe; |
|
597 |
rfs4_state_t *state; |
|
598 |
stateid_t lockid; |
|
599 |
rfs4_lockowner_t *locker; |
|
600 |
seqid4 seqid; |
|
601 |
unsigned skip_seqid_check:1; |
|
602 |
unsigned locks_cleaned:1; |
|
603 |
unsigned lock_completed:1; |
|
604 |
rfs4_state_wait_t ls_sw; |
|
605 |
rfs4_lo_state_list_t lockownerlist; |
|
606 |
nfs_resop4 reply[1]; |
|
607 |
} rfs4_lo_state_t; |
|
608 |
||
609 |
/* |
|
610 |
* Delegation state - per client |
|
611 |
* |
|
612 |
* dbe - encapsulation struct |
|
613 |
* dtype - type of delegation (NONE, READ, WRITE) |
|
614 |
* delegid - stateid for this delegation |
|
615 |
* time_granted - time this delegation was assigned to client |
|
616 |
* time_recalled - time when the server started recall process |
|
617 |
* time_revoked - if revoked, time that the revoke occurred |
|
618 |
* finfo - reference to the file associated with this delegation |
|
619 |
* client - reference to client for which this delegation is associated |
|
620 |
* delegationlist - list of delegations for the file (WRITE == 1, READ == ) |
|
621 |
* clientdeleglist - list of delegations for the client |
|
622 |
*/ |
|
623 |
typedef struct rfs4_deleg_state { |
|
624 |
rfs4_dbe_t *dbe; |
|
625 |
open_delegation_type4 dtype; |
|
626 |
stateid_t delegid; |
|
627 |
time_t time_granted; |
|
628 |
time_t time_recalled; |
|
629 |
time_t time_revoked; |
|
630 |
struct rfs4_file *finfo; |
|
631 |
rfs4_client_t *client; |
|
632 |
rfs4_deleg_list_t delegationlist; |
|
633 |
rfs4_deleg_list_t clientdeleglist; |
|
634 |
} rfs4_deleg_state_t; |
|
635 |
||
636 |
/* |
|
637 |
* Delegation info associated with the file |
|
638 |
* |
|
639 |
* dtype - type of delegation for file (NONE, READ, WRITE) |
|
640 |
* time_returned - time that last delegation was returned for file |
|
641 |
* time_recalled - time that recall sequence started |
|
642 |
* time_lastgrant - time that last delegation was provided to a client |
|
643 |
* time_lastwrite - time of last write to use the delegation stateid |
|
644 |
* time_rm_delayed - time of last remove/rename which was DELAYed |
|
645 |
* rdgrants - how many read delegations have been provided for this file |
|
646 |
* wrgrants - how many write delegations provided (can only be one) |
|
647 |
* recall_count - how many recall threads are outstanding |
|
648 |
* recall_lock - lock to protect contents of this struct |
|
649 |
* recall_cv - condition var for the "parent" thread to wait upon |
|
650 |
* deleg_change_grant - value for change attribute at time of write grant |
|
651 |
* deleg_change - most recent value of change obtained from client |
|
652 |
* deleg_change_ts - time of last deleg_change update |
|
653 |
* ever_recalled - has this particular delegation ever been recalled? |
|
654 |
* dont_grant - file deletion is impending, don't grant a delegation |
|
655 |
* conflicted_client - clientid of the client that caused a CB_RECALL |
|
656 |
* to occur. This is used for delegation policy (should a delegation |
|
657 |
* be granted shortly after it has been returned?) |
|
658 |
*/ |
|
659 |
typedef struct rfs4_dinfo { |
|
660 |
open_delegation_type4 dtype; |
|
661 |
time_t time_returned; |
|
662 |
time_t time_recalled; |
|
663 |
time_t time_lastgrant; |
|
664 |
time_t time_lastwrite; |
|
665 |
time_t time_rm_delayed; |
|
666 |
uint32_t rdgrants; |
|
667 |
uint32_t wrgrants; |
|
668 |
int32_t recall_count; |
|
669 |
kmutex_t recall_lock[1]; |
|
670 |
kcondvar_t recall_cv[1]; |
|
671 |
bool_t ever_recalled; |
|
672 |
uint32_t hold_grant; |
|
673 |
clientid4 conflicted_client; |
|
674 |
} rfs4_dinfo_t; |
|
675 |
||
676 |
/* |
|
677 |
* File |
|
678 |
* |
|
679 |
* dbe - encapsulation struct |
|
680 |
* vp - vnode for the file that is open or has a delegation |
|
681 |
* filehandle - the filehandle generated by the server for this file |
|
682 |
* delegationlist - root of delegation list for this file |
|
683 |
* dinfo - see struct definition above |
|
684 |
* share_deny - union of all deny modes on file |
|
685 |
* share_access - union of all access modes on file |
|
686 |
* access_read - count of read access |
|
687 |
* access_write - count of write access |
|
688 |
* deny_read - count of deny reads |
|
689 |
* deny_write - count of deny writes |
|
690 |
* file_rwlock - lock for serializing the removal of a file while |
|
691 |
* the state structures are active within the server |
|
692 |
* |
|
693 |
* The only requirement for locking file_rwlock is that the |
|
694 |
* caller have a reference to the containing rfs4_file. The dbe |
|
695 |
* lock may or may not be held for lock/unlock of file_rwlock. |
|
696 |
* As mentioned above, the file_rwlock is used for serialization |
|
697 |
* of file removal and more specifically reference to the held |
|
698 |
* vnode (e.g. vp). |
|
699 |
*/ |
|
700 |
typedef struct rfs4_file { |
|
701 |
rfs4_dbe_t *dbe; |
|
702 |
vnode_t *vp; |
|
703 |
nfs_fh4 filehandle; |
|
704 |
rfs4_deleg_list_t delegationlist; |
|
705 |
rfs4_dinfo_t dinfo[1]; |
|
706 |
uint32_t share_deny; |
|
707 |
uint32_t share_access; |
|
708 |
uint32_t access_read; |
|
709 |
uint32_t access_write; |
|
710 |
uint32_t deny_read; |
|
711 |
uint32_t deny_write; |
|
712 |
krwlock_t file_rwlock; |
|
713 |
} rfs4_file_t; |
|
714 |
||
715 |
extern int rfs4_servinst_debug; |
|
716 |
extern int rfs4_seen_first_compound; /* set first time we see one */ |
|
717 |
||
718 |
extern rfs4_servinst_t *rfs4_cur_servinst; /* current server instance */ |
|
719 |
extern kmutex_t rfs4_servinst_lock; /* protects linked list */ |
|
720 |
extern void rfs4_servinst_create(int); |
|
721 |
extern void rfs4_servinst_destroy_all(void); |
|
722 |
extern void rfs4_servinst_assign(rfs4_client_t *, |
|
723 |
rfs4_servinst_t *); |
|
724 |
extern rfs4_servinst_t *rfs4_servinst(rfs4_client_t *); |
|
725 |
extern int rfs4_clnt_in_grace(rfs4_client_t *); |
|
726 |
extern int rfs4_servinst_in_grace(rfs4_servinst_t *); |
|
727 |
extern int rfs4_servinst_grace_new(rfs4_servinst_t *); |
|
728 |
extern void rfs4_grace_start(rfs4_servinst_t *); |
|
729 |
extern void rfs4_grace_start_new(void); |
|
730 |
extern void rfs4_grace_reset_all(void); |
|
731 |
||
732 |
/* |
|
733 |
* rfs4_deleg_policy is used to signify the server's global delegation |
|
734 |
* policy. The default is to NEVER delegate files and the |
|
735 |
* administrator must configure the server to enable delegations. |
|
736 |
* |
|
737 |
* The disable/enable delegation functions are used to eliminate a |
|
738 |
* race with exclusive creates. |
|
739 |
*/ |
|
740 |
typedef enum { |
|
741 |
SRV_NEVER_DELEGATE = 0, |
|
742 |
SRV_NORMAL_DELEGATE = 1 |
|
743 |
} srv_deleg_policy_t; |
|
744 |
||
745 |
extern srv_deleg_policy_t rfs4_deleg_policy; |
|
746 |
extern kmutex_t rfs4_deleg_lock; |
|
747 |
extern void rfs4_disable_delegation(void), rfs4_enable_delegation(void); |
|
748 |
||
749 |
/* |
|
750 |
* Request types for delegation. These correspond with |
|
751 |
* open_delegation_type4 with the addition of a new value, DELEG_ANY, |
|
752 |
* to reqequest any delegation. |
|
753 |
*/ |
|
754 |
typedef enum { |
|
755 |
DELEG_NONE = 0, /* Corresponds to OPEN_DELEG_NONE */ |
|
756 |
DELEG_READ = 1, /* Corresponds to OPEN_DELEG_READ */ |
|
757 |
DELEG_WRITE = 2, /* Corresponds to OPEN_DELEG_WRITE */ |
|
758 |
DELEG_ANY = -1 /* New value to request any delegation type */ |
|
759 |
} delegreq_t; |
|
760 |
||
761 |
#define NFS4_DELEG4TYPE2REQTYPE(x) (delegreq_t)(x) |
|
762 |
||
763 |
/* |
|
764 |
* Various interfaces to manipulate the state structures introduced |
|
765 |
* above |
|
766 |
*/ |
|
767 |
extern kmutex_t rfs4_state_lock; |
|
768 |
extern void rfs4_clean_state_exi(struct exportinfo *exi); |
|
769 |
extern void rfs4_free_reply(nfs_resop4 *); |
|
770 |
extern void rfs4_copy_reply(nfs_resop4 *, nfs_resop4 *); |
|
771 |
||
772 |
/* rfs4_client_t handling */ |
|
773 |
extern rfs4_client_t *rfs4_findclient(nfs_client_id4 *, |
|
774 |
bool_t *, rfs4_client_t *); |
|
775 |
extern rfs4_client_t *rfs4_findclient_by_id(clientid4, bool_t); |
|
776 |
extern void rfs4_client_rele(rfs4_client_t *); |
|
777 |
extern void rfs4_client_close(rfs4_client_t *); |
|
778 |
extern void rfs4_client_state_remove(rfs4_client_t *); |
|
779 |
extern void rfs4_client_scv_next(rfs4_client_t *); |
|
780 |
extern void rfs4_update_lease(rfs4_client_t *); |
|
781 |
extern bool_t rfs4_lease_expired(rfs4_client_t *); |
|
782 |
extern nfsstat4 rfs4_check_clientid(clientid4 *, int); |
|
783 |
||
784 |
/* rfs4_openowner_t handling */ |
|
785 |
extern rfs4_openowner_t *rfs4_findopenowner(open_owner4 *, bool_t *, seqid4); |
|
786 |
extern void rfs4_update_open_sequence(rfs4_openowner_t *); |
|
787 |
extern void rfs4_update_open_resp(rfs4_openowner_t *, |
|
788 |
nfs_resop4 *, nfs_fh4 *); |
|
789 |
extern void rfs4_openowner_rele(rfs4_openowner_t *); |
|
790 |
extern void rfs4_free_opens(rfs4_openowner_t *, bool_t, bool_t); |
|
791 |
||
792 |
/* rfs4_lockowner_t handling */ |
|
793 |
extern rfs4_lockowner_t *rfs4_findlockowner(lock_owner4 *, bool_t *); |
|
794 |
extern rfs4_lockowner_t *rfs4_findlockowner_by_pid(pid_t); |
|
795 |
extern void rfs4_lockowner_rele(rfs4_lockowner_t *); |
|
796 |
||
797 |
/* rfs4_state_t handling */ |
|
798 |
extern rfs4_state_t *rfs4_findstate_by_owner_file(rfs4_openowner_t *, |
|
799 |
rfs4_file_t *, bool_t *); |
|
800 |
extern void rfs4_state_rele(rfs4_state_t *); |
|
801 |
extern void rfs4_state_close(rfs4_state_t *, bool_t, |
|
802 |
bool_t, cred_t *); |
|
803 |
extern void rfs4_release_share_lock_state(rfs4_state_t *, |
|
804 |
cred_t *, bool_t); |
|
805 |
extern void rfs4_close_all_state(rfs4_file_t *); |
|
806 |
||
807 |
/* rfs4_lo_state_t handling */ |
|
808 |
extern rfs4_lo_state_t *rfs4_findlo_state_by_owner(rfs4_lockowner_t *, |
|
809 |
rfs4_state_t *, bool_t *); |
|
810 |
extern void rfs4_lo_state_rele(rfs4_lo_state_t *, bool_t); |
|
811 |
extern void rfs4_update_lock_sequence(rfs4_lo_state_t *); |
|
812 |
extern void rfs4_update_lock_resp(rfs4_lo_state_t *, |
|
813 |
nfs_resop4 *); |
|
814 |
||
815 |
/* rfs4_file_t handling */ |
|
816 |
extern rfs4_file_t *rfs4_findfile(vnode_t *, nfs_fh4 *, bool_t *); |
|
817 |
extern rfs4_file_t *rfs4_findfile_withlock(vnode_t *, nfs_fh4 *, |
|
818 |
bool_t *); |
|
819 |
extern void rfs4_file_rele(rfs4_file_t *); |
|
820 |
extern void rfs4_file_rele_withunlock(rfs4_file_t *); |
|
821 |
||
822 |
/* General collection of "get state" functions */ |
|
823 |
extern nfsstat4 rfs4_get_state(stateid4 *, rfs4_state_t **, |
|
824 |
rfs4_dbsearch_type_t); |
|
825 |
extern nfsstat4 rfs4_get_deleg_state(stateid4 *, |
|
826 |
rfs4_deleg_state_t **); |
|
827 |
extern nfsstat4 rfs4_get_lo_state(stateid4 *, rfs4_lo_state_t **, |
|
828 |
bool_t); |
|
829 |
extern nfsstat4 rfs4_check_stateid(int, vnode_t *, stateid4 *, |
|
830 |
bool_t, bool_t *, bool_t); |
|
831 |
extern int rfs4_check_stateid_seqid(rfs4_state_t *, stateid4 *); |
|
832 |
extern int rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *, |
|
833 |
stateid4 *); |
|
834 |
||
835 |
/* return values for rfs4_check_stateid_seqid() */ |
|
836 |
#define NFS4_CHECK_STATEID_OKAY 1 |
|
837 |
#define NFS4_CHECK_STATEID_OLD 2 |
|
838 |
#define NFS4_CHECK_STATEID_BAD 3 |
|
839 |
#define NFS4_CHECK_STATEID_EXPIRED 4 |
|
840 |
#define NFS4_CHECK_STATEID_REPLAY 5 |
|
841 |
#define NFS4_CHECK_STATEID_CLOSED 6 |
|
842 |
#define NFS4_CHECK_STATEID_UNCONFIRMED 7 |
|
843 |
||
844 |
/* delay() time that server is willing to briefly wait for a delegreturn */ |
|
845 |
#define NFS4_DELEGATION_CONFLICT_DELAY (hz/10) |
|
846 |
||
847 |
/* |
|
848 |
* Interfaces for handling of callback's client handle cache and |
|
849 |
* callback interfaces themselves. |
|
850 |
*/ |
|
851 |
extern void rfs4_cbinfo_free(rfs4_cbinfo_t *); |
|
852 |
extern void rfs4_client_setcb(rfs4_client_t *, cb_client4 *, |
|
853 |
uint32_t); |
|
854 |
extern void rfs4_deleg_cb_check(rfs4_client_t *); |
|
855 |
extern nfsstat4 rfs4_vop_getattr(vnode_t *, vattr_t *, int, cred_t *); |
|
856 |
||
857 |
/* rfs4_deleg_state_t handling and other delegation interfaces */ |
|
858 |
extern rfs4_deleg_state_t *rfs4_finddeleg(rfs4_state_t *, bool_t *); |
|
859 |
extern rfs4_deleg_state_t *rfs4_finddelegstate(stateid_t *); |
|
860 |
extern bool_t rfs4_check_recall(rfs4_state_t *, uint32_t); |
|
861 |
extern void rfs4_recall_deleg(rfs4_file_t *, |
|
862 |
bool_t, rfs4_client_t *); |
|
863 |
extern int rfs4_get_deleg(rfs4_state_t *, open_delegation_type4, |
|
864 |
open_delegation_type4 (*policy)(rfs4_state_t *, |
|
865 |
open_delegation_type4 dtype)); |
|
866 |
extern rfs4_deleg_state_t *rfs4_grant_delegation(delegreq_t, rfs4_state_t *, |
|
867 |
int *); |
|
868 |
extern void rfs4_set_deleg_response(rfs4_deleg_state_t *, |
|
869 |
open_delegation4 *, nfsace4 *, int); |
|
870 |
extern void rfs4_return_deleg(rfs4_deleg_state_t *, bool_t); |
|
871 |
extern bool_t rfs4_is_deleg(rfs4_state_t *); |
|
872 |
extern void rfs4_deleg_state_rele(rfs4_deleg_state_t *); |
|
873 |
extern bool_t rfs4_check_delegated_byfp(int, rfs4_file_t *, |
|
874 |
bool_t, bool_t, bool_t, clientid4 *); |
|
875 |
extern void rfs4_clear_dont_grant(rfs4_file_t *); |
|
876 |
||
877 |
/* |
|
878 |
* nfs4 monitored operations. |
|
879 |
*/ |
|
880 |
extern int deleg_rdopen(femarg_t *, int, cred_t *); |
|
881 |
extern int deleg_wropen(femarg_t *, int, cred_t *); |
|
882 |
extern int deleg_rd_rwlock(femarg_t *, int, caller_context_t *); |
|
883 |
extern int deleg_wr_rwlock(femarg_t *, int, caller_context_t *); |
|
884 |
extern int deleg_read(femarg_t *, uio_t *, int, cred_t *, caller_context_t *); |
|
885 |
extern int deleg_write(femarg_t *, uio_t *, int, cred_t *, caller_context_t *); |
|
886 |
extern int deleg_setattr(femarg_t *, vattr_t *, int, cred_t *, |
|
887 |
caller_context_t *); |
|
888 |
extern int deleg_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *, |
|
889 |
caller_context_t *); |
|
890 |
extern int deleg_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *); |
|
891 |
extern int deleg_vnevent(femarg_t *, vnevent_t); |
|
892 |
||
893 |
extern void rfs4_mon_hold(void *); |
|
894 |
extern void rfs4_mon_rele(void *); |
|
895 |
||
896 |
extern fem_t *deleg_rdops; |
|
897 |
extern fem_t *deleg_wrops; |
|
898 |
||
899 |
extern void rfs4_unshare(rfs4_state_t *); |
|
900 |
extern void rfs4_set_deleg_policy(srv_deleg_policy_t); |
|
901 |
#ifdef DEBUG |
|
902 |
#define NFS4_DEBUG(var, args) if (var) cmn_err args |
|
903 |
||
904 |
extern int rfs4_debug; |
|
905 |
extern int nfs4_client_attr_debug; |
|
906 |
extern int nfs4_client_state_debug; |
|
907 |
extern int nfs4_client_shadow_debug; |
|
908 |
extern int nfs4_client_lock_debug; |
|
909 |
extern int nfs4_client_lease_debug; |
|
910 |
extern int nfs4_seqid_sync; |
|
911 |
extern int nfs4_client_map_debug; |
|
912 |
extern int nfs4_client_inactive_debug; |
|
913 |
extern int nfs4_client_recov_debug; |
|
914 |
extern int nfs4_client_recov_stub_debug; |
|
915 |
extern int nfs4_client_failover_debug; |
|
916 |
extern int nfs4_client_call_debug; |
|
917 |
extern int nfs4_client_foo_debug; |
|
918 |
extern int nfs4_client_zone_debug; |
|
919 |
extern int nfs4_lost_rqst_debug; |
|
920 |
extern int nfs4_open_stream_debug; |
|
921 |
extern int nfs4_client_open_dg; |
|
922 |
extern int nfs4_srvmnt_debug; |
|
923 |
extern int nfs4_utf8_debug; |
|
924 |
||
925 |
void rfs4_dbe_debug(rfs4_dbe_t *e); |
|
926 |
||
927 |
#ifdef NFS4_DEBUG_MUTEX |
|
928 |
void nfs4_debug_mutex_enter(kmutex_t *, char *, int); |
|
929 |
void nfs4_debug_mutex_exit(kmutex_t *, char *, int); |
|
930 |
||
931 |
#define mutex_enter(m) nfs4_debug_mutex_enter((m), __FILE__, __LINE__) |
|
932 |
#define mutex_exit(m) nfs4_debug_mutex_exit((m), __FILE__, __LINE__) |
|
933 |
#endif /* NFS4_DEBUG_MUTEX */ |
|
934 |
||
935 |
#else /* ! DEBUG */ |
|
936 |
#define NFS4_DEBUG(var, args) |
|
937 |
#endif /* DEBUG */ |
|
938 |
||
939 |
/* |
|
940 |
* XXX - temporary for testing of volatile fh |
|
941 |
*/ |
|
942 |
||
943 |
#ifdef VOLATILE_FH_TEST |
|
944 |
||
945 |
struct nfs_fh4_fmt { |
|
1610
3436e82414c8
6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents:
1232
diff
changeset
|
946 |
fhandle4_t fh4_i; |
806 | 947 |
uint32_t fh4_flag; |
948 |
uint32_t fh4_volatile_id; |
|
0 | 949 |
}; |
950 |
||
951 |
#else /* VOLATILE_FH_TEST */ |
|
952 |
||
953 |
struct nfs_fh4_fmt { |
|
1610
3436e82414c8
6344186 NFSv3 needs to support .zfs (like NFSv4 already does)
thurlow
parents:
1232
diff
changeset
|
954 |
fhandle4_t fh4_i; |
806 | 955 |
uint32_t fh4_flag; |
0 | 956 |
}; |
957 |
||
958 |
#endif /* VOLATILE_FH_TEST */ |
|
959 |
||
960 |
#define FH4_NAMEDATTR 1 |
|
961 |
#define FH4_ATTRDIR 2 |
|
962 |
||
806 | 963 |
#define fh4_fsid fh4_i.fhx_fsid |
964 |
#define fh4_len fh4_i.fhx_len /* fid length */ |
|
965 |
#define fh4_data fh4_i.fhx_data /* fid bytes */ |
|
966 |
#define fh4_xlen fh4_i.fhx_xlen |
|
967 |
#define fh4_xdata fh4_i.fhx_xdata |
|
0 | 968 |
typedef struct nfs_fh4_fmt nfs_fh4_fmt_t; |
969 |
||
970 |
#define fh4_to_fmt4(fh4p) ((nfs_fh4_fmt_t *)(fh4p)->nfs_fh4_val) |
|
971 |
#define get_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) & (flag)) |
|
972 |
#define set_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) |= (flag)) |
|
973 |
#define clr_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) &= ~(flag)) |
|
974 |
||
975 |
#define NFS_FH4_LEN sizeof (nfs_fh4_fmt_t) |
|
976 |
||
977 |
||
978 |
/* |
|
979 |
* A few definitions of repeatedly used constructs for nfsv4 |
|
980 |
*/ |
|
981 |
#define UTF8STRING_FREE(str) \ |
|
982 |
kmem_free((str).utf8string_val, (str).utf8string_len); \ |
|
983 |
(str).utf8string_val = NULL; \ |
|
984 |
(str).utf8string_len = 0; |
|
985 |
||
986 |
/* |
|
987 |
* NFS4_VOLATILE_FH yields non-zero if the filesystem uses non-persistent |
|
988 |
* filehandles. |
|
989 |
*/ |
|
990 |
#define NFS4_VOLATILE_FH(mi) \ |
|
991 |
((mi)->mi_fh_expire_type & \ |
|
992 |
(FH4_VOLATILE_ANY | FH4_VOL_MIGRATION | FH4_VOL_RENAME)) |
|
993 |
||
994 |
/* |
|
995 |
* NFS_IS_DOTNAME checks if the name given represents a dot or dotdot entry |
|
996 |
*/ |
|
997 |
#define NFS_IS_DOTNAME(name) \ |
|
998 |
(((name)[0] == '.') && \ |
|
999 |
(((name)[1] == '\0') || (((name)[1] == '.') && ((name)[2] == '\0')))) |
|
1000 |
||
1001 |
/* |
|
1002 |
* Define the number of bits in a bitmap word (uint32) |
|
1003 |
*/ |
|
1004 |
#define NFS4_BITMAP4_BITSPERWORD (sizeof (uint32_t) * 8) |
|
1005 |
||
1006 |
/* |
|
1007 |
* Define the value for the access field of the compound_state structure |
|
1008 |
* based on the result of nfsauth access checking. |
|
1009 |
*/ |
|
1010 |
#define CS_ACCESS_OK 0x1 |
|
1011 |
#define CS_ACCESS_DENIED 0x2 |
|
1012 |
#define CS_ACCESS_LIMITED 0x4 |
|
1013 |
||
1014 |
/* |
|
1015 |
* compound state in nfsv4 server |
|
1016 |
*/ |
|
1017 |
struct compound_state { |
|
1018 |
struct exportinfo *exi; |
|
1019 |
struct exportinfo *saved_exi; /* export struct for saved_vp */ |
|
1020 |
cred_t *basecr; /* UNIX cred: only RPC request */ |
|
1021 |
caddr_t principal; |
|
1022 |
int nfsflavor; |
|
1023 |
cred_t *cr; /* UNIX cred: RPC request and */ |
|
1024 |
/* target export */ |
|
1025 |
bool_t cont; |
|
1026 |
uint_t access; /* access perm on vp per request */ |
|
1027 |
bool_t deleg; /* TRUE if current fh has */ |
|
1028 |
/* write delegated */ |
|
1029 |
vnode_t *vp; /* modified by PUTFH, and by ops that */ |
|
1030 |
/* input to GETFH */ |
|
1031 |
bool_t mandlock; /* Is mandatory locking in effect */ |
|
1032 |
/* for vp */ |
|
1033 |
vnode_t *saved_vp; /* modified by SAVEFH, copied to */ |
|
1034 |
/* vp by RESTOREFH */ |
|
1035 |
nfsstat4 *statusp; |
|
1036 |
nfs_fh4 fh; /* ditto. valid only if vp != NULL */ |
|
1037 |
nfs_fh4 saved_fh; /* ditto. valid only if */ |
|
1038 |
/* saved_vp != NULL */ |
|
1039 |
struct svc_req *req; |
|
1040 |
char fhbuf[NFS4_FHSIZE]; |
|
1041 |
}; |
|
1042 |
||
1043 |
/* |
|
1044 |
* Conversion commands for nfsv4 server attr checking |
|
1045 |
*/ |
|
1046 |
enum nfs4_attr_cmd { |
|
1047 |
NFS4ATTR_SUPPORTED = 0, /* check which attrs supported */ |
|
1048 |
NFS4ATTR_GETIT = 1, /* getattr - sys to fattr4 (r) */ |
|
1049 |
NFS4ATTR_SETIT = 2, /* setattr - fattr4 to sys (w) */ |
|
1050 |
NFS4ATTR_VERIT = 3, /* verify - fattr4 to sys (r) */ |
|
1051 |
NFS4ATTR_FREEIT = 4 /* free any alloc'd space for attr */ |
|
1052 |
}; |
|
1053 |
||
1054 |
typedef enum nfs4_attr_cmd nfs4_attr_cmd_t; |
|
1055 |
||
1056 |
struct nfs4_svgetit_arg { |
|
1057 |
nfs4_attr_cmd_t op; /* getit or setit */ |
|
1058 |
struct compound_state *cs; |
|
1059 |
struct statvfs64 *sbp; |
|
1060 |
uint_t flag; /* VOP_GETATTR/VOP_SETATTR flag */ |
|
1061 |
uint_t xattr; /* object is xattr */ |
|
1062 |
bool_t rdattr_error_req; /* if readdir & client wants */ |
|
1063 |
/* rdattr_error */ |
|
1064 |
nfsstat4 rdattr_error; /* used for per-entry status */ |
|
1065 |
/* (if rdattr_err) */ |
|
1066 |
bool_t mntdfid_set; |
|
1067 |
fattr4_mounted_on_fileid |
|
1068 |
mounted_on_fileid; |
|
1069 |
/* readdir op can always return */ |
|
1070 |
/* d_ino from server fs dirent */ |
|
1071 |
/* for mounted_on_fileid attr. */ |
|
1072 |
/* This field holds d_ino so */ |
|
1073 |
/* srv attr conv code can avoid */ |
|
1074 |
/* doing an untraverse. */ |
|
1075 |
vattr_t vap[1]; |
|
1076 |
}; |
|
1077 |
||
1078 |
struct nfs4_ntov_map { |
|
1079 |
bitmap4 fbit; /* FATTR4_XXX_MASKY */ |
|
1080 |
uint_t vbit; /* AT_XXX */ |
|
1081 |
bool_t vfsstat; |
|
1082 |
bool_t mandatory; /* attribute mandatory to implement? */ |
|
1083 |
uint_t nval; |
|
1084 |
int xdr_size; /* Size of XDR'd attr */ |
|
1085 |
xdrproc_t xfunc; |
|
1086 |
int (*sv_getit)(nfs4_attr_cmd_t, struct nfs4_svgetit_arg *, |
|
1087 |
union nfs4_attr_u *); /* subroutine for getting attr. */ |
|
1088 |
char *prtstr; /* string attr for printing */ |
|
1089 |
}; |
|
1090 |
||
1091 |
struct nfs4attr_to_vattr { |
|
1092 |
vnode_t *vp; |
|
1093 |
vattr_t *vap; |
|
1094 |
nfs_fh4 *fhp; |
|
1095 |
nfsstat4 rdattr_error; |
|
1096 |
uint32_t flag; |
|
1097 |
fattr4_change change; |
|
1098 |
fattr4_fsid srv_fsid; |
|
1099 |
fattr4_mounted_on_fileid mntd_fid; |
|
1100 |
}; |
|
1101 |
||
1102 |
typedef struct nfs4attr_to_vattr ntov4_t; |
|
1103 |
||
1104 |
/* |
|
1105 |
* nfs4attr_to_vattr flags |
|
1106 |
*/ |
|
1107 |
#define NTOV_FHP_VALID 0x01 |
|
1108 |
#define NTOV_RDATTR_ERROR_VALID 0x02 |
|
1109 |
#define NTOV_CHANGE_VALID 0x04 |
|
1110 |
#define NTOV_SUPP_VALID 0x08 |
|
1111 |
#define NTOV_SRV_FSID_VALID 0x10 |
|
1112 |
#define NTOV_MOUNTED_ON_FILEID_VALID 0x20 |
|
1113 |
||
1114 |
||
1115 |
#define FATTR4_MANDATTR_MASK ( \ |
|
1116 |
FATTR4_SUPPORTED_ATTRS_MASK | \ |
|
1117 |
FATTR4_TYPE_MASK | \ |
|
1118 |
FATTR4_FH_EXPIRE_TYPE_MASK | \ |
|
1119 |
FATTR4_CHANGE_MASK | \ |
|
1120 |
FATTR4_SIZE_MASK | \ |
|
1121 |
FATTR4_LINK_SUPPORT_MASK | \ |
|
1122 |
FATTR4_SYMLINK_SUPPORT_MASK | \ |
|
1123 |
FATTR4_NAMED_ATTR_MASK | \ |
|
1124 |
FATTR4_FSID_MASK | \ |
|
1125 |
FATTR4_UNIQUE_HANDLES_MASK | \ |
|
1126 |
FATTR4_LEASE_TIME_MASK | \ |
|
1127 |
FATTR4_RDATTR_ERROR_MASK | \ |
|
1128 |
FATTR4_FILEHANDLE_MASK) |
|
1129 |
||
1130 |
||
1131 |
struct nfs4attr_to_osattr { |
|
1132 |
void *attrconv_arg; |
|
1133 |
uint_t mask; |
|
1134 |
}; |
|
1135 |
||
1136 |
struct mntinfo4; |
|
1137 |
||
1138 |
/* |
|
1139 |
* lkp4_attr_setup lists the different options for attributes when calling |
|
1140 |
* nfs4lookup_setup - either no attributes (just lookups - e.g., secinfo), |
|
1141 |
* one component only (normal component lookup), get attributes for the |
|
1142 |
* last component (e.g., mount), attributes for each component (e.g., |
|
1143 |
* failovers later), just the filehandle for the last component (e.g., |
|
1144 |
* volatile filehandle recovery), or stuff that needs OPENATTR (e.g. |
|
1145 |
* looking up a named attribute or it's hidden directory). |
|
1146 |
*/ |
|
1147 |
enum lkp4_attr_setup { |
|
1148 |
LKP4_NO_ATTRIBUTES = 0, /* no attrs or filehandles */ |
|
1149 |
LKP4_ALL_ATTRIBUTES = 3, /* multi-comp: attrs for all comps */ |
|
1150 |
LKP4_LAST_NAMED_ATTR = 5, /* multi-comp: named attr & attrdir */ |
|
1151 |
LKP4_LAST_ATTRDIR = 6, /* multi-comp: just attrdir */ |
|
1152 |
LKP4_ALL_ATTR_SECINFO = 7 /* multi-comp: attrs for all comp and */ |
|
1153 |
/* secinfo for last comp */ |
|
1154 |
}; |
|
1155 |
||
1156 |
/* |
|
1157 |
* lookup4_param a set of parameters to nfs4lookup_setup - |
|
1158 |
* used to setup a path lookup compound request. |
|
1159 |
*/ |
|
1160 |
typedef struct lookup4_param { |
|
1161 |
enum lkp4_attr_setup l4_getattrs; /* (in) get attrs in the lookup? */ |
|
1162 |
int header_len; /* (in) num ops before first lookup */ |
|
1163 |
int trailer_len; /* (in) num ops after last */ |
|
1164 |
/* Lookup/Getattr */ |
|
1165 |
bitmap4 ga_bits; /* (in) Which attributes for Getattr */ |
|
1166 |
COMPOUND4args_clnt *argsp; /* (in/out) args for compound struct */ |
|
1167 |
COMPOUND4res_clnt *resp; /* (in/out) res for compound struct */ |
|
1168 |
int arglen; /* (out) argop buffer alloc'd length */ |
|
1169 |
struct mntinfo4 *mi; |
|
1170 |
} lookup4_param_t; |
|
1171 |
||
1172 |
||
1173 |
#define NFS4_FATTR4_FINISH -1 /* fattr4 index indicating finish */ |
|
1174 |
||
1175 |
typedef int (*nfs4attr_to_os_t)(int, union nfs4_attr_u *, |
|
1176 |
struct nfs4attr_to_osattr *); |
|
1177 |
||
1178 |
/* |
|
1179 |
* The nfs4_error_t is the basic structure to return error values |
|
1180 |
* from rfs4call. It encapsulates the unix errno |
|
1181 |
* value, the nfsstat4 value and the rpc status value into a single |
|
1182 |
* structure. |
|
1183 |
* |
|
1184 |
* If error is set, then stat is ignored and rpc_status may be |
|
1185 |
* set if the error occurred as the result of a CLNT_CALL. If |
|
1186 |
* stat is set, then rpc request succeeded, error and |
|
1187 |
* rpc_status are set to 0 and stat contains the result of |
|
1188 |
* operation, NFS4_OK or one of the NFS4ERR_* values. |
|
1189 |
* |
|
1190 |
* Functions which want to generate errors independently from |
|
1191 |
* rfs4call should set error to the desired errno value and |
|
1192 |
* set stat and rpc_status to 0. nfs4_error_init() is a |
|
1193 |
* convenient function to do this. |
|
1194 |
*/ |
|
1195 |
typedef struct { |
|
1196 |
int error; |
|
1197 |
nfsstat4 stat; |
|
1198 |
enum clnt_stat rpc_status; |
|
1199 |
} nfs4_error_t; |
|
1200 |
||
1201 |
/* |
|
1202 |
* Shared functions |
|
1203 |
*/ |
|
1204 |
extern void rfs4_op_readdir(nfs_argop4 *, nfs_resop4 *, |
|
1205 |
struct svc_req *, struct compound_state *); |
|
1206 |
extern void nfs_fh4_copy(nfs_fh4 *, nfs_fh4 *); |
|
1207 |
||
1208 |
extern void nfs4_fattr4_free(fattr4 *); |
|
1209 |
||
1210 |
extern int nfs4lookup_setup(char *, lookup4_param_t *, int); |
|
1211 |
extern void nfs4_getattr_otw_norecovery(vnode_t *, |
|
1212 |
nfs4_ga_res_t *, nfs4_error_t *, cred_t *, int); |
|
1213 |
extern int nfs4_getattr_otw(vnode_t *, nfs4_ga_res_t *, cred_t *, int); |
|
1214 |
extern int nfs4cmpfh(const nfs_fh4 *, const nfs_fh4 *); |
|
1215 |
extern int nfs4cmpfhandle(nfs4_fhandle_t *, nfs4_fhandle_t *); |
|
1216 |
extern int nfs4getattr(vnode_t *, struct vattr *, cred_t *); |
|
1217 |
extern int nfs4_waitfor_purge_complete(vnode_t *); |
|
1218 |
extern int nfs4_validate_caches(vnode_t *, cred_t *); |
|
1219 |
extern int nfs4init(int, char *); |
|
1220 |
extern void nfs4fini(void); |
|
1221 |
extern int nfs4_vfsinit(void); |
|
1222 |
extern void nfs4_vfsfini(void); |
|
1223 |
||
1224 |
extern void nfs4_vnops_init(void); |
|
1225 |
extern void nfs4_vnops_fini(void); |
|
1226 |
extern void nfs_idmap_init(void); |
|
1227 |
extern void nfs_idmap_flush(int); |
|
1228 |
extern void nfs_idmap_fini(void); |
|
1229 |
extern int nfs4_rnode_init(void); |
|
1230 |
extern int nfs4_rnode_fini(void); |
|
1231 |
extern int nfs4_shadow_init(void); |
|
1232 |
extern int nfs4_shadow_fini(void); |
|
1233 |
extern int nfs4_acache_init(void); |
|
1234 |
extern int nfs4_acache_fini(void); |
|
1235 |
extern int nfs4_subr_init(void); |
|
1236 |
extern int nfs4_subr_fini(void); |
|
1237 |
extern void nfs4_acl_init(void); |
|
1238 |
extern void nfs4_acl_free_cache(vsecattr_t *); |
|
1239 |
||
1240 |
extern int geterrno4(nfsstat4); |
|
1241 |
extern nfsstat4 puterrno4(int); |
|
1242 |
extern int nfs4_need_to_bump_seqid(COMPOUND4res_clnt *); |
|
1243 |
extern int nfs4tsize(void); |
|
1244 |
extern int checkauth4(struct compound_state *, struct svc_req *); |
|
1245 |
extern nfsstat4 call_checkauth4(struct compound_state *, struct svc_req *); |
|
1246 |
extern int is_exported_sec(int, struct exportinfo *); |
|
1247 |
extern void nfs4_vmask_to_nmask(uint_t, bitmap4 *); |
|
602
4ef537c7acd0
6284687 SETATTR(size) with special stateid=0 does not have bitmask set
jasmith
parents:
92
diff
changeset
|
1248 |
extern void nfs4_vmask_to_nmask_set(uint_t, bitmap4 *); |
0 | 1249 |
extern int nfs_idmap_str_uid(utf8string *u8s, uid_t *, bool_t); |
1250 |
extern int nfs_idmap_str_gid(utf8string *u8s, gid_t *, bool_t); |
|
1251 |
extern int nfs_idmap_uid_str(uid_t, utf8string *u8s, bool_t); |
|
1252 |
extern int nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t); |
|
1253 |
extern int nfs4_time_ntov(nfstime4 *, timestruc_t *); |
|
1254 |
extern int nfs4_time_vton(timestruc_t *, nfstime4 *); |
|
1255 |
extern char *utf8_to_str(utf8string *, uint_t *, char *); |
|
1256 |
extern char *utf8_to_fn(utf8string *, uint_t *, char *); |
|
1257 |
extern utf8string *str_to_utf8(char *, utf8string *); |
|
1258 |
extern utf8string *utf8_copy(utf8string *, utf8string *); |
|
1259 |
extern int utf8_compare(const utf8string *, const utf8string *); |
|
1260 |
extern int utf8_dir_verify(utf8string *); |
|
1261 |
extern char *utf8_strchr(utf8string *, const char); |
|
1262 |
extern int ln_ace4_cmp(nfsace4 *, nfsace4 *, int); |
|
1263 |
extern int vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int); |
|
1264 |
extern int vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t, |
|
1265 |
int, int, int); |
|
1266 |
extern int vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t, |
|
789 | 1267 |
int, int); |
1268 |
extern int vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int); |
|
0 | 1269 |
extern void vs_acet_destroy(vsecattr_t *); |
1270 |
extern void vs_ace4_destroy(vsecattr_t *); |
|
1271 |
extern void vs_aent_destroy(vsecattr_t *); |
|
1272 |
||
1273 |
extern int stateid4_cmp(stateid4 *, stateid4 *); |
|
1274 |
||
1275 |
extern vtype_t nf4_to_vt[]; |
|
1276 |
||
1277 |
extern struct nfs4_ntov_map nfs4_ntov_map[]; |
|
1278 |
extern uint_t nfs4_ntov_map_size; |
|
1279 |
||
1280 |
extern kstat_named_t *rfsproccnt_v4_ptr; |
|
1281 |
extern struct vfsops *nfs4_vfsops; |
|
1282 |
extern struct vnodeops *nfs4_vnodeops; |
|
1283 |
extern const struct fs_operation_def nfs4_vnodeops_template[]; |
|
1284 |
||
1285 |
extern uint_t nfs4_tsize(struct knetconfig *); |
|
1286 |
extern uint_t rfs4_tsize(struct svc_req *); |
|
1287 |
||
1232 | 1288 |
extern bool_t xdr_inline_decode_nfs_fh4(uint32_t *, nfs_fh4_fmt_t *, |
1289 |
uint32_t); |
|
806 | 1290 |
extern bool_t xdr_inline_encode_nfs_fh4(uint32_t **, uint32_t *, |
1291 |
nfs_fh4_fmt_t *); |
|
1292 |
||
0 | 1293 |
#ifdef DEBUG |
1294 |
extern int rfs4_do_pre_op_attr; |
|
1295 |
extern int rfs4_do_post_op_attr; |
|
1296 |
#endif |
|
1297 |
||
1298 |
extern stateid4 clnt_special0; |
|
1299 |
extern stateid4 clnt_special1; |
|
1300 |
#define CLNT_ISSPECIAL(id) (stateid4_cmp(id, &clnt_special0) || \ |
|
1301 |
stateid4_cmp(id, &clnt_special1)) |
|
1302 |
||
1303 |
/* |
|
1304 |
* The NFS Version 4 service procedures. |
|
1305 |
*/ |
|
1306 |
||
1307 |
extern void rfs4_compound(COMPOUND4args *, COMPOUND4res *, |
|
1308 |
struct exportinfo *, struct svc_req *, cred_t *); |
|
1309 |
extern void rfs4_compound_free(COMPOUND4res *); |
|
1310 |
extern void rfs4_compound_flagproc(COMPOUND4args *, int *); |
|
1311 |
||
1312 |
extern int rfs4_srvrinit(void); |
|
1313 |
extern void rfs4_srvrfini(void); |
|
1314 |
extern void rfs4_state_init(void); |
|
1315 |
extern void rfs4_state_fini(void); |
|
1316 |
||
1317 |
#endif |
|
1318 |
#ifdef __cplusplus |
|
1319 |
} |
|
1320 |
#endif |
|
1321 |
||
1322 |
#endif /* _NFS4_H */ |