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