Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/nfs/export.h
+++ new/usr/src/uts/common/nfs/export.h
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
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 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 25 * Copyright 2016 Jason King.
26 26 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
27 27 */
28 28
29 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 30 /* All Rights Reserved */
31 31
32 32 #ifndef _NFS_EXPORT_H
33 33 #define _NFS_EXPORT_H
34 34
35 35 #include <nfs/nfs_sec.h>
36 36 #include <nfs/auth.h>
37 37 #include <sys/vnode.h>
38 38 #include <nfs/nfs4.h>
39 39 #include <sys/kiconv.h>
40 40 #include <sys/avl.h>
41 41 #include <sys/zone.h>
42 42
43 43 #ifdef _KERNEL
44 44 #include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */
45 45 #endif /* _KERNEL */
46 46
47 47 #ifdef __cplusplus
48 48 extern "C" {
49 49 #endif
50 50
51 51 /*
52 52 * nfs pseudo flavor number is owned by IANA. Need to make sure the
53 53 * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
54 54 * new IANA defined pseudo flavor numbers. The chance for the overlap
55 55 * is very small since the growth of new flavor numbers is expected
56 56 * to be limited.
57 57 */
58 58 #define NFS_FLAVOR_NOMAP 999999 /* no nfs flavor mapping */
59 59
60 60 /*
61 61 * As duplicate flavors can be passed into exportfs in the arguments, we
62 62 * allocate a cleaned up array with non duplicate flavors on the stack.
63 63 * So we need to know how much to allocate.
64 64 */
65 65 #define MAX_FLAVORS 6 /* none, sys, dh, krb5, krb5i krb5p */
66 66
67 67 /*
68 68 * Note: exported_lock is currently used to ensure the integrity of
69 69 * the secinfo fields.
70 70 */
71 71 struct secinfo {
72 72 seconfig_t s_secinfo; /* /etc/nfssec.conf entry */
73 73 unsigned int s_flags; /* flags (see below) */
74 74 int32_t s_refcnt; /* reference count for tracking */
75 75 /* how many children (self included) */
76 76 /* use this flavor. */
77 77 int s_window; /* window */
78 78 uint_t s_rootid; /* UID to use for authorized roots */
79 79 int s_rootcnt; /* count of root names */
80 80 caddr_t *s_rootnames; /* array of root names */
81 81 /* they are strings for AUTH_DES and */
82 82 /* rpc_gss_principal_t for RPCSEC_GSS */
83 83 };
84 84
85 85 #ifdef _SYSCALL32
86 86 struct secinfo32 {
87 87 seconfig32_t s_secinfo; /* /etc/nfssec.conf entry */
88 88 uint32_t s_flags; /* flags (see below) */
89 89 int32_t s_refcnt; /* reference count for tracking */
90 90 /* how many children (self included) */
91 91 /* use this flavor. */
92 92 int32_t s_window; /* window */
93 93 uint32_t s_rootid; /* UID to use for authorized roots */
94 94 int32_t s_rootcnt; /* count of root names */
95 95 caddr32_t s_rootnames; /* array of root names */
96 96 /* they are strings for AUTH_DES and */
97 97 /* rpc_gss_principal_t for RPCSEC_GSS */
98 98 };
99 99 #endif /* _SYSCALL32 */
100 100
101 101 /*
102 102 * security negotiation related
103 103 */
104 104
105 105 #define SEC_QUERY 0x01 /* query sec modes */
106 106
107 107 struct sec_ol {
108 108 int sec_flags; /* security nego flags */
109 109 uint_t sec_index; /* index into sec flavor array */
110 110 };
111 111
112 112 /*
113 113 * Per-mode flags (secinfo.s_flags)
114 114 */
115 115 #define M_RO 0x01 /* exported ro to all */
116 116 #define M_ROL 0x02 /* exported ro to all listed */
117 117 #define M_RW 0x04 /* exported rw to all */
118 118 #define M_RWL 0x08 /* exported ro to all listed */
119 119 #define M_ROOT 0x10 /* root list is defined */
120 120 #define M_4SEC_EXPORTED 0x20 /* this is an explicitly shared flavor */
121 121 #define M_NONE 0x40 /* none list is defined */
122 122 #define M_MAP 0x80 /* uidmap and/or gidmap is defined */
123 123
124 124 /* invalid secinfo reference count */
125 125 #define SEC_REF_INVALID(p) ((p)->s_refcnt < 1)
126 126
127 127 /* last secinfo reference */
128 128 #define SEC_REF_LAST(p) ((p)->s_refcnt == 1)
129 129
130 130 /* sec flavor explicitly shared for the exported node */
131 131 #define SEC_REF_EXPORTED(p) ((p)->s_flags & M_4SEC_EXPORTED)
132 132
133 133 /* the only reference count left is for referring itself */
134 134 #define SEC_REF_SELF(p) (SEC_REF_LAST(p) && SEC_REF_EXPORTED(p))
135 135
136 136 /*
137 137 * The export information passed to exportfs() (Version 2)
138 138 */
139 139 #define EX_CURRENT_VERSION 2 /* current version of exportdata struct */
140 140
141 141 struct exportdata {
142 142 int ex_version; /* structure version */
143 143 char *ex_path; /* exported path */
144 144 size_t ex_pathlen; /* path length */
145 145 int ex_flags; /* flags */
146 146 unsigned int ex_anon; /* uid for unauthenticated requests */
147 147 int ex_seccnt; /* count of security modes */
148 148 struct secinfo *ex_secinfo; /* security mode info */
149 149 char *ex_index; /* index file for public filesystem */
150 150 char *ex_log_buffer; /* path to logging buffer file */
151 151 size_t ex_log_bufferlen; /* buffer file path len */
152 152 char *ex_tag; /* tag used to identify log config */
153 153 size_t ex_taglen; /* tag length */
154 154 };
155 155
156 156 #ifdef _SYSCALL32
157 157 struct exportdata32 {
158 158 int32_t ex_version; /* structure version */
159 159 caddr32_t ex_path; /* exported path */
160 160 int32_t ex_pathlen; /* path length */
161 161 int32_t ex_flags; /* flags */
162 162 uint32_t ex_anon; /* uid for unauthenticated requests */
163 163 int32_t ex_seccnt; /* count of security modes */
164 164 caddr32_t ex_secinfo; /* security mode info */
165 165 caddr32_t ex_index; /* index file for public filesystem */
166 166 caddr32_t ex_log_buffer; /* path to logging buffer file */
167 167 int32_t ex_log_bufferlen; /* buffer file path len */
168 168 caddr32_t ex_tag; /* tag used to identify log config */
169 169 int32_t ex_taglen; /* tag length */
170 170 };
171 171 #endif /* _SYSCALL32 */
172 172
173 173 /*
174 174 * exported vfs flags.
175 175 */
176 176
177 177 #define EX_NOSUID 0x01 /* exported with unsetable set[ug]ids */
178 178 #define EX_ACLOK 0x02 /* exported with maximal access if acl exists */
179 179 #define EX_PUBLIC 0x04 /* exported with public filehandle */
180 180 #define EX_NOSUB 0x08 /* no nfs_getfh or MCL below export point */
181 181 #define EX_INDEX 0x10 /* exported with index file specified */
182 182 #define EX_LOG 0x20 /* logging enabled */
183 183 #define EX_LOG_ALLOPS 0x40 /* logging of all RPC operations enabled */
184 184 /* by default only operations which affect */
185 185 /* transaction logging are enabled */
186 186 #define EX_PSEUDO 0x80 /* pseudo filesystem export */
187 187 #ifdef VOLATILE_FH_TEST
188 188 #define EX_VOLFH 0x100 /* XXX nfsv4 fh may expire anytime */
189 189 #define EX_VOLRNM 0x200 /* XXX nfsv4 fh expire at rename */
190 190 #define EX_VOLMIG 0x400 /* XXX nfsv4 fh expire at migration */
191 191 #define EX_NOEXPOPEN 0x800 /* XXX nfsv4 fh no expire with open */
192 192 #endif /* VOLATILE_FH_TEST */
193 193
194 194 #define EX_CHARMAP 0x1000 /* NFS may need a character set conversion */
195 195 #define EX_NOACLFAB 0x2000 /* If set, NFSv2 and v3 servers won't */
196 196 /* fabricate an aclent_t ACL on file systems */
197 197 /* that don't support aclent_t ACLs */
198 198 #define EX_NOHIDE 0x4000 /* traversable from exported parent */
199 199
200 200 #ifdef _KERNEL
201 201
202 202 #define RPC_IDEMPOTENT 0x1 /* idempotent or not */
203 203 /*
204 204 * Be very careful about which NFS procedures get the RPC_ALLOWANON bit.
205 205 * Right now, if this bit is on, we ignore the results of per NFS request
206 206 * access control.
207 207 */
208 208 #define RPC_ALLOWANON 0x2 /* allow anonymous access */
209 209 #define RPC_MAPRESP 0x4 /* use mapped response buffer */
210 210 #define RPC_AVOIDWORK 0x8 /* do work avoidance for dups */
211 211 #define RPC_PUBLICFH_OK 0x10 /* allow use of public filehandle */
212 212
213 213 /*
214 214 * RPC_ALL is an or of all above bits to be used with "don't care"
215 215 * nfsv4 ops. The flags of an nfsv4 request is the bit-AND of the
216 216 * per-op flags.
217 217 */
218 218 #define RPC_ALL (RPC_IDEMPOTENT|RPC_ALLOWANON|RPC_AVOIDWORK|RPC_PUBLICFH_OK)
219 219
220 220
221 221 #ifdef VOLATILE_FH_TEST
222 222 struct ex_vol_rename {
223 223 nfs_fh4_fmt_t vrn_fh_fmt;
224 224 struct ex_vol_rename *vrn_next;
225 225 };
226 226 #endif /* VOLATILE_FH_TEST */
227 227
228 228 /*
229 229 * An auth cache client entry. This is the umbrella structure and contains all
230 230 * related auth_cache entries in the authc_tree AVL tree.
231 231 */
232 232 struct auth_cache_clnt {
233 233 avl_node_t authc_link;
234 234 struct netbuf authc_addr; /* address of the client */
235 235 krwlock_t authc_lock; /* protects authc_tree */
236 236 avl_tree_t authc_tree; /* auth_cache entries */
237 237 };
238 238
239 239 /*
240 240 * An auth cache entry can exist in 6 states.
241 241 *
242 242 * A NEW entry was recently allocated and added to the cache. It does not
243 243 * contain the valid auth state yet.
244 244 *
245 245 * A WAITING entry is one which is actively engaging the user land mountd code
246 246 * to authenticate or re-authenticate it. The auth state might not be valid
247 247 * yet. The other threads should wait on auth_cv until the retrieving thread
248 248 * finishes the retrieval and changes the auth cache entry to FRESH, or NEW (in
249 249 * a case this entry had no valid auth state yet).
250 250 *
251 251 * A REFRESHING entry is one which is actively engaging the user land mountd
252 252 * code to re-authenticate the cache entry. There is currently no other thread
253 253 * waiting for the results of the refresh.
254 254 *
255 255 * A FRESH entry is one which is valid (it is either newly retrieved or has
256 256 * been refreshed at least once).
257 257 *
258 258 * A STALE entry is one which has been detected to be too old. The transition
259 259 * from FRESH to STALE prevents multiple threads from submitting refresh
260 260 * requests.
261 261 *
262 262 * An INVALID entry is one which was either STALE or REFRESHING and was deleted
263 263 * out of the encapsulating exi. Since we can't delete it yet, we mark it as
264 264 * INVALID, which lets the refresh thread know not to work on it and free it
265 265 * instead.
266 266 *
267 267 * Note that the auth state of the entry is valid, even if the entry is STALE.
268 268 * Just as you can eat stale bread, you can consume a stale cache entry. The
269 269 * only time the contents change could be during the transition from REFRESHING
270 270 * or WAITING to FRESH.
271 271 *
272 272 * Valid state transitions:
273 273 *
274 274 * alloc
275 275 * |
276 276 * v
277 277 * +-----+
278 278 * +--->| NEW |------>free
279 279 * | +-----+
280 280 * | |
281 281 * | v
282 282 * | +---------+
283 283 * +<-| WAITING |
284 284 * ^ +---------+
285 285 * | |
286 286 * | v
287 287 * | +<--------------------------+<---------------+
288 288 * | | ^ |
289 289 * | v | |
290 290 * | +-------+ +-------+ +------------+ +---------+
291 291 * +---| FRESH |--->| STALE |--->| REFRESHING |--->| WAITING |
292 292 * +-------+ +-------+ +------------+ +---------+
293 293 * | | |
294 294 * | v |
295 295 * v +---------+ |
296 296 * free<-----| INVALID |<--------+
297 297 * +---------+
298 298 */
299 299 typedef enum auth_state {
300 300 NFS_AUTH_FRESH,
301 301 NFS_AUTH_STALE,
302 302 NFS_AUTH_REFRESHING,
303 303 NFS_AUTH_INVALID,
304 304 NFS_AUTH_NEW,
305 305 NFS_AUTH_WAITING
306 306 } auth_state_t;
307 307
308 308 /*
309 309 * An authorization cache entry
310 310 *
311 311 * Either the state in auth_state will protect the
312 312 * contents or auth_lock must be held.
313 313 */
314 314 struct auth_cache {
315 315 avl_node_t auth_link;
316 316 struct auth_cache_clnt *auth_clnt;
317 317 int auth_flavor;
318 318 cred_t *auth_clnt_cred;
319 319 uid_t auth_srv_uid;
320 320 gid_t auth_srv_gid;
321 321 uint_t auth_srv_ngids;
322 322 gid_t *auth_srv_gids;
323 323 int auth_access;
324 324 time_t auth_time;
325 325 time_t auth_freshness;
326 326 auth_state_t auth_state;
327 327 kmutex_t auth_lock;
328 328 kcondvar_t auth_cv;
329 329 };
330 330
331 331 #define AUTH_TABLESIZE 32
332 332
333 333 /*
334 334 * Structure containing log file meta-data.
335 335 */
336 336 struct log_file {
337 337 unsigned int lf_flags; /* flags (see below) */
338 338 int lf_writers; /* outstanding writers */
339 339 int lf_refcnt; /* references to this struct */
340 340 caddr_t lf_path; /* buffer file location */
341 341 vnode_t *lf_vp; /* vnode for the buffer file */
342 342 kmutex_t lf_lock;
343 343 kcondvar_t lf_cv_waiters;
344 344 };
345 345
346 346 /*
347 347 * log_file and log_buffer flags.
348 348 */
349 349 #define L_WAITING 0x01 /* flush of in-core data to stable */
350 350 /* storage in progress */
351 351 #define L_PRINTED 0x02 /* error message printed to console */
352 352 #define L_ERROR 0x04 /* error condition detected */
353 353
354 354 /*
355 355 * The logging buffer information.
356 356 * This structure may be shared by multiple exportinfo structures,
357 357 * if they share the same buffer file.
358 358 * This structure contains the basic information about the buffer, such
359 359 * as it's location in the filesystem.
360 360 *
361 361 * 'lb_lock' protects all the fields in this structure except for 'lb_path',
362 362 * and 'lb_next'.
363 363 * 'lb_path' is a write-once/read-many field which needs no locking, it is
364 364 * set before the structure is linked to any exportinfo structure.
365 365 * 'lb_next' is protected by the log_buffer_list_lock.
366 366 */
367 367 struct log_buffer {
368 368 unsigned int lb_flags; /* L_ONLIST set? */
369 369 int lb_refcnt; /* references to this struct */
370 370 unsigned int lb_rec_id; /* used to generate unique id */
371 371 caddr_t lb_path; /* buffer file pathname */
372 372 struct log_file *lb_logfile; /* points to log_file structure */
373 373 kmutex_t lb_lock;
374 374 struct log_buffer *lb_next;
375 375 kcondvar_t lb_cv_waiters;
376 376 caddr_t lb_records; /* linked list of records to write */
377 377 int lb_num_recs; /* # of records to write */
378 378 ssize_t lb_size_queued; /* number of bytes queued for write */
379 379 };
380 380
381 381 #define LOG_BUFFER_HOLD(lbp) { \
382 382 mutex_enter(&(lbp)->lb_lock); \
383 383 (lbp)->lb_refcnt++; \
384 384 mutex_exit(&(lbp)->lb_lock); \
385 385 }
386 386
387 387 #define LOG_BUFFER_RELE(lbp) { \
388 388 log_buffer_rele(lbp); \
389 389 }
390 390
391 391 /*
392 392 * Structure for character set conversion mapping based on client address.
393 393 */
394 394 struct charset_cache {
395 395 struct charset_cache *next;
396 396 kiconv_t inbound;
397 397 kiconv_t outbound;
398 398 struct sockaddr client_addr;
399 399 };
400 400
401 401 /* Forward declarations */
402 402 struct exportinfo;
403 403 struct exp_visible;
404 404 struct svc_req;
405 405
406 406 /*
407 407 * Treenodes are used to build tree representing every node which is part
408 408 * of nfs server pseudo namespace. They are connected with both exportinfo
409 409 * and exp_visible struct. They were introduced to avoid lookup of ".."
410 410 * in the underlying file system during unshare, which was failing if the
411 411 * file system was forcibly unmounted or if the directory was removed.
412 412 * One exp_visible_t can be shared via several treenode_t, i.e.
413 413 * different tree_vis can point to the same exp_visible_t.
414 414 * This will happen if some directory is on two different shared paths:
415 415 * E.g. after share /tmp/a/b1 and share /tmp/a/b2 there will be two treenodes
416 416 * corresponding to /tmp/a and both will have same value in tree_vis.
417 417 *
418 418 *
419 419 *
420 420 * NEW DATA STRUCT ORIGINAL DATA STRUCT
421 421 *
422 422 * ns_root +---+ +----------+
423 423 * | / | |PSEUDO EXP|-->+---+ +---+ +---+
424 424 * +---+--------- ----+----------+ | a |-->| k |-->| b |
425 425 * /\ +---+ +---+ +---+
426 426 * / \ . . .
427 427 * +---+...\......... ..................... . .
428 428 * *| a | \ +----------+ . .
429 429 * +---+-----\------- ----|REAL EXP a| . .
430 430 * / \ +----------+ . .
431 431 * / +===+... ............................. .
432 432 * / *| k | +----------+ .
433 433 * / +===+--- ----|REAL EXP k| .
434 434 * / +----------+ .
435 435 * +===+................ .....................................
436 436 * *| b | +----------+
437 437 * +===+---------------- ----|REAL EXP b|-->+---+
438 438 * \ +----------+ | d |
439 439 * +===+............. ...................+---+
440 440 * | d | +----------+
441 441 * +===+------------- ----|PSEUDO EXP|-->+---+ +---+
442 442 * / +----------+ | e |-->| g |
443 443 * +---+................. ...................+---+ +---+
444 444 * | e | .
445 445 * +---+ .
446 446 * \ .
447 447 * +---+.............. ............................
448 448 * *| g | +----------+
449 449 * +---+-------------- ----|REAL EXP g|
450 450 * +----------+
451 451 *
452 452 *
453 453 *
454 454 * +===+ +---+ +---+
455 455 * | b |..mountpoint | e |..directory/file *| a |..node is shared
456 456 * +===+ (VROOT) +---+ +---+
457 457 *
458 458 *
459 459 * Bi-directional interconnect:
460 460 * treenode_t::tree_exi --------- exportinfo_t::exi_tree
461 461 * One-way direction connection:
462 462 * treenode_t::tree_vis .........> exp_visible_t
463 463 */
464 464 /* Access to treenode_t is under protection of exported_lock RW_LOCK */
465 465 typedef struct treenode {
466 466 /* support for generic n-ary trees */
467 467 struct treenode *tree_parent;
468 468 struct treenode *tree_child_first;
469 469 struct treenode *tree_sibling; /* next sibling */
470 470 /* private, nfs specific part */
471 471 struct exportinfo *tree_exi;
472 472 struct exp_visible *tree_vis;
473 473 } treenode_t;
474 474
475 475 /*
476 476 * TREE_ROOT checks if the node corresponds to a filesystem root or
477 477 * the zone's root directory.
478 478 * TREE_EXPORTED checks if the node is explicitly shared
479 479 */
480 480
481 481 #define TREE_ROOT(t) \
482 482 ((t)->tree_exi != NULL && \
483 483 (((t)->tree_exi->exi_vp->v_flag & VROOT) || \
484 484 VN_CMP((t)->tree_exi->exi_zone->zone_rootvp, (t)->tree_exi->exi_vp)))
485 485
486 486 #define TREE_EXPORTED(t) \
487 487 ((t)->tree_exi && !PSEUDO((t)->tree_exi))
488 488
489 489 #define EXPTABLESIZE 256
490 490
491 491 struct exp_hash {
492 492 struct exportinfo *prev; /* ptr to the previous exportinfo */
493 493 struct exportinfo *next; /* ptr to the next exportinfo */
494 494 struct exportinfo **bckt; /* backpointer to the hash bucket */
495 495 };
496 496
497 497 /*
498 498 * A node associated with an export entry on the
499 499 * list of exported filesystems.
500 500 *
501 501 * exi_count+exi_lock protects an individual exportinfo from being freed
502 502 * when in use.
503 503 *
504 504 * You must have the writer lock on exported_lock to add/delete an exportinfo
505 505 * structure to/from the list.
506 506 *
507 507 * exi_volatile_dev maps to VSW_VOLATILEDEV. It means that the
508 508 * underlying fs devno can change on each mount. When set, the server
509 509 * should not use va_fsid for a GETATTR(FATTR4_FSID) reply. It must
510 510 * use exi_fsid because it is guaranteed to be persistent. This isn't
511 511 * in any way related to NFS4 volatile filehandles.
512 512 *
513 513 * The exi_cache_lock protects the exi_cache AVL trees.
514 514 */
515 515 struct exportinfo {
516 516 struct exportdata exi_export;
517 517 fsid_t exi_fsid;
518 518 struct fid exi_fid;
519 519 struct exp_hash fid_hash;
520 520 struct exp_hash path_hash;
521 521 struct treenode *exi_tree;
522 522 fhandle_t exi_fh;
523 523 krwlock_t exi_cache_lock;
524 524 kmutex_t exi_lock;
525 525 uint_t exi_count;
526 526 vnode_t *exi_vp;
527 527 vnode_t *exi_dvp;
528 528 avl_tree_t *exi_cache[AUTH_TABLESIZE];
529 529 struct log_buffer *exi_logbuffer;
530 530 struct exp_visible *exi_visible;
531 531 struct charset_cache *exi_charset;
532 532 unsigned exi_volatile_dev:1;
533 533 unsigned exi_moved:1;
534 534 int exi_id;
535 535 avl_node_t exi_id_link;
536 536 /*
537 537 * Soft-reference/backpointer to the zone. The ZSD callbacks we have
538 538 * invoke cleanup code that crosses into OTHER cleanup functions that
539 539 * may assume same-zone context and attempt to find their own ZSD,
540 540 * using "curzone" when in fact "curzone" is global when called from
541 541 * NFS's ZSD cleanup (see lm_unexport->nlm_unexport for an example).
542 542 *
543 543 * During ZSD shutdown or destroy callbacks, the zone structure
|
↓ open down ↓ |
543 lines elided |
↑ open up ↑ |
544 544 * does not have its mutex held, and it has just-enough references
545 545 * to not free from underneath us. This field is not a proper
546 546 * referenced-held zone pointer, and only ZSD callbacks should use
547 547 * it.
548 548 */
549 549 struct zone *exi_zone;
550 550 #ifdef VOLATILE_FH_TEST
551 551 uint32_t exi_volatile_id;
552 552 struct ex_vol_rename *exi_vol_rename;
553 553 kmutex_t exi_vol_rename_lock;
554 -#endif /* VOLATILE_FH_TEST */
554 +#endif /* VOLATILE_FH_TEST -- keep last! */
555 555 };
556 556 #define exi_zoneid exi_zone->zone_id
557 557
558 558 typedef struct exportinfo exportinfo_t;
559 559 typedef struct exportdata exportdata_t;
560 560 typedef struct secinfo secinfo_t;
561 561
562 562 /*
563 563 * exp_visible is a visible list per filesystem. It is for filesystems
564 564 * that may need a limited view of its contents. A pseudo export and
565 565 * a real export at the mount point (VROOT) which has a subtree shared
566 566 * has a visible list.
567 567 *
568 568 * The exi_visible field is NULL for normal, non-pseudo filesystems
569 569 * which do not have any subtree exported. If the field is non-null,
570 570 * it points to a list of visible entries, identified by vis_fid and/or
571 571 * vis_ino. The presence of a "visible" list means that if this export
572 572 * can only have a limited view, it can only view the entries in the
573 573 * exp_visible list. The directories in the fid list comprise paths that
574 574 * lead to exported directories.
575 575 *
576 576 * The vis_count field records the number of paths in this filesystem
577 577 * that use this directory. The vis_exported field is non-zero if the
578 578 * entry is an exported directory (leaf node).
579 579 *
580 580 * exp_visible itself is not reference counted. Each exp_visible is
581 581 * referenced twice:
582 582 * 1) from treenode::tree_vis
583 583 * 2) linked from exportinfo::exi_visible
584 584 * The 'owner' of exp_visible is the exportinfo structure. exp_visible should
585 585 * be always freed only from exportinfo_t, never from treenode::tree_vis.
586 586 */
587 587
588 588 struct exp_visible {
589 589 vnode_t *vis_vp;
590 590 fid_t vis_fid;
591 591 u_longlong_t vis_ino;
592 592 int vis_count;
593 593 int vis_exported;
594 594 struct exp_visible *vis_next;
595 595 struct secinfo *vis_secinfo;
596 596 int vis_seccnt;
597 597 timespec_t vis_change;
598 598 };
599 599 typedef struct exp_visible exp_visible_t;
600 600
601 601 #define PSEUDO(exi) ((exi)->exi_export.ex_flags & EX_PSEUDO)
602 602 #define EXP_LINKED(exi) ((exi)->fid_hash.bckt != NULL)
603 603
604 604 #define EQFSID(fsidp1, fsidp2) \
605 605 (((fsidp1)->val[0] == (fsidp2)->val[0]) && \
606 606 ((fsidp1)->val[1] == (fsidp2)->val[1]))
607 607
608 608 #define EQFID(fidp1, fidp2) \
609 609 ((fidp1)->fid_len == (fidp2)->fid_len && \
610 610 bcmp((char *)(fidp1)->fid_data, (char *)(fidp2)->fid_data, \
611 611 (uint_t)(fidp1)->fid_len) == 0)
612 612
613 613 #define exportmatch(exi, fsid, fid) \
614 614 (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
615 615
616 616 /*
617 617 * Returns true iff exported filesystem is read-only to the given host.
618 618 *
619 619 * Note: this macro should be as fast as possible since it's called
620 620 * on each NFS modification request.
621 621 */
622 622 #define rdonly(ro, vp) ((ro) || vn_is_readonly(vp))
623 623 #define rdonly4(req, cs) \
624 624 (vn_is_readonly((cs)->vp) || \
625 625 (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
|
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
626 626 NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
627 627
628 628 extern int nfsauth4_access(struct exportinfo *, vnode_t *,
629 629 struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
630 630 extern int nfsauth4_secinfo_access(struct exportinfo *,
631 631 struct svc_req *, int, int, cred_t *);
632 632 extern int nfsauth_cache_clnt_compar(const void *, const void *);
633 633 extern int nfs_fhbcmp(char *, char *, int);
634 634 extern void nfs_exportinit(void);
635 635 extern void nfs_exportfini(void);
636 +extern void nfs_export_zone_init(nfs_globals_t *);
637 +extern void nfs_export_zone_fini(nfs_globals_t *);
638 +extern void nfs_export_zone_shutdown(nfs_globals_t *);
639 +extern int nfs_export_get_rootfh(nfs_globals_t *);
636 640 extern int chk_clnt_sec(struct exportinfo *, struct svc_req *);
637 641 extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *);
638 642 extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
639 643 extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
640 644 extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
641 645 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
642 646 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
643 647 extern struct exportinfo *checkexport(fsid_t *, struct fid *);
644 648 extern struct exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
645 649 extern void exi_hold(struct exportinfo *);
646 650 extern void exi_rele(struct exportinfo *);
647 651 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
648 652 int *, bool_t);
649 653 extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
650 654 struct exportinfo **);
651 655 extern vnode_t *untraverse(vnode_t *);
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
652 656 extern int vn_is_nfs_reparse(vnode_t *, cred_t *);
653 657 extern int client_is_downrev(struct svc_req *);
654 658 extern char *build_symlink(vnode_t *, cred_t *, size_t *);
655 659
656 660 extern fhandle_t nullfh2; /* for comparing V2 filehandles */
657 661
658 662 typedef struct nfs_export {
659 663 /* Root of nfs pseudo namespace */
660 664 treenode_t *ns_root;
661 665
666 + nfs_globals_t *ne_globals; /* "up" pointer */
667 +
662 668 struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
663 669 struct exportinfo *exptable[EXPTABLESIZE];
664 670
665 671 /*
666 672 * Read/Write lock that protects the exportinfo list. This lock
667 673 * must be held when searching or modifiying the exportinfo list.
668 674 */
669 675 krwlock_t exported_lock;
670 676
671 677 /* "public" and default (root) location for public filehandle */
672 678 struct exportinfo *exi_public, *exi_root;
673 679 /* For checking default public file handle */
674 680 fid_t exi_rootfid;
675 681 /* For comparing V2 filehandles */
676 682 fhandle_t nullfh2;
677 683
678 684 /* The change attribute value of the root of nfs pseudo namespace */
679 685 timespec_t ns_root_change;
680 686 } nfs_export_t;
681 687
682 688 /*
683 689 * Functions that handle the NFSv4 server namespace
684 690 */
685 691 extern exportinfo_t *vis2exi(treenode_t *);
686 692 extern int treeclimb_export(struct exportinfo *);
687 693 extern void treeclimb_unexport(nfs_export_t *, struct exportinfo *);
688 694 extern int nfs_visible(struct exportinfo *, vnode_t *, int *);
689 695 extern int nfs_visible_inode(struct exportinfo *, ino64_t,
690 696 struct exp_visible **);
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
691 697 extern int has_visible(struct exportinfo *, vnode_t *);
692 698 extern void free_visible(struct exp_visible *);
693 699 extern int nfs_exported(struct exportinfo *, vnode_t *);
694 700 extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
695 701 struct exp_visible *, struct exportdata *);
696 702 extern int vop_fid_pseudo(vnode_t *, fid_t *);
697 703 extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
698 704 extern bool_t nfs_visible_change(struct exportinfo *, vnode_t *,
699 705 timespec_t *);
700 706 extern void tree_update_change(nfs_export_t *, treenode_t *, timespec_t *);
707 +extern void rfs4_clean_state_exi(nfs_export_t *, struct exportinfo *);
701 708
702 709 /*
703 710 * Functions that handle the NFSv4 server namespace security flavors
704 711 * information.
705 712 */
706 713 extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
707 714 extern void srv_secinfo_list_free(struct secinfo *, int);
708 715
709 716 extern nfs_export_t *nfs_get_export();
710 717 extern void export_link(nfs_export_t *, struct exportinfo *);
711 718 extern void export_unlink(nfs_export_t *, struct exportinfo *);
712 719
713 720 /*
714 721 * exi_id support
715 722 */
716 723 extern kmutex_t nfs_exi_id_lock;
717 724 extern avl_tree_t exi_id_tree;
718 725 extern int exi_id_get_next(void);
719 726
720 727 /*
721 728 * Two macros for identifying public filehandles.
722 729 * A v2 public filehandle is 32 zero bytes.
723 730 * A v3 public filehandle is zero length.
724 731 */
725 732 #define PUBLIC_FH2(fh) \
726 733 ((fh)->fh_fsid.val[1] == 0 && \
727 734 bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
728 735
729 736 #define PUBLIC_FH3(fh) \
730 737 ((fh)->fh3_length == 0)
731 738
732 739 extern int makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
733 740 extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
734 741
735 742 #endif /* _KERNEL */
736 743
737 744 #ifdef __cplusplus
738 745 }
739 746 #endif
740 747
741 748 #endif /* _NFS_EXPORT_H */
|
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX