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