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