Print this page
NEX-20260 NFS hung in transitional state when RSF marks it maintenance
NEX-20423 NFSv4 state database entry locking is not always used around reference count.
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-19996 exi_id_get_next() calls should be WRITER locked
NEX-20014 NFS v4 state lock mutex exited before entered (on error path)
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
NEX-16452 NFS server in a zone state database needs to be per zone
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/nfs/nfs4_state.c
+++ new/usr/src/uts/common/fs/nfs/nfs4_state.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 +
21 22 /*
22 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 +/*
27 + * Copyright 2018 Nexenta Systems, Inc.
28 + */
29 +
26 30 #include <sys/systm.h>
27 31 #include <sys/kmem.h>
28 32 #include <sys/cmn_err.h>
29 33 #include <sys/atomic.h>
30 34 #include <sys/clconf.h>
31 35 #include <sys/cladm.h>
32 36 #include <sys/flock.h>
33 37 #include <nfs/export.h>
34 38 #include <nfs/nfs.h>
35 39 #include <nfs/nfs4.h>
36 40 #include <nfs/nfssys.h>
37 41 #include <nfs/lm.h>
38 42 #include <sys/pathname.h>
39 43 #include <sys/sdt.h>
40 44 #include <sys/nvpair.h>
41 45
42 46 extern u_longlong_t nfs4_srv_caller_id;
43 47
44 -extern time_t rfs4_start_time;
45 48 extern uint_t nfs4_srv_vkey;
46 49
47 50 stateid4 special0 = {
48 51 0,
49 52 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
50 53 };
51 54
52 55 stateid4 special1 = {
53 56 0xffffffff,
54 57 {
55 58 (char)0xff, (char)0xff, (char)0xff, (char)0xff,
56 59 (char)0xff, (char)0xff, (char)0xff, (char)0xff,
57 60 (char)0xff, (char)0xff, (char)0xff, (char)0xff
58 61 }
59 62 };
60 63
61 64
62 65 #define ISSPECIAL(id) (stateid4_cmp(id, &special0) || \
63 66 stateid4_cmp(id, &special1))
64 67
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
65 68 /* For embedding the cluster nodeid into our clientid */
66 69 #define CLUSTER_NODEID_SHIFT 24
67 70 #define CLUSTER_MAX_NODEID 255
68 71
69 72 #ifdef DEBUG
70 73 int rfs4_debug;
71 74 #endif
72 75
73 76 static uint32_t rfs4_database_debug = 0x00;
74 77
75 -static void rfs4_ss_clid_write(rfs4_client_t *cp, char *leaf);
78 +/* CSTYLED */
79 +static void rfs4_ss_clid_write(nfs4_srv_t *nsrv4, rfs4_client_t *cp, char *leaf);
76 80 static void rfs4_ss_clid_write_one(rfs4_client_t *cp, char *dir, char *leaf);
77 81 static void rfs4_dss_clear_oldstate(rfs4_servinst_t *sip);
78 82 static void rfs4_ss_chkclid_sip(rfs4_client_t *cp, rfs4_servinst_t *sip);
79 83
80 84 /*
81 85 * Couple of simple init/destroy functions for a general waiter
82 86 */
83 87 void
84 88 rfs4_sw_init(rfs4_state_wait_t *swp)
85 89 {
86 90 mutex_init(swp->sw_cv_lock, NULL, MUTEX_DEFAULT, NULL);
87 91 cv_init(swp->sw_cv, NULL, CV_DEFAULT, NULL);
88 92 swp->sw_active = FALSE;
89 93 swp->sw_wait_count = 0;
90 94 }
91 95
92 96 void
93 97 rfs4_sw_destroy(rfs4_state_wait_t *swp)
94 98 {
95 99 mutex_destroy(swp->sw_cv_lock);
96 100 cv_destroy(swp->sw_cv);
97 101 }
98 102
99 103 void
100 104 rfs4_sw_enter(rfs4_state_wait_t *swp)
101 105 {
102 106 mutex_enter(swp->sw_cv_lock);
103 107 while (swp->sw_active) {
104 108 swp->sw_wait_count++;
105 109 cv_wait(swp->sw_cv, swp->sw_cv_lock);
106 110 swp->sw_wait_count--;
107 111 }
108 112 ASSERT(swp->sw_active == FALSE);
109 113 swp->sw_active = TRUE;
110 114 mutex_exit(swp->sw_cv_lock);
111 115 }
112 116
113 117 void
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
114 118 rfs4_sw_exit(rfs4_state_wait_t *swp)
115 119 {
116 120 mutex_enter(swp->sw_cv_lock);
117 121 ASSERT(swp->sw_active == TRUE);
118 122 swp->sw_active = FALSE;
119 123 if (swp->sw_wait_count != 0)
120 124 cv_broadcast(swp->sw_cv);
121 125 mutex_exit(swp->sw_cv_lock);
122 126 }
123 127
124 -/*
125 - * CPR callback id -- not related to v4 callbacks
126 - */
127 -static callb_id_t cpr_id = 0;
128 -
129 128 static void
130 129 deep_lock_copy(LOCK4res *dres, LOCK4res *sres)
131 130 {
132 131 lock_owner4 *slo = &sres->LOCK4res_u.denied.owner;
133 132 lock_owner4 *dlo = &dres->LOCK4res_u.denied.owner;
134 133
135 134 if (sres->status == NFS4ERR_DENIED) {
136 135 dlo->owner_val = kmem_alloc(slo->owner_len, KM_SLEEP);
137 136 bcopy(slo->owner_val, dlo->owner_val, slo->owner_len);
138 137 }
139 138 }
140 139
140 +/*
141 + * CPR callback id -- not related to v4 callbacks
142 + */
143 +static callb_id_t cpr_id = 0;
144 +
141 145 static void
142 146 deep_lock_free(LOCK4res *res)
143 147 {
144 148 lock_owner4 *lo = &res->LOCK4res_u.denied.owner;
145 149
146 150 if (res->status == NFS4ERR_DENIED)
147 151 kmem_free(lo->owner_val, lo->owner_len);
148 152 }
149 153
150 154 static void
151 155 deep_open_copy(OPEN4res *dres, OPEN4res *sres)
152 156 {
153 157 nfsace4 *sacep, *dacep;
154 158
155 159 if (sres->status != NFS4_OK) {
156 160 return;
157 161 }
158 162
159 163 dres->attrset = sres->attrset;
160 164
161 165 switch (sres->delegation.delegation_type) {
162 166 case OPEN_DELEGATE_NONE:
163 167 return;
164 168 case OPEN_DELEGATE_READ:
165 169 sacep = &sres->delegation.open_delegation4_u.read.permissions;
166 170 dacep = &dres->delegation.open_delegation4_u.read.permissions;
167 171 break;
168 172 case OPEN_DELEGATE_WRITE:
169 173 sacep = &sres->delegation.open_delegation4_u.write.permissions;
170 174 dacep = &dres->delegation.open_delegation4_u.write.permissions;
171 175 break;
172 176 }
173 177 dacep->who.utf8string_val =
174 178 kmem_alloc(sacep->who.utf8string_len, KM_SLEEP);
175 179 bcopy(sacep->who.utf8string_val, dacep->who.utf8string_val,
176 180 sacep->who.utf8string_len);
177 181 }
178 182
179 183 static void
180 184 deep_open_free(OPEN4res *res)
181 185 {
182 186 nfsace4 *acep;
183 187 if (res->status != NFS4_OK)
184 188 return;
185 189
186 190 switch (res->delegation.delegation_type) {
187 191 case OPEN_DELEGATE_NONE:
188 192 return;
189 193 case OPEN_DELEGATE_READ:
190 194 acep = &res->delegation.open_delegation4_u.read.permissions;
191 195 break;
192 196 case OPEN_DELEGATE_WRITE:
193 197 acep = &res->delegation.open_delegation4_u.write.permissions;
194 198 break;
195 199 }
196 200
197 201 if (acep->who.utf8string_val) {
198 202 kmem_free(acep->who.utf8string_val, acep->who.utf8string_len);
199 203 acep->who.utf8string_val = NULL;
200 204 }
201 205 }
202 206
203 207 void
204 208 rfs4_free_reply(nfs_resop4 *rp)
205 209 {
206 210 switch (rp->resop) {
207 211 case OP_LOCK:
208 212 deep_lock_free(&rp->nfs_resop4_u.oplock);
209 213 break;
210 214 case OP_OPEN:
211 215 deep_open_free(&rp->nfs_resop4_u.opopen);
212 216 default:
213 217 break;
214 218 }
215 219 }
216 220
217 221 void
218 222 rfs4_copy_reply(nfs_resop4 *dst, nfs_resop4 *src)
219 223 {
220 224 *dst = *src;
221 225
222 226 /* Handle responses that need deep copy */
223 227 switch (src->resop) {
224 228 case OP_LOCK:
225 229 deep_lock_copy(&dst->nfs_resop4_u.oplock,
226 230 &src->nfs_resop4_u.oplock);
227 231 break;
228 232 case OP_OPEN:
229 233 deep_open_copy(&dst->nfs_resop4_u.opopen,
230 234 &src->nfs_resop4_u.opopen);
231 235 break;
232 236 default:
233 237 break;
234 238 };
235 239 }
236 240
237 241 /*
238 242 * This is the implementation of the underlying state engine. The
239 243 * public interface to this engine is described by
240 244 * nfs4_state.h. Callers to the engine should hold no state engine
241 245 * locks when they call in to it. If the protocol needs to lock data
242 246 * structures it should do so after acquiring all references to them
243 247 * first and then follow the following lock order:
244 248 *
245 249 * client > openowner > state > lo_state > lockowner > file.
246 250 *
247 251 * Internally we only allow a thread to hold one hash bucket lock at a
248 252 * time and the lock is higher in the lock order (must be acquired
249 253 * first) than the data structure that is on that hash list.
250 254 *
251 255 * If a new reference was acquired by the caller, that reference needs
252 256 * to be released after releasing all acquired locks with the
253 257 * corresponding rfs4_*_rele routine.
254 258 */
255 259
256 260 /*
257 261 * This code is some what prototypical for now. Its purpose currently is to
258 262 * implement the interfaces sufficiently to finish the higher protocol
259 263 * elements. This will be replaced by a dynamically resizeable tables
260 264 * backed by kmem_cache allocator. However synchronization is handled
261 265 * correctly (I hope) and will not change by much. The mutexes for
262 266 * the hash buckets that can be used to create new instances of data
263 267 * structures might be good candidates to evolve into reader writer
264 268 * locks. If it has to do a creation, it would be holding the
265 269 * mutex across a kmem_alloc with KM_SLEEP specified.
|
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
266 270 */
267 271
268 272 #ifdef DEBUG
269 273 #define TABSIZE 17
270 274 #else
271 275 #define TABSIZE 2047
272 276 #endif
273 277
274 278 #define ADDRHASH(key) ((unsigned long)(key) >> 3)
275 279
276 -/* Used to serialize create/destroy of rfs4_server_state database */
277 -kmutex_t rfs4_state_lock;
278 -static rfs4_database_t *rfs4_server_state = NULL;
279 -
280 -/* Used to serialize lookups of clientids */
281 -static krwlock_t rfs4_findclient_lock;
282 -
283 -/*
284 - * For now this "table" is exposed so that the CPR callback
285 - * function can tromp through it..
286 - */
287 -rfs4_table_t *rfs4_client_tab;
288 -
289 -static rfs4_index_t *rfs4_clientid_idx;
290 -static rfs4_index_t *rfs4_nfsclnt_idx;
291 -static rfs4_table_t *rfs4_clntip_tab;
292 -static rfs4_index_t *rfs4_clntip_idx;
293 -static rfs4_table_t *rfs4_openowner_tab;
294 -static rfs4_index_t *rfs4_openowner_idx;
295 -static rfs4_table_t *rfs4_state_tab;
296 -static rfs4_index_t *rfs4_state_idx;
297 -static rfs4_index_t *rfs4_state_owner_file_idx;
298 -static rfs4_index_t *rfs4_state_file_idx;
299 -static rfs4_table_t *rfs4_lo_state_tab;
300 -static rfs4_index_t *rfs4_lo_state_idx;
301 -static rfs4_index_t *rfs4_lo_state_owner_idx;
302 -static rfs4_table_t *rfs4_lockowner_tab;
303 -static rfs4_index_t *rfs4_lockowner_idx;
304 -static rfs4_index_t *rfs4_lockowner_pid_idx;
305 -static rfs4_table_t *rfs4_file_tab;
306 -static rfs4_index_t *rfs4_file_idx;
307 -static rfs4_table_t *rfs4_deleg_state_tab;
308 -static rfs4_index_t *rfs4_deleg_idx;
309 -static rfs4_index_t *rfs4_deleg_state_idx;
310 -
311 280 #define MAXTABSZ 1024*1024
312 281
313 282 /* The values below are rfs4_lease_time units */
314 283
315 284 #ifdef DEBUG
316 285 #define CLIENT_CACHE_TIME 1
317 286 #define OPENOWNER_CACHE_TIME 1
318 287 #define STATE_CACHE_TIME 1
319 288 #define LO_STATE_CACHE_TIME 1
320 289 #define LOCKOWNER_CACHE_TIME 1
321 290 #define FILE_CACHE_TIME 3
322 291 #define DELEG_STATE_CACHE_TIME 1
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
323 292 #else
324 293 #define CLIENT_CACHE_TIME 10
325 294 #define OPENOWNER_CACHE_TIME 5
326 295 #define STATE_CACHE_TIME 1
327 296 #define LO_STATE_CACHE_TIME 1
328 297 #define LOCKOWNER_CACHE_TIME 3
329 298 #define FILE_CACHE_TIME 40
330 299 #define DELEG_STATE_CACHE_TIME 1
331 300 #endif
332 301
302 +/*
303 + * NFSv4 server state databases
304 + *
305 + * Initilized when the module is loaded and used by NFSv4 state tables.
306 + * These kmem_cache databases are global, the tables that make use of these
307 + * are per zone.
308 + */
309 +kmem_cache_t *rfs4_client_mem_cache;
310 +kmem_cache_t *rfs4_clntIP_mem_cache;
311 +kmem_cache_t *rfs4_openown_mem_cache;
312 +kmem_cache_t *rfs4_openstID_mem_cache;
313 +kmem_cache_t *rfs4_lockstID_mem_cache;
314 +kmem_cache_t *rfs4_lockown_mem_cache;
315 +kmem_cache_t *rfs4_file_mem_cache;
316 +kmem_cache_t *rfs4_delegstID_mem_cache;
333 317
334 -static time_t rfs4_client_cache_time = 0;
335 -static time_t rfs4_clntip_cache_time = 0;
336 -static time_t rfs4_openowner_cache_time = 0;
337 -static time_t rfs4_state_cache_time = 0;
338 -static time_t rfs4_lo_state_cache_time = 0;
339 -static time_t rfs4_lockowner_cache_time = 0;
340 -static time_t rfs4_file_cache_time = 0;
341 -static time_t rfs4_deleg_state_cache_time = 0;
342 -
318 +/*
319 + * NFSv4 state table functions
320 + */
343 321 static bool_t rfs4_client_create(rfs4_entry_t, void *);
344 322 static void rfs4_dss_remove_cpleaf(rfs4_client_t *);
345 323 static void rfs4_dss_remove_leaf(rfs4_servinst_t *, char *, char *);
346 324 static void rfs4_client_destroy(rfs4_entry_t);
347 325 static bool_t rfs4_client_expiry(rfs4_entry_t);
348 326 static uint32_t clientid_hash(void *);
349 327 static bool_t clientid_compare(rfs4_entry_t, void *);
350 328 static void *clientid_mkkey(rfs4_entry_t);
351 329 static uint32_t nfsclnt_hash(void *);
352 330 static bool_t nfsclnt_compare(rfs4_entry_t, void *);
353 331 static void *nfsclnt_mkkey(rfs4_entry_t);
354 332 static bool_t rfs4_clntip_expiry(rfs4_entry_t);
355 333 static void rfs4_clntip_destroy(rfs4_entry_t);
356 334 static bool_t rfs4_clntip_create(rfs4_entry_t, void *);
357 335 static uint32_t clntip_hash(void *);
358 336 static bool_t clntip_compare(rfs4_entry_t, void *);
359 337 static void *clntip_mkkey(rfs4_entry_t);
360 338 static bool_t rfs4_openowner_create(rfs4_entry_t, void *);
361 339 static void rfs4_openowner_destroy(rfs4_entry_t);
362 340 static bool_t rfs4_openowner_expiry(rfs4_entry_t);
363 341 static uint32_t openowner_hash(void *);
364 342 static bool_t openowner_compare(rfs4_entry_t, void *);
365 343 static void *openowner_mkkey(rfs4_entry_t);
366 344 static bool_t rfs4_state_create(rfs4_entry_t, void *);
367 345 static void rfs4_state_destroy(rfs4_entry_t);
368 346 static bool_t rfs4_state_expiry(rfs4_entry_t);
369 347 static uint32_t state_hash(void *);
370 348 static bool_t state_compare(rfs4_entry_t, void *);
371 349 static void *state_mkkey(rfs4_entry_t);
372 350 static uint32_t state_owner_file_hash(void *);
373 351 static bool_t state_owner_file_compare(rfs4_entry_t, void *);
374 352 static void *state_owner_file_mkkey(rfs4_entry_t);
375 353 static uint32_t state_file_hash(void *);
376 354 static bool_t state_file_compare(rfs4_entry_t, void *);
377 355 static void *state_file_mkkey(rfs4_entry_t);
378 356 static bool_t rfs4_lo_state_create(rfs4_entry_t, void *);
379 357 static void rfs4_lo_state_destroy(rfs4_entry_t);
380 358 static bool_t rfs4_lo_state_expiry(rfs4_entry_t);
381 359 static uint32_t lo_state_hash(void *);
382 360 static bool_t lo_state_compare(rfs4_entry_t, void *);
383 361 static void *lo_state_mkkey(rfs4_entry_t);
384 362 static uint32_t lo_state_lo_hash(void *);
385 363 static bool_t lo_state_lo_compare(rfs4_entry_t, void *);
386 364 static void *lo_state_lo_mkkey(rfs4_entry_t);
387 365 static bool_t rfs4_lockowner_create(rfs4_entry_t, void *);
388 366 static void rfs4_lockowner_destroy(rfs4_entry_t);
389 367 static bool_t rfs4_lockowner_expiry(rfs4_entry_t);
390 368 static uint32_t lockowner_hash(void *);
391 369 static bool_t lockowner_compare(rfs4_entry_t, void *);
392 370 static void *lockowner_mkkey(rfs4_entry_t);
393 371 static uint32_t pid_hash(void *);
394 372 static bool_t pid_compare(rfs4_entry_t, void *);
395 373 static void *pid_mkkey(rfs4_entry_t);
396 374 static bool_t rfs4_file_create(rfs4_entry_t, void *);
397 375 static void rfs4_file_destroy(rfs4_entry_t);
398 376 static uint32_t file_hash(void *);
399 377 static bool_t file_compare(rfs4_entry_t, void *);
400 378 static void *file_mkkey(rfs4_entry_t);
401 379 static bool_t rfs4_deleg_state_create(rfs4_entry_t, void *);
402 380 static void rfs4_deleg_state_destroy(rfs4_entry_t);
403 381 static bool_t rfs4_deleg_state_expiry(rfs4_entry_t);
404 382 static uint32_t deleg_hash(void *);
405 383 static bool_t deleg_compare(rfs4_entry_t, void *);
406 384 static void *deleg_mkkey(rfs4_entry_t);
407 385 static uint32_t deleg_state_hash(void *);
408 386 static bool_t deleg_state_compare(rfs4_entry_t, void *);
409 387 static void *deleg_state_mkkey(rfs4_entry_t);
410 388
411 389 static void rfs4_state_rele_nounlock(rfs4_state_t *);
412 390
413 391 static int rfs4_ss_enabled = 0;
414 392
415 393 extern void (*rfs4_client_clrst)(struct nfs4clrst_args *);
416 394
417 395 void
418 396 rfs4_ss_pnfree(rfs4_ss_pn_t *ss_pn)
419 397 {
420 398 kmem_free(ss_pn, sizeof (rfs4_ss_pn_t));
421 399 }
422 400
423 401 static rfs4_ss_pn_t *
424 402 rfs4_ss_pnalloc(char *dir, char *leaf)
425 403 {
426 404 rfs4_ss_pn_t *ss_pn;
427 405 int dir_len, leaf_len;
428 406
429 407 /*
430 408 * validate we have a resonable path
431 409 * (account for the '/' and trailing null)
432 410 */
433 411 if ((dir_len = strlen(dir)) > MAXPATHLEN ||
434 412 (leaf_len = strlen(leaf)) > MAXNAMELEN ||
435 413 (dir_len + leaf_len + 2) > MAXPATHLEN) {
436 414 return (NULL);
437 415 }
438 416
439 417 ss_pn = kmem_alloc(sizeof (rfs4_ss_pn_t), KM_SLEEP);
440 418
441 419 (void) snprintf(ss_pn->pn, MAXPATHLEN, "%s/%s", dir, leaf);
442 420 /* Handy pointer to just the leaf name */
443 421 ss_pn->leaf = ss_pn->pn + dir_len + 1;
444 422 return (ss_pn);
445 423 }
446 424
447 425
448 426 /*
449 427 * Move the "leaf" filename from "sdir" directory
450 428 * to the "ddir" directory. Return the pathname of
451 429 * the destination unless the rename fails in which
452 430 * case we need to return the source pathname.
453 431 */
454 432 static rfs4_ss_pn_t *
455 433 rfs4_ss_movestate(char *sdir, char *ddir, char *leaf)
456 434 {
457 435 rfs4_ss_pn_t *src, *dst;
458 436
459 437 if ((src = rfs4_ss_pnalloc(sdir, leaf)) == NULL)
460 438 return (NULL);
461 439
462 440 if ((dst = rfs4_ss_pnalloc(ddir, leaf)) == NULL) {
463 441 rfs4_ss_pnfree(src);
464 442 return (NULL);
465 443 }
466 444
467 445 /*
468 446 * If the rename fails we shall return the src
469 447 * pathname and free the dst. Otherwise we need
470 448 * to free the src and return the dst pathanme.
471 449 */
472 450 if (vn_rename(src->pn, dst->pn, UIO_SYSSPACE)) {
473 451 rfs4_ss_pnfree(dst);
474 452 return (src);
475 453 }
476 454 rfs4_ss_pnfree(src);
477 455 return (dst);
478 456 }
479 457
480 458
481 459 static rfs4_oldstate_t *
482 460 rfs4_ss_getstate(vnode_t *dvp, rfs4_ss_pn_t *ss_pn)
483 461 {
484 462 struct uio uio;
485 463 struct iovec iov[3];
486 464
487 465 rfs4_oldstate_t *cl_ss = NULL;
488 466 vnode_t *vp;
489 467 vattr_t va;
490 468 uint_t id_len;
491 469 int err, kill_file, file_vers;
492 470
493 471 if (ss_pn == NULL)
494 472 return (NULL);
495 473
496 474 /*
497 475 * open the state file.
498 476 */
499 477 if (vn_open(ss_pn->pn, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0) != 0) {
500 478 return (NULL);
501 479 }
502 480
503 481 if (vp->v_type != VREG) {
504 482 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
505 483 VN_RELE(vp);
506 484 return (NULL);
507 485 }
508 486
509 487 err = VOP_ACCESS(vp, VREAD, 0, CRED(), NULL);
510 488 if (err) {
511 489 /*
512 490 * We don't have read access? better get the heck out.
513 491 */
514 492 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
515 493 VN_RELE(vp);
516 494 return (NULL);
517 495 }
518 496
519 497 (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
520 498 /*
521 499 * get the file size to do some basic validation
522 500 */
523 501 va.va_mask = AT_SIZE;
524 502 err = VOP_GETATTR(vp, &va, 0, CRED(), NULL);
525 503
526 504 kill_file = (va.va_size == 0 || va.va_size <
527 505 (NFS4_VERIFIER_SIZE + sizeof (uint_t)+1));
528 506
529 507 if (err || kill_file) {
530 508 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
531 509 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
532 510 VN_RELE(vp);
533 511 if (kill_file) {
534 512 (void) VOP_REMOVE(dvp, ss_pn->leaf, CRED(), NULL, 0);
535 513 }
536 514 return (NULL);
537 515 }
538 516
539 517 cl_ss = kmem_alloc(sizeof (rfs4_oldstate_t), KM_SLEEP);
540 518
541 519 /*
542 520 * build iovecs to read in the file_version, verifier and id_len
543 521 */
544 522 iov[0].iov_base = (caddr_t)&file_vers;
545 523 iov[0].iov_len = sizeof (int);
546 524 iov[1].iov_base = (caddr_t)&cl_ss->cl_id4.verifier;
547 525 iov[1].iov_len = NFS4_VERIFIER_SIZE;
548 526 iov[2].iov_base = (caddr_t)&id_len;
549 527 iov[2].iov_len = sizeof (uint_t);
550 528
551 529 uio.uio_iov = iov;
552 530 uio.uio_iovcnt = 3;
553 531 uio.uio_segflg = UIO_SYSSPACE;
554 532 uio.uio_loffset = 0;
555 533 uio.uio_resid = sizeof (int) + NFS4_VERIFIER_SIZE + sizeof (uint_t);
556 534
557 535 if (err = VOP_READ(vp, &uio, FREAD, CRED(), NULL)) {
558 536 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
559 537 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
560 538 VN_RELE(vp);
561 539 kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
562 540 return (NULL);
563 541 }
564 542
565 543 /*
566 544 * if the file_version doesn't match or if the
567 545 * id_len is zero or the combination of the verifier,
568 546 * id_len and id_val is bigger than the file we have
569 547 * a problem. If so ditch the file.
570 548 */
571 549 kill_file = (file_vers != NFS4_SS_VERSION || id_len == 0 ||
572 550 (id_len + NFS4_VERIFIER_SIZE + sizeof (uint_t)) > va.va_size);
573 551
574 552 if (err || kill_file) {
575 553 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
576 554 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
577 555 VN_RELE(vp);
578 556 kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
579 557 if (kill_file) {
580 558 (void) VOP_REMOVE(dvp, ss_pn->leaf, CRED(), NULL, 0);
581 559 }
582 560 return (NULL);
583 561 }
584 562
585 563 /*
586 564 * now get the client id value
587 565 */
588 566 cl_ss->cl_id4.id_val = kmem_alloc(id_len, KM_SLEEP);
589 567 iov[0].iov_base = cl_ss->cl_id4.id_val;
590 568 iov[0].iov_len = id_len;
591 569
592 570 uio.uio_iov = iov;
593 571 uio.uio_iovcnt = 1;
594 572 uio.uio_segflg = UIO_SYSSPACE;
595 573 uio.uio_resid = cl_ss->cl_id4.id_len = id_len;
596 574
597 575 if (err = VOP_READ(vp, &uio, FREAD, CRED(), NULL)) {
598 576 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
599 577 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
600 578 VN_RELE(vp);
601 579 kmem_free(cl_ss->cl_id4.id_val, id_len);
602 580 kmem_free(cl_ss, sizeof (rfs4_oldstate_t));
603 581 return (NULL);
604 582 }
605 583
606 584 VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
607 585 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, CRED(), NULL);
608 586 VN_RELE(vp);
609 587 return (cl_ss);
610 588 }
611 589
612 590 #ifdef nextdp
613 591 #undef nextdp
614 592 #endif
615 593 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
616 594
617 595 /*
618 596 * Add entries from statedir to supplied oldstate list.
619 597 * Optionally, move all entries from statedir -> destdir.
620 598 */
621 599 void
622 600 rfs4_ss_oldstate(rfs4_oldstate_t *oldstate, char *statedir, char *destdir)
623 601 {
624 602 rfs4_ss_pn_t *ss_pn;
625 603 rfs4_oldstate_t *cl_ss = NULL;
626 604 char *dirt = NULL;
627 605 int err, dir_eof = 0, size = 0;
628 606 vnode_t *dvp;
629 607 struct iovec iov;
630 608 struct uio uio;
631 609 struct dirent64 *dep;
632 610 offset_t dirchunk_offset = 0;
633 611
634 612 /*
635 613 * open the state directory
636 614 */
637 615 if (vn_open(statedir, UIO_SYSSPACE, FREAD, 0, &dvp, 0, 0))
638 616 return;
639 617
640 618 if (dvp->v_type != VDIR || VOP_ACCESS(dvp, VREAD, 0, CRED(), NULL))
641 619 goto out;
642 620
643 621 dirt = kmem_alloc(RFS4_SS_DIRSIZE, KM_SLEEP);
644 622
645 623 /*
646 624 * Get and process the directory entries
647 625 */
648 626 while (!dir_eof) {
649 627 (void) VOP_RWLOCK(dvp, V_WRITELOCK_FALSE, NULL);
650 628 iov.iov_base = dirt;
651 629 iov.iov_len = RFS4_SS_DIRSIZE;
652 630 uio.uio_iov = &iov;
653 631 uio.uio_iovcnt = 1;
654 632 uio.uio_segflg = UIO_SYSSPACE;
655 633 uio.uio_loffset = dirchunk_offset;
656 634 uio.uio_resid = RFS4_SS_DIRSIZE;
657 635
658 636 err = VOP_READDIR(dvp, &uio, CRED(), &dir_eof, NULL, 0);
659 637 VOP_RWUNLOCK(dvp, V_WRITELOCK_FALSE, NULL);
660 638 if (err)
661 639 goto out;
662 640
663 641 size = RFS4_SS_DIRSIZE - uio.uio_resid;
664 642
665 643 /*
666 644 * Process all the directory entries in this
667 645 * readdir chunk
668 646 */
669 647 for (dep = (struct dirent64 *)dirt; size > 0;
670 648 dep = nextdp(dep)) {
671 649
672 650 size -= dep->d_reclen;
673 651 dirchunk_offset = dep->d_off;
674 652
675 653 /*
676 654 * Skip '.' and '..'
677 655 */
678 656 if (NFS_IS_DOTNAME(dep->d_name))
679 657 continue;
680 658
681 659 ss_pn = rfs4_ss_pnalloc(statedir, dep->d_name);
682 660 if (ss_pn == NULL)
683 661 continue;
684 662
685 663 if (cl_ss = rfs4_ss_getstate(dvp, ss_pn)) {
686 664 if (destdir != NULL) {
687 665 rfs4_ss_pnfree(ss_pn);
688 666 cl_ss->ss_pn = rfs4_ss_movestate(
689 667 statedir, destdir, dep->d_name);
690 668 } else {
691 669 cl_ss->ss_pn = ss_pn;
692 670 }
693 671 insque(cl_ss, oldstate);
694 672 } else {
695 673 rfs4_ss_pnfree(ss_pn);
696 674 }
697 675 }
|
↓ open down ↓ |
345 lines elided |
↑ open up ↑ |
698 676 }
699 677
700 678 out:
701 679 (void) VOP_CLOSE(dvp, FREAD, 1, (offset_t)0, CRED(), NULL);
702 680 VN_RELE(dvp);
703 681 if (dirt)
704 682 kmem_free((caddr_t)dirt, RFS4_SS_DIRSIZE);
705 683 }
706 684
707 685 static void
708 -rfs4_ss_init(void)
686 +rfs4_ss_init(nfs4_srv_t *nsrv4)
709 687 {
710 688 int npaths = 1;
711 689 char *default_dss_path = NFS4_DSS_VAR_DIR;
712 690
713 691 /* read the default stable storage state */
714 - rfs4_dss_readstate(npaths, &default_dss_path);
692 + rfs4_dss_readstate(nsrv4, npaths, &default_dss_path);
715 693
716 694 rfs4_ss_enabled = 1;
717 695 }
718 696
719 697 static void
720 -rfs4_ss_fini(void)
698 +rfs4_ss_fini(nfs4_srv_t *nsrv4)
721 699 {
722 700 rfs4_servinst_t *sip;
723 701
724 - mutex_enter(&rfs4_servinst_lock);
725 - sip = rfs4_cur_servinst;
702 + mutex_enter(&nsrv4->servinst_lock);
703 + sip = nsrv4->nfs4_cur_servinst;
726 704 while (sip != NULL) {
727 705 rfs4_dss_clear_oldstate(sip);
728 706 sip = sip->next;
729 707 }
730 - mutex_exit(&rfs4_servinst_lock);
708 + mutex_exit(&nsrv4->servinst_lock);
731 709 }
732 710
733 711 /*
734 712 * Remove all oldstate files referenced by this servinst.
735 713 */
736 714 static void
737 715 rfs4_dss_clear_oldstate(rfs4_servinst_t *sip)
738 716 {
739 717 rfs4_oldstate_t *os_head, *osp;
740 718
741 719 rw_enter(&sip->oldstate_lock, RW_WRITER);
742 720 os_head = sip->oldstate;
743 721
744 722 if (os_head == NULL) {
745 723 rw_exit(&sip->oldstate_lock);
746 724 return;
747 725 }
748 726
749 727 /* skip dummy entry */
750 728 osp = os_head->next;
751 729 while (osp != os_head) {
752 730 char *leaf = osp->ss_pn->leaf;
753 731 rfs4_oldstate_t *os_next;
754 732
755 733 rfs4_dss_remove_leaf(sip, NFS4_DSS_OLDSTATE_LEAF, leaf);
756 734
757 735 if (osp->cl_id4.id_val)
758 736 kmem_free(osp->cl_id4.id_val, osp->cl_id4.id_len);
759 737 rfs4_ss_pnfree(osp->ss_pn);
760 738
761 739 os_next = osp->next;
762 740 remque(osp);
763 741 kmem_free(osp, sizeof (rfs4_oldstate_t));
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
764 742 osp = os_next;
765 743 }
766 744
767 745 rw_exit(&sip->oldstate_lock);
768 746 }
769 747
770 748 /*
771 749 * Form the state and oldstate paths, and read in the stable storage files.
772 750 */
773 751 void
774 -rfs4_dss_readstate(int npaths, char **paths)
752 +rfs4_dss_readstate(nfs4_srv_t *nsrv4, int npaths, char **paths)
775 753 {
776 754 int i;
777 755 char *state, *oldstate;
778 756
779 757 state = kmem_alloc(MAXPATHLEN, KM_SLEEP);
780 758 oldstate = kmem_alloc(MAXPATHLEN, KM_SLEEP);
781 759
782 760 for (i = 0; i < npaths; i++) {
783 761 char *path = paths[i];
784 762
785 763 (void) sprintf(state, "%s/%s", path, NFS4_DSS_STATE_LEAF);
786 764 (void) sprintf(oldstate, "%s/%s", path, NFS4_DSS_OLDSTATE_LEAF);
787 765
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
788 766 /*
789 767 * Populate the current server instance's oldstate list.
790 768 *
791 769 * 1. Read stable storage data from old state directory,
792 770 * leaving its contents alone.
793 771 *
794 772 * 2. Read stable storage data from state directory,
795 773 * and move the latter's contents to old state
796 774 * directory.
797 775 */
798 - rfs4_ss_oldstate(rfs4_cur_servinst->oldstate, oldstate, NULL);
799 - rfs4_ss_oldstate(rfs4_cur_servinst->oldstate, state, oldstate);
776 + /* CSTYLED */
777 + rfs4_ss_oldstate(nsrv4->nfs4_cur_servinst->oldstate, oldstate, NULL);
778 + /* CSTYLED */
779 + rfs4_ss_oldstate(nsrv4->nfs4_cur_servinst->oldstate, state, oldstate);
800 780 }
801 781
802 782 kmem_free(state, MAXPATHLEN);
803 783 kmem_free(oldstate, MAXPATHLEN);
804 784 }
805 785
806 786
807 787 /*
808 788 * Check if we are still in grace and if the client can be
809 789 * granted permission to perform reclaims.
810 790 */
811 791 void
812 -rfs4_ss_chkclid(rfs4_client_t *cp)
792 +rfs4_ss_chkclid(nfs4_srv_t *nsrv4, rfs4_client_t *cp)
813 793 {
814 794 rfs4_servinst_t *sip;
815 795
816 796 /*
817 797 * It should be sufficient to check the oldstate data for just
818 798 * this client's instance. However, since our per-instance
819 799 * client grouping is solely temporal, HA-NFSv4 RG failover
820 800 * might result in clients of the same RG being partitioned into
821 801 * separate instances.
822 802 *
823 803 * Until the client grouping is improved, we must check the
824 804 * oldstate data for all instances with an active grace period.
825 805 *
826 806 * This also serves as the mechanism to remove stale oldstate data.
827 807 * The first time we check an instance after its grace period has
828 808 * expired, the oldstate data should be cleared.
829 809 *
830 810 * Start at the current instance, and walk the list backwards
831 811 * to the first.
832 812 */
833 - mutex_enter(&rfs4_servinst_lock);
834 - for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
813 + mutex_enter(&nsrv4->servinst_lock);
814 + for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
835 815 rfs4_ss_chkclid_sip(cp, sip);
836 816
837 817 /* if the above check found this client, we're done */
838 818 if (cp->rc_can_reclaim)
839 819 break;
840 820 }
841 - mutex_exit(&rfs4_servinst_lock);
821 + mutex_exit(&nsrv4->servinst_lock);
842 822 }
843 823
844 824 static void
845 825 rfs4_ss_chkclid_sip(rfs4_client_t *cp, rfs4_servinst_t *sip)
846 826 {
847 827 rfs4_oldstate_t *osp, *os_head;
848 828
849 829 /* short circuit everything if this server instance has no oldstate */
850 830 rw_enter(&sip->oldstate_lock, RW_READER);
851 831 os_head = sip->oldstate;
852 832 rw_exit(&sip->oldstate_lock);
853 833 if (os_head == NULL)
854 834 return;
855 835
856 836 /*
857 837 * If this server instance is no longer in a grace period then
858 838 * the client won't be able to reclaim. No further need for this
859 839 * instance's oldstate data, so it can be cleared.
860 840 */
861 841 if (!rfs4_servinst_in_grace(sip))
862 842 return;
863 843
864 844 /* this instance is still in grace; search for the clientid */
865 845
866 846 rw_enter(&sip->oldstate_lock, RW_READER);
867 847
868 848 os_head = sip->oldstate;
869 849 /* skip dummy entry */
870 850 osp = os_head->next;
871 851 while (osp != os_head) {
872 852 if (osp->cl_id4.id_len == cp->rc_nfs_client.id_len) {
873 853 if (bcmp(osp->cl_id4.id_val, cp->rc_nfs_client.id_val,
874 854 osp->cl_id4.id_len) == 0) {
875 855 cp->rc_can_reclaim = 1;
876 856 break;
877 857 }
878 858 }
879 859 osp = osp->next;
880 860 }
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
881 861
882 862 rw_exit(&sip->oldstate_lock);
883 863 }
884 864
885 865 /*
886 866 * Place client information into stable storage: 1/3.
887 867 * First, generate the leaf filename, from the client's IP address and
888 868 * the server-generated short-hand clientid.
889 869 */
890 870 void
891 -rfs4_ss_clid(rfs4_client_t *cp)
871 +rfs4_ss_clid(nfs4_srv_t *nsrv4, rfs4_client_t *cp)
892 872 {
893 873 const char *kinet_ntop6(uchar_t *, char *, size_t);
894 874 char leaf[MAXNAMELEN], buf[INET6_ADDRSTRLEN];
895 875 struct sockaddr *ca;
896 876 uchar_t *b;
897 877
898 878 if (rfs4_ss_enabled == 0) {
899 879 return;
900 880 }
901 881
902 882 buf[0] = 0;
903 883
904 884 ca = (struct sockaddr *)&cp->rc_addr;
905 885
906 886 /*
907 887 * Convert the caller's IP address to a dotted string
908 888 */
909 889 if (ca->sa_family == AF_INET) {
910 890 b = (uchar_t *)&((struct sockaddr_in *)ca)->sin_addr;
911 891 (void) sprintf(buf, "%03d.%03d.%03d.%03d", b[0] & 0xFF,
912 892 b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
913 893 } else if (ca->sa_family == AF_INET6) {
914 894 struct sockaddr_in6 *sin6;
915 895
916 896 sin6 = (struct sockaddr_in6 *)ca;
917 897 (void) kinet_ntop6((uchar_t *)&sin6->sin6_addr,
918 898 buf, INET6_ADDRSTRLEN);
919 899 }
920 900
921 901 (void) snprintf(leaf, MAXNAMELEN, "%s-%llx", buf,
922 902 (longlong_t)cp->rc_clientid);
923 - rfs4_ss_clid_write(cp, leaf);
903 + rfs4_ss_clid_write(nsrv4, cp, leaf);
924 904 }
925 905
926 906 /*
927 907 * Place client information into stable storage: 2/3.
928 908 * DSS: distributed stable storage: the file may need to be written to
929 909 * multiple directories.
930 910 */
931 911 static void
932 -rfs4_ss_clid_write(rfs4_client_t *cp, char *leaf)
912 +rfs4_ss_clid_write(nfs4_srv_t *nsrv4, rfs4_client_t *cp, char *leaf)
933 913 {
934 914 rfs4_servinst_t *sip;
935 915
936 916 /*
937 917 * It should be sufficient to write the leaf file to (all) DSS paths
938 918 * associated with just this client's instance. However, since our
939 919 * per-instance client grouping is solely temporal, HA-NFSv4 RG
940 920 * failover might result in us losing DSS data.
941 921 *
942 922 * Until the client grouping is improved, we must write the DSS data
943 923 * to all instances' paths. Start at the current instance, and
944 924 * walk the list backwards to the first.
945 925 */
946 - mutex_enter(&rfs4_servinst_lock);
947 - for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
926 + mutex_enter(&nsrv4->servinst_lock);
927 + for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
948 928 int i, npaths = sip->dss_npaths;
949 929
950 930 /* write the leaf file to all DSS paths */
951 931 for (i = 0; i < npaths; i++) {
952 932 rfs4_dss_path_t *dss_path = sip->dss_paths[i];
953 933
954 934 /* HA-NFSv4 path might have been failed-away from us */
955 935 if (dss_path == NULL)
956 936 continue;
957 937
958 938 rfs4_ss_clid_write_one(cp, dss_path->path, leaf);
959 939 }
960 940 }
961 - mutex_exit(&rfs4_servinst_lock);
941 + mutex_exit(&nsrv4->servinst_lock);
962 942 }
963 943
964 944 /*
965 945 * Place client information into stable storage: 3/3.
966 946 * Write the stable storage data to the requested file.
967 947 */
968 948 static void
969 949 rfs4_ss_clid_write_one(rfs4_client_t *cp, char *dss_path, char *leaf)
970 950 {
971 951 int ioflag;
972 952 int file_vers = NFS4_SS_VERSION;
973 953 size_t dirlen;
974 954 struct uio uio;
975 955 struct iovec iov[4];
976 956 char *dir;
977 957 rfs4_ss_pn_t *ss_pn;
978 958 vnode_t *vp;
979 959 nfs_client_id4 *cl_id4 = &(cp->rc_nfs_client);
980 960
981 961 /* allow 2 extra bytes for '/' & NUL */
982 962 dirlen = strlen(dss_path) + strlen(NFS4_DSS_STATE_LEAF) + 2;
983 963 dir = kmem_alloc(dirlen, KM_SLEEP);
984 964 (void) sprintf(dir, "%s/%s", dss_path, NFS4_DSS_STATE_LEAF);
985 965
986 966 ss_pn = rfs4_ss_pnalloc(dir, leaf);
987 967 /* rfs4_ss_pnalloc takes its own copy */
988 968 kmem_free(dir, dirlen);
989 969 if (ss_pn == NULL)
990 970 return;
991 971
992 972 if (vn_open(ss_pn->pn, UIO_SYSSPACE, FCREAT|FWRITE, 0600, &vp,
993 973 CRCREAT, 0)) {
994 974 rfs4_ss_pnfree(ss_pn);
995 975 return;
996 976 }
997 977
998 978 /*
999 979 * We need to record leaf - i.e. the filename - so that we know
1000 980 * what to remove, in the future. However, the dir part of cp->ss_pn
1001 981 * should never be referenced directly, since it's potentially only
1002 982 * one of several paths with this leaf in it.
1003 983 */
1004 984 if (cp->rc_ss_pn != NULL) {
1005 985 if (strcmp(cp->rc_ss_pn->leaf, leaf) == 0) {
1006 986 /* we've already recorded *this* leaf */
1007 987 rfs4_ss_pnfree(ss_pn);
1008 988 } else {
1009 989 /* replace with this leaf */
1010 990 rfs4_ss_pnfree(cp->rc_ss_pn);
1011 991 cp->rc_ss_pn = ss_pn;
1012 992 }
1013 993 } else {
1014 994 cp->rc_ss_pn = ss_pn;
1015 995 }
1016 996
1017 997 /*
1018 998 * Build a scatter list that points to the nfs_client_id4
1019 999 */
1020 1000 iov[0].iov_base = (caddr_t)&file_vers;
1021 1001 iov[0].iov_len = sizeof (int);
1022 1002 iov[1].iov_base = (caddr_t)&(cl_id4->verifier);
1023 1003 iov[1].iov_len = NFS4_VERIFIER_SIZE;
1024 1004 iov[2].iov_base = (caddr_t)&(cl_id4->id_len);
1025 1005 iov[2].iov_len = sizeof (uint_t);
1026 1006 iov[3].iov_base = (caddr_t)cl_id4->id_val;
1027 1007 iov[3].iov_len = cl_id4->id_len;
1028 1008
1029 1009 uio.uio_iov = iov;
1030 1010 uio.uio_iovcnt = 4;
1031 1011 uio.uio_loffset = 0;
1032 1012 uio.uio_segflg = UIO_SYSSPACE;
1033 1013 uio.uio_llimit = (rlim64_t)MAXOFFSET_T;
1034 1014 uio.uio_resid = cl_id4->id_len + sizeof (int) +
1035 1015 NFS4_VERIFIER_SIZE + sizeof (uint_t);
1036 1016
1037 1017 ioflag = uio.uio_fmode = (FWRITE|FSYNC);
1038 1018 uio.uio_extflg = UIO_COPY_DEFAULT;
1039 1019
1040 1020 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
1041 1021 /* write the full client id to the file. */
1042 1022 (void) VOP_WRITE(vp, &uio, ioflag, CRED(), NULL);
1043 1023 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
1044 1024
1045 1025 (void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
1046 1026 VN_RELE(vp);
1047 1027 }
1048 1028
1049 1029 /*
1050 1030 * DSS: distributed stable storage.
1051 1031 * Unpack the list of paths passed by nfsd.
1052 1032 * Use nvlist_alloc(9F) to manage the data.
1053 1033 * The caller is responsible for allocating and freeing the buffer.
1054 1034 */
1055 1035 int
1056 1036 rfs4_dss_setpaths(char *buf, size_t buflen)
1057 1037 {
1058 1038 int error;
1059 1039
1060 1040 /*
1061 1041 * If this is a "warm start", i.e. we previously had DSS paths,
1062 1042 * preserve the old paths.
1063 1043 */
1064 1044 if (rfs4_dss_paths != NULL) {
1065 1045 /*
1066 1046 * Before we lose the ptr, destroy the nvlist and pathnames
1067 1047 * array from the warm start before this one.
1068 1048 */
1069 1049 nvlist_free(rfs4_dss_oldpaths);
1070 1050 rfs4_dss_oldpaths = rfs4_dss_paths;
1071 1051 }
1072 1052
1073 1053 /* unpack the buffer into a searchable nvlist */
1074 1054 error = nvlist_unpack(buf, buflen, &rfs4_dss_paths, KM_SLEEP);
1075 1055 if (error)
1076 1056 return (error);
1077 1057
1078 1058 /*
1079 1059 * Search the nvlist for the pathnames nvpair (which is the only nvpair
1080 1060 * in the list, and record its location.
1081 1061 */
1082 1062 error = nvlist_lookup_string_array(rfs4_dss_paths, NFS4_DSS_NVPAIR_NAME,
1083 1063 &rfs4_dss_newpaths, &rfs4_dss_numnewpaths);
1084 1064 return (error);
1085 1065 }
1086 1066
1087 1067 /*
1088 1068 * Ultimately the nfssys() call NFS4_CLR_STATE endsup here
1089 1069 * to find and mark the client for forced expire.
1090 1070 */
1091 1071 static void
1092 1072 rfs4_client_scrub(rfs4_entry_t ent, void *arg)
1093 1073 {
1094 1074 rfs4_client_t *cp = (rfs4_client_t *)ent;
1095 1075 struct nfs4clrst_args *clr = arg;
1096 1076 struct sockaddr_in6 *ent_sin6;
1097 1077 struct in6_addr clr_in6;
1098 1078 struct sockaddr_in *ent_sin;
1099 1079 struct in_addr clr_in;
1100 1080
1101 1081 if (clr->addr_type != cp->rc_addr.ss_family) {
1102 1082 return;
1103 1083 }
1104 1084
1105 1085 switch (clr->addr_type) {
1106 1086
1107 1087 case AF_INET6:
1108 1088 /* copyin the address from user space */
1109 1089 if (copyin(clr->ap, &clr_in6, sizeof (clr_in6))) {
1110 1090 break;
1111 1091 }
1112 1092
1113 1093 ent_sin6 = (struct sockaddr_in6 *)&cp->rc_addr;
1114 1094
1115 1095 /*
1116 1096 * now compare, and if equivalent mark entry
1117 1097 * for forced expiration
1118 1098 */
1119 1099 if (IN6_ARE_ADDR_EQUAL(&ent_sin6->sin6_addr, &clr_in6)) {
1120 1100 cp->rc_forced_expire = 1;
1121 1101 }
1122 1102 break;
1123 1103
1124 1104 case AF_INET:
1125 1105 /* copyin the address from user space */
1126 1106 if (copyin(clr->ap, &clr_in, sizeof (clr_in))) {
1127 1107 break;
1128 1108 }
1129 1109
1130 1110 ent_sin = (struct sockaddr_in *)&cp->rc_addr;
1131 1111
1132 1112 /*
1133 1113 * now compare, and if equivalent mark entry
1134 1114 * for forced expiration
1135 1115 */
1136 1116 if (ent_sin->sin_addr.s_addr == clr_in.s_addr) {
1137 1117 cp->rc_forced_expire = 1;
1138 1118 }
1139 1119 break;
1140 1120
1141 1121 default:
1142 1122 /* force this assert to fail */
1143 1123 ASSERT(clr->addr_type != clr->addr_type);
|
↓ open down ↓ |
172 lines elided |
↑ open up ↑ |
1144 1124 }
1145 1125 }
1146 1126
1147 1127 /*
1148 1128 * This is called from nfssys() in order to clear server state
1149 1129 * for the specified client IP Address.
1150 1130 */
1151 1131 void
1152 1132 rfs4_clear_client_state(struct nfs4clrst_args *clr)
1153 1133 {
1154 - (void) rfs4_dbe_walk(rfs4_client_tab, rfs4_client_scrub, clr);
1134 + nfs4_srv_t *nsrv4;
1135 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1136 + (void) rfs4_dbe_walk(nsrv4->rfs4_client_tab, rfs4_client_scrub, clr);
1155 1137 }
1156 1138
1157 1139 /*
1158 1140 * Used to initialize the NFSv4 server's state or database. All of
1159 - * the tables are created and timers are set. Only called when NFSv4
1160 - * service is provided.
1141 + * the tables are created and timers are set.
1161 1142 */
1162 1143 void
1163 -rfs4_state_init()
1144 +rfs4_state_g_init()
1164 1145 {
1165 - int start_grace;
1166 1146 extern boolean_t rfs4_cpr_callb(void *, int);
1167 - char *dss_path = NFS4_DSS_VAR_DIR;
1168 - time_t start_time;
1147 + /*
1148 + * Add a CPR callback so that we can update client
1149 + * access times to extend the lease after a suspend
1150 + * and resume (using the same class as rpcmod/connmgr)
1151 + */
1152 + cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
1169 1153
1170 - mutex_enter(&rfs4_state_lock);
1154 + /*
1155 + * NFSv4 server state databases
1156 + *
1157 + * Initilized when the module is loaded and used by NFSv4 state tables.
1158 + * These kmem_cache free pools are used globally, the NFSv4 state
1159 + * tables which make use of these kmem_cache free pools are per zone.
1160 + *
1161 + * initialize the global kmem_cache free pools which will be used by
1162 + * the NFSv4 state tables.
1163 + */
1164 + /* CSTYLED */
1165 + rfs4_client_mem_cache = nfs4_init_mem_cache("Client_entry_cache", 2, sizeof (rfs4_client_t), 0);
1166 + /* CSTYLED */
1167 + rfs4_clntIP_mem_cache = nfs4_init_mem_cache("ClntIP_entry_cache", 1, sizeof (rfs4_clntip_t), 1);
1168 + /* CSTYLED */
1169 + rfs4_openown_mem_cache = nfs4_init_mem_cache("OpenOwner_entry_cache", 1, sizeof (rfs4_openowner_t), 2);
1170 + /* CSTYLED */
1171 + rfs4_openstID_mem_cache = nfs4_init_mem_cache("OpenStateID_entry_cache", 3, sizeof (rfs4_state_t), 3);
1172 + /* CSTYLED */
1173 + rfs4_lockstID_mem_cache = nfs4_init_mem_cache("LockStateID_entry_cache", 3, sizeof (rfs4_lo_state_t), 4);
1174 + /* CSTYLED */
1175 + rfs4_lockown_mem_cache = nfs4_init_mem_cache("Lockowner_entry_cache", 2, sizeof (rfs4_lockowner_t), 5);
1176 + /* CSTYLED */
1177 + rfs4_file_mem_cache = nfs4_init_mem_cache("File_entry_cache", 1, sizeof (rfs4_file_t), 6);
1178 + /* CSTYLED */
1179 + rfs4_delegstID_mem_cache = nfs4_init_mem_cache("DelegStateID_entry_cache", 2, sizeof (rfs4_deleg_state_t), 7);
1171 1180
1181 + rfs4_client_clrst = rfs4_clear_client_state;
1182 +}
1183 +
1184 +
1185 +/*
1186 + * Used at server shutdown to cleanup all of the NFSv4 server's structures
1187 + * and other state.
1188 + */
1189 +void
1190 +rfs4_state_g_fini()
1191 +{
1192 + int i;
1172 1193 /*
1173 - * If the server state database has already been initialized,
1174 - * skip it
1194 + * Cleanup the CPR callback.
1175 1195 */
1176 - if (rfs4_server_state != NULL) {
1177 - mutex_exit(&rfs4_state_lock);
1178 - return;
1196 + if (cpr_id)
1197 + (void) callb_delete(cpr_id);
1198 +
1199 + rfs4_client_clrst = NULL;
1200 +
1201 + /* free the NFSv4 state databases */
1202 + for (i = 0; i < RFS4_DB_MEM_CACHE_NUM; i++) {
1203 + kmem_cache_destroy(rfs4_db_mem_cache_table[i].r_db_mem_cache);
1204 + rfs4_db_mem_cache_table[i].r_db_mem_cache = NULL;
1179 1205 }
1180 1206
1181 - rw_init(&rfs4_findclient_lock, NULL, RW_DEFAULT, NULL);
1207 + rfs4_client_mem_cache = NULL;
1208 + rfs4_clntIP_mem_cache = NULL;
1209 + rfs4_openown_mem_cache = NULL;
1210 + rfs4_openstID_mem_cache = NULL;
1211 + rfs4_lockstID_mem_cache = NULL;
1212 + rfs4_lockown_mem_cache = NULL;
1213 + rfs4_file_mem_cache = NULL;
1214 + rfs4_delegstID_mem_cache = NULL;
1182 1215
1216 + /* DSS: distributed stable storage */
1217 + nvlist_free(rfs4_dss_oldpaths);
1218 + nvlist_free(rfs4_dss_paths);
1219 + rfs4_dss_paths = rfs4_dss_oldpaths = NULL;
1220 +}
1221 +
1222 +/*
1223 + * Used to initialize the per zone NFSv4 server's state
1224 + */
1225 +void
1226 +rfs4_state_zone_init(nfs4_srv_t *nsrv4)
1227 +{
1228 + time_t start_time;
1229 + int start_grace;
1230 + char *dss_path = NFS4_DSS_VAR_DIR;
1231 +
1232 + /* DSS: distributed stable storage: initialise served paths list */
1233 + nsrv4->dss_pathlist = NULL;
1234 +
1183 1235 /*
1184 1236 * Set the boot time. If the server
1185 1237 * has been restarted quickly and has had the opportunity to
1186 1238 * service clients, then the start_time needs to be bumped
1187 1239 * regardless. A small window but it exists...
1188 1240 */
1189 1241 start_time = gethrestime_sec();
1190 - if (rfs4_start_time < start_time)
1191 - rfs4_start_time = start_time;
1242 + if (nsrv4->rfs4_start_time < start_time)
1243 + nsrv4->rfs4_start_time = start_time;
1192 1244 else
1193 - rfs4_start_time++;
1245 + nsrv4->rfs4_start_time++;
1194 1246
1195 - /* DSS: distributed stable storage: initialise served paths list */
1196 - rfs4_dss_pathlist = NULL;
1197 -
1198 1247 /*
1199 1248 * Create the first server instance, or a new one if the server has
1200 1249 * been restarted; see above comments on rfs4_start_time. Don't
1201 1250 * start its grace period; that will be done later, to maximise the
1202 1251 * clients' recovery window.
1203 1252 */
1204 1253 start_grace = 0;
1205 - rfs4_servinst_create(start_grace, 1, &dss_path);
1254 + rfs4_servinst_create(nsrv4, start_grace, 1, &dss_path);
1206 1255
1207 1256 /* reset the "first NFSv4 request" status */
1208 - rfs4_seen_first_compound = 0;
1257 + nsrv4->seen_first_compound = 0;
1209 1258
1259 + mutex_enter(&nsrv4->state_lock);
1260 +
1210 1261 /*
1211 - * Add a CPR callback so that we can update client
1212 - * access times to extend the lease after a suspend
1213 - * and resume (using the same class as rpcmod/connmgr)
1262 + * If the server state database has already been initialized,
1263 + * skip it
1214 1264 */
1215 - cpr_id = callb_add(rfs4_cpr_callb, 0, CB_CL_CPR_RPC, "rfs4");
1265 + if (nsrv4->nfs4_server_state != NULL) {
1266 + mutex_exit(&nsrv4->state_lock);
1267 + return;
1268 + }
1216 1269
1270 + rw_init(&nsrv4->rfs4_findclient_lock, NULL, RW_DEFAULT, NULL);
1271 +
1217 1272 /* set the various cache timers for table creation */
1218 - if (rfs4_client_cache_time == 0)
1219 - rfs4_client_cache_time = CLIENT_CACHE_TIME;
1220 - if (rfs4_openowner_cache_time == 0)
1221 - rfs4_openowner_cache_time = OPENOWNER_CACHE_TIME;
1222 - if (rfs4_state_cache_time == 0)
1223 - rfs4_state_cache_time = STATE_CACHE_TIME;
1224 - if (rfs4_lo_state_cache_time == 0)
1225 - rfs4_lo_state_cache_time = LO_STATE_CACHE_TIME;
1226 - if (rfs4_lockowner_cache_time == 0)
1227 - rfs4_lockowner_cache_time = LOCKOWNER_CACHE_TIME;
1228 - if (rfs4_file_cache_time == 0)
1229 - rfs4_file_cache_time = FILE_CACHE_TIME;
1230 - if (rfs4_deleg_state_cache_time == 0)
1231 - rfs4_deleg_state_cache_time = DELEG_STATE_CACHE_TIME;
1273 + if (nsrv4->rfs4_client_cache_time == 0)
1274 + nsrv4->rfs4_client_cache_time = CLIENT_CACHE_TIME;
1275 + if (nsrv4->rfs4_openowner_cache_time == 0)
1276 + nsrv4->rfs4_openowner_cache_time = OPENOWNER_CACHE_TIME;
1277 + if (nsrv4->rfs4_state_cache_time == 0)
1278 + nsrv4->rfs4_state_cache_time = STATE_CACHE_TIME;
1279 + if (nsrv4->rfs4_lo_state_cache_time == 0)
1280 + nsrv4->rfs4_lo_state_cache_time = LO_STATE_CACHE_TIME;
1281 + if (nsrv4->rfs4_lockowner_cache_time == 0)
1282 + nsrv4->rfs4_lockowner_cache_time = LOCKOWNER_CACHE_TIME;
1283 + if (nsrv4->rfs4_file_cache_time == 0)
1284 + nsrv4->rfs4_file_cache_time = FILE_CACHE_TIME;
1285 + if (nsrv4->rfs4_deleg_state_cache_time == 0)
1286 + nsrv4->rfs4_deleg_state_cache_time = DELEG_STATE_CACHE_TIME;
1232 1287
1233 1288 /* Create the overall database to hold all server state */
1234 - rfs4_server_state = rfs4_database_create(rfs4_database_debug);
1289 + nsrv4->nfs4_server_state = rfs4_database_create(rfs4_database_debug);
1235 1290
1236 1291 /* Now create the individual tables */
1237 - rfs4_client_cache_time *= rfs4_lease_time;
1238 - rfs4_client_tab = rfs4_table_create(rfs4_server_state,
1292 + nsrv4->rfs4_client_cache_time *= rfs4_lease_time;
1293 + nsrv4->rfs4_client_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1239 1294 "Client",
1240 - rfs4_client_cache_time,
1295 + nsrv4->rfs4_client_cache_time,
1241 1296 2,
1242 1297 rfs4_client_create,
1243 1298 rfs4_client_destroy,
1244 1299 rfs4_client_expiry,
1245 1300 sizeof (rfs4_client_t),
1246 1301 TABSIZE,
1247 1302 MAXTABSZ/8, 100);
1248 - rfs4_nfsclnt_idx = rfs4_index_create(rfs4_client_tab,
1303 + nsrv4->rfs4_nfsclnt_idx = rfs4_index_create(nsrv4->rfs4_client_tab,
1249 1304 "nfs_client_id4", nfsclnt_hash,
1250 1305 nfsclnt_compare, nfsclnt_mkkey,
1251 1306 TRUE);
1252 - rfs4_clientid_idx = rfs4_index_create(rfs4_client_tab,
1307 + nsrv4->rfs4_clientid_idx = rfs4_index_create(nsrv4->rfs4_client_tab,
1253 1308 "client_id", clientid_hash,
1254 1309 clientid_compare, clientid_mkkey,
1255 1310 FALSE);
1256 1311
1257 - rfs4_clntip_cache_time = 86400 * 365; /* about a year */
1258 - rfs4_clntip_tab = rfs4_table_create(rfs4_server_state,
1312 + nsrv4->rfs4_clntip_cache_time = 86400 * 365; /* about a year */
1313 + nsrv4->rfs4_clntip_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1259 1314 "ClntIP",
1260 - rfs4_clntip_cache_time,
1315 + nsrv4->rfs4_clntip_cache_time,
1261 1316 1,
1262 1317 rfs4_clntip_create,
1263 1318 rfs4_clntip_destroy,
1264 1319 rfs4_clntip_expiry,
1265 1320 sizeof (rfs4_clntip_t),
1266 1321 TABSIZE,
1267 1322 MAXTABSZ, 100);
1268 - rfs4_clntip_idx = rfs4_index_create(rfs4_clntip_tab,
1323 + nsrv4->rfs4_clntip_idx = rfs4_index_create(nsrv4->rfs4_clntip_tab,
1269 1324 "client_ip", clntip_hash,
1270 1325 clntip_compare, clntip_mkkey,
1271 1326 TRUE);
1272 1327
1273 - rfs4_openowner_cache_time *= rfs4_lease_time;
1274 - rfs4_openowner_tab = rfs4_table_create(rfs4_server_state,
1328 + nsrv4->rfs4_openowner_cache_time *= rfs4_lease_time;
1329 + nsrv4->rfs4_openowner_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1275 1330 "OpenOwner",
1276 - rfs4_openowner_cache_time,
1331 + nsrv4->rfs4_openowner_cache_time,
1277 1332 1,
1278 1333 rfs4_openowner_create,
1279 1334 rfs4_openowner_destroy,
1280 1335 rfs4_openowner_expiry,
1281 1336 sizeof (rfs4_openowner_t),
1282 1337 TABSIZE,
1283 1338 MAXTABSZ, 100);
1284 - rfs4_openowner_idx = rfs4_index_create(rfs4_openowner_tab,
1339 + nsrv4->rfs4_openowner_idx = rfs4_index_create(nsrv4->rfs4_openowner_tab,
1285 1340 "open_owner4", openowner_hash,
1286 1341 openowner_compare,
1287 1342 openowner_mkkey, TRUE);
1288 1343
1289 - rfs4_state_cache_time *= rfs4_lease_time;
1290 - rfs4_state_tab = rfs4_table_create(rfs4_server_state,
1344 + nsrv4->rfs4_state_cache_time *= rfs4_lease_time;
1345 + nsrv4->rfs4_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1291 1346 "OpenStateID",
1292 - rfs4_state_cache_time,
1347 + nsrv4->rfs4_state_cache_time,
1293 1348 3,
1294 1349 rfs4_state_create,
1295 1350 rfs4_state_destroy,
1296 1351 rfs4_state_expiry,
1297 1352 sizeof (rfs4_state_t),
1298 1353 TABSIZE,
1299 1354 MAXTABSZ, 100);
1300 1355
1301 - rfs4_state_owner_file_idx = rfs4_index_create(rfs4_state_tab,
1356 + /* CSTYLED */
1357 + nsrv4->rfs4_state_owner_file_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1302 1358 "Openowner-File",
1303 1359 state_owner_file_hash,
1304 1360 state_owner_file_compare,
1305 1361 state_owner_file_mkkey, TRUE);
1306 1362
1307 - rfs4_state_idx = rfs4_index_create(rfs4_state_tab,
1363 + nsrv4->rfs4_state_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1308 1364 "State-id", state_hash,
1309 1365 state_compare, state_mkkey, FALSE);
1310 1366
1311 - rfs4_state_file_idx = rfs4_index_create(rfs4_state_tab,
1367 + nsrv4->rfs4_state_file_idx = rfs4_index_create(nsrv4->rfs4_state_tab,
1312 1368 "File", state_file_hash,
1313 1369 state_file_compare, state_file_mkkey,
1314 1370 FALSE);
1315 1371
1316 - rfs4_lo_state_cache_time *= rfs4_lease_time;
1317 - rfs4_lo_state_tab = rfs4_table_create(rfs4_server_state,
1372 + nsrv4->rfs4_lo_state_cache_time *= rfs4_lease_time;
1373 + nsrv4->rfs4_lo_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1318 1374 "LockStateID",
1319 - rfs4_lo_state_cache_time,
1375 + nsrv4->rfs4_lo_state_cache_time,
1320 1376 2,
1321 1377 rfs4_lo_state_create,
1322 1378 rfs4_lo_state_destroy,
1323 1379 rfs4_lo_state_expiry,
1324 1380 sizeof (rfs4_lo_state_t),
1325 1381 TABSIZE,
1326 1382 MAXTABSZ, 100);
1327 1383
1328 - rfs4_lo_state_owner_idx = rfs4_index_create(rfs4_lo_state_tab,
1384 + /* CSTYLED */
1385 + nsrv4->rfs4_lo_state_owner_idx = rfs4_index_create(nsrv4->rfs4_lo_state_tab,
1329 1386 "lockownerxstate",
1330 1387 lo_state_lo_hash,
1331 1388 lo_state_lo_compare,
1332 1389 lo_state_lo_mkkey, TRUE);
1333 1390
1334 - rfs4_lo_state_idx = rfs4_index_create(rfs4_lo_state_tab,
1391 + nsrv4->rfs4_lo_state_idx = rfs4_index_create(nsrv4->rfs4_lo_state_tab,
1335 1392 "State-id",
1336 1393 lo_state_hash, lo_state_compare,
1337 1394 lo_state_mkkey, FALSE);
1338 1395
1339 - rfs4_lockowner_cache_time *= rfs4_lease_time;
1396 + nsrv4->rfs4_lockowner_cache_time *= rfs4_lease_time;
1340 1397
1341 - rfs4_lockowner_tab = rfs4_table_create(rfs4_server_state,
1398 + nsrv4->rfs4_lockowner_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1342 1399 "Lockowner",
1343 - rfs4_lockowner_cache_time,
1400 + nsrv4->rfs4_lockowner_cache_time,
1344 1401 2,
1345 1402 rfs4_lockowner_create,
1346 1403 rfs4_lockowner_destroy,
1347 1404 rfs4_lockowner_expiry,
1348 1405 sizeof (rfs4_lockowner_t),
1349 1406 TABSIZE,
1350 1407 MAXTABSZ, 100);
1351 1408
1352 - rfs4_lockowner_idx = rfs4_index_create(rfs4_lockowner_tab,
1409 + nsrv4->rfs4_lockowner_idx = rfs4_index_create(nsrv4->rfs4_lockowner_tab,
1353 1410 "lock_owner4", lockowner_hash,
1354 1411 lockowner_compare,
1355 1412 lockowner_mkkey, TRUE);
1356 1413
1357 - rfs4_lockowner_pid_idx = rfs4_index_create(rfs4_lockowner_tab,
1414 + /* CSTYLED */
1415 + nsrv4->rfs4_lockowner_pid_idx = rfs4_index_create(nsrv4->rfs4_lockowner_tab,
1358 1416 "pid", pid_hash,
1359 1417 pid_compare, pid_mkkey,
1360 1418 FALSE);
1361 1419
1362 - rfs4_file_cache_time *= rfs4_lease_time;
1363 - rfs4_file_tab = rfs4_table_create(rfs4_server_state,
1420 + nsrv4->rfs4_file_cache_time *= rfs4_lease_time;
1421 + nsrv4->rfs4_file_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1364 1422 "File",
1365 - rfs4_file_cache_time,
1423 + nsrv4->rfs4_file_cache_time,
1366 1424 1,
1367 1425 rfs4_file_create,
1368 1426 rfs4_file_destroy,
1369 1427 NULL,
1370 1428 sizeof (rfs4_file_t),
1371 1429 TABSIZE,
1372 1430 MAXTABSZ, -1);
1373 1431
1374 - rfs4_file_idx = rfs4_index_create(rfs4_file_tab,
1432 + nsrv4->rfs4_file_idx = rfs4_index_create(nsrv4->rfs4_file_tab,
1375 1433 "Filehandle", file_hash,
1376 1434 file_compare, file_mkkey, TRUE);
1377 1435
1378 - rfs4_deleg_state_cache_time *= rfs4_lease_time;
1379 - rfs4_deleg_state_tab = rfs4_table_create(rfs4_server_state,
1436 + nsrv4->rfs4_deleg_state_cache_time *= rfs4_lease_time;
1437 + /* CSTYLED */
1438 + nsrv4->rfs4_deleg_state_tab = rfs4_table_create(nsrv4->nfs4_server_state,
1380 1439 "DelegStateID",
1381 - rfs4_deleg_state_cache_time,
1440 + nsrv4->rfs4_deleg_state_cache_time,
1382 1441 2,
1383 1442 rfs4_deleg_state_create,
1384 1443 rfs4_deleg_state_destroy,
1385 1444 rfs4_deleg_state_expiry,
1386 1445 sizeof (rfs4_deleg_state_t),
1387 1446 TABSIZE,
1388 1447 MAXTABSZ, 100);
1389 - rfs4_deleg_idx = rfs4_index_create(rfs4_deleg_state_tab,
1448 + nsrv4->rfs4_deleg_idx = rfs4_index_create(nsrv4->rfs4_deleg_state_tab,
1390 1449 "DelegByFileClient",
1391 1450 deleg_hash,
1392 1451 deleg_compare,
1393 1452 deleg_mkkey, TRUE);
1394 1453
1395 - rfs4_deleg_state_idx = rfs4_index_create(rfs4_deleg_state_tab,
1454 + /* CSTYLED */
1455 + nsrv4->rfs4_deleg_state_idx = rfs4_index_create(nsrv4->rfs4_deleg_state_tab,
1396 1456 "DelegState",
1397 1457 deleg_state_hash,
1398 1458 deleg_state_compare,
1399 1459 deleg_state_mkkey, FALSE);
1400 1460
1461 + mutex_exit(&nsrv4->state_lock);
1462 +
1401 1463 /*
1402 1464 * Init the stable storage.
1403 1465 */
1404 - rfs4_ss_init();
1405 -
1406 - rfs4_client_clrst = rfs4_clear_client_state;
1407 -
1408 - mutex_exit(&rfs4_state_lock);
1466 + rfs4_ss_init(nsrv4);
1409 1467 }
1410 1468
1411 -
1412 1469 /*
1413 - * Used at server shutdown to cleanup all of the NFSv4 server's structures
1414 - * and other state.
1470 + * Used at server shutdown to cleanup all of NFSv4 server's zone structures
1471 + * and state.
1415 1472 */
1416 1473 void
1417 -rfs4_state_fini()
1474 +rfs4_state_zone_fini()
1418 1475 {
1419 1476 rfs4_database_t *dbp;
1477 + nfs4_srv_t *nsrv4;
1478 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1420 1479
1421 - mutex_enter(&rfs4_state_lock);
1480 + rfs4_set_deleg_policy(nsrv4, SRV_NEVER_DELEGATE);
1422 1481
1423 - if (rfs4_server_state == NULL) {
1424 - mutex_exit(&rfs4_state_lock);
1482 + mutex_enter(&nsrv4->state_lock);
1483 +
1484 + if (nsrv4->nfs4_server_state == NULL) {
1485 + mutex_exit(&nsrv4->state_lock);
1425 1486 return;
1426 1487 }
1427 1488
1428 - rfs4_client_clrst = NULL;
1489 + /* destroy server instances and current instance ptr */
1490 + rfs4_servinst_destroy_all(nsrv4);
1429 1491
1430 - rfs4_set_deleg_policy(SRV_NEVER_DELEGATE);
1431 - dbp = rfs4_server_state;
1432 - rfs4_server_state = NULL;
1492 + /* reset the "first NFSv4 request" status */
1493 + nsrv4->seen_first_compound = 0;
1433 1494
1434 - /*
1435 - * Cleanup the CPR callback.
1436 - */
1437 - if (cpr_id)
1438 - (void) callb_delete(cpr_id);
1495 + dbp = nsrv4->nfs4_server_state;
1496 + nsrv4->nfs4_server_state = NULL;
1439 1497
1440 - rw_destroy(&rfs4_findclient_lock);
1498 + rw_destroy(&nsrv4->rfs4_findclient_lock);
1441 1499
1442 1500 /* First stop all of the reaper threads in the database */
1443 1501 rfs4_database_shutdown(dbp);
1444 - /* clean up any dangling stable storage structures */
1445 - rfs4_ss_fini();
1446 - /* Now actually destroy/release the database and its tables */
1447 - rfs4_database_destroy(dbp);
1502 + /*
1503 + * XXX workaround
1504 + * Skip destrying the state database yet just in case there
1505 + * are unfinished operations depending on it.
1506 + */
1507 + /* Now destroy/release the database tables */
1508 + /* rfs4_database_destroy(dbp); */
1448 1509
1449 1510 /* Reset the cache timers for next time */
1450 - rfs4_client_cache_time = 0;
1451 - rfs4_openowner_cache_time = 0;
1452 - rfs4_state_cache_time = 0;
1453 - rfs4_lo_state_cache_time = 0;
1454 - rfs4_lockowner_cache_time = 0;
1455 - rfs4_file_cache_time = 0;
1456 - rfs4_deleg_state_cache_time = 0;
1511 + nsrv4->rfs4_client_cache_time = 0;
1512 + nsrv4->rfs4_openowner_cache_time = 0;
1513 + nsrv4->rfs4_state_cache_time = 0;
1514 + nsrv4->rfs4_lo_state_cache_time = 0;
1515 + nsrv4->rfs4_lockowner_cache_time = 0;
1516 + nsrv4->rfs4_file_cache_time = 0;
1517 + nsrv4->rfs4_deleg_state_cache_time = 0;
1457 1518
1458 - mutex_exit(&rfs4_state_lock);
1519 + mutex_exit(&nsrv4->state_lock);
1459 1520
1460 - /* destroy server instances and current instance ptr */
1461 - rfs4_servinst_destroy_all();
1462 -
1463 - /* reset the "first NFSv4 request" status */
1464 - rfs4_seen_first_compound = 0;
1465 -
1466 - /* DSS: distributed stable storage */
1467 - nvlist_free(rfs4_dss_oldpaths);
1468 - nvlist_free(rfs4_dss_paths);
1469 - rfs4_dss_paths = rfs4_dss_oldpaths = NULL;
1521 + /* clean up any dangling stable storage structures */
1522 + rfs4_ss_fini(nsrv4);
1470 1523 }
1471 1524
1472 1525 typedef union {
1473 1526 struct {
1474 1527 uint32_t start_time;
1475 1528 uint32_t c_id;
1476 1529 } impl_id;
1477 1530 clientid4 id4;
1478 1531 } cid;
1479 1532
1480 1533 static int foreign_stateid(stateid_t *id);
1481 1534 static int foreign_clientid(cid *cidp);
1482 1535 static void embed_nodeid(cid *cidp);
1483 1536
1484 1537 typedef union {
1485 1538 struct {
1486 1539 uint32_t c_id;
1487 1540 uint32_t gen_num;
1488 1541 } cv_impl;
1489 1542 verifier4 confirm_verf;
1490 1543 } scid_confirm_verf;
1491 1544
1492 1545 static uint32_t
1493 1546 clientid_hash(void *key)
1494 1547 {
1495 1548 cid *idp = key;
1496 1549
1497 1550 return (idp->impl_id.c_id);
1498 1551 }
1499 1552
1500 1553 static bool_t
1501 1554 clientid_compare(rfs4_entry_t entry, void *key)
1502 1555 {
1503 1556 rfs4_client_t *cp = (rfs4_client_t *)entry;
1504 1557 clientid4 *idp = key;
1505 1558
1506 1559 return (*idp == cp->rc_clientid);
1507 1560 }
1508 1561
1509 1562 static void *
1510 1563 clientid_mkkey(rfs4_entry_t entry)
1511 1564 {
1512 1565 rfs4_client_t *cp = (rfs4_client_t *)entry;
1513 1566
1514 1567 return (&cp->rc_clientid);
1515 1568 }
1516 1569
1517 1570 static uint32_t
1518 1571 nfsclnt_hash(void *key)
1519 1572 {
1520 1573 nfs_client_id4 *client = key;
1521 1574 int i;
1522 1575 uint32_t hash = 0;
1523 1576
1524 1577 for (i = 0; i < client->id_len; i++) {
1525 1578 hash <<= 1;
1526 1579 hash += (uint_t)client->id_val[i];
1527 1580 }
1528 1581 return (hash);
1529 1582 }
1530 1583
1531 1584
1532 1585 static bool_t
1533 1586 nfsclnt_compare(rfs4_entry_t entry, void *key)
1534 1587 {
1535 1588 rfs4_client_t *cp = (rfs4_client_t *)entry;
1536 1589 nfs_client_id4 *nfs_client = key;
1537 1590
1538 1591 if (cp->rc_nfs_client.id_len != nfs_client->id_len)
1539 1592 return (FALSE);
1540 1593
1541 1594 return (bcmp(cp->rc_nfs_client.id_val, nfs_client->id_val,
1542 1595 nfs_client->id_len) == 0);
1543 1596 }
1544 1597
1545 1598 static void *
1546 1599 nfsclnt_mkkey(rfs4_entry_t entry)
1547 1600 {
1548 1601 rfs4_client_t *cp = (rfs4_client_t *)entry;
1549 1602
1550 1603 return (&cp->rc_nfs_client);
1551 1604 }
1552 1605
1553 1606 static bool_t
1554 1607 rfs4_client_expiry(rfs4_entry_t u_entry)
1555 1608 {
1556 1609 rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1557 1610 bool_t cp_expired;
1558 1611
1559 1612 if (rfs4_dbe_is_invalid(cp->rc_dbe)) {
1560 1613 cp->rc_ss_remove = 1;
1561 1614 return (TRUE);
1562 1615 }
1563 1616 /*
1564 1617 * If the sysadmin has used clear_locks for this
1565 1618 * entry then forced_expire will be set and we
1566 1619 * want this entry to be reaped. Or the entry
1567 1620 * has exceeded its lease period.
1568 1621 */
1569 1622 cp_expired = (cp->rc_forced_expire ||
1570 1623 (gethrestime_sec() - cp->rc_last_access
1571 1624 > rfs4_lease_time));
1572 1625
1573 1626 if (!cp->rc_ss_remove && cp_expired)
|
↓ open down ↓ |
94 lines elided |
↑ open up ↑ |
1574 1627 cp->rc_ss_remove = 1;
1575 1628 return (cp_expired);
1576 1629 }
1577 1630
1578 1631 /*
1579 1632 * Remove the leaf file from all distributed stable storage paths.
1580 1633 */
1581 1634 static void
1582 1635 rfs4_dss_remove_cpleaf(rfs4_client_t *cp)
1583 1636 {
1637 + nfs4_srv_t *nsrv4;
1584 1638 rfs4_servinst_t *sip;
1585 1639 char *leaf = cp->rc_ss_pn->leaf;
1586 1640
1587 1641 /*
1588 1642 * since the state files are written to all DSS
1589 1643 * paths we must remove this leaf file instance
1590 1644 * from all server instances.
1591 1645 */
1592 1646
1593 - mutex_enter(&rfs4_servinst_lock);
1594 - for (sip = rfs4_cur_servinst; sip != NULL; sip = sip->prev) {
1647 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1648 + mutex_enter(&nsrv4->servinst_lock);
1649 + for (sip = nsrv4->nfs4_cur_servinst; sip != NULL; sip = sip->prev) {
1595 1650 /* remove the leaf file associated with this server instance */
1596 1651 rfs4_dss_remove_leaf(sip, NFS4_DSS_STATE_LEAF, leaf);
1597 1652 }
1598 - mutex_exit(&rfs4_servinst_lock);
1653 + mutex_exit(&nsrv4->servinst_lock);
1599 1654 }
1600 1655
1601 1656 static void
1602 1657 rfs4_dss_remove_leaf(rfs4_servinst_t *sip, char *dir_leaf, char *leaf)
1603 1658 {
1604 1659 int i, npaths = sip->dss_npaths;
1605 1660
1606 1661 for (i = 0; i < npaths; i++) {
1607 1662 rfs4_dss_path_t *dss_path = sip->dss_paths[i];
1608 1663 char *path, *dir;
1609 1664 size_t pathlen;
1610 1665
1611 1666 /* the HA-NFSv4 path might have been failed-over away from us */
1612 1667 if (dss_path == NULL)
1613 1668 continue;
1614 1669
1615 1670 dir = dss_path->path;
1616 1671
1617 1672 /* allow 3 extra bytes for two '/' & a NUL */
1618 1673 pathlen = strlen(dir) + strlen(dir_leaf) + strlen(leaf) + 3;
1619 1674 path = kmem_alloc(pathlen, KM_SLEEP);
1620 1675 (void) sprintf(path, "%s/%s/%s", dir, dir_leaf, leaf);
1621 1676
1622 1677 (void) vn_remove(path, UIO_SYSSPACE, RMFILE);
1623 1678
1624 1679 kmem_free(path, pathlen);
1625 1680 }
1626 1681 }
1627 1682
1628 1683 static void
1629 1684 rfs4_client_destroy(rfs4_entry_t u_entry)
1630 1685 {
1631 1686 rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1632 1687
1633 1688 mutex_destroy(cp->rc_cbinfo.cb_lock);
1634 1689 cv_destroy(cp->rc_cbinfo.cb_cv);
1635 1690 cv_destroy(cp->rc_cbinfo.cb_cv_nullcaller);
1636 1691 list_destroy(&cp->rc_openownerlist);
1637 1692
1638 1693 /* free callback info */
1639 1694 rfs4_cbinfo_free(&cp->rc_cbinfo);
1640 1695
1641 1696 if (cp->rc_cp_confirmed)
1642 1697 rfs4_client_rele(cp->rc_cp_confirmed);
1643 1698
1644 1699 if (cp->rc_ss_pn) {
1645 1700 /* check if the stable storage files need to be removed */
1646 1701 if (cp->rc_ss_remove)
1647 1702 rfs4_dss_remove_cpleaf(cp);
1648 1703 rfs4_ss_pnfree(cp->rc_ss_pn);
1649 1704 }
1650 1705
1651 1706 /* Free the client supplied client id */
1652 1707 kmem_free(cp->rc_nfs_client.id_val, cp->rc_nfs_client.id_len);
1653 1708
1654 1709 if (cp->rc_sysidt != LM_NOSYSID)
1655 1710 lm_free_sysidt(cp->rc_sysidt);
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
1656 1711 }
1657 1712
1658 1713 static bool_t
1659 1714 rfs4_client_create(rfs4_entry_t u_entry, void *arg)
1660 1715 {
1661 1716 rfs4_client_t *cp = (rfs4_client_t *)u_entry;
1662 1717 nfs_client_id4 *client = (nfs_client_id4 *)arg;
1663 1718 struct sockaddr *ca;
1664 1719 cid *cidp;
1665 1720 scid_confirm_verf *scvp;
1721 + nfs4_srv_t *nsrv4;
1666 1722
1723 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1724 +
1667 1725 /* Get a clientid to give to the client */
1668 1726 cidp = (cid *)&cp->rc_clientid;
1669 - cidp->impl_id.start_time = rfs4_start_time;
1727 + cidp->impl_id.start_time = nsrv4->rfs4_start_time;
1670 1728 cidp->impl_id.c_id = (uint32_t)rfs4_dbe_getid(cp->rc_dbe);
1671 1729
1672 1730 /* If we are booted as a cluster node, embed our nodeid */
1673 1731 if (cluster_bootflags & CLUSTER_BOOTED)
1674 1732 embed_nodeid(cidp);
1675 1733
1676 1734 /* Allocate and copy client's client id value */
1677 1735 cp->rc_nfs_client.id_val = kmem_alloc(client->id_len, KM_SLEEP);
1678 1736 cp->rc_nfs_client.id_len = client->id_len;
1679 1737 bcopy(client->id_val, cp->rc_nfs_client.id_val, client->id_len);
1680 1738 cp->rc_nfs_client.verifier = client->verifier;
1681 1739
1682 1740 /* Copy client's IP address */
1683 1741 ca = client->cl_addr;
1684 1742 if (ca->sa_family == AF_INET)
1685 1743 bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in));
1686 1744 else if (ca->sa_family == AF_INET6)
1687 1745 bcopy(ca, &cp->rc_addr, sizeof (struct sockaddr_in6));
1688 1746 cp->rc_nfs_client.cl_addr = (struct sockaddr *)&cp->rc_addr;
1689 1747
1690 1748 /* Init the value for the SETCLIENTID_CONFIRM verifier */
1691 1749 scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1692 1750 scvp->cv_impl.c_id = cidp->impl_id.c_id;
1693 1751 scvp->cv_impl.gen_num = 0;
1694 1752
1695 1753 /* An F_UNLKSYS has been done for this client */
1696 1754 cp->rc_unlksys_completed = FALSE;
1697 1755
1698 1756 /* We need the client to ack us */
1699 1757 cp->rc_need_confirm = TRUE;
1700 1758 cp->rc_cp_confirmed = NULL;
1701 1759
1702 1760 /* TRUE all the time until the callback path actually fails */
1703 1761 cp->rc_cbinfo.cb_notified_of_cb_path_down = TRUE;
1704 1762
1705 1763 /* Initialize the access time to now */
1706 1764 cp->rc_last_access = gethrestime_sec();
1707 1765
1708 1766 cp->rc_cr_set = NULL;
1709 1767
1710 1768 cp->rc_sysidt = LM_NOSYSID;
1711 1769
1712 1770 list_create(&cp->rc_openownerlist, sizeof (rfs4_openowner_t),
1713 1771 offsetof(rfs4_openowner_t, ro_node));
1714 1772
1715 1773 /* set up the callback control structure */
1716 1774 cp->rc_cbinfo.cb_state = CB_UNINIT;
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
1717 1775 mutex_init(cp->rc_cbinfo.cb_lock, NULL, MUTEX_DEFAULT, NULL);
1718 1776 cv_init(cp->rc_cbinfo.cb_cv, NULL, CV_DEFAULT, NULL);
1719 1777 cv_init(cp->rc_cbinfo.cb_cv_nullcaller, NULL, CV_DEFAULT, NULL);
1720 1778
1721 1779 /*
1722 1780 * Associate the client_t with the current server instance.
1723 1781 * The hold is solely to satisfy the calling requirement of
1724 1782 * rfs4_servinst_assign(). In this case it's not strictly necessary.
1725 1783 */
1726 1784 rfs4_dbe_hold(cp->rc_dbe);
1727 - rfs4_servinst_assign(cp, rfs4_cur_servinst);
1785 + rfs4_servinst_assign(nsrv4, cp, nsrv4->nfs4_cur_servinst);
1728 1786 rfs4_dbe_rele(cp->rc_dbe);
1729 1787
1730 1788 return (TRUE);
1731 1789 }
1732 1790
1733 1791 /*
1734 1792 * Caller wants to generate/update the setclientid_confirm verifier
1735 1793 * associated with a client. This is done during the SETCLIENTID
1736 1794 * processing.
1737 1795 */
1738 1796 void
1739 1797 rfs4_client_scv_next(rfs4_client_t *cp)
1740 1798 {
1741 1799 scid_confirm_verf *scvp;
1742 1800
1743 1801 /* Init the value for the SETCLIENTID_CONFIRM verifier */
1744 1802 scvp = (scid_confirm_verf *)&cp->rc_confirm_verf;
1745 1803 scvp->cv_impl.gen_num++;
1746 1804 }
1747 1805
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
1748 1806 void
1749 1807 rfs4_client_rele(rfs4_client_t *cp)
1750 1808 {
1751 1809 rfs4_dbe_rele(cp->rc_dbe);
1752 1810 }
1753 1811
1754 1812 rfs4_client_t *
1755 1813 rfs4_findclient(nfs_client_id4 *client, bool_t *create, rfs4_client_t *oldcp)
1756 1814 {
1757 1815 rfs4_client_t *cp;
1816 + nfs4_srv_t *nsrv4;
1817 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1758 1818
1759 1819
1760 1820 if (oldcp) {
1761 - rw_enter(&rfs4_findclient_lock, RW_WRITER);
1821 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_WRITER);
1762 1822 rfs4_dbe_hide(oldcp->rc_dbe);
1763 1823 } else {
1764 - rw_enter(&rfs4_findclient_lock, RW_READER);
1824 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1765 1825 }
1766 1826
1767 - cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_nfsclnt_idx, client,
1827 + cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_nfsclnt_idx, client,
1768 1828 create, (void *)client, RFS4_DBS_VALID);
1769 1829
1770 1830 if (oldcp)
1771 1831 rfs4_dbe_unhide(oldcp->rc_dbe);
1772 1832
1773 - rw_exit(&rfs4_findclient_lock);
1833 + rw_exit(&nsrv4->rfs4_findclient_lock);
1774 1834
1775 1835 return (cp);
1776 1836 }
1777 1837
1778 1838 rfs4_client_t *
1779 1839 rfs4_findclient_by_id(clientid4 clientid, bool_t find_unconfirmed)
1780 1840 {
1781 1841 rfs4_client_t *cp;
1782 1842 bool_t create = FALSE;
1783 1843 cid *cidp = (cid *)&clientid;
1844 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1784 1845
1785 1846 /* If we're a cluster and the nodeid isn't right, short-circuit */
1786 1847 if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
1787 1848 return (NULL);
1788 1849
1789 - rw_enter(&rfs4_findclient_lock, RW_READER);
1850 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1790 1851
1791 - cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx, &clientid,
1852 + cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx, &clientid,
1792 1853 &create, NULL, RFS4_DBS_VALID);
1793 1854
1794 - rw_exit(&rfs4_findclient_lock);
1855 + rw_exit(&nsrv4->rfs4_findclient_lock);
1795 1856
1796 1857 if (cp && cp->rc_need_confirm && find_unconfirmed == FALSE) {
1797 1858 rfs4_client_rele(cp);
1798 1859 return (NULL);
1799 1860 } else {
1800 1861 return (cp);
1801 1862 }
1802 1863 }
1803 1864
1804 1865 static uint32_t
1805 1866 clntip_hash(void *key)
1806 1867 {
1807 1868 struct sockaddr *addr = key;
1808 1869 int i, len = 0;
1809 1870 uint32_t hash = 0;
1810 1871 char *ptr;
1811 1872
1812 1873 if (addr->sa_family == AF_INET) {
1813 1874 struct sockaddr_in *a = (struct sockaddr_in *)addr;
1814 1875 len = sizeof (struct in_addr);
1815 1876 ptr = (char *)&a->sin_addr;
1816 1877 } else if (addr->sa_family == AF_INET6) {
1817 1878 struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr;
1818 1879 len = sizeof (struct in6_addr);
1819 1880 ptr = (char *)&a->sin6_addr;
1820 1881 } else
1821 1882 return (0);
1822 1883
1823 1884 for (i = 0; i < len; i++) {
1824 1885 hash <<= 1;
1825 1886 hash += (uint_t)ptr[i];
1826 1887 }
1827 1888 return (hash);
1828 1889 }
1829 1890
1830 1891 static bool_t
1831 1892 clntip_compare(rfs4_entry_t entry, void *key)
1832 1893 {
1833 1894 rfs4_clntip_t *cp = (rfs4_clntip_t *)entry;
1834 1895 struct sockaddr *addr = key;
1835 1896 int len = 0;
1836 1897 char *p1, *p2;
1837 1898
1838 1899 if (addr->sa_family == AF_INET) {
1839 1900 struct sockaddr_in *a1 = (struct sockaddr_in *)&cp->ri_addr;
1840 1901 struct sockaddr_in *a2 = (struct sockaddr_in *)addr;
1841 1902 len = sizeof (struct in_addr);
1842 1903 p1 = (char *)&a1->sin_addr;
1843 1904 p2 = (char *)&a2->sin_addr;
1844 1905 } else if (addr->sa_family == AF_INET6) {
1845 1906 struct sockaddr_in6 *a1 = (struct sockaddr_in6 *)&cp->ri_addr;
1846 1907 struct sockaddr_in6 *a2 = (struct sockaddr_in6 *)addr;
1847 1908 len = sizeof (struct in6_addr);
1848 1909 p1 = (char *)&a1->sin6_addr;
1849 1910 p2 = (char *)&a2->sin6_addr;
1850 1911 } else
1851 1912 return (0);
1852 1913
1853 1914 return (bcmp(p1, p2, len) == 0);
1854 1915 }
1855 1916
1856 1917 static void *
1857 1918 clntip_mkkey(rfs4_entry_t entry)
1858 1919 {
1859 1920 rfs4_clntip_t *cp = (rfs4_clntip_t *)entry;
1860 1921
1861 1922 return (&cp->ri_addr);
1862 1923 }
1863 1924
1864 1925 static bool_t
1865 1926 rfs4_clntip_expiry(rfs4_entry_t u_entry)
1866 1927 {
1867 1928 rfs4_clntip_t *cp = (rfs4_clntip_t *)u_entry;
1868 1929
1869 1930 if (rfs4_dbe_is_invalid(cp->ri_dbe))
1870 1931 return (TRUE);
1871 1932 return (FALSE);
1872 1933 }
1873 1934
1874 1935 /* ARGSUSED */
1875 1936 static void
1876 1937 rfs4_clntip_destroy(rfs4_entry_t u_entry)
1877 1938 {
1878 1939 }
1879 1940
1880 1941 static bool_t
1881 1942 rfs4_clntip_create(rfs4_entry_t u_entry, void *arg)
1882 1943 {
1883 1944 rfs4_clntip_t *cp = (rfs4_clntip_t *)u_entry;
1884 1945 struct sockaddr *ca = (struct sockaddr *)arg;
1885 1946
1886 1947 /* Copy client's IP address */
1887 1948 if (ca->sa_family == AF_INET)
1888 1949 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in));
1889 1950 else if (ca->sa_family == AF_INET6)
1890 1951 bcopy(ca, &cp->ri_addr, sizeof (struct sockaddr_in6));
1891 1952 else
|
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
1892 1953 return (FALSE);
1893 1954 cp->ri_no_referrals = 1;
1894 1955
1895 1956 return (TRUE);
1896 1957 }
1897 1958
1898 1959 rfs4_clntip_t *
1899 1960 rfs4_find_clntip(struct sockaddr *addr, bool_t *create)
1900 1961 {
1901 1962 rfs4_clntip_t *cp;
1963 + nfs4_srv_t *nsrv4;
1902 1964
1903 - rw_enter(&rfs4_findclient_lock, RW_READER);
1965 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1904 1966
1905 - cp = (rfs4_clntip_t *)rfs4_dbsearch(rfs4_clntip_idx, addr,
1967 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1968 +
1969 + cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1906 1970 create, addr, RFS4_DBS_VALID);
1907 1971
1908 - rw_exit(&rfs4_findclient_lock);
1972 + rw_exit(&nsrv4->rfs4_findclient_lock);
1909 1973
1910 1974 return (cp);
1911 1975 }
1912 1976
1913 1977 void
1914 1978 rfs4_invalidate_clntip(struct sockaddr *addr)
1915 1979 {
1916 1980 rfs4_clntip_t *cp;
1917 1981 bool_t create = FALSE;
1982 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
1918 1983
1919 - rw_enter(&rfs4_findclient_lock, RW_READER);
1984 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
1920 1985
1921 - cp = (rfs4_clntip_t *)rfs4_dbsearch(rfs4_clntip_idx, addr,
1986 + cp = (rfs4_clntip_t *)rfs4_dbsearch(nsrv4->rfs4_clntip_idx, addr,
1922 1987 &create, NULL, RFS4_DBS_VALID);
1923 1988 if (cp == NULL) {
1924 - rw_exit(&rfs4_findclient_lock);
1989 + rw_exit(&nsrv4->rfs4_findclient_lock);
1925 1990 return;
1926 1991 }
1927 1992 rfs4_dbe_invalidate(cp->ri_dbe);
1928 1993 rfs4_dbe_rele(cp->ri_dbe);
1929 1994
1930 - rw_exit(&rfs4_findclient_lock);
1995 + rw_exit(&nsrv4->rfs4_findclient_lock);
1931 1996 }
1932 1997
1933 1998 bool_t
1934 1999 rfs4_lease_expired(rfs4_client_t *cp)
1935 2000 {
1936 2001 bool_t rc;
1937 2002
1938 2003 rfs4_dbe_lock(cp->rc_dbe);
1939 2004
1940 2005 /*
1941 2006 * If the admin has executed clear_locks for this
1942 2007 * client id, force expire will be set, so no need
1943 2008 * to calculate anything because it's "outa here".
1944 2009 */
1945 2010 if (cp->rc_forced_expire) {
1946 2011 rc = TRUE;
1947 2012 } else {
1948 2013 rc = (gethrestime_sec() - cp->rc_last_access > rfs4_lease_time);
1949 2014 }
1950 2015
1951 2016 /*
1952 2017 * If the lease has expired we will also want
1953 2018 * to remove any stable storage state data. So
1954 2019 * mark the client id accordingly.
1955 2020 */
1956 2021 if (!cp->rc_ss_remove)
1957 2022 cp->rc_ss_remove = (rc == TRUE);
1958 2023
1959 2024 rfs4_dbe_unlock(cp->rc_dbe);
1960 2025
1961 2026 return (rc);
1962 2027 }
1963 2028
1964 2029 void
1965 2030 rfs4_update_lease(rfs4_client_t *cp)
1966 2031 {
1967 2032 rfs4_dbe_lock(cp->rc_dbe);
1968 2033 if (!cp->rc_forced_expire)
1969 2034 cp->rc_last_access = gethrestime_sec();
1970 2035 rfs4_dbe_unlock(cp->rc_dbe);
1971 2036 }
1972 2037
1973 2038
1974 2039 static bool_t
1975 2040 EQOPENOWNER(open_owner4 *a, open_owner4 *b)
1976 2041 {
1977 2042 bool_t rc;
1978 2043
1979 2044 if (a->clientid != b->clientid)
1980 2045 return (FALSE);
1981 2046
1982 2047 if (a->owner_len != b->owner_len)
1983 2048 return (FALSE);
1984 2049
1985 2050 rc = (bcmp(a->owner_val, b->owner_val, a->owner_len) == 0);
1986 2051
1987 2052 return (rc);
1988 2053 }
1989 2054
1990 2055 static uint_t
1991 2056 openowner_hash(void *key)
1992 2057 {
1993 2058 int i;
1994 2059 open_owner4 *openowner = key;
1995 2060 uint_t hash = 0;
1996 2061
1997 2062 for (i = 0; i < openowner->owner_len; i++) {
1998 2063 hash <<= 4;
1999 2064 hash += (uint_t)openowner->owner_val[i];
2000 2065 }
2001 2066 hash += (uint_t)openowner->clientid;
2002 2067 hash |= (openowner->clientid >> 32);
2003 2068
2004 2069 return (hash);
2005 2070 }
2006 2071
2007 2072 static bool_t
2008 2073 openowner_compare(rfs4_entry_t u_entry, void *key)
2009 2074 {
2010 2075 rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2011 2076 open_owner4 *arg = key;
2012 2077
2013 2078 return (EQOPENOWNER(&oo->ro_owner, arg));
2014 2079 }
2015 2080
2016 2081 void *
2017 2082 openowner_mkkey(rfs4_entry_t u_entry)
2018 2083 {
2019 2084 rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2020 2085
2021 2086 return (&oo->ro_owner);
2022 2087 }
2023 2088
2024 2089 /* ARGSUSED */
2025 2090 static bool_t
2026 2091 rfs4_openowner_expiry(rfs4_entry_t u_entry)
2027 2092 {
2028 2093 /* openstateid held us and did all needed delay */
2029 2094 return (TRUE);
2030 2095 }
2031 2096
2032 2097 static void
2033 2098 rfs4_openowner_destroy(rfs4_entry_t u_entry)
2034 2099 {
2035 2100 rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2036 2101
2037 2102 /* Remove open owner from client's lists of open owners */
2038 2103 rfs4_dbe_lock(oo->ro_client->rc_dbe);
2039 2104 list_remove(&oo->ro_client->rc_openownerlist, oo);
2040 2105 rfs4_dbe_unlock(oo->ro_client->rc_dbe);
2041 2106
2042 2107 /* One less reference to the client */
2043 2108 rfs4_client_rele(oo->ro_client);
2044 2109 oo->ro_client = NULL;
2045 2110
2046 2111 /* Free the last reply for this lock owner */
2047 2112 rfs4_free_reply(&oo->ro_reply);
2048 2113
2049 2114 if (oo->ro_reply_fh.nfs_fh4_val) {
2050 2115 kmem_free(oo->ro_reply_fh.nfs_fh4_val,
2051 2116 oo->ro_reply_fh.nfs_fh4_len);
2052 2117 oo->ro_reply_fh.nfs_fh4_val = NULL;
2053 2118 oo->ro_reply_fh.nfs_fh4_len = 0;
2054 2119 }
2055 2120
2056 2121 rfs4_sw_destroy(&oo->ro_sw);
2057 2122 list_destroy(&oo->ro_statelist);
2058 2123
2059 2124 /* Free the lock owner id */
2060 2125 kmem_free(oo->ro_owner.owner_val, oo->ro_owner.owner_len);
2061 2126 }
2062 2127
2063 2128 void
2064 2129 rfs4_openowner_rele(rfs4_openowner_t *oo)
2065 2130 {
2066 2131 rfs4_dbe_rele(oo->ro_dbe);
2067 2132 }
|
↓ open down ↓ |
127 lines elided |
↑ open up ↑ |
2068 2133
2069 2134 static bool_t
2070 2135 rfs4_openowner_create(rfs4_entry_t u_entry, void *arg)
2071 2136 {
2072 2137 rfs4_openowner_t *oo = (rfs4_openowner_t *)u_entry;
2073 2138 rfs4_openowner_t *argp = (rfs4_openowner_t *)arg;
2074 2139 open_owner4 *openowner = &argp->ro_owner;
2075 2140 seqid4 seqid = argp->ro_open_seqid;
2076 2141 rfs4_client_t *cp;
2077 2142 bool_t create = FALSE;
2143 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2078 2144
2079 - rw_enter(&rfs4_findclient_lock, RW_READER);
2145 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2080 2146
2081 - cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx,
2147 + cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2082 2148 &openowner->clientid,
2083 2149 &create, NULL, RFS4_DBS_VALID);
2084 2150
2085 - rw_exit(&rfs4_findclient_lock);
2151 + rw_exit(&nsrv4->rfs4_findclient_lock);
2086 2152
2087 2153 if (cp == NULL)
2088 2154 return (FALSE);
2089 2155
2090 2156 oo->ro_reply_fh.nfs_fh4_len = 0;
2091 2157 oo->ro_reply_fh.nfs_fh4_val = NULL;
2092 2158
2093 2159 oo->ro_owner.clientid = openowner->clientid;
2094 2160 oo->ro_owner.owner_val =
2095 2161 kmem_alloc(openowner->owner_len, KM_SLEEP);
2096 2162
2097 2163 bcopy(openowner->owner_val,
2098 2164 oo->ro_owner.owner_val, openowner->owner_len);
2099 2165
2100 2166 oo->ro_owner.owner_len = openowner->owner_len;
2101 2167
2102 2168 oo->ro_need_confirm = TRUE;
2103 2169
2104 2170 rfs4_sw_init(&oo->ro_sw);
2105 2171
2106 2172 oo->ro_open_seqid = seqid;
2107 2173 bzero(&oo->ro_reply, sizeof (nfs_resop4));
2108 2174 oo->ro_client = cp;
2109 2175 oo->ro_cr_set = NULL;
2110 2176
2111 2177 list_create(&oo->ro_statelist, sizeof (rfs4_state_t),
2112 2178 offsetof(rfs4_state_t, rs_node));
2113 2179
2114 2180 /* Insert openowner into client's open owner list */
2115 2181 rfs4_dbe_lock(cp->rc_dbe);
2116 2182 list_insert_tail(&cp->rc_openownerlist, oo);
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
2117 2183 rfs4_dbe_unlock(cp->rc_dbe);
2118 2184
2119 2185 return (TRUE);
2120 2186 }
2121 2187
2122 2188 rfs4_openowner_t *
2123 2189 rfs4_findopenowner(open_owner4 *openowner, bool_t *create, seqid4 seqid)
2124 2190 {
2125 2191 rfs4_openowner_t *oo;
2126 2192 rfs4_openowner_t arg;
2193 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2127 2194
2128 2195 arg.ro_owner = *openowner;
2129 2196 arg.ro_open_seqid = seqid;
2130 - oo = (rfs4_openowner_t *)rfs4_dbsearch(rfs4_openowner_idx, openowner,
2197 + /* CSTYLED */
2198 + oo = (rfs4_openowner_t *)rfs4_dbsearch(nsrv4->rfs4_openowner_idx, openowner,
2131 2199 create, &arg, RFS4_DBS_VALID);
2132 2200
2133 2201 return (oo);
2134 2202 }
2135 2203
2136 2204 void
2137 2205 rfs4_update_open_sequence(rfs4_openowner_t *oo)
2138 2206 {
2139 2207
2140 2208 rfs4_dbe_lock(oo->ro_dbe);
2141 2209
2142 2210 oo->ro_open_seqid++;
2143 2211
2144 2212 rfs4_dbe_unlock(oo->ro_dbe);
2145 2213 }
2146 2214
2147 2215 void
2148 2216 rfs4_update_open_resp(rfs4_openowner_t *oo, nfs_resop4 *resp, nfs_fh4 *fh)
2149 2217 {
2150 2218
2151 2219 rfs4_dbe_lock(oo->ro_dbe);
2152 2220
2153 2221 rfs4_free_reply(&oo->ro_reply);
2154 2222
2155 2223 rfs4_copy_reply(&oo->ro_reply, resp);
2156 2224
2157 2225 /* Save the filehandle if provided and free if not used */
2158 2226 if (resp->nfs_resop4_u.opopen.status == NFS4_OK &&
2159 2227 fh && fh->nfs_fh4_len) {
2160 2228 if (oo->ro_reply_fh.nfs_fh4_val == NULL)
2161 2229 oo->ro_reply_fh.nfs_fh4_val =
2162 2230 kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
2163 2231 nfs_fh4_copy(fh, &oo->ro_reply_fh);
2164 2232 } else {
2165 2233 if (oo->ro_reply_fh.nfs_fh4_val) {
2166 2234 kmem_free(oo->ro_reply_fh.nfs_fh4_val,
2167 2235 oo->ro_reply_fh.nfs_fh4_len);
2168 2236 oo->ro_reply_fh.nfs_fh4_val = NULL;
2169 2237 oo->ro_reply_fh.nfs_fh4_len = 0;
2170 2238 }
2171 2239 }
2172 2240
2173 2241 rfs4_dbe_unlock(oo->ro_dbe);
2174 2242 }
2175 2243
2176 2244 static bool_t
2177 2245 lockowner_compare(rfs4_entry_t u_entry, void *key)
2178 2246 {
2179 2247 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2180 2248 lock_owner4 *b = (lock_owner4 *)key;
2181 2249
2182 2250 if (lo->rl_owner.clientid != b->clientid)
2183 2251 return (FALSE);
2184 2252
2185 2253 if (lo->rl_owner.owner_len != b->owner_len)
2186 2254 return (FALSE);
2187 2255
2188 2256 return (bcmp(lo->rl_owner.owner_val, b->owner_val,
2189 2257 lo->rl_owner.owner_len) == 0);
2190 2258 }
2191 2259
2192 2260 void *
2193 2261 lockowner_mkkey(rfs4_entry_t u_entry)
2194 2262 {
2195 2263 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2196 2264
2197 2265 return (&lo->rl_owner);
2198 2266 }
2199 2267
2200 2268 static uint32_t
2201 2269 lockowner_hash(void *key)
2202 2270 {
2203 2271 int i;
2204 2272 lock_owner4 *lockowner = key;
2205 2273 uint_t hash = 0;
2206 2274
2207 2275 for (i = 0; i < lockowner->owner_len; i++) {
2208 2276 hash <<= 4;
2209 2277 hash += (uint_t)lockowner->owner_val[i];
2210 2278 }
2211 2279 hash += (uint_t)lockowner->clientid;
2212 2280 hash |= (lockowner->clientid >> 32);
2213 2281
2214 2282 return (hash);
2215 2283 }
2216 2284
2217 2285 static uint32_t
2218 2286 pid_hash(void *key)
2219 2287 {
2220 2288 return ((uint32_t)(uintptr_t)key);
2221 2289 }
2222 2290
2223 2291 static void *
2224 2292 pid_mkkey(rfs4_entry_t u_entry)
2225 2293 {
2226 2294 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2227 2295
2228 2296 return ((void *)(uintptr_t)lo->rl_pid);
2229 2297 }
2230 2298
2231 2299 static bool_t
2232 2300 pid_compare(rfs4_entry_t u_entry, void *key)
2233 2301 {
2234 2302 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2235 2303
2236 2304 return (lo->rl_pid == (pid_t)(uintptr_t)key);
2237 2305 }
2238 2306
2239 2307 static void
2240 2308 rfs4_lockowner_destroy(rfs4_entry_t u_entry)
2241 2309 {
2242 2310 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2243 2311
2244 2312 /* Free the lock owner id */
2245 2313 kmem_free(lo->rl_owner.owner_val, lo->rl_owner.owner_len);
2246 2314 rfs4_client_rele(lo->rl_client);
2247 2315 }
2248 2316
2249 2317 void
2250 2318 rfs4_lockowner_rele(rfs4_lockowner_t *lo)
2251 2319 {
2252 2320 rfs4_dbe_rele(lo->rl_dbe);
2253 2321 }
2254 2322
2255 2323 /* ARGSUSED */
2256 2324 static bool_t
2257 2325 rfs4_lockowner_expiry(rfs4_entry_t u_entry)
2258 2326 {
2259 2327 /*
2260 2328 * Since expiry is called with no other references on
2261 2329 * this struct, go ahead and have it removed.
2262 2330 */
|
↓ open down ↓ |
122 lines elided |
↑ open up ↑ |
2263 2331 return (TRUE);
2264 2332 }
2265 2333
2266 2334 static bool_t
2267 2335 rfs4_lockowner_create(rfs4_entry_t u_entry, void *arg)
2268 2336 {
2269 2337 rfs4_lockowner_t *lo = (rfs4_lockowner_t *)u_entry;
2270 2338 lock_owner4 *lockowner = (lock_owner4 *)arg;
2271 2339 rfs4_client_t *cp;
2272 2340 bool_t create = FALSE;
2341 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2273 2342
2274 - rw_enter(&rfs4_findclient_lock, RW_READER);
2343 + rw_enter(&nsrv4->rfs4_findclient_lock, RW_READER);
2275 2344
2276 - cp = (rfs4_client_t *)rfs4_dbsearch(rfs4_clientid_idx,
2345 + cp = (rfs4_client_t *)rfs4_dbsearch(nsrv4->rfs4_clientid_idx,
2277 2346 &lockowner->clientid,
2278 2347 &create, NULL, RFS4_DBS_VALID);
2279 2348
2280 - rw_exit(&rfs4_findclient_lock);
2349 + rw_exit(&nsrv4->rfs4_findclient_lock);
2281 2350
2282 2351 if (cp == NULL)
2283 2352 return (FALSE);
2284 2353
2285 2354 /* Reference client */
2286 2355 lo->rl_client = cp;
2287 2356 lo->rl_owner.clientid = lockowner->clientid;
2288 2357 lo->rl_owner.owner_val = kmem_alloc(lockowner->owner_len, KM_SLEEP);
2289 2358 bcopy(lockowner->owner_val, lo->rl_owner.owner_val,
2290 2359 lockowner->owner_len);
2291 2360 lo->rl_owner.owner_len = lockowner->owner_len;
2292 2361 lo->rl_pid = rfs4_dbe_getid(lo->rl_dbe);
2293 2362
2294 2363 return (TRUE);
2295 2364 }
2296 2365
2297 2366 rfs4_lockowner_t *
2298 2367 rfs4_findlockowner(lock_owner4 *lockowner, bool_t *create)
2299 2368 {
2300 2369 rfs4_lockowner_t *lo;
2370 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2301 2371
2302 - lo = (rfs4_lockowner_t *)rfs4_dbsearch(rfs4_lockowner_idx, lockowner,
2372 + /* CSTYLED */
2373 + lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_idx, lockowner,
2303 2374 create, lockowner, RFS4_DBS_VALID);
2304 2375
2305 2376 return (lo);
2306 2377 }
2307 2378
2308 2379 rfs4_lockowner_t *
2309 2380 rfs4_findlockowner_by_pid(pid_t pid)
2310 2381 {
2311 2382 rfs4_lockowner_t *lo;
2312 2383 bool_t create = FALSE;
2384 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2313 2385
2314 - lo = (rfs4_lockowner_t *)rfs4_dbsearch(rfs4_lockowner_pid_idx,
2386 + lo = (rfs4_lockowner_t *)rfs4_dbsearch(nsrv4->rfs4_lockowner_pid_idx,
2315 2387 (void *)(uintptr_t)pid, &create, NULL, RFS4_DBS_VALID);
2316 2388
2317 2389 return (lo);
2318 2390 }
2319 2391
2320 2392
2321 2393 static uint32_t
2322 2394 file_hash(void *key)
2323 2395 {
2324 2396 return (ADDRHASH(key));
2325 2397 }
2326 2398
2327 2399 static void *
2328 2400 file_mkkey(rfs4_entry_t u_entry)
2329 2401 {
2330 2402 rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2331 2403
2332 2404 return (fp->rf_vp);
2333 2405 }
2334 2406
2335 2407 static bool_t
2336 2408 file_compare(rfs4_entry_t u_entry, void *key)
2337 2409 {
2338 2410 rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2339 2411
2340 2412 return (fp->rf_vp == (vnode_t *)key);
2341 2413 }
2342 2414
2343 2415 static void
2344 2416 rfs4_file_destroy(rfs4_entry_t u_entry)
2345 2417 {
2346 2418 rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2347 2419
2348 2420 list_destroy(&fp->rf_delegstatelist);
2349 2421
2350 2422 if (fp->rf_filehandle.nfs_fh4_val)
2351 2423 kmem_free(fp->rf_filehandle.nfs_fh4_val,
2352 2424 fp->rf_filehandle.nfs_fh4_len);
2353 2425 cv_destroy(fp->rf_dinfo.rd_recall_cv);
2354 2426 if (fp->rf_vp) {
2355 2427 vnode_t *vp = fp->rf_vp;
2356 2428
2357 2429 mutex_enter(&vp->v_vsd_lock);
2358 2430 (void) vsd_set(vp, nfs4_srv_vkey, NULL);
2359 2431 mutex_exit(&vp->v_vsd_lock);
2360 2432 VN_RELE(vp);
2361 2433 fp->rf_vp = NULL;
2362 2434 }
2363 2435 rw_destroy(&fp->rf_file_rwlock);
2364 2436 }
2365 2437
2366 2438 /*
2367 2439 * Used to unlock the underlying dbe struct only
2368 2440 */
2369 2441 void
2370 2442 rfs4_file_rele(rfs4_file_t *fp)
2371 2443 {
2372 2444 rfs4_dbe_rele(fp->rf_dbe);
2373 2445 }
2374 2446
2375 2447 typedef struct {
2376 2448 vnode_t *vp;
2377 2449 nfs_fh4 *fh;
2378 2450 } rfs4_fcreate_arg;
2379 2451
2380 2452 static bool_t
2381 2453 rfs4_file_create(rfs4_entry_t u_entry, void *arg)
2382 2454 {
2383 2455 rfs4_file_t *fp = (rfs4_file_t *)u_entry;
2384 2456 rfs4_fcreate_arg *ap = (rfs4_fcreate_arg *)arg;
2385 2457 vnode_t *vp = ap->vp;
2386 2458 nfs_fh4 *fh = ap->fh;
2387 2459
2388 2460 VN_HOLD(vp);
2389 2461
2390 2462 fp->rf_filehandle.nfs_fh4_len = 0;
2391 2463 fp->rf_filehandle.nfs_fh4_val = NULL;
2392 2464 ASSERT(fh && fh->nfs_fh4_len);
2393 2465 if (fh && fh->nfs_fh4_len) {
2394 2466 fp->rf_filehandle.nfs_fh4_val =
2395 2467 kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
2396 2468 nfs_fh4_copy(fh, &fp->rf_filehandle);
2397 2469 }
2398 2470 fp->rf_vp = vp;
2399 2471
2400 2472 list_create(&fp->rf_delegstatelist, sizeof (rfs4_deleg_state_t),
2401 2473 offsetof(rfs4_deleg_state_t, rds_node));
2402 2474
2403 2475 fp->rf_share_deny = fp->rf_share_access = fp->rf_access_read = 0;
2404 2476 fp->rf_access_write = fp->rf_deny_read = fp->rf_deny_write = 0;
2405 2477
2406 2478 mutex_init(fp->rf_dinfo.rd_recall_lock, NULL, MUTEX_DEFAULT, NULL);
2407 2479 cv_init(fp->rf_dinfo.rd_recall_cv, NULL, CV_DEFAULT, NULL);
2408 2480
2409 2481 fp->rf_dinfo.rd_dtype = OPEN_DELEGATE_NONE;
2410 2482
2411 2483 rw_init(&fp->rf_file_rwlock, NULL, RW_DEFAULT, NULL);
2412 2484
2413 2485 mutex_enter(&vp->v_vsd_lock);
2414 2486 VERIFY(vsd_set(vp, nfs4_srv_vkey, (void *)fp) == 0);
|
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
2415 2487 mutex_exit(&vp->v_vsd_lock);
2416 2488
2417 2489 return (TRUE);
2418 2490 }
2419 2491
2420 2492 rfs4_file_t *
2421 2493 rfs4_findfile(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2422 2494 {
2423 2495 rfs4_file_t *fp;
2424 2496 rfs4_fcreate_arg arg;
2497 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2425 2498
2426 2499 arg.vp = vp;
2427 2500 arg.fh = fh;
2428 2501
2429 2502 if (*create == TRUE)
2430 - fp = (rfs4_file_t *)rfs4_dbsearch(rfs4_file_idx, vp, create,
2503 + /* CSTYLED */
2504 + fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp, create,
2431 2505 &arg, RFS4_DBS_VALID);
2432 2506 else {
2433 2507 mutex_enter(&vp->v_vsd_lock);
2434 2508 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2435 2509 if (fp) {
2436 2510 rfs4_dbe_lock(fp->rf_dbe);
2437 2511 if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2438 2512 (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2439 2513 rfs4_dbe_unlock(fp->rf_dbe);
2440 2514 fp = NULL;
2441 2515 } else {
2442 2516 rfs4_dbe_hold(fp->rf_dbe);
2443 2517 rfs4_dbe_unlock(fp->rf_dbe);
2444 2518 }
2445 2519 }
2446 2520 mutex_exit(&vp->v_vsd_lock);
2447 2521 }
2448 2522 return (fp);
2449 2523 }
2450 2524
2451 2525 /*
2452 2526 * Find a file in the db and once it is located, take the rw lock.
2453 2527 * Need to check the vnode pointer and if it does not exist (it was
2454 2528 * removed between the db location and check) redo the find. This
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
2455 2529 * assumes that a file struct that has a NULL vnode pointer is marked
2456 2530 * at 'invalid' and will not be found in the db the second time
2457 2531 * around.
2458 2532 */
2459 2533 rfs4_file_t *
2460 2534 rfs4_findfile_withlock(vnode_t *vp, nfs_fh4 *fh, bool_t *create)
2461 2535 {
2462 2536 rfs4_file_t *fp;
2463 2537 rfs4_fcreate_arg arg;
2464 2538 bool_t screate = *create;
2539 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2465 2540
2466 2541 if (screate == FALSE) {
2467 2542 mutex_enter(&vp->v_vsd_lock);
2468 2543 fp = (rfs4_file_t *)vsd_get(vp, nfs4_srv_vkey);
2469 2544 if (fp) {
2470 2545 rfs4_dbe_lock(fp->rf_dbe);
2471 2546 if (rfs4_dbe_is_invalid(fp->rf_dbe) ||
2472 2547 (rfs4_dbe_refcnt(fp->rf_dbe) == 0)) {
2473 2548 rfs4_dbe_unlock(fp->rf_dbe);
2474 2549 mutex_exit(&vp->v_vsd_lock);
2475 2550 fp = NULL;
2476 2551 } else {
2477 2552 rfs4_dbe_hold(fp->rf_dbe);
2478 2553 rfs4_dbe_unlock(fp->rf_dbe);
2479 2554 mutex_exit(&vp->v_vsd_lock);
2480 2555 rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2481 2556 if (fp->rf_vp == NULL) {
2482 2557 rw_exit(&fp->rf_file_rwlock);
2483 2558 rfs4_file_rele(fp);
2484 2559 fp = NULL;
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2485 2560 }
2486 2561 }
2487 2562 } else {
2488 2563 mutex_exit(&vp->v_vsd_lock);
2489 2564 }
2490 2565 } else {
2491 2566 retry:
2492 2567 arg.vp = vp;
2493 2568 arg.fh = fh;
2494 2569
2495 - fp = (rfs4_file_t *)rfs4_dbsearch(rfs4_file_idx, vp, create,
2496 - &arg, RFS4_DBS_VALID);
2570 + fp = (rfs4_file_t *)rfs4_dbsearch(nsrv4->rfs4_file_idx, vp,
2571 + create, &arg, RFS4_DBS_VALID);
2497 2572 if (fp != NULL) {
2498 2573 rw_enter(&fp->rf_file_rwlock, RW_WRITER);
2499 2574 if (fp->rf_vp == NULL) {
2500 2575 rw_exit(&fp->rf_file_rwlock);
2501 2576 rfs4_file_rele(fp);
2502 2577 *create = screate;
2503 2578 goto retry;
2504 2579 }
2505 2580 }
2506 2581 }
2507 2582
2508 2583 return (fp);
2509 2584 }
2510 2585
2511 2586 static uint32_t
2512 2587 lo_state_hash(void *key)
2513 2588 {
2514 2589 stateid_t *id = key;
2515 2590
2516 2591 return (id->bits.ident+id->bits.pid);
2517 2592 }
2518 2593
2519 2594 static bool_t
2520 2595 lo_state_compare(rfs4_entry_t u_entry, void *key)
2521 2596 {
2522 2597 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2523 2598 stateid_t *id = key;
2524 2599 bool_t rc;
2525 2600
2526 2601 rc = (lsp->rls_lockid.bits.boottime == id->bits.boottime &&
2527 2602 lsp->rls_lockid.bits.type == id->bits.type &&
2528 2603 lsp->rls_lockid.bits.ident == id->bits.ident &&
2529 2604 lsp->rls_lockid.bits.pid == id->bits.pid);
2530 2605
2531 2606 return (rc);
2532 2607 }
2533 2608
2534 2609 static void *
2535 2610 lo_state_mkkey(rfs4_entry_t u_entry)
2536 2611 {
2537 2612 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2538 2613
2539 2614 return (&lsp->rls_lockid);
2540 2615 }
2541 2616
2542 2617 static bool_t
2543 2618 rfs4_lo_state_expiry(rfs4_entry_t u_entry)
2544 2619 {
2545 2620 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2546 2621
2547 2622 if (rfs4_dbe_is_invalid(lsp->rls_dbe))
2548 2623 return (TRUE);
2549 2624 if (lsp->rls_state->rs_closed)
2550 2625 return (TRUE);
2551 2626 return ((gethrestime_sec() -
2552 2627 lsp->rls_state->rs_owner->ro_client->rc_last_access
2553 2628 > rfs4_lease_time));
2554 2629 }
2555 2630
2556 2631 static void
2557 2632 rfs4_lo_state_destroy(rfs4_entry_t u_entry)
2558 2633 {
2559 2634 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2560 2635
2561 2636 rfs4_dbe_lock(lsp->rls_state->rs_dbe);
2562 2637 list_remove(&lsp->rls_state->rs_lostatelist, lsp);
2563 2638 rfs4_dbe_unlock(lsp->rls_state->rs_dbe);
2564 2639
2565 2640 rfs4_sw_destroy(&lsp->rls_sw);
2566 2641
2567 2642 /* Make sure to release the file locks */
2568 2643 if (lsp->rls_locks_cleaned == FALSE) {
2569 2644 lsp->rls_locks_cleaned = TRUE;
2570 2645 if (lsp->rls_locker->rl_client->rc_sysidt != LM_NOSYSID) {
2571 2646 /* Is the PxFS kernel module loaded? */
2572 2647 if (lm_remove_file_locks != NULL) {
2573 2648 int new_sysid;
2574 2649
2575 2650 /* Encode the cluster nodeid in new sysid */
2576 2651 new_sysid =
2577 2652 lsp->rls_locker->rl_client->rc_sysidt;
2578 2653 lm_set_nlmid_flk(&new_sysid);
2579 2654
2580 2655 /*
2581 2656 * This PxFS routine removes file locks for a
2582 2657 * client over all nodes of a cluster.
2583 2658 */
2584 2659 DTRACE_PROBE1(nfss_i_clust_rm_lck,
2585 2660 int, new_sysid);
2586 2661 (*lm_remove_file_locks)(new_sysid);
2587 2662 } else {
2588 2663 (void) cleanlocks(
2589 2664 lsp->rls_state->rs_finfo->rf_vp,
2590 2665 lsp->rls_locker->rl_pid,
2591 2666 lsp->rls_locker->rl_client->rc_sysidt);
2592 2667 }
2593 2668 }
2594 2669 }
2595 2670
2596 2671 /* Free the last reply for this state */
2597 2672 rfs4_free_reply(&lsp->rls_reply);
2598 2673
2599 2674 rfs4_lockowner_rele(lsp->rls_locker);
2600 2675 lsp->rls_locker = NULL;
2601 2676
2602 2677 rfs4_state_rele_nounlock(lsp->rls_state);
2603 2678 lsp->rls_state = NULL;
2604 2679 }
2605 2680
2606 2681 static bool_t
2607 2682 rfs4_lo_state_create(rfs4_entry_t u_entry, void *arg)
2608 2683 {
2609 2684 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2610 2685 rfs4_lo_state_t *argp = (rfs4_lo_state_t *)arg;
2611 2686 rfs4_lockowner_t *lo = argp->rls_locker;
2612 2687 rfs4_state_t *sp = argp->rls_state;
2613 2688
2614 2689 lsp->rls_state = sp;
2615 2690
2616 2691 lsp->rls_lockid = sp->rs_stateid;
2617 2692 lsp->rls_lockid.bits.type = LOCKID;
2618 2693 lsp->rls_lockid.bits.chgseq = 0;
2619 2694 lsp->rls_lockid.bits.pid = lo->rl_pid;
2620 2695
2621 2696 lsp->rls_locks_cleaned = FALSE;
2622 2697 lsp->rls_lock_completed = FALSE;
2623 2698
2624 2699 rfs4_sw_init(&lsp->rls_sw);
2625 2700
2626 2701 /* Attached the supplied lock owner */
2627 2702 rfs4_dbe_hold(lo->rl_dbe);
2628 2703 lsp->rls_locker = lo;
2629 2704
2630 2705 rfs4_dbe_lock(sp->rs_dbe);
2631 2706 list_insert_tail(&sp->rs_lostatelist, lsp);
2632 2707 rfs4_dbe_hold(sp->rs_dbe);
2633 2708 rfs4_dbe_unlock(sp->rs_dbe);
2634 2709
2635 2710 return (TRUE);
2636 2711 }
2637 2712
2638 2713 void
2639 2714 rfs4_lo_state_rele(rfs4_lo_state_t *lsp, bool_t unlock_fp)
2640 2715 {
|
↓ open down ↓ |
134 lines elided |
↑ open up ↑ |
2641 2716 if (unlock_fp == TRUE)
2642 2717 rw_exit(&lsp->rls_state->rs_finfo->rf_file_rwlock);
2643 2718 rfs4_dbe_rele(lsp->rls_dbe);
2644 2719 }
2645 2720
2646 2721 static rfs4_lo_state_t *
2647 2722 rfs4_findlo_state(stateid_t *id, bool_t lock_fp)
2648 2723 {
2649 2724 rfs4_lo_state_t *lsp;
2650 2725 bool_t create = FALSE;
2726 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2651 2727
2652 - lsp = (rfs4_lo_state_t *)rfs4_dbsearch(rfs4_lo_state_idx, id,
2728 + lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_idx, id,
2653 2729 &create, NULL, RFS4_DBS_VALID);
2654 2730 if (lock_fp == TRUE && lsp != NULL)
2655 2731 rw_enter(&lsp->rls_state->rs_finfo->rf_file_rwlock, RW_READER);
2656 2732
2657 2733 return (lsp);
2658 2734 }
2659 2735
2660 2736
2661 2737 static uint32_t
2662 2738 lo_state_lo_hash(void *key)
2663 2739 {
2664 2740 rfs4_lo_state_t *lsp = key;
2665 2741
2666 2742 return (ADDRHASH(lsp->rls_locker) ^ ADDRHASH(lsp->rls_state));
2667 2743 }
2668 2744
2669 2745 static bool_t
2670 2746 lo_state_lo_compare(rfs4_entry_t u_entry, void *key)
2671 2747 {
2672 2748 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
2673 2749 rfs4_lo_state_t *keyp = key;
2674 2750
2675 2751 return (keyp->rls_locker == lsp->rls_locker &&
2676 2752 keyp->rls_state == lsp->rls_state);
2677 2753 }
2678 2754
2679 2755 static void *
2680 2756 lo_state_lo_mkkey(rfs4_entry_t u_entry)
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
2681 2757 {
2682 2758 return (u_entry);
2683 2759 }
2684 2760
2685 2761 rfs4_lo_state_t *
2686 2762 rfs4_findlo_state_by_owner(rfs4_lockowner_t *lo, rfs4_state_t *sp,
2687 2763 bool_t *create)
2688 2764 {
2689 2765 rfs4_lo_state_t *lsp;
2690 2766 rfs4_lo_state_t arg;
2767 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2691 2768
2692 2769 arg.rls_locker = lo;
2693 2770 arg.rls_state = sp;
2694 2771
2695 - lsp = (rfs4_lo_state_t *)rfs4_dbsearch(rfs4_lo_state_owner_idx, &arg,
2696 - create, &arg, RFS4_DBS_VALID);
2772 + lsp = (rfs4_lo_state_t *)rfs4_dbsearch(nsrv4->rfs4_lo_state_owner_idx,
2773 + &arg, create, &arg, RFS4_DBS_VALID);
2697 2774
2698 2775 return (lsp);
2699 2776 }
2700 2777
2701 2778 static stateid_t
2702 2779 get_stateid(id_t eid)
2703 2780 {
2704 2781 stateid_t id;
2782 + nfs4_srv_t *nsrv4;
2705 2783
2706 - id.bits.boottime = rfs4_start_time;
2784 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2785 +
2786 + id.bits.boottime = nsrv4->rfs4_start_time;
2707 2787 id.bits.ident = eid;
2708 2788 id.bits.chgseq = 0;
2709 2789 id.bits.type = 0;
2710 2790 id.bits.pid = 0;
2711 2791
2712 2792 /*
2713 2793 * If we are booted as a cluster node, embed our nodeid.
2714 2794 * We've already done sanity checks in rfs4_client_create() so no
2715 2795 * need to repeat them here.
2716 2796 */
2717 2797 id.bits.clnodeid = (cluster_bootflags & CLUSTER_BOOTED) ?
2718 2798 clconf_get_nodeid() : 0;
2719 2799
2720 2800 return (id);
2721 2801 }
2722 2802
2723 2803 /*
2724 2804 * For use only when booted as a cluster node.
2725 2805 * Returns TRUE if the embedded nodeid indicates that this stateid was
2726 2806 * generated on another node.
2727 2807 */
2728 2808 static int
2729 2809 foreign_stateid(stateid_t *id)
2730 2810 {
2731 2811 ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2732 2812 return (id->bits.clnodeid != (uint32_t)clconf_get_nodeid());
2733 2813 }
2734 2814
2735 2815 /*
2736 2816 * For use only when booted as a cluster node.
2737 2817 * Returns TRUE if the embedded nodeid indicates that this clientid was
2738 2818 * generated on another node.
2739 2819 */
2740 2820 static int
2741 2821 foreign_clientid(cid *cidp)
2742 2822 {
2743 2823 ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2744 2824 return (cidp->impl_id.c_id >> CLUSTER_NODEID_SHIFT !=
2745 2825 (uint32_t)clconf_get_nodeid());
2746 2826 }
2747 2827
2748 2828 /*
2749 2829 * For use only when booted as a cluster node.
2750 2830 * Embed our cluster nodeid into the clientid.
2751 2831 */
2752 2832 static void
2753 2833 embed_nodeid(cid *cidp)
2754 2834 {
2755 2835 int clnodeid;
2756 2836 /*
2757 2837 * Currently, our state tables are small enough that their
2758 2838 * ids will leave enough bits free for the nodeid. If the
2759 2839 * tables become larger, we mustn't overwrite the id.
2760 2840 * Equally, we only have room for so many bits of nodeid, so
2761 2841 * must check that too.
2762 2842 */
2763 2843 ASSERT(cluster_bootflags & CLUSTER_BOOTED);
2764 2844 ASSERT(cidp->impl_id.c_id >> CLUSTER_NODEID_SHIFT == 0);
2765 2845 clnodeid = clconf_get_nodeid();
2766 2846 ASSERT(clnodeid <= CLUSTER_MAX_NODEID);
2767 2847 ASSERT(clnodeid != NODEID_UNKNOWN);
2768 2848 cidp->impl_id.c_id |= (clnodeid << CLUSTER_NODEID_SHIFT);
2769 2849 }
2770 2850
2771 2851 static uint32_t
2772 2852 state_hash(void *key)
2773 2853 {
2774 2854 stateid_t *ip = (stateid_t *)key;
2775 2855
2776 2856 return (ip->bits.ident);
2777 2857 }
2778 2858
2779 2859 static bool_t
2780 2860 state_compare(rfs4_entry_t u_entry, void *key)
2781 2861 {
2782 2862 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2783 2863 stateid_t *id = (stateid_t *)key;
2784 2864 bool_t rc;
2785 2865
2786 2866 rc = (sp->rs_stateid.bits.boottime == id->bits.boottime &&
2787 2867 sp->rs_stateid.bits.ident == id->bits.ident);
2788 2868
2789 2869 return (rc);
2790 2870 }
2791 2871
2792 2872 static void *
2793 2873 state_mkkey(rfs4_entry_t u_entry)
2794 2874 {
2795 2875 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2796 2876
2797 2877 return (&sp->rs_stateid);
2798 2878 }
2799 2879
2800 2880 static void
2801 2881 rfs4_state_destroy(rfs4_entry_t u_entry)
2802 2882 {
2803 2883 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
2804 2884
2805 2885 /* remove from openowner list */
2806 2886 rfs4_dbe_lock(sp->rs_owner->ro_dbe);
2807 2887 list_remove(&sp->rs_owner->ro_statelist, sp);
2808 2888 rfs4_dbe_unlock(sp->rs_owner->ro_dbe);
2809 2889
2810 2890 list_destroy(&sp->rs_lostatelist);
2811 2891
2812 2892 /* release any share locks for this stateid if it's still open */
2813 2893 if (!sp->rs_closed) {
2814 2894 rfs4_dbe_lock(sp->rs_dbe);
2815 2895 (void) rfs4_unshare(sp);
2816 2896 rfs4_dbe_unlock(sp->rs_dbe);
2817 2897 }
2818 2898
2819 2899 /* Were done with the file */
2820 2900 rfs4_file_rele(sp->rs_finfo);
2821 2901 sp->rs_finfo = NULL;
2822 2902
2823 2903 /* And now with the openowner */
2824 2904 rfs4_openowner_rele(sp->rs_owner);
2825 2905 sp->rs_owner = NULL;
2826 2906 }
2827 2907
2828 2908 static void
2829 2909 rfs4_state_rele_nounlock(rfs4_state_t *sp)
2830 2910 {
2831 2911 rfs4_dbe_rele(sp->rs_dbe);
2832 2912 }
2833 2913
2834 2914 void
2835 2915 rfs4_state_rele(rfs4_state_t *sp)
2836 2916 {
2837 2917 rw_exit(&sp->rs_finfo->rf_file_rwlock);
2838 2918 rfs4_dbe_rele(sp->rs_dbe);
2839 2919 }
2840 2920
2841 2921 static uint32_t
2842 2922 deleg_hash(void *key)
2843 2923 {
2844 2924 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)key;
2845 2925
2846 2926 return (ADDRHASH(dsp->rds_client) ^ ADDRHASH(dsp->rds_finfo));
2847 2927 }
2848 2928
2849 2929 static bool_t
2850 2930 deleg_compare(rfs4_entry_t u_entry, void *key)
2851 2931 {
2852 2932 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2853 2933 rfs4_deleg_state_t *kdsp = (rfs4_deleg_state_t *)key;
2854 2934
2855 2935 return (dsp->rds_client == kdsp->rds_client &&
2856 2936 dsp->rds_finfo == kdsp->rds_finfo);
2857 2937 }
2858 2938
2859 2939 static void *
2860 2940 deleg_mkkey(rfs4_entry_t u_entry)
2861 2941 {
2862 2942 return (u_entry);
2863 2943 }
2864 2944
2865 2945 static uint32_t
2866 2946 deleg_state_hash(void *key)
2867 2947 {
2868 2948 stateid_t *ip = (stateid_t *)key;
2869 2949
2870 2950 return (ip->bits.ident);
2871 2951 }
2872 2952
2873 2953 static bool_t
2874 2954 deleg_state_compare(rfs4_entry_t u_entry, void *key)
2875 2955 {
2876 2956 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2877 2957 stateid_t *id = (stateid_t *)key;
2878 2958 bool_t rc;
2879 2959
2880 2960 if (id->bits.type != DELEGID)
2881 2961 return (FALSE);
2882 2962
2883 2963 rc = (dsp->rds_delegid.bits.boottime == id->bits.boottime &&
2884 2964 dsp->rds_delegid.bits.ident == id->bits.ident);
2885 2965
2886 2966 return (rc);
2887 2967 }
2888 2968
2889 2969 static void *
2890 2970 deleg_state_mkkey(rfs4_entry_t u_entry)
2891 2971 {
2892 2972 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2893 2973
2894 2974 return (&dsp->rds_delegid);
2895 2975 }
2896 2976
2897 2977 static bool_t
2898 2978 rfs4_deleg_state_expiry(rfs4_entry_t u_entry)
2899 2979 {
2900 2980 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2901 2981
2902 2982 if (rfs4_dbe_is_invalid(dsp->rds_dbe))
2903 2983 return (TRUE);
2904 2984
2905 2985 if (dsp->rds_dtype == OPEN_DELEGATE_NONE)
2906 2986 return (TRUE);
2907 2987
2908 2988 if ((gethrestime_sec() - dsp->rds_client->rc_last_access
2909 2989 > rfs4_lease_time)) {
2910 2990 rfs4_dbe_invalidate(dsp->rds_dbe);
2911 2991 return (TRUE);
2912 2992 }
2913 2993
2914 2994 return (FALSE);
2915 2995 }
2916 2996
2917 2997 static bool_t
2918 2998 rfs4_deleg_state_create(rfs4_entry_t u_entry, void *argp)
2919 2999 {
2920 3000 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2921 3001 rfs4_file_t *fp = ((rfs4_deleg_state_t *)argp)->rds_finfo;
2922 3002 rfs4_client_t *cp = ((rfs4_deleg_state_t *)argp)->rds_client;
2923 3003
2924 3004 rfs4_dbe_hold(fp->rf_dbe);
2925 3005 rfs4_dbe_hold(cp->rc_dbe);
2926 3006
2927 3007 dsp->rds_delegid = get_stateid(rfs4_dbe_getid(dsp->rds_dbe));
2928 3008 dsp->rds_delegid.bits.type = DELEGID;
2929 3009 dsp->rds_finfo = fp;
2930 3010 dsp->rds_client = cp;
2931 3011 dsp->rds_dtype = OPEN_DELEGATE_NONE;
2932 3012
2933 3013 dsp->rds_time_granted = gethrestime_sec(); /* observability */
2934 3014 dsp->rds_time_revoked = 0;
2935 3015
2936 3016 list_link_init(&dsp->rds_node);
2937 3017
2938 3018 return (TRUE);
2939 3019 }
2940 3020
2941 3021 static void
2942 3022 rfs4_deleg_state_destroy(rfs4_entry_t u_entry)
2943 3023 {
2944 3024 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
2945 3025
2946 3026 /* return delegation if necessary */
2947 3027 rfs4_return_deleg(dsp, FALSE);
2948 3028
2949 3029 /* Were done with the file */
2950 3030 rfs4_file_rele(dsp->rds_finfo);
2951 3031 dsp->rds_finfo = NULL;
|
↓ open down ↓ |
235 lines elided |
↑ open up ↑ |
2952 3032
2953 3033 /* And now with the openowner */
2954 3034 rfs4_client_rele(dsp->rds_client);
2955 3035 dsp->rds_client = NULL;
2956 3036 }
2957 3037
2958 3038 rfs4_deleg_state_t *
2959 3039 rfs4_finddeleg(rfs4_state_t *sp, bool_t *create)
2960 3040 {
2961 3041 rfs4_deleg_state_t ds, *dsp;
3042 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2962 3043
2963 3044 ds.rds_client = sp->rs_owner->ro_client;
2964 3045 ds.rds_finfo = sp->rs_finfo;
2965 3046
2966 - dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(rfs4_deleg_idx, &ds,
3047 + dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_idx, &ds,
2967 3048 create, &ds, RFS4_DBS_VALID);
2968 3049
2969 3050 return (dsp);
2970 3051 }
2971 3052
2972 3053 rfs4_deleg_state_t *
2973 3054 rfs4_finddelegstate(stateid_t *id)
2974 3055 {
2975 3056 rfs4_deleg_state_t *dsp;
2976 3057 bool_t create = FALSE;
3058 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
2977 3059
2978 - dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(rfs4_deleg_state_idx, id,
2979 - &create, NULL, RFS4_DBS_VALID);
3060 + dsp = (rfs4_deleg_state_t *)rfs4_dbsearch(nsrv4->rfs4_deleg_state_idx,
3061 + id, &create, NULL, RFS4_DBS_VALID);
2980 3062
2981 3063 return (dsp);
2982 3064 }
2983 3065
2984 3066 void
2985 3067 rfs4_deleg_state_rele(rfs4_deleg_state_t *dsp)
2986 3068 {
2987 3069 rfs4_dbe_rele(dsp->rds_dbe);
2988 3070 }
2989 3071
2990 3072 void
2991 3073 rfs4_update_lock_sequence(rfs4_lo_state_t *lsp)
2992 3074 {
2993 3075
2994 3076 rfs4_dbe_lock(lsp->rls_dbe);
2995 3077
2996 3078 /*
2997 3079 * If we are skipping sequence id checking, this means that
2998 3080 * this is the first lock request and therefore the sequence
2999 3081 * id does not need to be updated. This only happens on the
3000 3082 * first lock request for a lockowner
3001 3083 */
3002 3084 if (!lsp->rls_skip_seqid_check)
3003 3085 lsp->rls_seqid++;
3004 3086
3005 3087 rfs4_dbe_unlock(lsp->rls_dbe);
3006 3088 }
3007 3089
3008 3090 void
3009 3091 rfs4_update_lock_resp(rfs4_lo_state_t *lsp, nfs_resop4 *resp)
3010 3092 {
3011 3093
3012 3094 rfs4_dbe_lock(lsp->rls_dbe);
3013 3095
3014 3096 rfs4_free_reply(&lsp->rls_reply);
3015 3097
3016 3098 rfs4_copy_reply(&lsp->rls_reply, resp);
3017 3099
3018 3100 rfs4_dbe_unlock(lsp->rls_dbe);
3019 3101 }
3020 3102
3021 3103 void
3022 3104 rfs4_free_opens(rfs4_openowner_t *oo, bool_t invalidate,
3023 3105 bool_t close_of_client)
3024 3106 {
3025 3107 rfs4_state_t *sp;
3026 3108
3027 3109 rfs4_dbe_lock(oo->ro_dbe);
3028 3110
3029 3111 for (sp = list_head(&oo->ro_statelist); sp != NULL;
3030 3112 sp = list_next(&oo->ro_statelist, sp)) {
3031 3113 rfs4_state_close(sp, FALSE, close_of_client, CRED());
3032 3114 if (invalidate == TRUE)
3033 3115 rfs4_dbe_invalidate(sp->rs_dbe);
3034 3116 }
3035 3117
3036 3118 rfs4_dbe_invalidate(oo->ro_dbe);
3037 3119 rfs4_dbe_unlock(oo->ro_dbe);
3038 3120 }
3039 3121
3040 3122 static uint32_t
3041 3123 state_owner_file_hash(void *key)
3042 3124 {
3043 3125 rfs4_state_t *sp = key;
3044 3126
3045 3127 return (ADDRHASH(sp->rs_owner) ^ ADDRHASH(sp->rs_finfo));
3046 3128 }
3047 3129
3048 3130 static bool_t
3049 3131 state_owner_file_compare(rfs4_entry_t u_entry, void *key)
3050 3132 {
3051 3133 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3052 3134 rfs4_state_t *arg = key;
3053 3135
3054 3136 if (sp->rs_closed == TRUE)
3055 3137 return (FALSE);
3056 3138
3057 3139 return (arg->rs_owner == sp->rs_owner && arg->rs_finfo == sp->rs_finfo);
3058 3140 }
3059 3141
3060 3142 static void *
3061 3143 state_owner_file_mkkey(rfs4_entry_t u_entry)
3062 3144 {
3063 3145 return (u_entry);
3064 3146 }
3065 3147
3066 3148 static uint32_t
3067 3149 state_file_hash(void *key)
3068 3150 {
3069 3151 return (ADDRHASH(key));
3070 3152 }
3071 3153
3072 3154 static bool_t
3073 3155 state_file_compare(rfs4_entry_t u_entry, void *key)
3074 3156 {
3075 3157 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3076 3158 rfs4_file_t *fp = key;
3077 3159
3078 3160 if (sp->rs_closed == TRUE)
3079 3161 return (FALSE);
3080 3162
3081 3163 return (fp == sp->rs_finfo);
3082 3164 }
3083 3165
|
↓ open down ↓ |
94 lines elided |
↑ open up ↑ |
3084 3166 static void *
3085 3167 state_file_mkkey(rfs4_entry_t u_entry)
3086 3168 {
3087 3169 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3088 3170
3089 3171 return (sp->rs_finfo);
3090 3172 }
3091 3173
3092 3174 rfs4_state_t *
3093 3175 rfs4_findstate_by_owner_file(rfs4_openowner_t *oo, rfs4_file_t *fp,
3094 - bool_t *create)
3176 + bool_t *create)
3095 3177 {
3096 3178 rfs4_state_t *sp;
3097 3179 rfs4_state_t key;
3180 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3098 3181
3099 3182 key.rs_owner = oo;
3100 3183 key.rs_finfo = fp;
3101 3184
3102 - sp = (rfs4_state_t *)rfs4_dbsearch(rfs4_state_owner_file_idx, &key,
3103 - create, &key, RFS4_DBS_VALID);
3185 + sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_owner_file_idx,
3186 + &key, create, &key, RFS4_DBS_VALID);
3104 3187
3105 3188 return (sp);
3106 3189 }
3107 3190
3108 3191 /* This returns ANY state struct that refers to this file */
3109 3192 static rfs4_state_t *
3110 3193 rfs4_findstate_by_file(rfs4_file_t *fp)
3111 3194 {
3112 3195 bool_t create = FALSE;
3196 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3113 3197
3114 - return ((rfs4_state_t *)rfs4_dbsearch(rfs4_state_file_idx, fp,
3198 + return ((rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_file_idx, fp,
3115 3199 &create, fp, RFS4_DBS_VALID));
3116 3200 }
3117 3201
3118 3202 static bool_t
3119 3203 rfs4_state_expiry(rfs4_entry_t u_entry)
3120 3204 {
3121 3205 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3122 3206
3123 3207 if (rfs4_dbe_is_invalid(sp->rs_dbe))
3124 3208 return (TRUE);
3125 3209
3126 3210 if (sp->rs_closed == TRUE &&
3127 3211 ((gethrestime_sec() - rfs4_dbe_get_timerele(sp->rs_dbe))
3128 3212 > rfs4_lease_time))
3129 3213 return (TRUE);
3130 3214
3131 3215 return ((gethrestime_sec() - sp->rs_owner->ro_client->rc_last_access
3132 3216 > rfs4_lease_time));
3133 3217 }
3134 3218
3135 3219 static bool_t
3136 3220 rfs4_state_create(rfs4_entry_t u_entry, void *argp)
3137 3221 {
3138 3222 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3139 3223 rfs4_file_t *fp = ((rfs4_state_t *)argp)->rs_finfo;
3140 3224 rfs4_openowner_t *oo = ((rfs4_state_t *)argp)->rs_owner;
3141 3225
3142 3226 rfs4_dbe_hold(fp->rf_dbe);
3143 3227 rfs4_dbe_hold(oo->ro_dbe);
3144 3228 sp->rs_stateid = get_stateid(rfs4_dbe_getid(sp->rs_dbe));
3145 3229 sp->rs_stateid.bits.type = OPENID;
3146 3230 sp->rs_owner = oo;
3147 3231 sp->rs_finfo = fp;
3148 3232
3149 3233 list_create(&sp->rs_lostatelist, sizeof (rfs4_lo_state_t),
3150 3234 offsetof(rfs4_lo_state_t, rls_node));
3151 3235
3152 3236 /* Insert state on per open owner's list */
3153 3237 rfs4_dbe_lock(oo->ro_dbe);
3154 3238 list_insert_tail(&oo->ro_statelist, sp);
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
3155 3239 rfs4_dbe_unlock(oo->ro_dbe);
3156 3240
3157 3241 return (TRUE);
3158 3242 }
3159 3243
3160 3244 static rfs4_state_t *
3161 3245 rfs4_findstate(stateid_t *id, rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3162 3246 {
3163 3247 rfs4_state_t *sp;
3164 3248 bool_t create = FALSE;
3249 + nfs4_srv_t *nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3165 3250
3166 - sp = (rfs4_state_t *)rfs4_dbsearch(rfs4_state_idx, id,
3251 + sp = (rfs4_state_t *)rfs4_dbsearch(nsrv4->rfs4_state_idx, id,
3167 3252 &create, NULL, find_invalid);
3168 3253 if (lock_fp == TRUE && sp != NULL)
3169 3254 rw_enter(&sp->rs_finfo->rf_file_rwlock, RW_READER);
3170 3255
3171 3256 return (sp);
3172 3257 }
3173 3258
3174 3259 void
3175 3260 rfs4_state_close(rfs4_state_t *sp, bool_t lock_held, bool_t close_of_client,
3176 3261 cred_t *cr)
3177 3262 {
3178 3263 /* Remove the associated lo_state owners */
3179 3264 if (!lock_held)
3180 3265 rfs4_dbe_lock(sp->rs_dbe);
3181 3266
3182 3267 /*
3183 3268 * If refcnt == 0, the dbe is about to be destroyed.
3184 3269 * lock state will be released by the reaper thread.
3185 3270 */
3186 3271
3187 3272 if (rfs4_dbe_refcnt(sp->rs_dbe) > 0) {
3188 3273 if (sp->rs_closed == FALSE) {
3189 3274 rfs4_release_share_lock_state(sp, cr, close_of_client);
3190 3275 sp->rs_closed = TRUE;
3191 3276 }
3192 3277 }
3193 3278
3194 3279 if (!lock_held)
3195 3280 rfs4_dbe_unlock(sp->rs_dbe);
3196 3281 }
3197 3282
3198 3283 /*
3199 3284 * Remove all state associated with the given client.
3200 3285 */
3201 3286 void
3202 3287 rfs4_client_state_remove(rfs4_client_t *cp)
3203 3288 {
3204 3289 rfs4_openowner_t *oo;
3205 3290
3206 3291 rfs4_dbe_lock(cp->rc_dbe);
3207 3292
3208 3293 for (oo = list_head(&cp->rc_openownerlist); oo != NULL;
3209 3294 oo = list_next(&cp->rc_openownerlist, oo)) {
3210 3295 rfs4_free_opens(oo, TRUE, TRUE);
3211 3296 }
3212 3297
3213 3298 rfs4_dbe_unlock(cp->rc_dbe);
3214 3299 }
3215 3300
3216 3301 void
3217 3302 rfs4_client_close(rfs4_client_t *cp)
3218 3303 {
3219 3304 /* Mark client as going away. */
3220 3305 rfs4_dbe_lock(cp->rc_dbe);
3221 3306 rfs4_dbe_invalidate(cp->rc_dbe);
3222 3307 rfs4_dbe_unlock(cp->rc_dbe);
3223 3308
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
3224 3309 rfs4_client_state_remove(cp);
3225 3310
3226 3311 /* Release the client */
3227 3312 rfs4_client_rele(cp);
3228 3313 }
3229 3314
3230 3315 nfsstat4
3231 3316 rfs4_check_clientid(clientid4 *cp, int setclid_confirm)
3232 3317 {
3233 3318 cid *cidp = (cid *) cp;
3319 + nfs4_srv_t *nsrv4;
3234 3320
3321 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3322 +
3235 3323 /*
3236 3324 * If we are booted as a cluster node, check the embedded nodeid.
3237 3325 * If it indicates that this clientid was generated on another node,
3238 3326 * inform the client accordingly.
3239 3327 */
3240 3328 if (cluster_bootflags & CLUSTER_BOOTED && foreign_clientid(cidp))
3241 3329 return (NFS4ERR_STALE_CLIENTID);
3242 3330
3243 3331 /*
3244 3332 * If the server start time matches the time provided
3245 3333 * by the client (via the clientid) and this is NOT a
3246 3334 * setclientid_confirm then return EXPIRED.
3247 3335 */
3248 - if (!setclid_confirm && cidp->impl_id.start_time == rfs4_start_time)
3336 + if (!setclid_confirm &&
3337 + cidp->impl_id.start_time == nsrv4->rfs4_start_time)
3249 3338 return (NFS4ERR_EXPIRED);
3250 3339
3251 3340 return (NFS4ERR_STALE_CLIENTID);
3252 3341 }
3253 3342
3254 3343 /*
3255 3344 * This is used when a stateid has not been found amongst the
3256 3345 * current server's state. Check the stateid to see if it
3257 3346 * was from this server instantiation or not.
3258 3347 */
3259 3348 static nfsstat4
3260 3349 what_stateid_error(stateid_t *id, stateid_type_t type)
3261 3350 {
3351 + nfs4_srv_t *nsrv4;
3352 +
3353 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
3354 +
3262 3355 /* If we are booted as a cluster node, was stateid locally generated? */
3263 3356 if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3264 3357 return (NFS4ERR_STALE_STATEID);
3265 3358
3266 3359 /* If types don't match then no use checking further */
3267 3360 if (type != id->bits.type)
3268 3361 return (NFS4ERR_BAD_STATEID);
3269 3362
3270 3363 /* From a different server instantiation, return STALE */
3271 - if (id->bits.boottime != rfs4_start_time)
3364 + if (id->bits.boottime != nsrv4->rfs4_start_time)
3272 3365 return (NFS4ERR_STALE_STATEID);
3273 3366
3274 3367 /*
3275 3368 * From this server but the state is most likely beyond lease
3276 3369 * timeout: return NFS4ERR_EXPIRED. However, there is the
3277 3370 * case of a delegation stateid. For delegations, there is a
3278 3371 * case where the state can be removed without the client's
3279 3372 * knowledge/consent: revocation. In the case of delegation
3280 3373 * revocation, the delegation state will be removed and will
3281 3374 * not be found. If the client does something like a
3282 3375 * DELEGRETURN or even a READ/WRITE with a delegatoin stateid
3283 3376 * that has been revoked, the server should return BAD_STATEID
3284 3377 * instead of the more common EXPIRED error.
3285 3378 */
3286 - if (id->bits.boottime == rfs4_start_time) {
3379 + if (id->bits.boottime == nsrv4->rfs4_start_time) {
3287 3380 if (type == DELEGID)
3288 3381 return (NFS4ERR_BAD_STATEID);
3289 3382 else
3290 3383 return (NFS4ERR_EXPIRED);
3291 3384 }
3292 3385
3293 3386 return (NFS4ERR_BAD_STATEID);
3294 3387 }
3295 3388
3296 3389 /*
3297 3390 * Used later on to find the various state structs. When called from
3298 3391 * rfs4_check_stateid()->rfs4_get_all_state(), no file struct lock is
3299 3392 * taken (it is not needed) and helps on the read/write path with
3300 3393 * respect to performance.
3301 3394 */
3302 3395 static nfsstat4
3303 3396 rfs4_get_state_lockit(stateid4 *stateid, rfs4_state_t **spp,
3304 3397 rfs4_dbsearch_type_t find_invalid, bool_t lock_fp)
3305 3398 {
3306 3399 stateid_t *id = (stateid_t *)stateid;
3307 3400 rfs4_state_t *sp;
3308 3401
3309 3402 *spp = NULL;
3310 3403
3311 3404 /* If we are booted as a cluster node, was stateid locally generated? */
3312 3405 if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3313 3406 return (NFS4ERR_STALE_STATEID);
3314 3407
3315 3408 sp = rfs4_findstate(id, find_invalid, lock_fp);
3316 3409 if (sp == NULL) {
3317 3410 return (what_stateid_error(id, OPENID));
3318 3411 }
3319 3412
3320 3413 if (rfs4_lease_expired(sp->rs_owner->ro_client)) {
3321 3414 if (lock_fp == TRUE)
3322 3415 rfs4_state_rele(sp);
3323 3416 else
3324 3417 rfs4_state_rele_nounlock(sp);
3325 3418 return (NFS4ERR_EXPIRED);
3326 3419 }
3327 3420
3328 3421 *spp = sp;
3329 3422
3330 3423 return (NFS4_OK);
3331 3424 }
3332 3425
3333 3426 nfsstat4
3334 3427 rfs4_get_state(stateid4 *stateid, rfs4_state_t **spp,
3335 3428 rfs4_dbsearch_type_t find_invalid)
3336 3429 {
3337 3430 return (rfs4_get_state_lockit(stateid, spp, find_invalid, TRUE));
3338 3431 }
3339 3432
3340 3433 int
3341 3434 rfs4_check_stateid_seqid(rfs4_state_t *sp, stateid4 *stateid)
3342 3435 {
3343 3436 stateid_t *id = (stateid_t *)stateid;
3344 3437
3345 3438 if (rfs4_lease_expired(sp->rs_owner->ro_client))
3346 3439 return (NFS4_CHECK_STATEID_EXPIRED);
3347 3440
3348 3441 /* Stateid is some time in the future - that's bad */
3349 3442 if (sp->rs_stateid.bits.chgseq < id->bits.chgseq)
3350 3443 return (NFS4_CHECK_STATEID_BAD);
3351 3444
3352 3445 if (sp->rs_stateid.bits.chgseq == id->bits.chgseq + 1)
3353 3446 return (NFS4_CHECK_STATEID_REPLAY);
3354 3447
3355 3448 /* Stateid is some time in the past - that's old */
3356 3449 if (sp->rs_stateid.bits.chgseq > id->bits.chgseq)
3357 3450 return (NFS4_CHECK_STATEID_OLD);
3358 3451
3359 3452 /* Caller needs to know about confirmation before closure */
3360 3453 if (sp->rs_owner->ro_need_confirm)
3361 3454 return (NFS4_CHECK_STATEID_UNCONFIRMED);
3362 3455
3363 3456 if (sp->rs_closed == TRUE)
3364 3457 return (NFS4_CHECK_STATEID_CLOSED);
3365 3458
3366 3459 return (NFS4_CHECK_STATEID_OKAY);
3367 3460 }
3368 3461
3369 3462 int
3370 3463 rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *lsp, stateid4 *stateid)
3371 3464 {
3372 3465 stateid_t *id = (stateid_t *)stateid;
3373 3466
3374 3467 if (rfs4_lease_expired(lsp->rls_state->rs_owner->ro_client))
3375 3468 return (NFS4_CHECK_STATEID_EXPIRED);
3376 3469
3377 3470 /* Stateid is some time in the future - that's bad */
3378 3471 if (lsp->rls_lockid.bits.chgseq < id->bits.chgseq)
3379 3472 return (NFS4_CHECK_STATEID_BAD);
3380 3473
3381 3474 if (lsp->rls_lockid.bits.chgseq == id->bits.chgseq + 1)
3382 3475 return (NFS4_CHECK_STATEID_REPLAY);
3383 3476
3384 3477 /* Stateid is some time in the past - that's old */
3385 3478 if (lsp->rls_lockid.bits.chgseq > id->bits.chgseq)
3386 3479 return (NFS4_CHECK_STATEID_OLD);
3387 3480
3388 3481 if (lsp->rls_state->rs_closed == TRUE)
3389 3482 return (NFS4_CHECK_STATEID_CLOSED);
3390 3483
3391 3484 return (NFS4_CHECK_STATEID_OKAY);
3392 3485 }
3393 3486
3394 3487 nfsstat4
3395 3488 rfs4_get_deleg_state(stateid4 *stateid, rfs4_deleg_state_t **dspp)
3396 3489 {
3397 3490 stateid_t *id = (stateid_t *)stateid;
3398 3491 rfs4_deleg_state_t *dsp;
3399 3492
3400 3493 *dspp = NULL;
3401 3494
3402 3495 /* If we are booted as a cluster node, was stateid locally generated? */
3403 3496 if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3404 3497 return (NFS4ERR_STALE_STATEID);
3405 3498
3406 3499 dsp = rfs4_finddelegstate(id);
3407 3500 if (dsp == NULL) {
3408 3501 return (what_stateid_error(id, DELEGID));
3409 3502 }
3410 3503
3411 3504 if (rfs4_lease_expired(dsp->rds_client)) {
3412 3505 rfs4_deleg_state_rele(dsp);
3413 3506 return (NFS4ERR_EXPIRED);
3414 3507 }
3415 3508
3416 3509 *dspp = dsp;
3417 3510
3418 3511 return (NFS4_OK);
3419 3512 }
3420 3513
3421 3514 nfsstat4
3422 3515 rfs4_get_lo_state(stateid4 *stateid, rfs4_lo_state_t **lspp, bool_t lock_fp)
3423 3516 {
3424 3517 stateid_t *id = (stateid_t *)stateid;
3425 3518 rfs4_lo_state_t *lsp;
3426 3519
3427 3520 *lspp = NULL;
3428 3521
3429 3522 /* If we are booted as a cluster node, was stateid locally generated? */
3430 3523 if ((cluster_bootflags & CLUSTER_BOOTED) && foreign_stateid(id))
3431 3524 return (NFS4ERR_STALE_STATEID);
3432 3525
3433 3526 lsp = rfs4_findlo_state(id, lock_fp);
3434 3527 if (lsp == NULL) {
3435 3528 return (what_stateid_error(id, LOCKID));
3436 3529 }
3437 3530
3438 3531 if (rfs4_lease_expired(lsp->rls_state->rs_owner->ro_client)) {
3439 3532 rfs4_lo_state_rele(lsp, lock_fp);
3440 3533 return (NFS4ERR_EXPIRED);
3441 3534 }
3442 3535
3443 3536 *lspp = lsp;
3444 3537
3445 3538 return (NFS4_OK);
3446 3539 }
3447 3540
3448 3541 static nfsstat4
3449 3542 rfs4_get_all_state(stateid4 *sid, rfs4_state_t **spp,
3450 3543 rfs4_deleg_state_t **dspp, rfs4_lo_state_t **lspp)
3451 3544 {
3452 3545 rfs4_state_t *sp = NULL;
3453 3546 rfs4_deleg_state_t *dsp = NULL;
3454 3547 rfs4_lo_state_t *lsp = NULL;
3455 3548 stateid_t *id;
3456 3549 nfsstat4 status;
3457 3550
3458 3551 *spp = NULL; *dspp = NULL; *lspp = NULL;
3459 3552
3460 3553 id = (stateid_t *)sid;
3461 3554 switch (id->bits.type) {
3462 3555 case OPENID:
3463 3556 status = rfs4_get_state_lockit(sid, &sp, FALSE, FALSE);
3464 3557 break;
3465 3558 case DELEGID:
3466 3559 status = rfs4_get_deleg_state(sid, &dsp);
3467 3560 break;
3468 3561 case LOCKID:
3469 3562 status = rfs4_get_lo_state(sid, &lsp, FALSE);
3470 3563 if (status == NFS4_OK) {
3471 3564 sp = lsp->rls_state;
3472 3565 rfs4_dbe_hold(sp->rs_dbe);
3473 3566 }
3474 3567 break;
3475 3568 default:
3476 3569 status = NFS4ERR_BAD_STATEID;
3477 3570 }
3478 3571
3479 3572 if (status == NFS4_OK) {
3480 3573 *spp = sp;
3481 3574 *dspp = dsp;
3482 3575 *lspp = lsp;
3483 3576 }
3484 3577
3485 3578 return (status);
3486 3579 }
3487 3580
3488 3581 /*
3489 3582 * Given the I/O mode (FREAD or FWRITE), this checks whether the
3490 3583 * rfs4_state_t struct has access to do this operation and if so
3491 3584 * return NFS4_OK; otherwise the proper NFSv4 error is returned.
3492 3585 */
3493 3586 nfsstat4
3494 3587 rfs4_state_has_access(rfs4_state_t *sp, int mode, vnode_t *vp)
3495 3588 {
3496 3589 nfsstat4 stat = NFS4_OK;
3497 3590 rfs4_file_t *fp;
3498 3591 bool_t create = FALSE;
3499 3592
3500 3593 rfs4_dbe_lock(sp->rs_dbe);
3501 3594 if (mode == FWRITE) {
3502 3595 if (!(sp->rs_share_access & OPEN4_SHARE_ACCESS_WRITE)) {
3503 3596 stat = NFS4ERR_OPENMODE;
3504 3597 }
3505 3598 } else if (mode == FREAD) {
3506 3599 if (!(sp->rs_share_access & OPEN4_SHARE_ACCESS_READ)) {
3507 3600 /*
3508 3601 * If we have OPENed the file with DENYing access
3509 3602 * to both READ and WRITE then no one else could
3510 3603 * have OPENed the file, hence no conflicting READ
3511 3604 * deny. This check is merely an optimization.
3512 3605 */
3513 3606 if (sp->rs_share_deny == OPEN4_SHARE_DENY_BOTH)
3514 3607 goto out;
3515 3608
3516 3609 /* Check against file struct's DENY mode */
3517 3610 fp = rfs4_findfile(vp, NULL, &create);
3518 3611 if (fp != NULL) {
3519 3612 int deny_read = 0;
3520 3613 rfs4_dbe_lock(fp->rf_dbe);
3521 3614 /*
3522 3615 * Check if any other open owner has the file
3523 3616 * OPENed with deny READ.
3524 3617 */
3525 3618 if (sp->rs_share_deny & OPEN4_SHARE_DENY_READ)
3526 3619 deny_read = 1;
3527 3620 ASSERT(fp->rf_deny_read >= deny_read);
3528 3621 if (fp->rf_deny_read > deny_read)
3529 3622 stat = NFS4ERR_OPENMODE;
3530 3623 rfs4_dbe_unlock(fp->rf_dbe);
3531 3624 rfs4_file_rele(fp);
3532 3625 }
3533 3626 }
3534 3627 } else {
3535 3628 /* Illegal I/O mode */
3536 3629 stat = NFS4ERR_INVAL;
3537 3630 }
3538 3631 out:
3539 3632 rfs4_dbe_unlock(sp->rs_dbe);
3540 3633 return (stat);
3541 3634 }
3542 3635
3543 3636 /*
3544 3637 * Given the I/O mode (FREAD or FWRITE), the vnode, the stateid and whether
3545 3638 * the file is being truncated, return NFS4_OK if allowed or appropriate
3546 3639 * V4 error if not. Note NFS4ERR_DELAY will be returned and a recall on
3547 3640 * the associated file will be done if the I/O is not consistent with any
3548 3641 * delegation in effect on the file. Should be holding VOP_RWLOCK, either
3549 3642 * as reader or writer as appropriate. rfs4_op_open will acquire the
3550 3643 * VOP_RWLOCK as writer when setting up delegation. If the stateid is bad
3551 3644 * this routine will return NFS4ERR_BAD_STATEID. In addition, through the
3552 3645 * deleg parameter, we will return whether a write delegation is held by
3553 3646 * the client associated with this stateid.
3554 3647 * If the server instance associated with the relevant client is in its
3555 3648 * grace period, return NFS4ERR_GRACE.
3556 3649 */
3557 3650
3558 3651 nfsstat4
3559 3652 rfs4_check_stateid(int mode, vnode_t *vp,
3560 3653 stateid4 *stateid, bool_t trunc, bool_t *deleg,
3561 3654 bool_t do_access, caller_context_t *ct)
3562 3655 {
3563 3656 rfs4_file_t *fp;
3564 3657 bool_t create = FALSE;
3565 3658 rfs4_state_t *sp;
3566 3659 rfs4_deleg_state_t *dsp;
3567 3660 rfs4_lo_state_t *lsp;
3568 3661 stateid_t *id = (stateid_t *)stateid;
3569 3662 nfsstat4 stat = NFS4_OK;
3570 3663
3571 3664 if (ct != NULL) {
3572 3665 ct->cc_sysid = 0;
3573 3666 ct->cc_pid = 0;
3574 3667 ct->cc_caller_id = nfs4_srv_caller_id;
3575 3668 ct->cc_flags = CC_DONTBLOCK;
3576 3669 }
3577 3670
3578 3671 if (ISSPECIAL(stateid)) {
3579 3672 fp = rfs4_findfile(vp, NULL, &create);
3580 3673 if (fp == NULL)
3581 3674 return (NFS4_OK);
3582 3675 if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_NONE) {
3583 3676 rfs4_file_rele(fp);
3584 3677 return (NFS4_OK);
3585 3678 }
3586 3679 if (mode == FWRITE ||
3587 3680 fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_WRITE) {
3588 3681 rfs4_recall_deleg(fp, trunc, NULL);
3589 3682 rfs4_file_rele(fp);
3590 3683 return (NFS4ERR_DELAY);
3591 3684 }
3592 3685 rfs4_file_rele(fp);
3593 3686 return (NFS4_OK);
3594 3687 } else {
3595 3688 stat = rfs4_get_all_state(stateid, &sp, &dsp, &lsp);
3596 3689 if (stat != NFS4_OK)
3597 3690 return (stat);
3598 3691 if (lsp != NULL) {
3599 3692 /* Is associated server instance in its grace period? */
3600 3693 if (rfs4_clnt_in_grace(lsp->rls_locker->rl_client)) {
3601 3694 rfs4_lo_state_rele(lsp, FALSE);
3602 3695 if (sp != NULL)
3603 3696 rfs4_state_rele_nounlock(sp);
3604 3697 return (NFS4ERR_GRACE);
3605 3698 }
3606 3699 if (id->bits.type == LOCKID) {
3607 3700 /* Seqid in the future? - that's bad */
3608 3701 if (lsp->rls_lockid.bits.chgseq <
3609 3702 id->bits.chgseq) {
3610 3703 rfs4_lo_state_rele(lsp, FALSE);
3611 3704 if (sp != NULL)
3612 3705 rfs4_state_rele_nounlock(sp);
3613 3706 return (NFS4ERR_BAD_STATEID);
3614 3707 }
3615 3708 /* Seqid in the past? - that's old */
3616 3709 if (lsp->rls_lockid.bits.chgseq >
3617 3710 id->bits.chgseq) {
3618 3711 rfs4_lo_state_rele(lsp, FALSE);
3619 3712 if (sp != NULL)
3620 3713 rfs4_state_rele_nounlock(sp);
3621 3714 return (NFS4ERR_OLD_STATEID);
3622 3715 }
3623 3716 /* Ensure specified filehandle matches */
3624 3717 if (lsp->rls_state->rs_finfo->rf_vp != vp) {
3625 3718 rfs4_lo_state_rele(lsp, FALSE);
3626 3719 if (sp != NULL)
3627 3720 rfs4_state_rele_nounlock(sp);
3628 3721 return (NFS4ERR_BAD_STATEID);
3629 3722 }
3630 3723 }
3631 3724 if (ct != NULL) {
3632 3725 ct->cc_sysid =
3633 3726 lsp->rls_locker->rl_client->rc_sysidt;
3634 3727 ct->cc_pid = lsp->rls_locker->rl_pid;
3635 3728 }
3636 3729 rfs4_lo_state_rele(lsp, FALSE);
3637 3730 }
3638 3731
3639 3732 /* Stateid provided was an "open" stateid */
3640 3733 if (sp != NULL) {
3641 3734 /* Is associated server instance in its grace period? */
3642 3735 if (rfs4_clnt_in_grace(sp->rs_owner->ro_client)) {
3643 3736 rfs4_state_rele_nounlock(sp);
3644 3737 return (NFS4ERR_GRACE);
3645 3738 }
3646 3739 if (id->bits.type == OPENID) {
3647 3740 /* Seqid in the future? - that's bad */
3648 3741 if (sp->rs_stateid.bits.chgseq <
3649 3742 id->bits.chgseq) {
3650 3743 rfs4_state_rele_nounlock(sp);
3651 3744 return (NFS4ERR_BAD_STATEID);
3652 3745 }
3653 3746 /* Seqid in the past - that's old */
3654 3747 if (sp->rs_stateid.bits.chgseq >
3655 3748 id->bits.chgseq) {
3656 3749 rfs4_state_rele_nounlock(sp);
3657 3750 return (NFS4ERR_OLD_STATEID);
3658 3751 }
3659 3752 }
3660 3753 /* Ensure specified filehandle matches */
3661 3754 if (sp->rs_finfo->rf_vp != vp) {
3662 3755 rfs4_state_rele_nounlock(sp);
3663 3756 return (NFS4ERR_BAD_STATEID);
3664 3757 }
3665 3758
3666 3759 if (sp->rs_owner->ro_need_confirm) {
3667 3760 rfs4_state_rele_nounlock(sp);
3668 3761 return (NFS4ERR_BAD_STATEID);
3669 3762 }
3670 3763
3671 3764 if (sp->rs_closed == TRUE) {
3672 3765 rfs4_state_rele_nounlock(sp);
3673 3766 return (NFS4ERR_OLD_STATEID);
3674 3767 }
3675 3768
3676 3769 if (do_access)
3677 3770 stat = rfs4_state_has_access(sp, mode, vp);
3678 3771 else
3679 3772 stat = NFS4_OK;
3680 3773
3681 3774 /*
3682 3775 * Return whether this state has write
3683 3776 * delegation if desired
3684 3777 */
3685 3778 if (deleg && (sp->rs_finfo->rf_dinfo.rd_dtype ==
3686 3779 OPEN_DELEGATE_WRITE))
3687 3780 *deleg = TRUE;
3688 3781
3689 3782 /*
3690 3783 * We got a valid stateid, so we update the
3691 3784 * lease on the client. Ideally we would like
3692 3785 * to do this after the calling op succeeds,
3693 3786 * but for now this will be good
3694 3787 * enough. Callers of this routine are
3695 3788 * currently insulated from the state stuff.
3696 3789 */
3697 3790 rfs4_update_lease(sp->rs_owner->ro_client);
3698 3791
3699 3792 /*
3700 3793 * If a delegation is present on this file and
3701 3794 * this is a WRITE, then update the lastwrite
3702 3795 * time to indicate that activity is present.
3703 3796 */
3704 3797 if (sp->rs_finfo->rf_dinfo.rd_dtype ==
3705 3798 OPEN_DELEGATE_WRITE &&
3706 3799 mode == FWRITE) {
3707 3800 sp->rs_finfo->rf_dinfo.rd_time_lastwrite =
3708 3801 gethrestime_sec();
3709 3802 }
3710 3803
3711 3804 rfs4_state_rele_nounlock(sp);
3712 3805
3713 3806 return (stat);
3714 3807 }
3715 3808
3716 3809 if (dsp != NULL) {
3717 3810 /* Is associated server instance in its grace period? */
3718 3811 if (rfs4_clnt_in_grace(dsp->rds_client)) {
3719 3812 rfs4_deleg_state_rele(dsp);
3720 3813 return (NFS4ERR_GRACE);
3721 3814 }
3722 3815 if (dsp->rds_delegid.bits.chgseq != id->bits.chgseq) {
3723 3816 rfs4_deleg_state_rele(dsp);
3724 3817 return (NFS4ERR_BAD_STATEID);
3725 3818 }
3726 3819
3727 3820 /* Ensure specified filehandle matches */
3728 3821 if (dsp->rds_finfo->rf_vp != vp) {
3729 3822 rfs4_deleg_state_rele(dsp);
3730 3823 return (NFS4ERR_BAD_STATEID);
3731 3824 }
3732 3825 /*
3733 3826 * Return whether this state has write
3734 3827 * delegation if desired
3735 3828 */
3736 3829 if (deleg && (dsp->rds_finfo->rf_dinfo.rd_dtype ==
3737 3830 OPEN_DELEGATE_WRITE))
3738 3831 *deleg = TRUE;
3739 3832
3740 3833 rfs4_update_lease(dsp->rds_client);
3741 3834
3742 3835 /*
3743 3836 * If a delegation is present on this file and
3744 3837 * this is a WRITE, then update the lastwrite
3745 3838 * time to indicate that activity is present.
3746 3839 */
3747 3840 if (dsp->rds_finfo->rf_dinfo.rd_dtype ==
3748 3841 OPEN_DELEGATE_WRITE && mode == FWRITE) {
3749 3842 dsp->rds_finfo->rf_dinfo.rd_time_lastwrite =
3750 3843 gethrestime_sec();
3751 3844 }
3752 3845
3753 3846 /*
3754 3847 * XXX - what happens if this is a WRITE and the
3755 3848 * delegation type of for READ.
3756 3849 */
3757 3850 rfs4_deleg_state_rele(dsp);
3758 3851
3759 3852 return (stat);
3760 3853 }
3761 3854 /*
3762 3855 * If we got this far, something bad happened
3763 3856 */
3764 3857 return (NFS4ERR_BAD_STATEID);
3765 3858 }
3766 3859 }
3767 3860
3768 3861
3769 3862 /*
3770 3863 * This is a special function in that for the file struct provided the
3771 3864 * server wants to remove/close all current state associated with the
3772 3865 * file. The prime use of this would be with OP_REMOVE to force the
3773 3866 * release of state and particularly of file locks.
3774 3867 *
3775 3868 * There is an assumption that there is no delegations outstanding on
3776 3869 * this file at this point. The caller should have waited for those
3777 3870 * to be returned or revoked.
|
↓ open down ↓ |
481 lines elided |
↑ open up ↑ |
3778 3871 */
3779 3872 void
3780 3873 rfs4_close_all_state(rfs4_file_t *fp)
3781 3874 {
3782 3875 rfs4_state_t *sp;
3783 3876
3784 3877 rfs4_dbe_lock(fp->rf_dbe);
3785 3878
3786 3879 #ifdef DEBUG
3787 3880 /* only applies when server is handing out delegations */
3788 - if (rfs4_deleg_policy != SRV_NEVER_DELEGATE)
3881 + if (nfs4_get_deleg_policy() != SRV_NEVER_DELEGATE)
3789 3882 ASSERT(fp->rf_dinfo.rd_hold_grant > 0);
3790 3883 #endif
3791 3884
3792 3885 /* No delegations for this file */
3793 3886 ASSERT(list_is_empty(&fp->rf_delegstatelist));
3794 3887
3795 3888 /* Make sure that it can not be found */
3796 3889 rfs4_dbe_invalidate(fp->rf_dbe);
3797 3890
3798 3891 if (fp->rf_vp == NULL) {
3799 3892 rfs4_dbe_unlock(fp->rf_dbe);
3800 3893 return;
3801 3894 }
3802 3895 rfs4_dbe_unlock(fp->rf_dbe);
3803 3896
3804 3897 /*
3805 3898 * Hold as writer to prevent other server threads from
3806 3899 * processing requests related to the file while all state is
3807 3900 * being removed.
3808 3901 */
3809 3902 rw_enter(&fp->rf_file_rwlock, RW_WRITER);
3810 3903
3811 3904 /* Remove ALL state from the file */
3812 3905 while (sp = rfs4_findstate_by_file(fp)) {
3813 3906 rfs4_state_close(sp, FALSE, FALSE, CRED());
3814 3907 rfs4_state_rele_nounlock(sp);
3815 3908 }
3816 3909
3817 3910 /*
3818 3911 * This is only safe since there are no further references to
3819 3912 * the file.
3820 3913 */
3821 3914 rfs4_dbe_lock(fp->rf_dbe);
3822 3915 if (fp->rf_vp) {
3823 3916 vnode_t *vp = fp->rf_vp;
3824 3917
3825 3918 mutex_enter(&vp->v_vsd_lock);
3826 3919 (void) vsd_set(vp, nfs4_srv_vkey, NULL);
3827 3920 mutex_exit(&vp->v_vsd_lock);
3828 3921 VN_RELE(vp);
3829 3922 fp->rf_vp = NULL;
3830 3923 }
3831 3924 rfs4_dbe_unlock(fp->rf_dbe);
3832 3925
3833 3926 /* Finally let other references to proceed */
3834 3927 rw_exit(&fp->rf_file_rwlock);
3835 3928 }
3836 3929
3837 3930 /*
3838 3931 * This function is used as a target for the rfs4_dbe_walk() call
3839 3932 * below. The purpose of this function is to see if the
3840 3933 * lockowner_state refers to a file that resides within the exportinfo
3841 3934 * export. If so, then remove the lock_owner state (file locks and
3842 3935 * share "locks") for this object since the intent is the server is
3843 3936 * unexporting the specified directory. Be sure to invalidate the
3844 3937 * object after the state has been released
3845 3938 */
3846 3939 static void
3847 3940 rfs4_lo_state_walk_callout(rfs4_entry_t u_entry, void *e)
3848 3941 {
3849 3942 rfs4_lo_state_t *lsp = (rfs4_lo_state_t *)u_entry;
3850 3943 struct exportinfo *exi = (struct exportinfo *)e;
3851 3944 nfs_fh4_fmt_t fhfmt4, *exi_fhp, *finfo_fhp;
3852 3945 fhandle_t *efhp;
3853 3946
3854 3947 efhp = (fhandle_t *)&exi->exi_fh;
3855 3948 exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3856 3949
3857 3950 FH_TO_FMT4(efhp, exi_fhp);
3858 3951
3859 3952 finfo_fhp = (nfs_fh4_fmt_t *)lsp->rls_state->rs_finfo->
3860 3953 rf_filehandle.nfs_fh4_val;
3861 3954
3862 3955 if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3863 3956 bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3864 3957 exi_fhp->fh4_xlen) == 0) {
3865 3958 rfs4_state_close(lsp->rls_state, FALSE, FALSE, CRED());
3866 3959 rfs4_dbe_invalidate(lsp->rls_dbe);
3867 3960 rfs4_dbe_invalidate(lsp->rls_state->rs_dbe);
3868 3961 }
3869 3962 }
3870 3963
3871 3964 /*
3872 3965 * This function is used as a target for the rfs4_dbe_walk() call
3873 3966 * below. The purpose of this function is to see if the state refers
3874 3967 * to a file that resides within the exportinfo export. If so, then
3875 3968 * remove the open state for this object since the intent is the
3876 3969 * server is unexporting the specified directory. The main result for
3877 3970 * this type of entry is to invalidate it such it will not be found in
3878 3971 * the future.
3879 3972 */
3880 3973 static void
3881 3974 rfs4_state_walk_callout(rfs4_entry_t u_entry, void *e)
3882 3975 {
3883 3976 rfs4_state_t *sp = (rfs4_state_t *)u_entry;
3884 3977 struct exportinfo *exi = (struct exportinfo *)e;
3885 3978 nfs_fh4_fmt_t fhfmt4, *exi_fhp, *finfo_fhp;
3886 3979 fhandle_t *efhp;
3887 3980
3888 3981 efhp = (fhandle_t *)&exi->exi_fh;
3889 3982 exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3890 3983
3891 3984 FH_TO_FMT4(efhp, exi_fhp);
3892 3985
3893 3986 finfo_fhp =
3894 3987 (nfs_fh4_fmt_t *)sp->rs_finfo->rf_filehandle.nfs_fh4_val;
3895 3988
3896 3989 if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3897 3990 bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3898 3991 exi_fhp->fh4_xlen) == 0) {
3899 3992 rfs4_state_close(sp, TRUE, FALSE, CRED());
3900 3993 rfs4_dbe_invalidate(sp->rs_dbe);
3901 3994 }
3902 3995 }
3903 3996
3904 3997 /*
3905 3998 * This function is used as a target for the rfs4_dbe_walk() call
3906 3999 * below. The purpose of this function is to see if the state refers
3907 4000 * to a file that resides within the exportinfo export. If so, then
3908 4001 * remove the deleg state for this object since the intent is the
3909 4002 * server is unexporting the specified directory. The main result for
3910 4003 * this type of entry is to invalidate it such it will not be found in
3911 4004 * the future.
3912 4005 */
3913 4006 static void
3914 4007 rfs4_deleg_state_walk_callout(rfs4_entry_t u_entry, void *e)
3915 4008 {
3916 4009 rfs4_deleg_state_t *dsp = (rfs4_deleg_state_t *)u_entry;
3917 4010 struct exportinfo *exi = (struct exportinfo *)e;
3918 4011 nfs_fh4_fmt_t fhfmt4, *exi_fhp, *finfo_fhp;
3919 4012 fhandle_t *efhp;
3920 4013
3921 4014 efhp = (fhandle_t *)&exi->exi_fh;
3922 4015 exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3923 4016
3924 4017 FH_TO_FMT4(efhp, exi_fhp);
3925 4018
3926 4019 finfo_fhp =
3927 4020 (nfs_fh4_fmt_t *)dsp->rds_finfo->rf_filehandle.nfs_fh4_val;
3928 4021
3929 4022 if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3930 4023 bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3931 4024 exi_fhp->fh4_xlen) == 0) {
3932 4025 rfs4_dbe_invalidate(dsp->rds_dbe);
3933 4026 }
3934 4027 }
3935 4028
3936 4029 /*
3937 4030 * This function is used as a target for the rfs4_dbe_walk() call
3938 4031 * below. The purpose of this function is to see if the state refers
3939 4032 * to a file that resides within the exportinfo export. If so, then
3940 4033 * release vnode hold for this object since the intent is the server
3941 4034 * is unexporting the specified directory. Invalidation will prevent
3942 4035 * this struct from being found in the future.
3943 4036 */
3944 4037 static void
3945 4038 rfs4_file_walk_callout(rfs4_entry_t u_entry, void *e)
3946 4039 {
3947 4040 rfs4_file_t *fp = (rfs4_file_t *)u_entry;
3948 4041 struct exportinfo *exi = (struct exportinfo *)e;
3949 4042 nfs_fh4_fmt_t fhfmt4, *exi_fhp, *finfo_fhp;
3950 4043 fhandle_t *efhp;
3951 4044
3952 4045 efhp = (fhandle_t *)&exi->exi_fh;
3953 4046 exi_fhp = (nfs_fh4_fmt_t *)&fhfmt4;
3954 4047
3955 4048 FH_TO_FMT4(efhp, exi_fhp);
3956 4049
3957 4050 finfo_fhp = (nfs_fh4_fmt_t *)fp->rf_filehandle.nfs_fh4_val;
3958 4051
3959 4052 if (EQFSID(&finfo_fhp->fh4_fsid, &exi_fhp->fh4_fsid) &&
3960 4053 bcmp(&finfo_fhp->fh4_xdata, &exi_fhp->fh4_xdata,
3961 4054 exi_fhp->fh4_xlen) == 0) {
3962 4055 if (fp->rf_vp) {
3963 4056 vnode_t *vp = fp->rf_vp;
3964 4057
3965 4058 /*
3966 4059 * don't leak monitors and remove the reference
3967 4060 * put on the vnode when the delegation was granted.
3968 4061 */
3969 4062 if (fp->rf_dinfo.rd_dtype == OPEN_DELEGATE_READ) {
3970 4063 (void) fem_uninstall(vp, deleg_rdops,
3971 4064 (void *)fp);
3972 4065 vn_open_downgrade(vp, FREAD);
3973 4066 } else if (fp->rf_dinfo.rd_dtype ==
3974 4067 OPEN_DELEGATE_WRITE) {
3975 4068 (void) fem_uninstall(vp, deleg_wrops,
3976 4069 (void *)fp);
3977 4070 vn_open_downgrade(vp, FREAD|FWRITE);
3978 4071 }
3979 4072 mutex_enter(&vp->v_vsd_lock);
3980 4073 (void) vsd_set(vp, nfs4_srv_vkey, NULL);
3981 4074 mutex_exit(&vp->v_vsd_lock);
3982 4075 VN_RELE(vp);
3983 4076 fp->rf_vp = NULL;
3984 4077 }
3985 4078 rfs4_dbe_invalidate(fp->rf_dbe);
3986 4079 }
3987 4080 }
|
↓ open down ↓ |
189 lines elided |
↑ open up ↑ |
3988 4081
3989 4082 /*
3990 4083 * Given a directory that is being unexported, cleanup/release all
3991 4084 * state in the server that refers to objects residing underneath this
3992 4085 * particular export. The ordering of the release is important.
3993 4086 * Lock_owner, then state and then file.
3994 4087 */
3995 4088 void
3996 4089 rfs4_clean_state_exi(struct exportinfo *exi)
3997 4090 {
3998 - mutex_enter(&rfs4_state_lock);
4091 + nfs4_srv_t *nsrv4;
3999 4092
4000 - if (rfs4_server_state == NULL) {
4001 - mutex_exit(&rfs4_state_lock);
4093 + nsrv4 = zone_getspecific(rfs4_zone_key, curzone);
4094 + mutex_enter(&nsrv4->state_lock);
4095 +
4096 + if (nsrv4->nfs4_server_state == NULL) {
4097 + mutex_exit(&nsrv4->state_lock);
4002 4098 return;
4003 4099 }
4004 4100
4005 - rfs4_dbe_walk(rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
4006 - rfs4_dbe_walk(rfs4_state_tab, rfs4_state_walk_callout, exi);
4007 - rfs4_dbe_walk(rfs4_deleg_state_tab, rfs4_deleg_state_walk_callout, exi);
4008 - rfs4_dbe_walk(rfs4_file_tab, rfs4_file_walk_callout, exi);
4101 + /* CSTYLED */
4102 + rfs4_dbe_walk(nsrv4->rfs4_lo_state_tab, rfs4_lo_state_walk_callout, exi);
4103 + rfs4_dbe_walk(nsrv4->rfs4_state_tab, rfs4_state_walk_callout, exi);
4104 + /* CSTYLED */
4105 + rfs4_dbe_walk(nsrv4->rfs4_deleg_state_tab, rfs4_deleg_state_walk_callout, exi);
4106 + rfs4_dbe_walk(nsrv4->rfs4_file_tab, rfs4_file_walk_callout, exi);
4009 4107
4010 - mutex_exit(&rfs4_state_lock);
4108 + mutex_exit(&nsrv4->state_lock);
4011 4109 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX