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