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