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_srv_attr.c
+++ new/usr/src/uts/common/fs/nfs/nfs4_srv_attr.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 2010 Sun Microsystems, Inc. All rights reserved.
23 24 * Use is subject to license terms.
24 25 */
26 +
25 27 /*
26 - * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
28 + * Copyright 2018 Nexenta Systems, Inc.
27 29 */
28 30
29 31 #include <sys/systm.h>
30 32 #include <sys/cmn_err.h>
31 33 #include <nfs/nfs.h>
32 34 #include <nfs/export.h>
33 35 #include <nfs/nfs4.h>
34 36 #include <sys/ddi.h>
35 37 #include <sys/door.h>
36 38 #include <sys/sdt.h>
37 39 #include <nfs/nfssys.h>
38 40
39 41 void rfs4_init_compound_state(struct compound_state *);
40 42
41 43 bitmap4 rfs4_supported_attrs;
42 44 int MSG_PRT_DEBUG = FALSE;
43 45
44 46 /* If building with DEBUG enabled, enable mandattr tunable by default */
45 47 #ifdef DEBUG
46 48 #ifndef RFS4_SUPPORT_MANDATTR_ONLY
47 49 #define RFS4_SUPPORT_MANDATTR_ONLY
48 50 #endif
49 51 #endif
50 52
51 53 /*
52 54 * If building with mandattr only code, disable it by default.
53 55 * To enable, set rfs4_mandattr_only in /etc/system and reboot.
54 56 * When building without mandattr ifdef, the compiler should
55 57 * optimize away the the comparisons because RFS4_MANDATTR_ONLY
56 58 * is defined to be 0.
57 59 */
58 60 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
59 61 #define NFS4_LAST_MANDATTR FATTR4_RDATTR_ERROR
60 62 #define RFS4_MANDATTR_ONLY rfs4_mandattr_only
61 63 int rfs4_mandattr_only = 0;
62 64 #else
63 65 #define RFS4_MANDATTR_ONLY 0
64 66 #endif
65 67
66 68
67 69 static void rfs4_ntov_init(void);
68 70 static int rfs4_fattr4_supported_attrs();
69 71 static int rfs4_fattr4_type();
70 72 static int rfs4_fattr4_fh_expire_type();
71 73 static int rfs4_fattr4_change();
72 74 static int rfs4_fattr4_size();
73 75 static int rfs4_fattr4_link_support();
74 76 static int rfs4_fattr4_symlink_support();
75 77 static int rfs4_fattr4_named_attr();
76 78 static int rfs4_fattr4_fsid();
77 79 static int rfs4_fattr4_unique_handles();
78 80 static int rfs4_fattr4_lease_time();
79 81 static int rfs4_fattr4_rdattr_error();
80 82 static int rfs4_fattr4_acl();
81 83 static int rfs4_fattr4_aclsupport();
82 84 static int rfs4_fattr4_archive();
83 85 static int rfs4_fattr4_cansettime();
84 86 static int rfs4_fattr4_case_insensitive();
85 87 static int rfs4_fattr4_case_preserving();
86 88 static int rfs4_fattr4_chown_restricted();
87 89 static int rfs4_fattr4_filehandle();
88 90 static int rfs4_fattr4_fileid();
89 91 static int rfs4_fattr4_files_avail();
90 92 static int rfs4_fattr4_files_free();
91 93 static int rfs4_fattr4_files_total();
92 94 static int rfs4_fattr4_fs_locations();
93 95 static int rfs4_fattr4_hidden();
94 96 static int rfs4_fattr4_homogeneous();
95 97 static int rfs4_fattr4_maxfilesize();
96 98 static int rfs4_fattr4_maxlink();
97 99 static int rfs4_fattr4_maxname();
98 100 static int rfs4_fattr4_maxread();
99 101 static int rfs4_fattr4_maxwrite();
100 102 static int rfs4_fattr4_mimetype();
101 103 static int rfs4_fattr4_mode();
102 104 static int rfs4_fattr4_no_trunc();
103 105 static int rfs4_fattr4_numlinks();
104 106 static int rfs4_fattr4_owner();
105 107 static int rfs4_fattr4_owner_group();
106 108 static int rfs4_fattr4_quota_avail_hard();
107 109 static int rfs4_fattr4_quota_avail_soft();
108 110 static int rfs4_fattr4_quota_used();
109 111 static int rfs4_fattr4_rawdev();
110 112 static int rfs4_fattr4_space_avail();
111 113 static int rfs4_fattr4_space_free();
112 114 static int rfs4_fattr4_space_total();
113 115 static int rfs4_fattr4_space_used();
114 116 static int rfs4_fattr4_system();
115 117 static int rfs4_fattr4_time_access();
116 118 static int rfs4_fattr4_time_access_set();
117 119 static int rfs4_fattr4_time_backup();
118 120 static int rfs4_fattr4_time_create();
119 121 static int rfs4_fattr4_time_delta();
120 122 static int rfs4_fattr4_time_metadata();
121 123 static int rfs4_fattr4_time_modify();
122 124 static int rfs4_fattr4_time_modify_set();
123 125
124 126 /*
125 127 * Initialize the supported attributes
|
↓ open down ↓ |
89 lines elided |
↑ open up ↑ |
126 128 */
127 129 void
128 130 rfs4_attr_init()
129 131 {
130 132 int i;
131 133 struct nfs4_svgetit_arg sarg;
132 134 struct compound_state cs;
133 135 struct statvfs64 sb;
134 136
135 137 rfs4_init_compound_state(&cs);
138 + /*
139 + * This is global state checking, called once. We might be in
140 + * non-global-zone context here (say a modload happens from a zone
141 + * process) so in this case, we want the global-zone root vnode.
142 + */
136 143 cs.vp = rootvp;
137 144 cs.fh.nfs_fh4_val = NULL;
138 145 cs.cr = kcred;
139 146
140 147 /*
141 148 * Get all the supported attributes
142 149 */
143 150 sarg.op = NFS4ATTR_SUPPORTED;
144 151 sarg.cs = &cs;
145 152 sarg.vap->va_mask = AT_ALL;
146 153 sarg.sbp = &sb;
147 154 sarg.flag = 0;
148 155 sarg.rdattr_error = NFS4_OK;
149 156 sarg.rdattr_error_req = FALSE;
150 157 sarg.is_referral = B_FALSE;
151 158
152 159 rfs4_ntov_init();
153 160
154 161 rfs4_supported_attrs = 0;
155 162 for (i = 0; i < NFS4_MAXNUM_ATTRS; i++) {
156 163 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
157 164 if (rfs4_mandattr_only == TRUE && i > NFS4_LAST_MANDATTR)
158 165 continue;
159 166 #endif
160 167 if ((*nfs4_ntov_map[i].sv_getit)(NFS4ATTR_SUPPORTED,
161 168 &sarg, NULL) == 0) {
162 169 rfs4_supported_attrs |= nfs4_ntov_map[i].fbit;
163 170 }
164 171 }
165 172 }
166 173
167 174 /*
168 175 * The following rfs4_fattr4_* functions convert between the fattr4
169 176 * arguments/attributes and the system (e.g. vattr) values. The following
170 177 * commands are currently in use:
171 178 *
172 179 * NFS4ATTR_SUPPORTED: checks if the attribute in question is supported:
173 180 * sarg.op = SUPPORTED - all supported attrs
174 181 * sarg.op = GETIT - only supported readable attrs
175 182 * sarg.op = SETIT - only supported writable attrs
176 183 *
177 184 * NFS4ATTR_GETIT: getattr type conversion - convert system values
178 185 * (e.g. vattr struct) to fattr4 type values to be returned to the
179 186 * user - usually in response to nfsv4 getattr request.
180 187 *
181 188 * NFS4ATTR_SETIT: convert fattr4 type values to system values to use by
182 189 * setattr. Allows only read/write and write attributes,
183 190 * even if not supported by the filesystem. Note that ufs only allows setattr
184 191 * of owner/group, mode, size, atime/mtime.
185 192 *
186 193 * NFS4ATTR_VERIT: convert fattr4 type values to system values to use by
187 194 * verify/nverify. Implemented to allow
188 195 * almost everything that can be returned by getattr into known structs
189 196 * (like vfsstat64 or vattr_t), that is, both read only and read/write attrs.
190 197 * The function will return -1 if it found that the arguments don't match.
191 198 * This applies to system-wide values that don't require a VOP_GETATTR
192 199 * or other further checks to verify. It will return no error if they
193 200 * either match or were retrieved successfully for later checking.
194 201 *
195 202 * NFS4ATTR_FREEIT: free up any space allocated by either of the above.
196 203 * The sargp->op should be either NFS4ATTR_GETIT or NFS4ATTR_SETIT
197 204 * to indicate which op was used to allocate the space.
198 205 *
199 206 * XXX Note: these functions are currently used by the server only. A
200 207 * XXX different method of conversion is used on the client side.
201 208 * XXX Eventually combining the two (possibly by adding NFS4ATTR_CLNT_GETIT
202 209 * XXX and SETIT) may be a cleaner approach.
203 210 */
204 211
205 212 /*
206 213 * Mandatory attributes
207 214 */
208 215
209 216 /* ARGSUSED */
210 217 static int
211 218 rfs4_fattr4_supported_attrs(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
212 219 union nfs4_attr_u *na)
213 220 {
214 221 int error = 0;
215 222
216 223 switch (cmd) {
217 224 case NFS4ATTR_SUPPORTED:
218 225 if (sarg->op == NFS4ATTR_SETIT)
219 226 error = EINVAL;
220 227 break; /* this attr is supported */
221 228 case NFS4ATTR_GETIT:
222 229 na->supported_attrs = rfs4_supported_attrs;
223 230 break;
224 231 case NFS4ATTR_SETIT:
225 232 /*
226 233 * read-only attr
227 234 */
228 235 error = EINVAL;
229 236 break;
230 237 case NFS4ATTR_VERIT:
231 238 /*
232 239 * Compare the input bitmap to the server's bitmap
233 240 */
234 241 if (na->supported_attrs != rfs4_supported_attrs) {
235 242 error = -1; /* no match */
236 243 }
237 244 break;
238 245 case NFS4ATTR_FREEIT:
239 246 break;
240 247 }
241 248 return (error);
242 249 }
243 250
244 251 /*
245 252 * Translate vnode vtype to nfsv4_ftype.
246 253 */
247 254 static nfs_ftype4 vt_to_nf4[] = {
248 255 0, NF4REG, NF4DIR, NF4BLK, NF4CHR, NF4LNK, NF4FIFO, 0, 0, NF4SOCK, 0
249 256 };
250 257
251 258 /* ARGSUSED */
252 259 static int
253 260 rfs4_fattr4_type(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
254 261 union nfs4_attr_u *na)
255 262 {
256 263 int error = 0;
257 264
258 265 switch (cmd) {
259 266 case NFS4ATTR_SUPPORTED:
260 267 if (sarg->op == NFS4ATTR_SETIT)
261 268 error = EINVAL;
262 269 break; /* this attr is supported */
263 270 case NFS4ATTR_GETIT:
264 271 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_TYPE)) {
265 272 error = -1; /* may be okay if rdattr_error */
266 273 break;
267 274 }
268 275 ASSERT(sarg->vap->va_mask & AT_TYPE);
269 276
270 277 /*
271 278 * if xattr flag not set, use v4_to_nf4 mapping;
272 279 * otherwise verify xattr flag is in sync with va_type
273 280 * and set xattr types.
274 281 */
275 282 if (! (sarg->xattr & (FH4_NAMEDATTR | FH4_ATTRDIR)))
276 283 na->type = vt_to_nf4[sarg->vap->va_type];
277 284 else {
278 285 /*
279 286 * FH4 flag was set. Dir type maps to attrdir,
280 287 * and all other types map to namedattr.
281 288 */
282 289 if (sarg->vap->va_type == VDIR)
283 290 na->type = NF4ATTRDIR;
284 291 else
285 292 na->type = NF4NAMEDATTR;
286 293 }
287 294 break;
288 295 case NFS4ATTR_SETIT:
289 296 /*
290 297 * read-only attr
291 298 */
292 299 error = EINVAL;
293 300 break;
294 301 case NFS4ATTR_VERIT:
295 302 /*
296 303 * Compare the input type to the object type on server
297 304 */
298 305 ASSERT(sarg->vap->va_mask & AT_TYPE);
299 306 if (sarg->vap->va_type != nf4_to_vt[na->type])
300 307 error = -1; /* no match */
301 308 break;
302 309 case NFS4ATTR_FREEIT:
303 310 break;
304 311 }
305 312 return (error);
306 313 }
307 314
308 315 /* ARGSUSED */
309 316 static int
310 317 fattr4_get_fh_expire_type(struct exportinfo *exi, uint32_t *fh_expire_typep)
311 318 {
312 319 #ifdef VOLATILE_FH_TEST
313 320 int ex_flags;
314 321
315 322 if (exi == NULL)
316 323 return (ESTALE);
317 324 ex_flags = exi->exi_export.ex_flags;
318 325 if ((ex_flags & (EX_VOLFH | EX_VOLRNM | EX_VOLMIG | EX_NOEXPOPEN))
319 326 == 0) {
320 327 *fh_expire_typep = FH4_PERSISTENT;
321 328 return (0);
322 329 }
323 330 *fh_expire_typep = 0;
324 331
325 332 if (ex_flags & EX_NOEXPOPEN) {
326 333 /* file handles should not expire with open - not used */
327 334 *fh_expire_typep = FH4_NOEXPIRE_WITH_OPEN;
328 335 }
329 336 if (ex_flags & EX_VOLFH) {
330 337 /*
331 338 * file handles may expire any time - on share here.
332 339 * If volatile any, no need to check other flags.
333 340 */
334 341 *fh_expire_typep |= FH4_VOLATILE_ANY;
335 342 return (0);
336 343 }
337 344 if (ex_flags & EX_VOLRNM) {
338 345 /* file handles may expire on rename */
339 346 *fh_expire_typep |= FH4_VOL_RENAME;
340 347 }
341 348 if (ex_flags & EX_VOLMIG) {
342 349 /* file handles may expire on migration - not used */
343 350 *fh_expire_typep |= FH4_VOL_MIGRATION;
344 351 }
345 352 #else /* not VOLATILE_FH_TEST */
346 353 *fh_expire_typep = FH4_PERSISTENT;
347 354 #endif /* VOLATILE_FH_TEST */
348 355
349 356 return (0);
350 357 }
351 358
352 359 /*
353 360 * At this point the only volatile filehandles we allow (for test purposes
354 361 * only) are either fh's that expire when the filesystem is shared (reshared),
355 362 * fh's that expire on a rename and persistent ones.
356 363 */
357 364 /* ARGSUSED */
358 365 static int
359 366 rfs4_fattr4_fh_expire_type(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
360 367 union nfs4_attr_u *na)
361 368 {
362 369 uint32_t fh_expire_type;
363 370 int error = 0;
364 371
365 372 switch (cmd) {
366 373 case NFS4ATTR_SUPPORTED:
367 374 if (sarg->op == NFS4ATTR_SETIT)
368 375 error = EINVAL;
369 376 break; /* this attr is supported */
370 377 case NFS4ATTR_GETIT:
371 378 error = fattr4_get_fh_expire_type(sarg->cs->exi,
372 379 &na->fh_expire_type);
373 380 break;
374 381 case NFS4ATTR_SETIT:
375 382 /*
376 383 * read-only attr
377 384 */
378 385 error = EINVAL;
379 386 break;
380 387 case NFS4ATTR_VERIT:
381 388 error = fattr4_get_fh_expire_type(sarg->cs->exi,
382 389 &fh_expire_type);
383 390 if (!error && (na->fh_expire_type != fh_expire_type))
384 391 error = -1; /* no match */
385 392 break;
386 393 case NFS4ATTR_FREEIT:
387 394 break;
388 395 }
389 396 return (error);
390 397 }
391 398
392 399 static int
393 400 fattr4_get_change(struct nfs4_svgetit_arg *sarg, fattr4_change *changep)
394 401 {
395 402 vattr_t vap2[1], *vap = sarg->vap;
396 403 struct compound_state *cs = sarg->cs;
397 404 vnode_t *vp = cs->vp;
398 405 nfsstat4 status;
399 406 timespec_t vis_change;
400 407
401 408 if ((vap->va_mask & AT_CTIME) == 0) {
402 409 if (sarg->rdattr_error && (vp == NULL)) {
403 410 return (-1); /* may be okay if rdattr_error */
404 411 }
405 412 ASSERT(vp != NULL);
406 413 vap = vap2;
407 414 vap->va_mask = AT_CTIME;
408 415 status = rfs4_vop_getattr(vp, vap, 0, cs->cr);
409 416 if (status != NFS4_OK)
410 417 return (geterrno4(status));
411 418 }
412 419 NFS4_SET_FATTR4_CHANGE(*changep, vap->va_ctime);
413 420
414 421 if (nfs_visible_change(cs->exi, vp, &vis_change)) {
415 422 fattr4_change visch;
416 423 NFS4_SET_FATTR4_CHANGE(visch, vis_change);
417 424 if (visch > *changep)
418 425 *changep = visch;
419 426 }
420 427
421 428 return (0);
422 429 }
423 430
424 431 /* ARGSUSED */
425 432 static int
426 433 rfs4_fattr4_change(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
427 434 union nfs4_attr_u *na)
428 435 {
429 436 int error = 0;
430 437 fattr4_change change;
431 438 uint_t mask;
432 439 vattr_t *vap = sarg->vap;
433 440
434 441 switch (cmd) {
435 442 case NFS4ATTR_SUPPORTED:
436 443 if (sarg->op == NFS4ATTR_SETIT)
437 444 error = EINVAL;
438 445 break; /* this attr is supported */
439 446 case NFS4ATTR_GETIT:
440 447 error = fattr4_get_change(sarg, &na->change);
441 448 break;
442 449 case NFS4ATTR_SETIT:
443 450 /*
444 451 * read-only attr
445 452 */
446 453 error = EINVAL;
447 454 break;
448 455 case NFS4ATTR_VERIT:
449 456 mask = vap->va_mask;
450 457 vap->va_mask &= ~AT_CTIME; /* force a VOP_GETATTR */
451 458 error = fattr4_get_change(sarg, &change);
452 459 vap->va_mask = mask;
453 460 if (!error && (na->change != change))
454 461 error = -1;
455 462 break;
456 463 case NFS4ATTR_FREEIT:
457 464 break;
458 465 }
459 466 return (error);
460 467 }
461 468
462 469 /* ARGSUSED */
463 470 static int
464 471 rfs4_fattr4_size(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
465 472 union nfs4_attr_u *na)
466 473 {
467 474 int error = 0;
468 475
469 476 switch (cmd) {
470 477 case NFS4ATTR_SUPPORTED:
471 478 break; /* this attr is supported */
472 479 case NFS4ATTR_GETIT:
473 480 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_SIZE)) {
474 481 error = -1; /* may be okay if rdattr_error */
475 482 break;
476 483 }
477 484 ASSERT(sarg->vap->va_mask & AT_SIZE);
478 485 na->size = sarg->vap->va_size;
479 486 break;
480 487 case NFS4ATTR_SETIT:
481 488 ASSERT(sarg->vap->va_mask & AT_SIZE);
482 489 sarg->vap->va_size = na->size;
483 490 break;
484 491 case NFS4ATTR_VERIT:
485 492 ASSERT(sarg->vap->va_mask & AT_SIZE);
486 493 if (sarg->vap->va_size != na->size)
487 494 error = -1; /* no match */
488 495 break;
489 496 case NFS4ATTR_FREEIT:
490 497 break;
491 498 }
492 499 return (error);
493 500 }
494 501
495 502 /*
496 503 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
497 504 * hard links.
498 505 */
499 506 /* ARGSUSED */
500 507 static int
501 508 rfs4_fattr4_link_support(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
502 509 union nfs4_attr_u *na)
503 510 {
504 511 int error = 0;
505 512
506 513 switch (cmd) {
507 514 case NFS4ATTR_SUPPORTED:
508 515 if (sarg->op == NFS4ATTR_SETIT)
509 516 error = EINVAL;
510 517 break; /* this attr is supported */
511 518 case NFS4ATTR_GETIT:
512 519 na->link_support = TRUE;
513 520 break;
514 521 case NFS4ATTR_SETIT:
515 522 /*
516 523 * read-only attr
517 524 */
518 525 error = EINVAL;
519 526 break;
520 527 case NFS4ATTR_VERIT:
521 528 if (!na->link_support)
522 529 error = -1; /* no match */
523 530 break;
524 531 case NFS4ATTR_FREEIT:
525 532 break;
526 533 }
527 534 return (error);
528 535 }
529 536
530 537 /*
531 538 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
532 539 * sym links.
533 540 */
534 541 /* ARGSUSED */
535 542 static int
536 543 rfs4_fattr4_symlink_support(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
537 544 union nfs4_attr_u *na)
538 545 {
539 546 int error = 0;
540 547
541 548 switch (cmd) {
542 549 case NFS4ATTR_SUPPORTED:
543 550 if (sarg->op == NFS4ATTR_SETIT)
544 551 error = EINVAL;
545 552 break; /* this attr is supported */
546 553 case NFS4ATTR_GETIT:
547 554 na->symlink_support = TRUE;
548 555 break;
549 556 case NFS4ATTR_SETIT:
550 557 /*
551 558 * read-only attr
552 559 */
553 560 error = EINVAL;
554 561 break;
555 562 case NFS4ATTR_VERIT:
556 563 if (!na->symlink_support)
557 564 error = -1; /* no match */
558 565 break;
559 566 case NFS4ATTR_FREEIT:
560 567 break;
561 568 }
562 569 return (error);
563 570 }
564 571
565 572 /* ARGSUSED */
566 573 static int
567 574 rfs4_fattr4_named_attr(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
568 575 union nfs4_attr_u *na)
569 576 {
570 577 int error = 0;
571 578 ulong_t val;
572 579
573 580 switch (cmd) {
574 581 case NFS4ATTR_SUPPORTED:
575 582 if (sarg->op == NFS4ATTR_SETIT)
576 583 error = EINVAL;
577 584 break; /* this attr is supported */
578 585 case NFS4ATTR_GETIT:
579 586 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
580 587 error = -1; /* may be okay if rdattr_error */
581 588 break;
582 589 }
583 590 ASSERT(sarg->cs->vp != NULL);
584 591
585 592 /*
586 593 * Solaris xattr model requires that VFS_XATTR is set
587 594 * in file systems enabled for generic xattr. If VFS_XATTR
588 595 * not set, no need to call pathconf for _PC_XATTR_EXISTS..
589 596 *
590 597 * However the VFS_XATTR flag doesn't indicate sysattr support
591 598 * so always check for sysattrs and then only do the
592 599 * _PC_XATTR_EXISTS pathconf if needed.
593 600 */
594 601
595 602 val = 0;
596 603 error = VOP_PATHCONF(sarg->cs->vp, _PC_SATTR_EXISTS,
597 604 &val, sarg->cs->cr, NULL);
598 605 if ((error || val == 0) &&
599 606 sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) {
600 607 error = VOP_PATHCONF(sarg->cs->vp,
601 608 _PC_XATTR_EXISTS, &val, sarg->cs->cr, NULL);
602 609 if (error)
603 610 break;
604 611 }
605 612 na->named_attr = (val ? TRUE : FALSE);
606 613 break;
607 614 case NFS4ATTR_SETIT:
608 615 /*
609 616 * read-only attr
610 617 */
611 618 error = EINVAL;
612 619 break;
613 620 case NFS4ATTR_VERIT:
614 621 ASSERT(sarg->cs->vp != NULL);
615 622 if (sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) {
616 623 error = VOP_PATHCONF(sarg->cs->vp, _PC_SATTR_EXISTS,
617 624 &val, sarg->cs->cr, NULL);
618 625 if (error || val == 0)
619 626 error = VOP_PATHCONF(sarg->cs->vp,
620 627 _PC_XATTR_EXISTS, &val,
621 628 sarg->cs->cr, NULL);
622 629 if (error)
623 630 break;
624 631 } else
625 632 val = 0;
626 633 if (na->named_attr != (val ? TRUE : FALSE))
627 634 error = -1; /* no match */
628 635 break;
629 636 case NFS4ATTR_FREEIT:
630 637 break;
631 638 }
632 639 return (error);
633 640 }
634 641
635 642 /* ARGSUSED */
636 643 static int
637 644 rfs4_fattr4_fsid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
638 645 union nfs4_attr_u *na)
639 646 {
640 647 int error = 0;
641 648 int *pmaj = (int *)&na->fsid.major;
642 649
643 650 /*
644 651 * fsid_t is 64bits so it fits completely in fattr4_fsid.major.
645 652 * fattr4_fsid.minor is always set to 0 since it isn't needed (yet).
646 653 */
647 654 switch (cmd) {
648 655 case NFS4ATTR_SUPPORTED:
649 656 if (sarg->op == NFS4ATTR_SETIT)
650 657 error = EINVAL;
651 658 break; /* this attr is supported */
652 659 case NFS4ATTR_GETIT:
653 660 if (sarg->is_referral) {
654 661 na->fsid.major = 1;
655 662 na->fsid.minor = 0;
656 663 } else if (sarg->cs->exi->exi_volatile_dev) {
657 664 pmaj[0] = sarg->cs->exi->exi_fsid.val[0];
658 665 pmaj[1] = sarg->cs->exi->exi_fsid.val[1];
659 666 na->fsid.minor = 0;
660 667 } else {
661 668 na->fsid.major = getmajor(sarg->vap->va_fsid);
662 669 na->fsid.minor = getminor(sarg->vap->va_fsid);
663 670 }
664 671 break;
665 672 case NFS4ATTR_SETIT:
666 673 error = EINVAL;
667 674 break;
668 675 case NFS4ATTR_VERIT:
669 676 if (sarg->is_referral) {
670 677 if (na->fsid.major != 1 ||
671 678 na->fsid.minor != 0)
672 679 error = -1;
673 680 } else if (sarg->cs->exi->exi_volatile_dev) {
674 681 if (pmaj[0] != sarg->cs->exi->exi_fsid.val[0] ||
675 682 pmaj[1] != sarg->cs->exi->exi_fsid.val[1] ||
676 683 na->fsid.minor != 0)
677 684 error = -1;
678 685 } else {
679 686 if (na->fsid.major != getmajor(sarg->vap->va_fsid) ||
680 687 na->fsid.minor != getminor(sarg->vap->va_fsid))
681 688 error = -1;
682 689 }
683 690 break;
684 691 case NFS4ATTR_FREEIT:
685 692 break;
686 693 }
687 694 return (error);
688 695 }
689 696
690 697 /* ARGSUSED */
691 698 static int
692 699 rfs4_fattr4_unique_handles(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
693 700 union nfs4_attr_u *na)
694 701 {
695 702 /*
696 703 * XXX
697 704 * For now, we can't support this. Problem of /export, beinging
698 705 * a file system, /export/a and /export/b shared separately,
699 706 * and /export/a/l and /export/b/l are ahrd links of each other.
700 707 */
701 708 int error = 0;
702 709
703 710 switch (cmd) {
704 711 case NFS4ATTR_SUPPORTED:
705 712 if (sarg->op == NFS4ATTR_SETIT)
706 713 error = EINVAL;
707 714 break; /* this attr is supported */
708 715 case NFS4ATTR_GETIT:
709 716 na->unique_handles = FALSE;
710 717 break;
711 718 case NFS4ATTR_SETIT:
712 719 /*
713 720 * read-only attr
714 721 */
715 722 error = EINVAL;
716 723 break;
717 724 case NFS4ATTR_VERIT:
718 725 if (na->unique_handles)
719 726 error = -1; /* no match */
720 727 break;
721 728 case NFS4ATTR_FREEIT:
722 729 break;
723 730 }
724 731 return (error);
725 732 }
726 733
727 734 /* ARGSUSED */
728 735 static int
729 736 rfs4_fattr4_lease_time(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
730 737 union nfs4_attr_u *na)
731 738 {
732 739 int error = 0;
733 740
734 741 switch (cmd) {
735 742 case NFS4ATTR_SUPPORTED:
736 743 if (sarg->op == NFS4ATTR_SETIT)
737 744 error = EINVAL;
738 745 break; /* this attr is supported */
739 746 case NFS4ATTR_GETIT:
740 747 na->lease_time = rfs4_lease_time;
741 748 break;
742 749 case NFS4ATTR_SETIT:
743 750 /*
744 751 * read-only attr
745 752 */
746 753 error = EINVAL;
747 754 break;
748 755 case NFS4ATTR_VERIT:
749 756 if (na->lease_time != rfs4_lease_time)
750 757 error = -1; /* no match */
751 758 break;
752 759 case NFS4ATTR_FREEIT:
753 760 break;
754 761 }
755 762 return (error);
756 763 }
757 764
758 765 /* ARGSUSED */
759 766 static int
760 767 rfs4_fattr4_rdattr_error(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
761 768 union nfs4_attr_u *na)
762 769 {
763 770 int error = 0;
764 771
765 772 switch (cmd) {
766 773 case NFS4ATTR_SUPPORTED:
767 774 if ((sarg->op == NFS4ATTR_SETIT) ||
768 775 (sarg->op == NFS4ATTR_VERIT))
769 776 error = EINVAL;
770 777 break; /* this attr is supported */
771 778 case NFS4ATTR_GETIT:
772 779 ASSERT(sarg->rdattr_error_req);
773 780 na->rdattr_error = sarg->rdattr_error;
774 781 break;
775 782 case NFS4ATTR_SETIT:
776 783 case NFS4ATTR_VERIT:
777 784 /*
778 785 * read-only attr
779 786 */
780 787 error = EINVAL;
781 788 break;
782 789 case NFS4ATTR_FREEIT:
783 790 break;
784 791 }
785 792 return (error);
786 793 }
787 794
788 795 /*
789 796 * Server side compare of a filehandle from the wire to a native
790 797 * server filehandle.
791 798 */
792 799 static int
793 800 rfs4fhcmp(nfs_fh4 *wirefh, nfs_fh4 *srvfh)
794 801 {
795 802 nfs_fh4_fmt_t fh;
796 803
797 804 ASSERT(IS_P2ALIGNED(wirefh->nfs_fh4_val, sizeof (uint32_t)));
798 805
799 806 bzero(&fh, sizeof (nfs_fh4_fmt_t));
800 807 if (!xdr_inline_decode_nfs_fh4((uint32_t *)wirefh->nfs_fh4_val, &fh,
801 808 wirefh->nfs_fh4_len))
802 809 return (1);
803 810
804 811 return (bcmp(srvfh->nfs_fh4_val, &fh, srvfh->nfs_fh4_len));
805 812 }
806 813
807 814 /* ARGSUSED */
808 815 static int
809 816 rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
810 817 union nfs4_attr_u *na)
811 818 {
812 819 nfs_fh4 *fh;
813 820
814 821 switch (cmd) {
815 822 case NFS4ATTR_SUPPORTED:
816 823 if (sarg->op == NFS4ATTR_SETIT)
817 824 return (EINVAL);
818 825 return (0); /* this attr is supported */
819 826 case NFS4ATTR_GETIT:
820 827 /*
821 828 * If sarg->cs->fh is all zeros then should makefh a new
822 829 * one, otherwise, copy that one over.
823 830 */
824 831 fh = &sarg->cs->fh;
825 832 if (sarg->cs->fh.nfs_fh4_len == 0) {
826 833 if (sarg->rdattr_error && (sarg->cs->vp == NULL))
827 834 return (-1); /* okay if rdattr_error */
828 835 ASSERT(sarg->cs->vp != NULL);
829 836 na->filehandle.nfs_fh4_val =
830 837 kmem_alloc(NFS_FH4_LEN, KM_SLEEP);
831 838 return (makefh4(&na->filehandle, sarg->cs->vp,
832 839 sarg->cs->exi));
833 840 }
834 841 na->filehandle.nfs_fh4_val =
835 842 kmem_alloc(fh->nfs_fh4_len, KM_SLEEP);
836 843 nfs_fh4_copy(fh, &na->filehandle);
837 844 return (0);
838 845 case NFS4ATTR_SETIT:
839 846 /*
840 847 * read-only attr
841 848 */
842 849 return (EINVAL);
843 850 case NFS4ATTR_VERIT:
844 851 /*
845 852 * A verify of a filehandle will have the client sending
846 853 * the raw format which needs to be compared to the
847 854 * native format.
848 855 */
849 856 if (rfs4fhcmp(&na->filehandle, &sarg->cs->fh) == 1)
850 857 return (-1); /* no match */
851 858 return (0);
852 859 case NFS4ATTR_FREEIT:
853 860 if (sarg->op != NFS4ATTR_GETIT)
854 861 return (0);
855 862 if (na->filehandle.nfs_fh4_val == NULL)
856 863 return (0);
857 864 kmem_free(na->filehandle.nfs_fh4_val,
858 865 na->filehandle.nfs_fh4_len);
859 866 na->filehandle.nfs_fh4_val = NULL;
860 867 na->filehandle.nfs_fh4_len = 0;
861 868 return (0);
862 869 }
863 870 return (0);
864 871 }
865 872
866 873 /*
867 874 * Recommended attributes
868 875 */
869 876
870 877 /* ARGSUSED */
871 878 static int
872 879 rfs4_fattr4_acl(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
873 880 union nfs4_attr_u *na)
874 881 {
875 882 int error = 0;
876 883 vsecattr_t vs_native, vs_ace4;
877 884 ulong_t whichacl;
878 885 nfsstat4 status;
879 886 vattr_t va, *vap = sarg->vap;
880 887 vnode_t *vp = sarg->cs->vp;
881 888
882 889 if (RFS4_MANDATTR_ONLY)
883 890 return (ENOTSUP);
884 891
885 892 switch (cmd) {
886 893 case NFS4ATTR_SUPPORTED:
887 894 break;
888 895
889 896 case NFS4ATTR_VERIT:
890 897 case NFS4ATTR_GETIT:
891 898 if (sarg->rdattr_error && (vp == NULL)) {
892 899 return (-1);
893 900 }
894 901 ASSERT(vp != NULL);
895 902 bzero(&vs_native, sizeof (vs_native));
896 903
897 904 /* see which ACLs fs supports */
898 905 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl,
899 906 sarg->cs->cr, NULL);
900 907 if (error != 0) {
901 908 /*
902 909 * If we got an error, then the filesystem
903 910 * likely does not understand the _PC_ACL_ENABLED
904 911 * pathconf. In this case, we fall back to trying
905 912 * POSIX-draft (aka UFS-style) ACLs, since that's
906 913 * the behavior used by earlier version of NFS.
907 914 */
908 915 error = 0;
909 916 whichacl = _ACL_ACLENT_ENABLED;
910 917 }
911 918
912 919 if (!(whichacl & (_ACL_ACE_ENABLED | _ACL_ACLENT_ENABLED))) {
913 920 /*
914 921 * If the file system supports neither ACE nor
915 922 * ACLENT ACLs we will fall back to UFS-style ACLs
916 923 * like we did above if there was an error upon
917 924 * calling VOP_PATHCONF.
918 925 *
919 926 * ACE and ACLENT type ACLs are the only interfaces
920 927 * supported thus far. If any other bits are set on
921 928 * 'whichacl' upon return from VOP_PATHCONF, we will
922 929 * ignore them.
923 930 */
924 931 whichacl = _ACL_ACLENT_ENABLED;
925 932 }
926 933
927 934 if (whichacl & _ACL_ACE_ENABLED)
928 935 vs_native.vsa_mask = VSA_ACE | VSA_ACECNT;
929 936 else if (whichacl & _ACL_ACLENT_ENABLED)
930 937 vs_native.vsa_mask = VSA_ACL | VSA_ACLCNT |
931 938 VSA_DFACL | VSA_DFACLCNT;
932 939
933 940 if (error != 0)
934 941 break;
935 942
936 943 /* get the ACL, and translate it into nfsace4 style */
937 944 error = VOP_GETSECATTR(vp, &vs_native,
938 945 0, sarg->cs->cr, NULL);
939 946 if (error != 0)
940 947 break;
941 948 if (whichacl & _ACL_ACE_ENABLED) {
942 949 error = vs_acet_to_ace4(&vs_native, &vs_ace4, TRUE);
943 950 vs_acet_destroy(&vs_native);
944 951 } else {
945 952 error = vs_aent_to_ace4(&vs_native, &vs_ace4,
946 953 vp->v_type == VDIR, TRUE);
947 954 vs_aent_destroy(&vs_native);
948 955 }
949 956 if (error != 0)
950 957 break;
951 958
952 959 if (cmd == NFS4ATTR_GETIT) {
953 960 na->acl.fattr4_acl_len = vs_ace4.vsa_aclcnt;
954 961 /* see case NFS4ATTR_FREEIT for this being freed */
955 962 na->acl.fattr4_acl_val = vs_ace4.vsa_aclentp;
956 963 } else {
957 964 if (na->acl.fattr4_acl_len != vs_ace4.vsa_aclcnt)
958 965 error = -1; /* no match */
959 966 else if (ln_ace4_cmp(na->acl.fattr4_acl_val,
960 967 vs_ace4.vsa_aclentp,
961 968 vs_ace4.vsa_aclcnt) != 0)
962 969 error = -1; /* no match */
963 970 }
964 971
965 972 break;
966 973
967 974 case NFS4ATTR_SETIT:
968 975 if (sarg->rdattr_error && (vp == NULL)) {
969 976 return (-1);
970 977 }
971 978 ASSERT(vp != NULL);
972 979
973 980 /* prepare vs_ace4 from fattr4 data */
974 981 bzero(&vs_ace4, sizeof (vs_ace4));
975 982 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT;
976 983 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len;
977 984 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val;
978 985 vs_ace4.vsa_aclentsz = vs_ace4.vsa_aclcnt * sizeof (ace_t);
979 986 /* make sure we have correct owner/group */
980 987 if ((vap->va_mask & (AT_UID | AT_GID)) !=
981 988 (AT_UID | AT_GID)) {
982 989 vap = &va;
983 990 vap->va_mask = AT_UID | AT_GID;
984 991 status = rfs4_vop_getattr(vp,
985 992 vap, 0, sarg->cs->cr);
986 993 if (status != NFS4_OK)
987 994 return (geterrno4(status));
988 995 }
989 996
990 997 /* see which ACLs the fs supports */
991 998 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl,
992 999 sarg->cs->cr, NULL);
993 1000 if (error != 0) {
994 1001 /*
995 1002 * If we got an error, then the filesystem
996 1003 * likely does not understand the _PC_ACL_ENABLED
997 1004 * pathconf. In this case, we fall back to trying
998 1005 * POSIX-draft (aka UFS-style) ACLs, since that's
999 1006 * the behavior used by earlier version of NFS.
1000 1007 */
1001 1008 error = 0;
1002 1009 whichacl = _ACL_ACLENT_ENABLED;
1003 1010 }
1004 1011
1005 1012 if (!(whichacl & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED))) {
1006 1013 /*
1007 1014 * If the file system supports neither ACE nor
1008 1015 * ACLENT ACLs we will fall back to UFS-style ACLs
1009 1016 * like we did above if there was an error upon
1010 1017 * calling VOP_PATHCONF.
1011 1018 *
1012 1019 * ACE and ACLENT type ACLs are the only interfaces
1013 1020 * supported thus far. If any other bits are set on
1014 1021 * 'whichacl' upon return from VOP_PATHCONF, we will
1015 1022 * ignore them.
1016 1023 */
1017 1024 whichacl = _ACL_ACLENT_ENABLED;
1018 1025 }
1019 1026
1020 1027 if (whichacl & _ACL_ACE_ENABLED) {
1021 1028 error = vs_ace4_to_acet(&vs_ace4, &vs_native,
1022 1029 vap->va_uid, vap->va_gid, TRUE);
1023 1030 if (error != 0)
1024 1031 break;
1025 1032 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
1026 1033 error = VOP_SETSECATTR(vp, &vs_native,
1027 1034 0, sarg->cs->cr, NULL);
1028 1035 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
1029 1036 vs_acet_destroy(&vs_native);
1030 1037 } else if (whichacl & _ACL_ACLENT_ENABLED) {
1031 1038 error = vs_ace4_to_aent(&vs_ace4, &vs_native,
1032 1039 vap->va_uid, vap->va_gid, vp->v_type == VDIR, TRUE);
1033 1040 if (error != 0)
1034 1041 break;
1035 1042 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
1036 1043 error = VOP_SETSECATTR(vp, &vs_native,
1037 1044 0, sarg->cs->cr, NULL);
1038 1045 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
1039 1046 vs_aent_destroy(&vs_native);
1040 1047 }
1041 1048 break;
1042 1049
1043 1050 case NFS4ATTR_FREEIT:
1044 1051 if (sarg->op == NFS4ATTR_GETIT) {
1045 1052 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT;
1046 1053 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len;
1047 1054 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val;
1048 1055 vs_ace4_destroy(&vs_ace4);
1049 1056 }
1050 1057 break;
1051 1058 }
1052 1059
1053 1060 return (error);
1054 1061 }
1055 1062
1056 1063 /* ARGSUSED */
1057 1064 static int
1058 1065 rfs4_fattr4_aclsupport(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1059 1066 union nfs4_attr_u *na)
1060 1067 {
1061 1068 int error = 0;
1062 1069
1063 1070 if (RFS4_MANDATTR_ONLY)
1064 1071 return (ENOTSUP);
1065 1072
1066 1073 switch (cmd) {
1067 1074 case NFS4ATTR_SUPPORTED:
1068 1075 if (sarg->op == NFS4ATTR_SETIT)
1069 1076 error = EINVAL;
1070 1077 break; /* supported */
1071 1078 case NFS4ATTR_GETIT:
1072 1079 na->aclsupport = ACL4_SUPPORT_ALLOW_ACL |
1073 1080 ACL4_SUPPORT_DENY_ACL;
1074 1081 break;
1075 1082 case NFS4ATTR_SETIT:
1076 1083 error = EINVAL;
1077 1084 break;
1078 1085 case NFS4ATTR_VERIT:
1079 1086 if (na->aclsupport != (ACL4_SUPPORT_ALLOW_ACL |
1080 1087 ACL4_SUPPORT_DENY_ACL))
1081 1088 error = -1; /* no match */
1082 1089 break;
1083 1090 }
1084 1091
1085 1092 return (error);
1086 1093 }
1087 1094
1088 1095 /* ARGSUSED */
1089 1096 static int
1090 1097 rfs4_fattr4_archive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1091 1098 union nfs4_attr_u *na)
1092 1099 {
1093 1100 return (ENOTSUP);
1094 1101 }
1095 1102
1096 1103 /* ARGSUSED */
1097 1104 static int
1098 1105 rfs4_fattr4_cansettime(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1099 1106 union nfs4_attr_u *na)
1100 1107 {
1101 1108 int error = 0;
1102 1109
1103 1110 if (RFS4_MANDATTR_ONLY)
1104 1111 return (ENOTSUP);
1105 1112
1106 1113 switch (cmd) {
1107 1114 case NFS4ATTR_SUPPORTED:
1108 1115 if (sarg->op == NFS4ATTR_SETIT)
1109 1116 error = EINVAL;
1110 1117 break; /* this attr is supported */
1111 1118 case NFS4ATTR_GETIT:
1112 1119 na->cansettime = TRUE;
1113 1120 break;
1114 1121 case NFS4ATTR_SETIT:
1115 1122 /*
1116 1123 * read-only attr
1117 1124 */
1118 1125 error = EINVAL;
1119 1126 break;
1120 1127 case NFS4ATTR_VERIT:
1121 1128 if (!na->cansettime)
1122 1129 error = -1; /* no match */
1123 1130 break;
1124 1131 case NFS4ATTR_FREEIT:
1125 1132 break;
1126 1133 }
1127 1134 return (error);
1128 1135 }
1129 1136
1130 1137 /*
1131 1138 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
1132 1139 * case insensitive.
1133 1140 */
1134 1141 /* ARGSUSED */
1135 1142 static int
1136 1143 rfs4_fattr4_case_insensitive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1137 1144 union nfs4_attr_u *na)
1138 1145 {
1139 1146 int error = 0;
1140 1147
1141 1148 if (RFS4_MANDATTR_ONLY)
1142 1149 return (ENOTSUP);
1143 1150
1144 1151 switch (cmd) {
1145 1152 case NFS4ATTR_SUPPORTED:
1146 1153 if (sarg->op == NFS4ATTR_SETIT)
1147 1154 error = EINVAL;
1148 1155 break; /* this attr is supported */
1149 1156 case NFS4ATTR_GETIT:
1150 1157 na->case_insensitive = FALSE;
1151 1158 break;
1152 1159 case NFS4ATTR_SETIT:
1153 1160 /*
1154 1161 * read-only attr
1155 1162 */
1156 1163 error = EINVAL;
1157 1164 break;
1158 1165 case NFS4ATTR_VERIT:
1159 1166 if (!na->case_insensitive)
1160 1167 error = -1; /* no match */
1161 1168 break;
1162 1169 case NFS4ATTR_FREEIT:
1163 1170 break;
1164 1171 }
1165 1172 return (error);
1166 1173 }
1167 1174
1168 1175 /* ARGSUSED */
1169 1176 static int
1170 1177 rfs4_fattr4_case_preserving(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1171 1178 union nfs4_attr_u *na)
1172 1179 {
1173 1180 int error = 0;
1174 1181
1175 1182 if (RFS4_MANDATTR_ONLY)
1176 1183 return (ENOTSUP);
1177 1184
1178 1185 switch (cmd) {
1179 1186 case NFS4ATTR_SUPPORTED:
1180 1187 if (sarg->op == NFS4ATTR_SETIT)
1181 1188 error = EINVAL;
1182 1189 break; /* this attr is supported */
1183 1190 case NFS4ATTR_GETIT:
1184 1191 na->case_preserving = TRUE;
1185 1192 break;
1186 1193 case NFS4ATTR_SETIT:
1187 1194 /*
1188 1195 * read-only attr
1189 1196 */
1190 1197 error = EINVAL;
1191 1198 break;
1192 1199 case NFS4ATTR_VERIT:
1193 1200 if (!na->case_preserving)
1194 1201 error = -1; /* no match */
1195 1202 break;
1196 1203 case NFS4ATTR_FREEIT:
1197 1204 break;
1198 1205 }
1199 1206 return (error);
1200 1207 }
1201 1208
1202 1209 /* fattr4_chown_restricted should reall be fattr4_chown_allowed */
1203 1210 /* ARGSUSED */
1204 1211 static int
1205 1212 rfs4_fattr4_chown_restricted(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1206 1213 union nfs4_attr_u *na)
1207 1214 {
1208 1215 int error = 0;
1209 1216 ulong_t val;
1210 1217
1211 1218 if (RFS4_MANDATTR_ONLY)
1212 1219 return (ENOTSUP);
1213 1220
1214 1221 switch (cmd) {
1215 1222 case NFS4ATTR_SUPPORTED:
1216 1223 if (sarg->op == NFS4ATTR_SETIT)
1217 1224 error = EINVAL;
1218 1225 break; /* this attr is supported */
1219 1226 case NFS4ATTR_GETIT:
1220 1227 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
1221 1228 error = -1; /* may be okay if rdattr_error */
1222 1229 break;
1223 1230 }
1224 1231 ASSERT(sarg->cs->vp != NULL);
1225 1232 error = VOP_PATHCONF(sarg->cs->vp,
1226 1233 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr, NULL);
1227 1234 if (error)
1228 1235 break;
1229 1236
1230 1237 na->chown_restricted = (val == 1);
1231 1238 break;
1232 1239 case NFS4ATTR_SETIT:
1233 1240 /*
1234 1241 * read-only attr
1235 1242 */
1236 1243 error = EINVAL;
1237 1244 break;
1238 1245 case NFS4ATTR_VERIT:
1239 1246 ASSERT(sarg->cs->vp != NULL);
1240 1247 error = VOP_PATHCONF(sarg->cs->vp,
1241 1248 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr, NULL);
1242 1249 if (error)
1243 1250 break;
1244 1251 if (na->chown_restricted != (val == 1))
1245 1252 error = -1; /* no match */
1246 1253 break;
1247 1254 case NFS4ATTR_FREEIT:
1248 1255 break;
1249 1256 }
1250 1257 return (error);
1251 1258 }
1252 1259
1253 1260 /* ARGSUSED */
1254 1261 static int
1255 1262 rfs4_fattr4_fileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1256 1263 union nfs4_attr_u *na)
1257 1264 {
1258 1265 int error = 0;
1259 1266
1260 1267 if (RFS4_MANDATTR_ONLY)
1261 1268 return (ENOTSUP);
1262 1269
1263 1270 switch (cmd) {
1264 1271 case NFS4ATTR_SUPPORTED:
1265 1272 if (sarg->op == NFS4ATTR_SETIT)
1266 1273 error = EINVAL;
1267 1274 break; /* this attr is supported */
1268 1275 case NFS4ATTR_GETIT:
1269 1276 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NODEID)) {
1270 1277 error = -1; /* may be okay if rdattr_error */
1271 1278 break;
1272 1279 }
1273 1280 ASSERT(sarg->vap->va_mask & AT_NODEID);
1274 1281 na->fileid = sarg->vap->va_nodeid;
1275 1282 break;
1276 1283 case NFS4ATTR_SETIT:
1277 1284 /*
1278 1285 * read-only attr
1279 1286 */
1280 1287 error = EINVAL;
1281 1288 break;
1282 1289 case NFS4ATTR_VERIT:
1283 1290 ASSERT(sarg->vap->va_mask & AT_NODEID);
1284 1291 if (sarg->vap->va_nodeid != na->fileid)
1285 1292 error = -1; /* no match */
1286 1293 break;
1287 1294 case NFS4ATTR_FREEIT:
1288 1295 break;
1289 1296 }
1290 1297 return (error);
1291 1298 }
1292 1299
1293 1300 /* ARGSUSED */
|
↓ open down ↓ |
1148 lines elided |
↑ open up ↑ |
1294 1301 static int
1295 1302 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg)
1296 1303 {
1297 1304 int error = 0;
1298 1305 vattr_t *vap, va;
1299 1306 vnode_t *stubvp = NULL, *vp;
1300 1307
1301 1308 vp = sarg->cs->vp;
1302 1309 sarg->mntdfid_set = FALSE;
1303 1310
1304 - /* VROOT object, must untraverse */
1305 - if (vp->v_flag & VROOT) {
1311 + /*
1312 + * VROOT object or zone's root, must untraverse.
1313 + *
1314 + * NOTE: Not doing reality checks on curzone vs. compound
1315 + * state vnode because it will mismatch once at initialization
1316 + * if a non-global-zone triggers the module load, BUT in that case
1317 + * the vp is literally "/" which has VROOT set.
1318 + */
1319 + if ((vp->v_flag & VROOT) || VN_IS_CURZONEROOT(vp)) {
1306 1320
1307 1321 /* extra hold for vp since untraverse might rele */
1308 1322 VN_HOLD(vp);
1309 - stubvp = untraverse(vp);
1323 + stubvp = untraverse(vp, ZONE_ROOTVP());
1310 1324
1311 1325 /*
1312 - * If vp/stubvp are same, we must be at system
1326 + * If vp/stubvp are same, we must be at system-or-zone
1313 1327 * root because untraverse returned same vp
1314 1328 * for a VROOT object. sarg->vap was setup
1315 1329 * before we got here, so there's no need to do
1316 1330 * another getattr -- just use the one in sarg.
1317 1331 */
1318 1332 if (VN_CMP(vp, stubvp)) {
1319 - ASSERT(VN_CMP(vp, rootdir));
1333 + ASSERT(VN_IS_CURZONEROOT(vp));
1320 1334 vap = sarg->vap;
1321 1335 } else {
1322 1336 va.va_mask = AT_NODEID;
1323 1337 vap = &va;
1324 1338 error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr);
1325 1339 }
1326 1340
1327 1341 /*
1328 1342 * Done with stub, time to rele. If vp and stubvp
1329 1343 * were the same, then we need to rele either vp or
1330 1344 * stubvp. If they weren't the same, then untraverse()
1331 1345 * already took case of the extra hold on vp, and only
1332 1346 * the stub needs to be rele'd. Both cases are handled
1333 1347 * by unconditionally rele'ing the stub.
1334 1348 */
1335 1349 VN_RELE(stubvp);
1336 1350 } else
1337 1351 vap = sarg->vap;
1338 1352
1339 1353 /*
1340 1354 * At this point, vap should contain "correct" AT_NODEID --
1341 1355 * (for V_ROOT case, nodeid of stub, for non-VROOT case,
1342 1356 * nodeid of vp). If error or AT_NODEID not available, then
1343 1357 * make the obligatory (yet mysterious) rdattr_error
1344 1358 * check that is so common in the attr code.
1345 1359 */
1346 1360 if (!error && (vap->va_mask & AT_NODEID)) {
1347 1361 sarg->mounted_on_fileid = vap->va_nodeid;
1348 1362 sarg->mntdfid_set = TRUE;
1349 1363 } else if (sarg->rdattr_error)
1350 1364 error = -1;
1351 1365
1352 1366 /*
1353 1367 * error describes these cases:
1354 1368 * 0 : success
1355 1369 * -1: failure due to previous attr processing error (rddir only).
1356 1370 * * : new attr failure (if rddir, caller will set rdattr_error)
1357 1371 */
1358 1372 return (error);
1359 1373 }
1360 1374
1361 1375 /* ARGSUSED */
1362 1376 static int
1363 1377 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd,
1364 1378 struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na)
1365 1379 {
1366 1380 int error = 0;
1367 1381
|
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
1368 1382 if (RFS4_MANDATTR_ONLY)
1369 1383 return (ENOTSUP);
1370 1384
1371 1385 switch (cmd) {
1372 1386 case NFS4ATTR_SUPPORTED:
1373 1387 if (sarg->op == NFS4ATTR_SETIT)
1374 1388 error = EINVAL;
1375 1389 break; /* this attr is supported */
1376 1390 case NFS4ATTR_GETIT:
1377 1391 case NFS4ATTR_VERIT:
1378 - if (! sarg->mntdfid_set)
1392 + if (!sarg->mntdfid_set)
1379 1393 error = rfs4_get_mntdfileid(cmd, sarg);
1380 1394
1381 - if (! error && sarg->mntdfid_set) {
1395 + if (!error && sarg->mntdfid_set) {
1382 1396 if (cmd == NFS4ATTR_GETIT)
1383 1397 na->mounted_on_fileid = sarg->mounted_on_fileid;
1384 1398 else
1385 1399 if (na->mounted_on_fileid !=
1386 1400 sarg->mounted_on_fileid)
1387 1401 error = -1;
1388 1402 }
1389 1403 break;
1390 1404 case NFS4ATTR_SETIT:
1391 1405 /* read-only attr */
1392 1406 error = EINVAL;
1393 1407 break;
1394 1408 case NFS4ATTR_FREEIT:
1395 1409 break;
1396 1410 }
1397 1411 return (error);
1398 1412 }
1399 1413
1400 1414 /* ARGSUSED */
1401 1415 static int
1402 1416 rfs4_fattr4_files_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1403 1417 union nfs4_attr_u *na)
1404 1418 {
1405 1419 int error = 0;
1406 1420
1407 1421 if (RFS4_MANDATTR_ONLY)
1408 1422 return (ENOTSUP);
1409 1423
1410 1424 switch (cmd) {
1411 1425 case NFS4ATTR_SUPPORTED:
1412 1426 if (sarg->op == NFS4ATTR_SETIT)
1413 1427 error = EINVAL;
1414 1428 break; /* this attr is supported */
1415 1429 case NFS4ATTR_GETIT:
1416 1430 if (sarg->rdattr_error && (sarg->sbp == NULL)) {
1417 1431 error = -1; /* may be okay if rdattr_error */
1418 1432 break;
1419 1433 }
1420 1434 ASSERT(sarg->sbp != NULL);
1421 1435 na->files_avail = sarg->sbp->f_favail;
1422 1436 break;
1423 1437 case NFS4ATTR_SETIT:
1424 1438 /*
1425 1439 * read-only attr
1426 1440 */
1427 1441 error = EINVAL;
1428 1442 break;
1429 1443 case NFS4ATTR_VERIT:
1430 1444 ASSERT(sarg->sbp != NULL);
1431 1445 if (sarg->sbp->f_favail != na->files_avail)
1432 1446 error = -1; /* no match */
1433 1447 break;
1434 1448 case NFS4ATTR_FREEIT:
1435 1449 break;
1436 1450 }
1437 1451 return (error);
1438 1452 }
1439 1453
1440 1454 /* ARGSUSED */
1441 1455 static int
1442 1456 rfs4_fattr4_files_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1443 1457 union nfs4_attr_u *na)
1444 1458 {
1445 1459 int error = 0;
1446 1460
1447 1461 if (RFS4_MANDATTR_ONLY)
1448 1462 return (ENOTSUP);
1449 1463
1450 1464 switch (cmd) {
1451 1465 case NFS4ATTR_SUPPORTED:
1452 1466 if (sarg->op == NFS4ATTR_SETIT)
1453 1467 error = EINVAL;
1454 1468 break; /* this attr is supported */
1455 1469 case NFS4ATTR_GETIT:
1456 1470 if (sarg->rdattr_error && (sarg->sbp == NULL)) {
1457 1471 error = -1; /* may be okay if rdattr_error */
1458 1472 break;
1459 1473 }
1460 1474 ASSERT(sarg->sbp != NULL);
1461 1475 na->files_free = sarg->sbp->f_ffree;
1462 1476 break;
1463 1477 case NFS4ATTR_SETIT:
1464 1478 /*
1465 1479 * read-only attr
1466 1480 */
1467 1481 error = EINVAL;
1468 1482 break;
1469 1483 case NFS4ATTR_VERIT:
1470 1484 ASSERT(sarg->sbp != NULL);
1471 1485 if (sarg->sbp->f_ffree != na->files_free)
1472 1486 error = -1; /* no match */
1473 1487 break;
1474 1488 case NFS4ATTR_FREEIT:
1475 1489 break;
1476 1490 }
1477 1491 return (error);
1478 1492 }
1479 1493
1480 1494 /* ARGSUSED */
1481 1495 static int
1482 1496 rfs4_fattr4_files_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1483 1497 union nfs4_attr_u *na)
1484 1498 {
1485 1499 int error = 0;
1486 1500
1487 1501 if (RFS4_MANDATTR_ONLY)
1488 1502 return (ENOTSUP);
1489 1503
1490 1504 switch (cmd) {
1491 1505 case NFS4ATTR_SUPPORTED:
1492 1506 if (sarg->op == NFS4ATTR_SETIT)
1493 1507 error = EINVAL;
1494 1508 break; /* this attr is supported */
1495 1509 case NFS4ATTR_GETIT:
1496 1510 if (sarg->rdattr_error && (sarg->sbp == NULL)) {
1497 1511 error = -1; /* may be okay if rdattr_error */
1498 1512 break;
1499 1513 }
1500 1514 ASSERT(sarg->sbp != NULL);
1501 1515 na->files_total = sarg->sbp->f_files;
1502 1516 break;
1503 1517 case NFS4ATTR_SETIT:
1504 1518 /*
1505 1519 * read-only attr
1506 1520 */
1507 1521 error = EINVAL;
1508 1522 break;
1509 1523 case NFS4ATTR_VERIT:
1510 1524 ASSERT(sarg->sbp != NULL);
1511 1525 if (sarg->sbp->f_files != na->files_total)
1512 1526 error = -1; /* no match */
1513 1527 break;
1514 1528 case NFS4ATTR_FREEIT:
1515 1529 break;
1516 1530 }
1517 1531 return (error);
1518 1532 }
1519 1533
1520 1534 static void
1521 1535 rfs4_free_pathname4(pathname4 *pn4)
1522 1536 {
1523 1537 int i, len;
1524 1538 utf8string *utf8s;
1525 1539
1526 1540 if (pn4 == NULL || (len = pn4->pathname4_len) == 0 ||
1527 1541 (utf8s = pn4->pathname4_val) == NULL)
1528 1542 return;
1529 1543
1530 1544 for (i = 0; i < len; i++, utf8s++) {
1531 1545 if (utf8s->utf8string_val == NULL ||
1532 1546 utf8s->utf8string_len == 0)
1533 1547 continue;
1534 1548
1535 1549 kmem_free(utf8s->utf8string_val, utf8s->utf8string_len);
1536 1550 utf8s->utf8string_val = NULL;
1537 1551 }
1538 1552
1539 1553 kmem_free(pn4->pathname4_val,
1540 1554 sizeof (utf8string) * pn4->pathname4_len);
1541 1555 pn4->pathname4_val = 0;
1542 1556 }
1543 1557
1544 1558 static void
1545 1559 rfs4_free_fs_location4(fs_location4 *fsl4)
1546 1560 {
1547 1561 if (fsl4 == NULL)
1548 1562 return;
1549 1563
1550 1564 rfs4_free_pathname4((pathname4 *)&fsl4->server_len);
1551 1565 rfs4_free_pathname4(&fsl4->rootpath);
1552 1566 }
1553 1567
1554 1568 void
1555 1569 rfs4_free_fs_locations4(fs_locations4 *fsls4)
1556 1570 {
1557 1571 int i, len;
1558 1572 fs_location4 *fsl4;
1559 1573
1560 1574 if (fsls4 == NULL)
1561 1575 return;
1562 1576
1563 1577 /* free fs_root */
1564 1578 rfs4_free_pathname4(&fsls4->fs_root);
1565 1579
1566 1580 if ((len = fsls4->locations_len) == 0 ||
1567 1581 (fsl4 = fsls4->locations_val) == NULL)
1568 1582 return;
1569 1583
1570 1584 /* free fs_location4 */
1571 1585 for (i = 0; i < len; i++) {
1572 1586 rfs4_free_fs_location4(fsl4);
1573 1587 fsl4++;
1574 1588 }
1575 1589
1576 1590 kmem_free(fsls4->locations_val, sizeof (fs_location4) * len);
1577 1591 fsls4->locations_val = NULL;
1578 1592 }
1579 1593
1580 1594 /* ARGSUSED */
1581 1595 static int
1582 1596 rfs4_fattr4_fs_locations(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1583 1597 union nfs4_attr_u *na)
1584 1598 {
1585 1599 int error = 0;
1586 1600 fs_locations4 *fsl;
1587 1601
|
↓ open down ↓ |
196 lines elided |
↑ open up ↑ |
1588 1602 if (RFS4_MANDATTR_ONLY)
1589 1603 return (ENOTSUP);
1590 1604
1591 1605 switch (cmd) {
1592 1606 case NFS4ATTR_SUPPORTED:
1593 1607 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1594 1608 error = EINVAL;
1595 1609 break; /* this attr is supported */
1596 1610
1597 1611 case NFS4ATTR_GETIT:
1612 + {
1613 + kstat_named_t *stat =
1614 + sarg->cs->exi->exi_ne->ne_globals->svstat[NFS_V4];
1615 +
1598 1616 fsl = fetch_referral(sarg->cs->vp, sarg->cs->cr);
1599 1617 if (fsl == NULL)
1600 1618 (void) memset(&(na->fs_locations), 0,
1601 1619 sizeof (fs_locations4));
1602 1620 else {
1603 1621 na->fs_locations = *fsl;
1604 1622 kmem_free(fsl, sizeof (fs_locations4));
1605 1623 }
1606 - global_svstat_ptr[4][NFS_REFERRALS].value.ui64++;
1624 + stat[NFS_REFERRALS].value.ui64++;
1607 1625 break;
1608 -
1626 + }
1609 1627 case NFS4ATTR_FREEIT:
1610 1628 if (sarg->op == NFS4ATTR_SETIT || sarg->op == NFS4ATTR_VERIT)
1611 1629 error = EINVAL;
1612 1630 rfs4_free_fs_locations4(&na->fs_locations);
1613 1631 break;
1614 1632
1615 1633 case NFS4ATTR_SETIT:
1616 1634 case NFS4ATTR_VERIT:
1617 1635 /*
1618 1636 * read-only attr
1619 1637 */
1620 1638 error = EINVAL;
1621 1639 break;
1622 1640 }
1623 1641 return (error);
1624 1642 }
1625 1643
1626 1644 /* ARGSUSED */
1627 1645 static int
1628 1646 rfs4_fattr4_hidden(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1629 1647 union nfs4_attr_u *na)
1630 1648 {
1631 1649 return (ENOTSUP);
1632 1650 }
1633 1651
1634 1652 /* ARGSUSED */
1635 1653 static int
1636 1654 rfs4_fattr4_homogeneous(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1637 1655 union nfs4_attr_u *na)
1638 1656 {
1639 1657 int error = 0;
1640 1658
1641 1659 if (RFS4_MANDATTR_ONLY)
1642 1660 return (ENOTSUP);
1643 1661
1644 1662 switch (cmd) {
1645 1663 case NFS4ATTR_SUPPORTED:
1646 1664 if (sarg->op == NFS4ATTR_SETIT)
1647 1665 error = EINVAL;
1648 1666 break; /* this attr is supported */
1649 1667 case NFS4ATTR_GETIT:
1650 1668 na->homogeneous = TRUE; /* XXX - need a VOP extension */
1651 1669 break;
1652 1670 case NFS4ATTR_SETIT:
1653 1671 /*
1654 1672 * read-only attr
1655 1673 */
1656 1674 error = EINVAL;
1657 1675 break;
1658 1676 case NFS4ATTR_VERIT:
1659 1677 if (!na->homogeneous)
1660 1678 error = -1; /* no match */
1661 1679 break;
1662 1680 case NFS4ATTR_FREEIT:
1663 1681 break;
1664 1682 }
1665 1683 return (error);
1666 1684 }
1667 1685
1668 1686 /* ARGSUSED */
1669 1687 static int
1670 1688 rfs4_fattr4_maxfilesize(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1671 1689 union nfs4_attr_u *na)
1672 1690 {
1673 1691 int error = 0;
1674 1692 ulong_t val;
1675 1693 fattr4_maxfilesize maxfilesize;
1676 1694
1677 1695 if (RFS4_MANDATTR_ONLY)
1678 1696 return (ENOTSUP);
1679 1697
1680 1698 switch (cmd) {
1681 1699 case NFS4ATTR_SUPPORTED:
1682 1700 if (sarg->op == NFS4ATTR_SETIT)
1683 1701 error = EINVAL;
1684 1702 break; /* this attr is supported */
1685 1703 case NFS4ATTR_GETIT:
1686 1704 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
1687 1705 error = -1; /* may be okay if rdattr_error */
1688 1706 break;
1689 1707 }
1690 1708 ASSERT(sarg->cs->vp != NULL);
1691 1709 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val,
1692 1710 sarg->cs->cr, NULL);
1693 1711 if (error)
1694 1712 break;
1695 1713
1696 1714 /*
1697 1715 * If the underlying file system does not support
1698 1716 * _PC_FILESIZEBITS, return a reasonable default. Note that
1699 1717 * error code on VOP_PATHCONF will be 0, even if the underlying
1700 1718 * file system does not support _PC_FILESIZEBITS.
1701 1719 */
1702 1720 if (val == (ulong_t)-1) {
1703 1721 na->maxfilesize = MAXOFF32_T;
1704 1722 } else {
1705 1723 if (val >= (sizeof (uint64_t) * 8))
1706 1724 na->maxfilesize = INT64_MAX;
1707 1725 else
1708 1726 na->maxfilesize = ((1LL << (val - 1)) - 1);
1709 1727 }
1710 1728 break;
1711 1729 case NFS4ATTR_SETIT:
1712 1730 /*
1713 1731 * read-only attr
1714 1732 */
1715 1733 error = EINVAL;
1716 1734 break;
1717 1735 case NFS4ATTR_VERIT:
1718 1736 ASSERT(sarg->cs->vp != NULL);
1719 1737 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val,
1720 1738 sarg->cs->cr, NULL);
1721 1739 if (error)
1722 1740 break;
1723 1741 /*
1724 1742 * If the underlying file system does not support
1725 1743 * _PC_FILESIZEBITS, return a reasonable default. Note that
1726 1744 * error code on VOP_PATHCONF will be 0, even if the underlying
1727 1745 * file system does not support _PC_FILESIZEBITS.
1728 1746 */
1729 1747 if (val == (ulong_t)-1) {
1730 1748 maxfilesize = MAXOFF32_T;
1731 1749 } else {
1732 1750 if (val >= (sizeof (uint64_t) * 8))
1733 1751 maxfilesize = INT64_MAX;
1734 1752 else
1735 1753 maxfilesize = ((1LL << (val - 1)) - 1);
1736 1754 }
1737 1755 if (na->maxfilesize != maxfilesize)
1738 1756 error = -1; /* no match */
1739 1757 break;
1740 1758 case NFS4ATTR_FREEIT:
1741 1759 break;
1742 1760 }
1743 1761 return (error);
1744 1762 }
1745 1763
1746 1764 /* ARGSUSED */
1747 1765 static int
1748 1766 rfs4_fattr4_maxlink(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1749 1767 union nfs4_attr_u *na)
1750 1768 {
1751 1769 int error = 0;
1752 1770 ulong_t val;
1753 1771
1754 1772 if (RFS4_MANDATTR_ONLY)
1755 1773 return (ENOTSUP);
1756 1774
1757 1775 switch (cmd) {
1758 1776 case NFS4ATTR_SUPPORTED:
1759 1777 if (sarg->op == NFS4ATTR_SETIT)
1760 1778 error = EINVAL;
1761 1779 break; /* this attr is supported */
1762 1780 case NFS4ATTR_GETIT:
1763 1781 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
1764 1782 error = -1; /* may be okay if rdattr_error */
1765 1783 break;
1766 1784 }
1767 1785 ASSERT(sarg->cs->vp != NULL);
1768 1786 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val,
1769 1787 sarg->cs->cr, NULL);
1770 1788 if (error == 0) {
1771 1789 na->maxlink = val;
1772 1790 }
1773 1791 break;
1774 1792 case NFS4ATTR_SETIT:
1775 1793 /*
1776 1794 * read-only attr
1777 1795 */
1778 1796 error = EINVAL;
1779 1797 break;
1780 1798 case NFS4ATTR_VERIT:
1781 1799 ASSERT(sarg->cs->vp != NULL);
1782 1800 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val,
1783 1801 sarg->cs->cr, NULL);
1784 1802 if (!error && (na->maxlink != (uint32_t)val))
1785 1803 error = -1; /* no match */
1786 1804 break;
1787 1805 case NFS4ATTR_FREEIT:
1788 1806 break;
1789 1807 }
1790 1808 return (error);
1791 1809 }
1792 1810
1793 1811 /* ARGSUSED */
1794 1812 static int
1795 1813 rfs4_fattr4_maxname(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1796 1814 union nfs4_attr_u *na)
1797 1815 {
1798 1816 int error = 0;
1799 1817 ulong_t val;
1800 1818
1801 1819 if (RFS4_MANDATTR_ONLY)
1802 1820 return (ENOTSUP);
1803 1821
1804 1822 switch (cmd) {
1805 1823 case NFS4ATTR_SUPPORTED:
1806 1824 if (sarg->op == NFS4ATTR_SETIT)
1807 1825 error = EINVAL;
1808 1826 break; /* this attr is supported */
1809 1827 case NFS4ATTR_GETIT:
1810 1828 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) {
1811 1829 error = -1; /* may be okay if rdattr_error */
1812 1830 break;
1813 1831 }
1814 1832 ASSERT(sarg->cs->vp != NULL);
1815 1833 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val,
1816 1834 sarg->cs->cr, NULL);
1817 1835 if (error == 0) {
1818 1836 na->maxname = val;
1819 1837 }
1820 1838 break;
1821 1839 case NFS4ATTR_SETIT:
1822 1840 /*
1823 1841 * read-only attr
1824 1842 */
1825 1843 error = EINVAL;
1826 1844 break;
1827 1845 case NFS4ATTR_VERIT:
1828 1846 ASSERT(sarg->cs->vp != NULL);
1829 1847 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val,
1830 1848 sarg->cs->cr, NULL);
1831 1849 if (!error && (na->maxname != val))
1832 1850 error = -1; /* no match */
1833 1851 break;
1834 1852 case NFS4ATTR_FREEIT:
1835 1853 break;
1836 1854 }
1837 1855 return (error);
1838 1856 }
1839 1857
1840 1858 /* ARGSUSED */
1841 1859 static int
1842 1860 rfs4_fattr4_maxread(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1843 1861 union nfs4_attr_u *na)
1844 1862 {
1845 1863 int error = 0;
1846 1864
1847 1865 if (RFS4_MANDATTR_ONLY)
1848 1866 return (ENOTSUP);
1849 1867
1850 1868 switch (cmd) {
1851 1869 case NFS4ATTR_SUPPORTED:
1852 1870 if (sarg->op == NFS4ATTR_SETIT)
1853 1871 error = EINVAL;
1854 1872 break; /* this attr is supported */
1855 1873 case NFS4ATTR_GETIT:
1856 1874 na->maxread = rfs4_tsize(sarg->cs->req);
1857 1875 break;
1858 1876 case NFS4ATTR_SETIT:
1859 1877 /*
1860 1878 * read-only attr
1861 1879 */
1862 1880 error = EINVAL;
1863 1881 break;
1864 1882 case NFS4ATTR_VERIT:
1865 1883 if (na->maxread != rfs4_tsize(sarg->cs->req))
1866 1884 error = -1; /* no match */
1867 1885 break;
1868 1886 case NFS4ATTR_FREEIT:
1869 1887 break;
1870 1888 }
1871 1889 return (error);
1872 1890 }
1873 1891
1874 1892 /* ARGSUSED */
1875 1893 static int
1876 1894 rfs4_fattr4_maxwrite(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1877 1895 union nfs4_attr_u *na)
1878 1896 {
1879 1897 int error = 0;
1880 1898
1881 1899 if (RFS4_MANDATTR_ONLY)
1882 1900 return (ENOTSUP);
1883 1901
1884 1902 switch (cmd) {
1885 1903 case NFS4ATTR_SUPPORTED:
1886 1904 if (sarg->op == NFS4ATTR_SETIT)
1887 1905 error = EINVAL;
1888 1906 break; /* this attr is supported */
1889 1907 case NFS4ATTR_GETIT:
1890 1908 na->maxwrite = rfs4_tsize(sarg->cs->req);
1891 1909 break;
1892 1910 case NFS4ATTR_SETIT:
1893 1911 /*
1894 1912 * read-only attr
1895 1913 */
1896 1914 error = EINVAL;
1897 1915 break;
1898 1916 case NFS4ATTR_VERIT:
1899 1917 if (na->maxwrite != rfs4_tsize(sarg->cs->req))
1900 1918 error = -1; /* no match */
1901 1919 break;
1902 1920 case NFS4ATTR_FREEIT:
1903 1921 break;
1904 1922 }
1905 1923 return (error);
1906 1924 }
1907 1925
1908 1926 /* ARGSUSED */
1909 1927 static int
1910 1928 rfs4_fattr4_mimetype(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1911 1929 union nfs4_attr_u *na)
1912 1930 {
1913 1931 return (ENOTSUP);
1914 1932 }
1915 1933
1916 1934 /* ARGSUSED */
1917 1935 static int
1918 1936 rfs4_fattr4_mode(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1919 1937 union nfs4_attr_u *na)
1920 1938 {
1921 1939 int error = 0;
1922 1940
1923 1941 if (RFS4_MANDATTR_ONLY)
1924 1942 return (ENOTSUP);
1925 1943
1926 1944 switch (cmd) {
1927 1945 case NFS4ATTR_SUPPORTED:
1928 1946 break; /* this attr is supported */
1929 1947 case NFS4ATTR_GETIT:
1930 1948 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MODE)) {
1931 1949 error = -1; /* may be okay if rdattr_error */
1932 1950 break;
1933 1951 }
1934 1952 ASSERT(sarg->vap->va_mask & AT_MODE);
1935 1953 na->mode = sarg->vap->va_mode;
1936 1954 break;
1937 1955 case NFS4ATTR_SETIT:
1938 1956 ASSERT(sarg->vap->va_mask & AT_MODE);
1939 1957 sarg->vap->va_mode = na->mode;
1940 1958 /*
1941 1959 * If the filesystem is exported with nosuid, then mask off
1942 1960 * the setuid and setgid bits.
1943 1961 */
1944 1962 if (sarg->cs->vp->v_type == VREG &&
1945 1963 (sarg->cs->exi->exi_export.ex_flags & EX_NOSUID))
1946 1964 sarg->vap->va_mode &= ~(VSUID | VSGID);
1947 1965 break;
1948 1966 case NFS4ATTR_VERIT:
1949 1967 ASSERT(sarg->vap->va_mask & AT_MODE);
1950 1968 if (sarg->vap->va_mode != na->mode)
1951 1969 error = -1; /* no match */
1952 1970 break;
1953 1971 case NFS4ATTR_FREEIT:
1954 1972 break;
1955 1973 }
1956 1974 return (error);
1957 1975 }
1958 1976
1959 1977 /* ARGSUSED */
1960 1978 static int
1961 1979 rfs4_fattr4_no_trunc(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1962 1980 union nfs4_attr_u *na)
1963 1981 {
1964 1982 int error = 0;
1965 1983
1966 1984 if (RFS4_MANDATTR_ONLY)
1967 1985 return (ENOTSUP);
1968 1986
1969 1987 switch (cmd) {
1970 1988 case NFS4ATTR_SUPPORTED:
1971 1989 if (sarg->op == NFS4ATTR_SETIT)
1972 1990 error = EINVAL;
1973 1991 break; /* this attr is supported */
1974 1992 case NFS4ATTR_GETIT:
1975 1993 na->no_trunc = TRUE;
1976 1994 break;
1977 1995 case NFS4ATTR_SETIT:
1978 1996 /*
1979 1997 * read-only attr
1980 1998 */
1981 1999 error = EINVAL;
1982 2000 break;
1983 2001 case NFS4ATTR_VERIT:
1984 2002 if (!na->no_trunc)
1985 2003 error = -1; /* no match */
1986 2004 break;
1987 2005 case NFS4ATTR_FREEIT:
1988 2006 break;
1989 2007 }
1990 2008 return (error);
1991 2009 }
1992 2010
1993 2011 /* ARGSUSED */
1994 2012 static int
1995 2013 rfs4_fattr4_numlinks(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
1996 2014 union nfs4_attr_u *na)
1997 2015 {
1998 2016 int error = 0;
1999 2017
2000 2018 if (RFS4_MANDATTR_ONLY)
2001 2019 return (ENOTSUP);
2002 2020
2003 2021 switch (cmd) {
2004 2022 case NFS4ATTR_SUPPORTED:
2005 2023 if (sarg->op == NFS4ATTR_SETIT)
2006 2024 error = EINVAL;
2007 2025 break; /* this attr is supported */
2008 2026 case NFS4ATTR_GETIT:
2009 2027 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NLINK)) {
2010 2028 error = -1; /* may be okay if rdattr_error */
2011 2029 break;
2012 2030 }
2013 2031 ASSERT(sarg->vap->va_mask & AT_NLINK);
2014 2032 na->numlinks = sarg->vap->va_nlink;
2015 2033 break;
2016 2034 case NFS4ATTR_SETIT:
2017 2035 /*
2018 2036 * read-only attr
2019 2037 */
2020 2038 error = EINVAL;
2021 2039 break;
2022 2040 case NFS4ATTR_VERIT:
2023 2041 ASSERT(sarg->vap->va_mask & AT_NLINK);
2024 2042 if (sarg->vap->va_nlink != na->numlinks)
2025 2043 error = -1; /* no match */
2026 2044 break;
2027 2045 case NFS4ATTR_FREEIT:
2028 2046 break;
2029 2047 }
2030 2048 return (error);
2031 2049 }
2032 2050
2033 2051 /* ARGSUSED */
2034 2052 static int
2035 2053 rfs4_fattr4_owner(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2036 2054 union nfs4_attr_u *na)
2037 2055 {
2038 2056 int error = 0;
2039 2057 uid_t uid;
2040 2058
2041 2059 if (RFS4_MANDATTR_ONLY)
2042 2060 return (ENOTSUP);
2043 2061
2044 2062 switch (cmd) {
2045 2063 case NFS4ATTR_SUPPORTED:
2046 2064 break; /* this attr is supported */
2047 2065 case NFS4ATTR_GETIT:
2048 2066 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_UID)) {
2049 2067 error = -1; /* may be okay if rdattr_error */
2050 2068 break;
2051 2069 }
2052 2070 ASSERT(sarg->vap->va_mask & AT_UID);
2053 2071
2054 2072 /*
2055 2073 * There are well defined polices for what happens on server-
2056 2074 * side GETATTR when uid to attribute string conversion cannot
2057 2075 * occur. Please refer to nfs4_idmap.c for details.
2058 2076 */
2059 2077 error = nfs_idmap_uid_str(sarg->vap->va_uid, &na->owner, TRUE);
2060 2078 switch (error) {
2061 2079 case ECONNREFUSED:
2062 2080 error = NFS4ERR_DELAY;
2063 2081 break;
2064 2082 default:
2065 2083 break;
2066 2084 }
2067 2085 break;
2068 2086
2069 2087 case NFS4ATTR_SETIT:
2070 2088 ASSERT(sarg->vap->va_mask & AT_UID);
2071 2089
2072 2090 /*
2073 2091 * There are well defined policies for what happens on server-
2074 2092 * side SETATTR of 'owner' when a "user@domain" mapping cannot
2075 2093 * occur. Please refer to nfs4_idmap.c for details.
2076 2094 *
2077 2095 * Any other errors, such as the mapping not being found by
2078 2096 * nfsmapid(1m), and interrupted clnt_call, etc, will result
2079 2097 * in NFS4ERR_BADOWNER.
2080 2098 *
2081 2099 * XXX need to return consistent errors, perhaps all
2082 2100 * server side attribute routines should return NFS4ERR*.
2083 2101 */
2084 2102 error = nfs_idmap_str_uid(&na->owner, &sarg->vap->va_uid, TRUE);
2085 2103 switch (error) {
2086 2104 case NFS4_OK:
2087 2105 case ENOTSUP:
2088 2106 /*
2089 2107 * Ignore warning that we are the
2090 2108 * nfsmapid (can't happen on srv)
2091 2109 */
2092 2110 error = 0;
2093 2111 MSG_PRT_DEBUG = FALSE;
2094 2112 break;
2095 2113
2096 2114 case ECOMM:
2097 2115 case ECONNREFUSED:
2098 2116 if (!MSG_PRT_DEBUG) {
2099 2117 /*
2100 2118 * printed just once per daemon death,
2101 2119 * inform the user and then stay silent
2102 2120 */
2103 2121 cmn_err(CE_WARN, "!Unable to contact "
2104 2122 "nfsmapid");
2105 2123 MSG_PRT_DEBUG = TRUE;
2106 2124 }
2107 2125 error = NFS4ERR_DELAY;
2108 2126 break;
2109 2127
2110 2128 case EINVAL:
2111 2129 error = NFS4ERR_INVAL;
2112 2130 break;
2113 2131
2114 2132 default:
2115 2133 error = NFS4ERR_BADOWNER;
2116 2134 break;
2117 2135 }
2118 2136 break;
2119 2137
2120 2138 case NFS4ATTR_VERIT:
2121 2139 ASSERT(sarg->vap->va_mask & AT_UID);
2122 2140 error = nfs_idmap_str_uid(&na->owner, &uid, TRUE);
2123 2141 /*
2124 2142 * Ignore warning that we are the nfsmapid (can't happen on srv)
2125 2143 */
2126 2144 if (error == ENOTSUP)
2127 2145 error = 0;
2128 2146 if (error)
2129 2147 error = -1; /* no match */
2130 2148 else if (sarg->vap->va_uid != uid)
2131 2149 error = -1; /* no match */
2132 2150 break;
2133 2151 case NFS4ATTR_FREEIT:
2134 2152 if (sarg->op == NFS4ATTR_GETIT) {
2135 2153 if (na->owner.utf8string_val) {
2136 2154 UTF8STRING_FREE(na->owner)
2137 2155 bzero(&na->owner, sizeof (na->owner));
2138 2156 }
2139 2157 }
2140 2158 break;
2141 2159 }
2142 2160 return (error);
2143 2161 }
2144 2162
2145 2163 /* ARGSUSED */
2146 2164 static int
2147 2165 rfs4_fattr4_owner_group(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2148 2166 union nfs4_attr_u *na)
2149 2167 {
2150 2168 int error = 0;
2151 2169 gid_t gid;
2152 2170
2153 2171 if (RFS4_MANDATTR_ONLY)
2154 2172 return (ENOTSUP);
2155 2173
2156 2174 switch (cmd) {
2157 2175 case NFS4ATTR_SUPPORTED:
2158 2176 break; /* this attr is supported */
2159 2177 case NFS4ATTR_GETIT:
2160 2178 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_GID)) {
2161 2179 error = -1; /* may be okay if rdattr_error */
2162 2180 break;
2163 2181 }
2164 2182 ASSERT(sarg->vap->va_mask & AT_GID);
2165 2183
2166 2184 /*
2167 2185 * There are well defined polices for what happens on server-
2168 2186 * side GETATTR when gid to attribute string conversion cannot
2169 2187 * occur. Please refer to nfs4_idmap.c for details.
2170 2188 */
2171 2189 error = nfs_idmap_gid_str(sarg->vap->va_gid, &na->owner_group,
2172 2190 TRUE);
2173 2191 switch (error) {
2174 2192 case ECONNREFUSED:
2175 2193 error = NFS4ERR_DELAY;
2176 2194 break;
2177 2195 default:
2178 2196 break;
2179 2197 }
2180 2198 break;
2181 2199
2182 2200 case NFS4ATTR_SETIT:
2183 2201 ASSERT(sarg->vap->va_mask & AT_GID);
2184 2202
2185 2203 /*
2186 2204 * There are well defined policies for what happens on server-
2187 2205 * side SETATTR of 'owner_group' when a "group@domain" mapping
2188 2206 * cannot occur. Please refer to nfs4_idmap.c for details.
2189 2207 *
2190 2208 * Any other errors, such as the mapping not being found by
2191 2209 * nfsmapid(1m), and interrupted clnt_call, etc, will result
2192 2210 * in NFS4ERR_BADOWNER.
2193 2211 *
2194 2212 * XXX need to return consistent errors, perhaps all
2195 2213 * server side attribute routines should return NFS4ERR*.
2196 2214 */
2197 2215 error = nfs_idmap_str_gid(&na->owner_group, &sarg->vap->va_gid,
2198 2216 TRUE);
2199 2217 switch (error) {
2200 2218 case NFS4_OK:
2201 2219 case ENOTSUP:
2202 2220 /*
2203 2221 * Ignore warning that we are the
2204 2222 * nfsmapid (can't happen on srv)
2205 2223 */
2206 2224 error = 0;
2207 2225 MSG_PRT_DEBUG = FALSE;
2208 2226 break;
2209 2227
2210 2228 case ECOMM:
2211 2229 case ECONNREFUSED:
2212 2230 if (!MSG_PRT_DEBUG) {
2213 2231 /*
2214 2232 * printed just once per daemon death,
2215 2233 * inform the user and then stay silent
2216 2234 */
2217 2235 cmn_err(CE_WARN, "!Unable to contact "
2218 2236 "nfsmapid");
2219 2237 MSG_PRT_DEBUG = TRUE;
2220 2238 }
2221 2239 error = NFS4ERR_DELAY;
2222 2240 break;
2223 2241
2224 2242 case EINVAL:
2225 2243 error = NFS4ERR_INVAL;
2226 2244 break;
2227 2245
2228 2246 default:
2229 2247 error = NFS4ERR_BADOWNER;
2230 2248 break;
2231 2249 }
2232 2250 break;
2233 2251
2234 2252 case NFS4ATTR_VERIT:
2235 2253 ASSERT(sarg->vap->va_mask & AT_GID);
2236 2254 error = nfs_idmap_str_gid(&na->owner_group, &gid, TRUE);
2237 2255 /*
2238 2256 * Ignore warning that we are the nfsmapid (can't happen on srv)
2239 2257 */
2240 2258 if (error == ENOTSUP)
2241 2259 error = 0;
2242 2260 if (error)
2243 2261 error = -1; /* no match */
2244 2262 else if (sarg->vap->va_gid != gid)
2245 2263 error = -1; /* no match */
2246 2264 break;
2247 2265 case NFS4ATTR_FREEIT:
2248 2266 if (sarg->op == NFS4ATTR_GETIT) {
2249 2267 if (na->owner_group.utf8string_val) {
2250 2268 UTF8STRING_FREE(na->owner_group)
2251 2269 bzero(&na->owner_group,
2252 2270 sizeof (na->owner_group));
2253 2271 }
2254 2272 }
2255 2273 break;
2256 2274 }
2257 2275 return (error);
2258 2276 }
2259 2277
2260 2278 /* XXX - quota attributes should be supportable on Solaris 2 */
2261 2279 /* ARGSUSED */
2262 2280 static int
2263 2281 rfs4_fattr4_quota_avail_hard(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2264 2282 union nfs4_attr_u *na)
2265 2283 {
2266 2284 return (ENOTSUP);
2267 2285 }
2268 2286
2269 2287 /* ARGSUSED */
2270 2288 static int
2271 2289 rfs4_fattr4_quota_avail_soft(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2272 2290 union nfs4_attr_u *na)
2273 2291 {
2274 2292 return (ENOTSUP);
2275 2293 }
2276 2294
2277 2295 /* ARGSUSED */
2278 2296 static int
2279 2297 rfs4_fattr4_quota_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2280 2298 union nfs4_attr_u *na)
2281 2299 {
2282 2300 return (ENOTSUP);
2283 2301 }
2284 2302
2285 2303 /* ARGSUSED */
2286 2304 static int
2287 2305 rfs4_fattr4_rawdev(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2288 2306 union nfs4_attr_u *na)
2289 2307 {
2290 2308 int error = 0;
2291 2309
2292 2310 if (RFS4_MANDATTR_ONLY)
2293 2311 return (ENOTSUP);
2294 2312
2295 2313 switch (cmd) {
2296 2314 case NFS4ATTR_SUPPORTED:
2297 2315 if (sarg->op == NFS4ATTR_SETIT)
2298 2316 error = EINVAL;
2299 2317 break; /* this attr is supported */
2300 2318 case NFS4ATTR_GETIT:
2301 2319 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_RDEV)) {
2302 2320 error = -1; /* may be okay if rdattr_error */
2303 2321 break;
2304 2322 }
2305 2323 ASSERT(sarg->vap->va_mask & AT_RDEV);
2306 2324 na->rawdev.specdata1 = (uint32)getmajor(sarg->vap->va_rdev);
2307 2325 na->rawdev.specdata2 = (uint32)getminor(sarg->vap->va_rdev);
2308 2326 break;
2309 2327 case NFS4ATTR_SETIT:
2310 2328 /*
2311 2329 * read-only attr
2312 2330 */
2313 2331 error = EINVAL;
2314 2332 break;
2315 2333 case NFS4ATTR_VERIT:
2316 2334 ASSERT(sarg->vap->va_mask & AT_RDEV);
2317 2335 if ((na->rawdev.specdata1 !=
2318 2336 (uint32)getmajor(sarg->vap->va_rdev)) ||
2319 2337 (na->rawdev.specdata2 !=
2320 2338 (uint32)getminor(sarg->vap->va_rdev)))
2321 2339 error = -1; /* no match */
2322 2340 break;
2323 2341 case NFS4ATTR_FREEIT:
2324 2342 break;
2325 2343 }
2326 2344 return (error);
2327 2345 }
2328 2346
2329 2347 /* ARGSUSED */
2330 2348 static int
2331 2349 rfs4_fattr4_space_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2332 2350 union nfs4_attr_u *na)
2333 2351 {
2334 2352 int error = 0;
2335 2353
2336 2354 if (RFS4_MANDATTR_ONLY)
2337 2355 return (ENOTSUP);
2338 2356
2339 2357 switch (cmd) {
2340 2358 case NFS4ATTR_SUPPORTED:
2341 2359 if (sarg->op == NFS4ATTR_SETIT)
2342 2360 error = EINVAL;
2343 2361 break; /* this attr is supported */
2344 2362 case NFS4ATTR_GETIT:
2345 2363 if (sarg->rdattr_error && (sarg->sbp == NULL)) {
2346 2364 error = -1; /* may be okay if rdattr_error */
2347 2365 break;
2348 2366 }
2349 2367 ASSERT(sarg->sbp != NULL);
2350 2368 if (sarg->sbp->f_bavail != (fsblkcnt64_t)-1) {
2351 2369 na->space_avail =
2352 2370 (fattr4_space_avail) sarg->sbp->f_frsize *
2353 2371 (fattr4_space_avail) sarg->sbp->f_bavail;
2354 2372 } else {
2355 2373 na->space_avail =
2356 2374 (fattr4_space_avail) sarg->sbp->f_bavail;
2357 2375 }
2358 2376 break;
2359 2377 case NFS4ATTR_SETIT:
2360 2378 /*
2361 2379 * read-only attr
2362 2380 */
2363 2381 error = EINVAL;
2364 2382 break;
2365 2383 case NFS4ATTR_VERIT:
2366 2384 ASSERT(sarg->sbp != NULL);
2367 2385 if (sarg->sbp->f_bavail != na->space_avail)
2368 2386 error = -1; /* no match */
2369 2387 break;
2370 2388 case NFS4ATTR_FREEIT:
2371 2389 break;
2372 2390 }
2373 2391 return (error);
2374 2392 }
2375 2393
2376 2394 /* ARGSUSED */
2377 2395 static int
2378 2396 rfs4_fattr4_space_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2379 2397 union nfs4_attr_u *na)
2380 2398 {
2381 2399 int error = 0;
2382 2400
2383 2401 if (RFS4_MANDATTR_ONLY)
2384 2402 return (ENOTSUP);
2385 2403
2386 2404 switch (cmd) {
2387 2405 case NFS4ATTR_SUPPORTED:
2388 2406 if (sarg->op == NFS4ATTR_SETIT)
2389 2407 error = EINVAL;
2390 2408 break; /* this attr is supported */
2391 2409 case NFS4ATTR_GETIT:
2392 2410 if (sarg->rdattr_error && (sarg->sbp == NULL)) {
2393 2411 error = -1; /* may be okay if rdattr_error */
2394 2412 break;
2395 2413 }
2396 2414 ASSERT(sarg->sbp != NULL);
2397 2415 if (sarg->sbp->f_bfree != (fsblkcnt64_t)-1) {
2398 2416 na->space_free =
2399 2417 (fattr4_space_free) sarg->sbp->f_frsize *
2400 2418 (fattr4_space_free) sarg->sbp->f_bfree;
2401 2419 } else {
2402 2420 na->space_free =
2403 2421 (fattr4_space_free) sarg->sbp->f_bfree;
2404 2422 }
2405 2423 break;
2406 2424 case NFS4ATTR_SETIT:
2407 2425 /*
2408 2426 * read-only attr
2409 2427 */
2410 2428 error = EINVAL;
2411 2429 break;
2412 2430 case NFS4ATTR_VERIT:
2413 2431 ASSERT(sarg->sbp != NULL);
2414 2432 if (sarg->sbp->f_bfree != na->space_free)
2415 2433 error = -1; /* no match */
2416 2434 break;
2417 2435 case NFS4ATTR_FREEIT:
2418 2436 break;
2419 2437 }
2420 2438 return (error);
2421 2439 }
2422 2440
2423 2441 /* ARGSUSED */
2424 2442 static int
2425 2443 rfs4_fattr4_space_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2426 2444 union nfs4_attr_u *na)
2427 2445 {
2428 2446 int error = 0;
2429 2447
2430 2448 if (RFS4_MANDATTR_ONLY)
2431 2449 return (ENOTSUP);
2432 2450
2433 2451 switch (cmd) {
2434 2452 case NFS4ATTR_SUPPORTED:
2435 2453 if (sarg->op == NFS4ATTR_SETIT)
2436 2454 error = EINVAL;
2437 2455 break; /* this attr is supported */
2438 2456 case NFS4ATTR_GETIT:
2439 2457 if (sarg->rdattr_error_req && (sarg->sbp == NULL)) {
2440 2458 error = -1; /* may be okay if rdattr_error */
2441 2459 break;
2442 2460 }
2443 2461 ASSERT(sarg->sbp != NULL);
2444 2462 if (sarg->sbp->f_blocks != (fsblkcnt64_t)-1) {
2445 2463 na->space_total =
2446 2464 (fattr4_space_total) sarg->sbp->f_frsize *
2447 2465 (fattr4_space_total) sarg->sbp->f_blocks;
2448 2466 } else {
2449 2467 na->space_total =
2450 2468 (fattr4_space_total) sarg->sbp->f_blocks;
2451 2469 }
2452 2470 break;
2453 2471 case NFS4ATTR_SETIT:
2454 2472 /*
2455 2473 * read-only attr
2456 2474 */
2457 2475 error = EINVAL;
2458 2476 break;
2459 2477 case NFS4ATTR_VERIT:
2460 2478 ASSERT(sarg->sbp != NULL);
2461 2479 if (sarg->sbp->f_blocks != na->space_total)
2462 2480 error = -1; /* no match */
2463 2481 break;
2464 2482 case NFS4ATTR_FREEIT:
2465 2483 break;
2466 2484 }
2467 2485 return (error);
2468 2486 }
2469 2487
2470 2488 /* ARGSUSED */
2471 2489 static int
2472 2490 rfs4_fattr4_space_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2473 2491 union nfs4_attr_u *na)
2474 2492 {
2475 2493 int error = 0;
2476 2494
2477 2495 if (RFS4_MANDATTR_ONLY)
2478 2496 return (ENOTSUP);
2479 2497
2480 2498 switch (cmd) {
2481 2499 case NFS4ATTR_SUPPORTED:
2482 2500 if (sarg->op == NFS4ATTR_SETIT)
2483 2501 error = EINVAL;
2484 2502 break; /* this attr is supported */
2485 2503 case NFS4ATTR_GETIT:
2486 2504 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NBLOCKS)) {
2487 2505 error = -1; /* may be okay if rdattr_error */
2488 2506 break;
2489 2507 }
2490 2508 ASSERT(sarg->vap->va_mask & AT_NBLOCKS);
2491 2509 na->space_used = (fattr4_space_used) DEV_BSIZE *
2492 2510 (fattr4_space_used) sarg->vap->va_nblocks;
2493 2511 break;
2494 2512 case NFS4ATTR_SETIT:
2495 2513 /*
2496 2514 * read-only attr
2497 2515 */
2498 2516 error = EINVAL;
2499 2517 break;
2500 2518 case NFS4ATTR_VERIT:
2501 2519 ASSERT(sarg->vap->va_mask & AT_NBLOCKS);
2502 2520 if (sarg->vap->va_nblocks != na->space_used)
2503 2521 error = -1; /* no match */
2504 2522 break;
2505 2523 case NFS4ATTR_FREEIT:
2506 2524 break;
2507 2525 }
2508 2526 return (error);
2509 2527 }
2510 2528
2511 2529 /* ARGSUSED */
2512 2530 static int
2513 2531 rfs4_fattr4_system(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2514 2532 union nfs4_attr_u *na)
2515 2533 {
2516 2534 return (ENOTSUP);
2517 2535 }
2518 2536
2519 2537 /* ARGSUSED */
2520 2538 static int
2521 2539 rfs4_fattr4_time_access(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2522 2540 union nfs4_attr_u *na)
2523 2541 {
2524 2542 int error = 0;
2525 2543 timestruc_t atime;
2526 2544
2527 2545 if (RFS4_MANDATTR_ONLY)
2528 2546 return (ENOTSUP);
2529 2547
2530 2548 switch (cmd) {
2531 2549 case NFS4ATTR_SUPPORTED:
2532 2550 if (sarg->op == NFS4ATTR_SETIT)
2533 2551 error = EINVAL;
2534 2552 break; /* this attr is supported */
2535 2553 case NFS4ATTR_GETIT:
2536 2554 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_ATIME)) {
2537 2555 error = -1; /* may be okay if rdattr_error */
2538 2556 break;
2539 2557 }
2540 2558 ASSERT(sarg->vap->va_mask & AT_ATIME);
2541 2559 error = nfs4_time_vton(&sarg->vap->va_atime, &na->time_access);
2542 2560 break;
2543 2561 case NFS4ATTR_SETIT:
2544 2562 /*
2545 2563 * read-only attr
2546 2564 */
2547 2565 error = EINVAL;
2548 2566 break;
2549 2567 case NFS4ATTR_VERIT:
2550 2568 ASSERT(sarg->vap->va_mask & AT_ATIME);
2551 2569 error = nfs4_time_ntov(&na->time_access, &atime);
2552 2570 if (error)
2553 2571 break;
2554 2572 if (bcmp(&atime, &sarg->vap->va_atime, sizeof (atime)))
2555 2573 error = -1; /* no match */
2556 2574 break;
2557 2575 case NFS4ATTR_FREEIT:
2558 2576 break;
2559 2577 }
2560 2578 return (error);
2561 2579 }
2562 2580
2563 2581 /*
2564 2582 * XXX - need to support the setting of access time
2565 2583 */
2566 2584 /* ARGSUSED */
2567 2585 static int
2568 2586 rfs4_fattr4_time_access_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2569 2587 union nfs4_attr_u *na)
2570 2588 {
2571 2589 int error = 0;
2572 2590 settime4 *ta;
2573 2591
2574 2592 if (RFS4_MANDATTR_ONLY)
2575 2593 return (ENOTSUP);
2576 2594
2577 2595 switch (cmd) {
2578 2596 case NFS4ATTR_SUPPORTED:
2579 2597 if ((sarg->op == NFS4ATTR_GETIT) ||
2580 2598 (sarg->op == NFS4ATTR_VERIT))
2581 2599 error = EINVAL;
2582 2600 break; /* this attr is supported */
2583 2601 case NFS4ATTR_GETIT:
2584 2602 case NFS4ATTR_VERIT:
2585 2603 /*
2586 2604 * write only attr
2587 2605 */
2588 2606 error = EINVAL;
2589 2607 break;
2590 2608 case NFS4ATTR_SETIT:
2591 2609 ASSERT(sarg->vap->va_mask & AT_ATIME);
2592 2610 /*
2593 2611 * Set access time (by server or by client)
2594 2612 */
2595 2613 ta = &na->time_access_set;
2596 2614 if (ta->set_it == SET_TO_CLIENT_TIME4) {
2597 2615 error = nfs4_time_ntov(&ta->time, &sarg->vap->va_atime);
2598 2616 } else if (ta->set_it == SET_TO_SERVER_TIME4) {
2599 2617 gethrestime(&sarg->vap->va_atime);
2600 2618 } else {
2601 2619 error = EINVAL;
2602 2620 }
2603 2621 break;
2604 2622 case NFS4ATTR_FREEIT:
2605 2623 break;
2606 2624 }
2607 2625 return (error);
2608 2626 }
2609 2627
2610 2628 /* ARGSUSED */
2611 2629 static int
2612 2630 rfs4_fattr4_time_backup(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2613 2631 union nfs4_attr_u *na)
2614 2632 {
2615 2633 return (ENOTSUP);
2616 2634 }
2617 2635
2618 2636 /* ARGSUSED */
2619 2637 static int
2620 2638 rfs4_fattr4_time_create(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2621 2639 union nfs4_attr_u *na)
2622 2640 {
2623 2641 return (ENOTSUP);
2624 2642 }
2625 2643
2626 2644 /* ARGSUSED */
2627 2645 static int
2628 2646 rfs4_fattr4_time_delta(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2629 2647 union nfs4_attr_u *na)
2630 2648 {
2631 2649 int error = 0;
2632 2650
2633 2651 if (RFS4_MANDATTR_ONLY)
2634 2652 return (ENOTSUP);
2635 2653
2636 2654 switch (cmd) {
2637 2655 case NFS4ATTR_SUPPORTED:
2638 2656 if (sarg->op == NFS4ATTR_SETIT)
2639 2657 error = EINVAL;
2640 2658 break; /* this attr is supported */
2641 2659 case NFS4ATTR_GETIT:
2642 2660 na->time_delta.seconds = 0;
2643 2661 na->time_delta.nseconds = 1000;
2644 2662 break;
2645 2663 case NFS4ATTR_SETIT:
2646 2664 /*
2647 2665 * write only attr
2648 2666 */
2649 2667 error = EINVAL;
2650 2668 break;
2651 2669 case NFS4ATTR_VERIT:
2652 2670 if ((na->time_delta.seconds != 0) ||
2653 2671 (na->time_delta.nseconds != 1000))
2654 2672 error = -1; /* no match */
2655 2673 break;
2656 2674 case NFS4ATTR_FREEIT:
2657 2675 break;
2658 2676 }
2659 2677 return (error);
2660 2678 }
2661 2679
2662 2680 /* ARGSUSED */
2663 2681 static int
2664 2682 rfs4_fattr4_time_metadata(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2665 2683 union nfs4_attr_u *na)
2666 2684 {
2667 2685 int error = 0;
2668 2686 timestruc_t ctime;
2669 2687
2670 2688 if (RFS4_MANDATTR_ONLY)
2671 2689 return (ENOTSUP);
2672 2690
2673 2691 switch (cmd) {
2674 2692 case NFS4ATTR_SUPPORTED:
2675 2693 if (sarg->op == NFS4ATTR_SETIT)
2676 2694 error = EINVAL;
2677 2695 break; /* this attr is supported */
2678 2696 case NFS4ATTR_GETIT:
2679 2697 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_CTIME)) {
2680 2698 error = -1; /* may be okay if rdattr_error */
2681 2699 break;
2682 2700 }
2683 2701 ASSERT(sarg->vap->va_mask & AT_CTIME);
2684 2702 error = nfs4_time_vton(&sarg->vap->va_ctime,
2685 2703 &na->time_metadata);
2686 2704 break;
2687 2705 case NFS4ATTR_SETIT:
2688 2706 /*
2689 2707 * read-only attr
2690 2708 */
2691 2709 error = EINVAL;
2692 2710 break;
2693 2711 case NFS4ATTR_VERIT:
2694 2712 ASSERT(sarg->vap->va_mask & AT_CTIME);
2695 2713 error = nfs4_time_ntov(&na->time_metadata, &ctime);
2696 2714 if (error)
2697 2715 break;
2698 2716 if (bcmp(&ctime, &sarg->vap->va_ctime, sizeof (ctime)))
2699 2717 error = -1; /* no match */
2700 2718 break;
2701 2719 case NFS4ATTR_FREEIT:
2702 2720 break;
2703 2721 }
2704 2722 return (error);
2705 2723 }
2706 2724
2707 2725 /* ARGSUSED */
2708 2726 static int
2709 2727 rfs4_fattr4_time_modify(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2710 2728 union nfs4_attr_u *na)
2711 2729 {
2712 2730 int error = 0;
2713 2731 timestruc_t mtime;
2714 2732
2715 2733 if (RFS4_MANDATTR_ONLY)
2716 2734 return (ENOTSUP);
2717 2735
2718 2736 switch (cmd) {
2719 2737 case NFS4ATTR_SUPPORTED:
2720 2738 if (sarg->op == NFS4ATTR_SETIT)
2721 2739 error = EINVAL;
2722 2740 break; /* this attr is supported */
2723 2741 case NFS4ATTR_GETIT:
2724 2742 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MTIME)) {
2725 2743 error = -1; /* may be okay if rdattr_error */
2726 2744 break;
2727 2745 }
2728 2746 ASSERT(sarg->vap->va_mask & AT_MTIME);
2729 2747 error = nfs4_time_vton(&sarg->vap->va_mtime, &na->time_modify);
2730 2748 break;
2731 2749 case NFS4ATTR_SETIT:
2732 2750 /*
2733 2751 * read-only attr
2734 2752 */
2735 2753 error = EINVAL;
2736 2754 break;
2737 2755 case NFS4ATTR_VERIT:
2738 2756 ASSERT(sarg->vap->va_mask & AT_MTIME);
2739 2757 error = nfs4_time_ntov(&na->time_modify, &mtime);
2740 2758 if (error)
2741 2759 break;
2742 2760 if (bcmp(&mtime, &sarg->vap->va_mtime, sizeof (mtime)))
2743 2761 error = -1; /* no match */
2744 2762 break;
2745 2763 case NFS4ATTR_FREEIT:
2746 2764 break;
2747 2765 }
2748 2766 return (error);
2749 2767 }
2750 2768
2751 2769 /*
2752 2770 * XXX - need to add support for setting modify time
2753 2771 */
2754 2772 /* ARGSUSED */
2755 2773 static int
2756 2774 rfs4_fattr4_time_modify_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg,
2757 2775 union nfs4_attr_u *na)
2758 2776 {
2759 2777 int error = 0;
2760 2778 settime4 *tm;
2761 2779
2762 2780 if (RFS4_MANDATTR_ONLY)
2763 2781 return (ENOTSUP);
2764 2782
2765 2783 switch (cmd) {
2766 2784 case NFS4ATTR_SUPPORTED:
2767 2785 if ((sarg->op == NFS4ATTR_GETIT) ||
2768 2786 (sarg->op == NFS4ATTR_VERIT))
2769 2787 error = EINVAL;
2770 2788 break; /* this attr is supported */
2771 2789 case NFS4ATTR_GETIT:
2772 2790 case NFS4ATTR_VERIT:
2773 2791 /*
2774 2792 * write only attr
2775 2793 */
2776 2794 error = EINVAL;
2777 2795 break;
2778 2796 case NFS4ATTR_SETIT:
2779 2797 ASSERT(sarg->vap->va_mask & AT_MTIME);
2780 2798 /*
2781 2799 * Set modify time (by server or by client)
2782 2800 */
2783 2801 tm = &na->time_modify_set;
2784 2802 if (tm->set_it == SET_TO_CLIENT_TIME4) {
2785 2803 error = nfs4_time_ntov(&tm->time, &sarg->vap->va_mtime);
2786 2804 sarg->flag = ATTR_UTIME;
2787 2805 } else if (tm->set_it == SET_TO_SERVER_TIME4) {
2788 2806 gethrestime(&sarg->vap->va_mtime);
2789 2807 } else {
2790 2808 error = EINVAL;
2791 2809 }
2792 2810 break;
2793 2811 case NFS4ATTR_FREEIT:
2794 2812 break;
2795 2813 }
2796 2814 return (error);
2797 2815 }
2798 2816
2799 2817
2800 2818 static void
2801 2819 rfs4_ntov_init(void)
2802 2820 {
2803 2821 /* index must be same as corresponding FATTR4_* define */
2804 2822 nfs4_ntov_map[0].sv_getit = rfs4_fattr4_supported_attrs;
2805 2823 nfs4_ntov_map[1].sv_getit = rfs4_fattr4_type;
2806 2824 nfs4_ntov_map[2].sv_getit = rfs4_fattr4_fh_expire_type;
2807 2825 nfs4_ntov_map[3].sv_getit = rfs4_fattr4_change;
2808 2826 nfs4_ntov_map[4].sv_getit = rfs4_fattr4_size;
2809 2827 nfs4_ntov_map[5].sv_getit = rfs4_fattr4_link_support;
2810 2828 nfs4_ntov_map[6].sv_getit = rfs4_fattr4_symlink_support;
2811 2829 nfs4_ntov_map[7].sv_getit = rfs4_fattr4_named_attr;
2812 2830 nfs4_ntov_map[8].sv_getit = rfs4_fattr4_fsid;
2813 2831 nfs4_ntov_map[9].sv_getit = rfs4_fattr4_unique_handles;
2814 2832 nfs4_ntov_map[10].sv_getit = rfs4_fattr4_lease_time;
2815 2833 nfs4_ntov_map[11].sv_getit = rfs4_fattr4_rdattr_error;
2816 2834 nfs4_ntov_map[12].sv_getit = rfs4_fattr4_acl;
2817 2835 nfs4_ntov_map[13].sv_getit = rfs4_fattr4_aclsupport;
2818 2836 nfs4_ntov_map[14].sv_getit = rfs4_fattr4_archive;
2819 2837 nfs4_ntov_map[15].sv_getit = rfs4_fattr4_cansettime;
2820 2838 nfs4_ntov_map[16].sv_getit = rfs4_fattr4_case_insensitive;
2821 2839 nfs4_ntov_map[17].sv_getit = rfs4_fattr4_case_preserving;
2822 2840 nfs4_ntov_map[18].sv_getit = rfs4_fattr4_chown_restricted;
2823 2841 nfs4_ntov_map[19].sv_getit = rfs4_fattr4_filehandle;
2824 2842 nfs4_ntov_map[20].sv_getit = rfs4_fattr4_fileid;
2825 2843 nfs4_ntov_map[21].sv_getit = rfs4_fattr4_files_avail;
2826 2844 nfs4_ntov_map[22].sv_getit = rfs4_fattr4_files_free;
2827 2845 nfs4_ntov_map[23].sv_getit = rfs4_fattr4_files_total;
2828 2846 nfs4_ntov_map[24].sv_getit = rfs4_fattr4_fs_locations;
2829 2847 nfs4_ntov_map[25].sv_getit = rfs4_fattr4_hidden;
2830 2848 nfs4_ntov_map[26].sv_getit = rfs4_fattr4_homogeneous;
2831 2849 nfs4_ntov_map[27].sv_getit = rfs4_fattr4_maxfilesize;
2832 2850 nfs4_ntov_map[28].sv_getit = rfs4_fattr4_maxlink;
2833 2851 nfs4_ntov_map[29].sv_getit = rfs4_fattr4_maxname;
2834 2852 nfs4_ntov_map[30].sv_getit = rfs4_fattr4_maxread;
2835 2853 nfs4_ntov_map[31].sv_getit = rfs4_fattr4_maxwrite;
2836 2854 nfs4_ntov_map[32].sv_getit = rfs4_fattr4_mimetype;
2837 2855 nfs4_ntov_map[33].sv_getit = rfs4_fattr4_mode;
2838 2856 nfs4_ntov_map[34].sv_getit = rfs4_fattr4_no_trunc;
2839 2857 nfs4_ntov_map[35].sv_getit = rfs4_fattr4_numlinks;
2840 2858 nfs4_ntov_map[36].sv_getit = rfs4_fattr4_owner;
2841 2859 nfs4_ntov_map[37].sv_getit = rfs4_fattr4_owner_group;
2842 2860 nfs4_ntov_map[38].sv_getit = rfs4_fattr4_quota_avail_hard;
2843 2861 nfs4_ntov_map[39].sv_getit = rfs4_fattr4_quota_avail_soft;
2844 2862 nfs4_ntov_map[40].sv_getit = rfs4_fattr4_quota_used;
2845 2863 nfs4_ntov_map[41].sv_getit = rfs4_fattr4_rawdev;
2846 2864 nfs4_ntov_map[42].sv_getit = rfs4_fattr4_space_avail;
2847 2865 nfs4_ntov_map[43].sv_getit = rfs4_fattr4_space_free;
2848 2866 nfs4_ntov_map[44].sv_getit = rfs4_fattr4_space_total;
2849 2867 nfs4_ntov_map[45].sv_getit = rfs4_fattr4_space_used;
2850 2868 nfs4_ntov_map[46].sv_getit = rfs4_fattr4_system;
2851 2869 nfs4_ntov_map[47].sv_getit = rfs4_fattr4_time_access;
2852 2870 nfs4_ntov_map[48].sv_getit = rfs4_fattr4_time_access_set;
2853 2871 nfs4_ntov_map[49].sv_getit = rfs4_fattr4_time_backup;
2854 2872 nfs4_ntov_map[50].sv_getit = rfs4_fattr4_time_create;
2855 2873 nfs4_ntov_map[51].sv_getit = rfs4_fattr4_time_delta;
2856 2874 nfs4_ntov_map[52].sv_getit = rfs4_fattr4_time_metadata;
2857 2875 nfs4_ntov_map[53].sv_getit = rfs4_fattr4_time_modify;
2858 2876 nfs4_ntov_map[54].sv_getit = rfs4_fattr4_time_modify_set;
2859 2877 nfs4_ntov_map[55].sv_getit = rfs4_fattr4_mounted_on_fileid;
2860 2878 }
|
↓ open down ↓ |
1242 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX