442 }
443
444 /* ARGSUSED */
445 void
446 acl3_getacl(GETACL3args *args, GETACL3res *resp, struct exportinfo *exi,
447 struct svc_req *req, cred_t *cr)
448 {
449 int error;
450 vnode_t *vp;
451 vattr_t *vap;
452 vattr_t va;
453
454 vap = NULL;
455
456 vp = nfs3_fhtovp(&args->fh, exi);
457 if (vp == NULL) {
458 error = ESTALE;
459 goto out;
460 }
461
462 #ifdef DEBUG
463 if (rfs3_do_post_op_attr) {
464 va.va_mask = AT_ALL;
465 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
466 } else
467 vap = NULL;
468 #else
469 va.va_mask = AT_ALL;
470 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
471 #endif
472
473 bzero((caddr_t)&resp->resok.acl, sizeof (resp->resok.acl));
474
475 resp->resok.acl.vsa_mask = args->mask;
476
477 error = VOP_GETSECATTR(vp, &resp->resok.acl, 0, cr, NULL);
478
479 if ((error == ENOSYS) && !(exi->exi_export.ex_flags & EX_NOACLFAB)) {
480 /*
481 * If the underlying file system doesn't support
482 * aclent_t type acls, fabricate an acl. This is
483 * required in order to to support existing clients
484 * that require the call to VOP_GETSECATTR to
485 * succeed while making the assumption that all
486 * file systems support aclent_t type acls. This
487 * causes problems for servers exporting ZFS file
488 * systems because ZFS supports ace_t type acls,
489 * and fails (with ENOSYS) when asked for aclent_t
490 * type acls.
491 *
492 * Note: if the fs_fab_acl() fails, we have other problems.
493 * This error should be returned to the caller.
494 */
495 error = fs_fab_acl(vp, &resp->resok.acl, 0, cr, NULL);
496 }
497
498 if (error)
499 goto out;
500
501 #ifdef DEBUG
502 if (rfs3_do_post_op_attr) {
503 va.va_mask = AT_ALL;
504 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
505 } else
506 vap = NULL;
507 #else
508 va.va_mask = AT_ALL;
509 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
510 #endif
511
512 VN_RELE(vp);
513
514 resp->status = NFS3_OK;
515 vattr_to_post_op_attr(vap, &resp->resok.attr);
516 if (!(args->mask & NA_ACL)) {
517 if (resp->resok.acl.vsa_aclcnt > 0 &&
518 resp->resok.acl.vsa_aclentp != NULL) {
519 kmem_free((caddr_t)resp->resok.acl.vsa_aclentp,
520 resp->resok.acl.vsa_aclcnt * sizeof (aclent_t));
521 }
522 resp->resok.acl.vsa_aclentp = NULL;
523 }
524 if (!(args->mask & NA_DFACL)) {
525 if (resp->resok.acl.vsa_dfaclcnt > 0 &&
526 resp->resok.acl.vsa_dfaclentp != NULL) {
527 kmem_free((caddr_t)resp->resok.acl.vsa_dfaclentp,
528 resp->resok.acl.vsa_dfaclcnt * sizeof (aclent_t));
529 }
530 resp->resok.acl.vsa_dfaclentp = NULL;
571 /* ARGSUSED */
572 void
573 acl3_setacl(SETACL3args *args, SETACL3res *resp, struct exportinfo *exi,
574 struct svc_req *req, cred_t *cr)
575 {
576 int error;
577 vnode_t *vp;
578 vattr_t *vap;
579 vattr_t va;
580
581 vap = NULL;
582
583 vp = nfs3_fhtovp(&args->fh, exi);
584 if (vp == NULL) {
585 error = ESTALE;
586 goto out1;
587 }
588
589 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
590
591 #ifdef DEBUG
592 if (rfs3_do_post_op_attr) {
593 va.va_mask = AT_ALL;
594 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
595 } else
596 vap = NULL;
597 #else
598 va.va_mask = AT_ALL;
599 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
600 #endif
601
602 if (rdonly(exi, req) || vn_is_readonly(vp)) {
603 resp->status = NFS3ERR_ROFS;
604 goto out1;
605 }
606
607 error = VOP_SETSECATTR(vp, &args->acl, 0, cr, NULL);
608
609 #ifdef DEBUG
610 if (rfs3_do_post_op_attr) {
611 va.va_mask = AT_ALL;
612 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
613 } else
614 vap = NULL;
615 #else
616 va.va_mask = AT_ALL;
617 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
618 #endif
619
620 if (error)
621 goto out;
622
623 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
624 VN_RELE(vp);
625
626 resp->status = NFS3_OK;
627 vattr_to_post_op_attr(vap, &resp->resok.attr);
628 return;
629
630 out:
631 if (curthread->t_flag & T_WOULDBLOCK) {
632 curthread->t_flag &= ~T_WOULDBLOCK;
633 resp->status = NFS3ERR_JUKEBOX;
634 } else
635 resp->status = puterrno3(error);
636 out1:
637 if (vp != NULL) {
638 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
|
442 }
443
444 /* ARGSUSED */
445 void
446 acl3_getacl(GETACL3args *args, GETACL3res *resp, struct exportinfo *exi,
447 struct svc_req *req, cred_t *cr)
448 {
449 int error;
450 vnode_t *vp;
451 vattr_t *vap;
452 vattr_t va;
453
454 vap = NULL;
455
456 vp = nfs3_fhtovp(&args->fh, exi);
457 if (vp == NULL) {
458 error = ESTALE;
459 goto out;
460 }
461
462 va.va_mask = AT_ALL;
463 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
464
465 bzero((caddr_t)&resp->resok.acl, sizeof (resp->resok.acl));
466
467 resp->resok.acl.vsa_mask = args->mask;
468
469 error = VOP_GETSECATTR(vp, &resp->resok.acl, 0, cr, NULL);
470
471 if ((error == ENOSYS) && !(exi->exi_export.ex_flags & EX_NOACLFAB)) {
472 /*
473 * If the underlying file system doesn't support
474 * aclent_t type acls, fabricate an acl. This is
475 * required in order to to support existing clients
476 * that require the call to VOP_GETSECATTR to
477 * succeed while making the assumption that all
478 * file systems support aclent_t type acls. This
479 * causes problems for servers exporting ZFS file
480 * systems because ZFS supports ace_t type acls,
481 * and fails (with ENOSYS) when asked for aclent_t
482 * type acls.
483 *
484 * Note: if the fs_fab_acl() fails, we have other problems.
485 * This error should be returned to the caller.
486 */
487 error = fs_fab_acl(vp, &resp->resok.acl, 0, cr, NULL);
488 }
489
490 if (error)
491 goto out;
492
493 va.va_mask = AT_ALL;
494 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
495
496 VN_RELE(vp);
497
498 resp->status = NFS3_OK;
499 vattr_to_post_op_attr(vap, &resp->resok.attr);
500 if (!(args->mask & NA_ACL)) {
501 if (resp->resok.acl.vsa_aclcnt > 0 &&
502 resp->resok.acl.vsa_aclentp != NULL) {
503 kmem_free((caddr_t)resp->resok.acl.vsa_aclentp,
504 resp->resok.acl.vsa_aclcnt * sizeof (aclent_t));
505 }
506 resp->resok.acl.vsa_aclentp = NULL;
507 }
508 if (!(args->mask & NA_DFACL)) {
509 if (resp->resok.acl.vsa_dfaclcnt > 0 &&
510 resp->resok.acl.vsa_dfaclentp != NULL) {
511 kmem_free((caddr_t)resp->resok.acl.vsa_dfaclentp,
512 resp->resok.acl.vsa_dfaclcnt * sizeof (aclent_t));
513 }
514 resp->resok.acl.vsa_dfaclentp = NULL;
555 /* ARGSUSED */
556 void
557 acl3_setacl(SETACL3args *args, SETACL3res *resp, struct exportinfo *exi,
558 struct svc_req *req, cred_t *cr)
559 {
560 int error;
561 vnode_t *vp;
562 vattr_t *vap;
563 vattr_t va;
564
565 vap = NULL;
566
567 vp = nfs3_fhtovp(&args->fh, exi);
568 if (vp == NULL) {
569 error = ESTALE;
570 goto out1;
571 }
572
573 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
574
575 va.va_mask = AT_ALL;
576 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
577
578 if (rdonly(exi, req) || vn_is_readonly(vp)) {
579 resp->status = NFS3ERR_ROFS;
580 goto out1;
581 }
582
583 error = VOP_SETSECATTR(vp, &args->acl, 0, cr, NULL);
584
585 va.va_mask = AT_ALL;
586 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
587
588 if (error)
589 goto out;
590
591 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
592 VN_RELE(vp);
593
594 resp->status = NFS3_OK;
595 vattr_to_post_op_attr(vap, &resp->resok.attr);
596 return;
597
598 out:
599 if (curthread->t_flag & T_WOULDBLOCK) {
600 curthread->t_flag &= ~T_WOULDBLOCK;
601 resp->status = NFS3ERR_JUKEBOX;
602 } else
603 resp->status = puterrno3(error);
604 out1:
605 if (vp != NULL) {
606 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
|