Print this page
*** NO COMMENTS ***


  54 #include <nfs/nfs.h>
  55 #include <nfs/export.h>
  56 #include <nfs/nfs_cmd.h>
  57 
  58 #include <sys/strsubr.h>
  59 
  60 #include <sys/tsol/label.h>
  61 #include <sys/tsol/tndb.h>
  62 
  63 #include <sys/zone.h>
  64 
  65 #include <inet/ip.h>
  66 #include <inet/ip6.h>
  67 
  68 /*
  69  * These are the interface routines for the server side of the
  70  * Network File System.  See the NFS version 3 protocol specification
  71  * for a description of this interface.
  72  */
  73 
  74 #ifdef DEBUG
  75 int rfs3_do_pre_op_attr = 1;
  76 int rfs3_do_post_op_attr = 1;
  77 int rfs3_do_post_op_fh3 = 1;
  78 #endif
  79 
  80 static writeverf3 write3verf;
  81 
  82 static int      sattr3_to_vattr(sattr3 *, struct vattr *);
  83 static int      vattr_to_fattr3(struct vattr *, fattr3 *);
  84 static int      vattr_to_wcc_attr(struct vattr *, wcc_attr *);
  85 static void     vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
  86 static void     vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
  87 static int      rdma_setup_read_data3(READ3args *, READ3resok *);
  88 
  89 extern int nfs_loaned_buffers;
  90 
  91 u_longlong_t nfs3_srv_caller_id;
  92 
  93 /* ARGSUSED */
  94 void
  95 rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
  96         struct svc_req *req, cred_t *cr)
  97 {
  98         int error;
  99         vnode_t *vp;


 210          * delegated this file.  If so, then we return JUKEBOX to
 211          * allow the client to retrasmit its request.
 212          */
 213         if (vp->v_type == VREG && (ava.va_mask & AT_SIZE)) {
 214                 if (nbl_need_check(vp)) {
 215                         nbl_start_crit(vp, RW_READER);
 216                         in_crit = 1;
 217                 }
 218         }
 219 
 220         bva.va_mask = AT_ALL;
 221         error = rfs4_delegated_getattr(vp, &bva, 0, cr);
 222 
 223         /*
 224          * If we can't get the attributes, then we can't do the
 225          * right access checking.  So, we'll fail the request.
 226          */
 227         if (error)
 228                 goto out;
 229 
 230 #ifdef DEBUG
 231         if (rfs3_do_pre_op_attr)
 232                 bvap = &bva;
 233 #else
 234         bvap = &bva;
 235 #endif
 236 
 237         if (rdonly(exi, req) || vn_is_readonly(vp)) {
 238                 resp->status = NFS3ERR_ROFS;
 239                 goto out1;
 240         }
 241 
 242         if (args->guard.check &&
 243             (args->guard.obj_ctime.seconds != bva.va_ctime.tv_sec ||
 244             args->guard.obj_ctime.nseconds != bva.va_ctime.tv_nsec)) {
 245                 resp->status = NFS3ERR_NOT_SYNC;
 246                 goto out1;
 247         }
 248 
 249         if (args->new_attributes.mtime.set_it == SET_TO_CLIENT_TIME)
 250                 flag = ATTR_UTIME;
 251         else
 252                 flag = 0;
 253 
 254         /*
 255          * If the filesystem is exported with nosuid, then mask off


 305                         bf.l_type = F_WRLCK;
 306                         bf.l_whence = 0;
 307                         bf.l_start = (off64_t)ava.va_size;
 308                         bf.l_len = 0;
 309                         bf.l_sysid = 0;
 310                         bf.l_pid = 0;
 311                         error = VOP_SPACE(vp, F_FREESP, &bf, FWRITE,
 312                             (offset_t)ava.va_size, cr, &ct);
 313                 }
 314         }
 315 
 316         if (!error && ava.va_mask)
 317                 error = VOP_SETATTR(vp, &ava, flag, cr, &ct);
 318 
 319         /* check if a monitor detected a delegation conflict */
 320         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
 321                 resp->status = NFS3ERR_JUKEBOX;
 322                 goto out1;
 323         }
 324 
 325 #ifdef DEBUG
 326         if (rfs3_do_post_op_attr) {
 327                 ava.va_mask = AT_ALL;
 328                 avap = rfs4_delegated_getattr(vp, &ava, 0, cr) ? NULL : &ava;
 329         } else
 330                 avap = NULL;
 331 #else
 332         ava.va_mask = AT_ALL;
 333         avap = rfs4_delegated_getattr(vp, &ava, 0, cr) ? NULL : &ava;
 334 #endif
 335 
 336         /*
 337          * Force modified metadata out to stable storage.
 338          */
 339         (void) VOP_FSYNC(vp, FNODSYNC, cr, &ct);
 340 
 341         if (error)
 342                 goto out;
 343 
 344         if (in_crit)
 345                 nbl_end_crit(vp);
 346 
 347         resp->status = NFS3_OK;
 348         vattr_to_wcc_data(bvap, avap, &resp->resok.obj_wcc);
 349 
 350         DTRACE_NFSV3_4(op__setattr__done, struct svc_req *, req,
 351             cred_t *, cr, vnode_t *, vp, SETATTR3res *, resp);
 352 
 353         VN_RELE(vp);
 354 


 404          * location of the public filehandle.
 405          */
 406         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 407                 dvp = rootdir;
 408                 VN_HOLD(dvp);
 409 
 410                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 411                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 412         } else {
 413                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 414 
 415                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 416                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 417 
 418                 if (dvp == NULL) {
 419                         error = ESTALE;
 420                         goto out;
 421                 }
 422         }
 423 
 424 #ifdef DEBUG
 425         if (rfs3_do_pre_op_attr) {
 426                 dva.va_mask = AT_ALL;
 427                 dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 428         }
 429 #else
 430         dva.va_mask = AT_ALL;
 431         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 432 #endif
 433 
 434         if (args->what.name == nfs3nametoolong) {
 435                 resp->status = NFS3ERR_NAMETOOLONG;
 436                 goto out1;
 437         }
 438 
 439         if (args->what.name == NULL || *(args->what.name) == '\0') {
 440                 resp->status = NFS3ERR_ACCES;
 441                 goto out1;
 442         }
 443 
 444         fhp = &args->what.dir;
 445         if (strcmp(args->what.name, "..") == 0 &&
 446             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 447                 resp->status = NFS3ERR_NOENT;
 448                 goto out1;
 449         }
 450 
 451         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 452         name = nfscmd_convname(ca, exi, args->what.name,
 453             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 454 
 455         if (name == NULL) {
 456                 resp->status = NFS3ERR_ACCES;
 457                 goto out1;
 458         }
 459 


 460         /*
 461          * If the public filehandle is used then allow
 462          * a multi-component lookup
 463          */
 464         if (PUBLIC_FH3(&args->what.dir)) {


 465                 publicfh_flag = TRUE;

 466                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 467                     &exi, &sec);
 468                 if (error && exi != NULL)
 469                         exi_rele(exi); /* See comment below Re: publicfh_flag */




 470                 /*
 471                  * Since WebNFS may bypass MOUNT, we need to ensure this
 472                  * request didn't come from an unlabeled admin_low client.
 473                  */
 474                 if (is_system_labeled() && error == 0) {
 475                         int             addr_type;
 476                         void            *ipaddr;
 477                         tsol_tpc_t      *tp;
 478 
 479                         if (ca->sa_family == AF_INET) {
 480                                 addr_type = IPV4_VERSION;
 481                                 ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
 482                         } else if (ca->sa_family == AF_INET6) {
 483                                 addr_type = IPV6_VERSION;
 484                                 ipaddr = &((struct sockaddr_in6 *)
 485                                     ca)->sin6_addr;
 486                         }
 487                         tp = find_tpc(ipaddr, addr_type, B_FALSE);
 488                         if (tp == NULL || tp->tpc_tp.tp_doi !=
 489                             l_admin_low->tsl_doi || tp->tpc_tp.host_type !=
 490                             SUN_CIPSO) {
 491                                 if (exi != NULL)
 492                                         exi_rele(exi);
 493                                 VN_RELE(vp);
 494                                 resp->status = NFS3ERR_ACCES;
 495                                 error = 1;
 496                         }
 497                         if (tp != NULL)
 498                                 TPC_RELE(tp);
 499                 }
 500         } else {
 501                 error = VOP_LOOKUP(dvp, name, &vp,
 502                     NULL, 0, NULL, cr, NULL, NULL, NULL);
 503         }
 504 
 505         if (name != args->what.name)
 506                 kmem_free(name, MAXPATHLEN + 1);
 507 






 508         if (is_system_labeled() && error == 0) {
 509                 bslabel_t *clabel = req->rq_label;
 510 
 511                 ASSERT(clabel != NULL);
 512                 DTRACE_PROBE2(tx__rfs3__log__info__oplookup__clabel, char *,
 513                     "got client label from request(1)", struct svc_req *, req);
 514 
 515                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 516                         if (!do_rfs_label_check(clabel, dvp,
 517                             DOMINANCE_CHECK, exi)) {
 518                                 if (publicfh_flag && exi != NULL)
 519                                         exi_rele(exi);
 520                                 VN_RELE(vp);
 521                                 resp->status = NFS3ERR_ACCES;
 522                                 error = 1;
 523                         }
 524                 }
 525         }
 526 
 527 #ifdef DEBUG
 528         if (rfs3_do_post_op_attr) {
 529                 dva.va_mask = AT_ALL;
 530                 dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 531         } else
 532                 dvap = NULL;
 533 #else
 534         dva.va_mask = AT_ALL;
 535         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;
 536 #endif
 537 
 538         if (error)
 539                 goto out;
 540 
 541         if (sec.sec_flags & SEC_QUERY) {
 542                 error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
 543         } else {
 544                 error = makefh3(&resp->resok.object, vp, exi);
 545                 if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
 546                         auth_weak = TRUE;
 547         }
 548 
 549         if (error) {
 550                 VN_RELE(vp);
 551                 goto out;
 552         }
 553 
 554         /*
 555          * If publicfh_flag is true then we have called rfs_publicfh_mclookup
 556          * and have obtained a new exportinfo in exi which needs to be
 557          * released. Note the the original exportinfo pointed to by exi
 558          * will be released by the caller, common_dispatch.
 559          */
 560         if (publicfh_flag)
 561                 exi_rele(exi);
 562 
 563 #ifdef DEBUG
 564         if (rfs3_do_post_op_attr) {
 565                 va.va_mask = AT_ALL;
 566                 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 567         } else
 568                 vap = NULL;
 569 #else
 570         va.va_mask = AT_ALL;
 571         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 572 #endif
 573 

 574         VN_RELE(vp);
 575 
 576         resp->status = NFS3_OK;
 577         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 578         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 579 
 580         /*
 581          * If it's public fh, no 0x81, and client's flavor is
 582          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 583          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 584          */
 585         if (auth_weak)
 586                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 587 
 588         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 589             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 590         VN_RELE(dvp);
 591 
 592         return;
 593 
 594 out:






 595         if (curthread->t_flag & T_WOULDBLOCK) {
 596                 curthread->t_flag &= ~T_WOULDBLOCK;
 597                 resp->status = NFS3ERR_JUKEBOX;
 598         } else
 599                 resp->status = puterrno3(error);
 600 out1:
 601         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 602             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 603 
 604         if (dvp != NULL)
 605                 VN_RELE(dvp);
 606         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 607 
 608 }
 609 
 610 void *
 611 rfs3_lookup_getfh(LOOKUP3args *args)
 612 {
 613 
 614         return (&args->what.dir);


 645          * to check write permissions for regular files and directories.
 646          * Special files are interpreted by the client, so the underlying
 647          * permissions are sent back to the client for interpretation.
 648          */
 649         if (rdonly(exi, req) && (vp->v_type == VREG || vp->v_type == VDIR))
 650                 checkwriteperm = 0;
 651         else
 652                 checkwriteperm = 1;
 653 
 654         /*
 655          * We need the mode so that we can correctly determine access
 656          * permissions relative to a mandatory lock file.  Access to
 657          * mandatory lock files is denied on the server, so it might
 658          * as well be reflected to the server during the open.
 659          */
 660         va.va_mask = AT_MODE;
 661         error = VOP_GETATTR(vp, &va, 0, cr, NULL);
 662         if (error)
 663                 goto out;
 664 
 665 #ifdef DEBUG
 666         if (rfs3_do_post_op_attr)
 667                 vap = &va;
 668 #else
 669         vap = &va;
 670 #endif
 671 
 672         resp->resok.access = 0;
 673 
 674         if (is_system_labeled()) {
 675                 bslabel_t *clabel = req->rq_label;
 676 
 677                 ASSERT(clabel != NULL);
 678                 DTRACE_PROBE2(tx__rfs3__log__info__opaccess__clabel, char *,
 679                     "got client label from request(1)", struct svc_req *, req);
 680 
 681                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 682                         if ((equal_label = do_rfs_label_check(clabel, vp,
 683                             EQUALITY_CHECK, exi)) == B_FALSE) {
 684                                 dominant_label = do_rfs_label_check(clabel,
 685                                     vp, DOMINANCE_CHECK, exi);
 686                         } else
 687                                 dominant_label = B_TRUE;
 688                         admin_low_client = B_FALSE;
 689                 } else
 690                         admin_low_client = B_TRUE;


 725             (args->access & ACCESS3_DELETE) && vp->v_type == VDIR) {
 726                 error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
 727                 if (error) {
 728                         if (curthread->t_flag & T_WOULDBLOCK)
 729                                 goto out;
 730                 } else if (!is_system_labeled() || admin_low_client ||
 731                     equal_label)
 732                         resp->resok.access |= ACCESS3_DELETE;
 733         }
 734         if (args->access & ACCESS3_EXECUTE) {
 735                 error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL);
 736                 if (error) {
 737                         if (curthread->t_flag & T_WOULDBLOCK)
 738                                 goto out;
 739                 } else if (!MANDLOCK(vp, va.va_mode) &&
 740                     (!is_system_labeled() || admin_low_client ||
 741                     dominant_label))
 742                         resp->resok.access |= ACCESS3_EXECUTE;
 743         }
 744 
 745 #ifdef DEBUG
 746         if (rfs3_do_post_op_attr) {
 747                 va.va_mask = AT_ALL;
 748                 vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 749         } else
 750                 vap = NULL;
 751 #else
 752         va.va_mask = AT_ALL;
 753         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;
 754 #endif
 755 
 756         resp->status = NFS3_OK;
 757         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 758 
 759         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 760             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 761 
 762         VN_RELE(vp);
 763 
 764         return;
 765 
 766 out:
 767         if (curthread->t_flag & T_WOULDBLOCK) {
 768                 curthread->t_flag &= ~T_WOULDBLOCK;
 769                 resp->status = NFS3ERR_JUKEBOX;
 770         } else
 771                 resp->status = puterrno3(error);
 772         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 773             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 774         if (vp != NULL)


 799         char *name = NULL;
 800         int is_referral = 0;
 801 
 802         vap = NULL;
 803 
 804         vp = nfs3_fhtovp(&args->symlink, exi);
 805 
 806         DTRACE_NFSV3_4(op__readlink__start, struct svc_req *, req,
 807             cred_t *, cr, vnode_t *, vp, READLINK3args *, args);
 808 
 809         if (vp == NULL) {
 810                 error = ESTALE;
 811                 goto out;
 812         }
 813 
 814         va.va_mask = AT_ALL;
 815         error = VOP_GETATTR(vp, &va, 0, cr, NULL);
 816         if (error)
 817                 goto out;
 818 
 819 #ifdef DEBUG
 820         if (rfs3_do_post_op_attr)
 821                 vap = &va;
 822 #else
 823         vap = &va;
 824 #endif
 825 
 826         /* We lied about the object type for a referral */
 827         if (vn_is_nfs_reparse(vp, cr))
 828                 is_referral = 1;
 829 
 830         if (vp->v_type != VLNK && !is_referral) {
 831                 resp->status = NFS3ERR_INVAL;
 832                 goto out1;
 833         }
 834 
 835         if (MANDLOCK(vp, va.va_mode)) {
 836                 resp->status = NFS3ERR_ACCES;
 837                 goto out1;
 838         }
 839 
 840         if (is_system_labeled()) {
 841                 bslabel_t *clabel = req->rq_label;
 842 
 843                 ASSERT(clabel != NULL);
 844                 DTRACE_PROBE2(tx__rfs3__log__info__opreadlink__clabel, char *,


 872                         kmem_free(s, strsz);
 873                 }
 874 
 875         } else {
 876 
 877                 iov.iov_base = data;
 878                 iov.iov_len = MAXPATHLEN;
 879                 uio.uio_iov = &iov;
 880                 uio.uio_iovcnt = 1;
 881                 uio.uio_segflg = UIO_SYSSPACE;
 882                 uio.uio_extflg = UIO_COPY_CACHED;
 883                 uio.uio_loffset = 0;
 884                 uio.uio_resid = MAXPATHLEN;
 885 
 886                 error = VOP_READLINK(vp, &uio, cr, NULL);
 887 
 888                 if (!error)
 889                         *(data + MAXPATHLEN - uio.uio_resid) = '\0';
 890         }
 891 
 892 #ifdef DEBUG
 893         if (rfs3_do_post_op_attr) {
 894                 va.va_mask = AT_ALL;
 895                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
 896         } else
 897                 vap = NULL;
 898 #else
 899         va.va_mask = AT_ALL;
 900         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
 901 #endif
 902         /* Lie about object type again just to be consistent */
 903         if (is_referral && vap != NULL)
 904                 vap->va_type = VLNK;
 905 
 906 #if 0 /* notyet */
 907         /*
 908          * Don't do this.  It causes local disk writes when just
 909          * reading the file and the overhead is deemed larger
 910          * than the benefit.
 911          */
 912         /*
 913          * Force modified metadata out to stable storage.
 914          */
 915         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
 916 #endif
 917 
 918         if (error) {
 919                 kmem_free(data, MAXPATHLEN + 1);
 920                 goto out;
 921         }


1060         error = VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &ct);
1061 
1062         /* check if a monitor detected a delegation conflict */
1063         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1064                 resp->status = NFS3ERR_JUKEBOX;
1065                 goto out1;
1066         }
1067 
1068         need_rwunlock = 1;
1069 
1070         va.va_mask = AT_ALL;
1071         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1072 
1073         /*
1074          * If we can't get the attributes, then we can't do the
1075          * right access checking.  So, we'll fail the request.
1076          */
1077         if (error)
1078                 goto out;
1079 
1080 #ifdef DEBUG
1081         if (rfs3_do_post_op_attr)
1082                 vap = &va;
1083 #else
1084         vap = &va;
1085 #endif
1086 
1087         if (vp->v_type != VREG) {
1088                 resp->status = NFS3ERR_INVAL;
1089                 goto out1;
1090         }
1091 
1092         if (crgetuid(cr) != va.va_uid) {
1093                 error = VOP_ACCESS(vp, VREAD, 0, cr, &ct);
1094                 if (error) {
1095                         if (curthread->t_flag & T_WOULDBLOCK)
1096                                 goto out;
1097                         error = VOP_ACCESS(vp, VEXEC, 0, cr, &ct);
1098                         if (error)
1099                                 goto out;
1100                 }
1101         }
1102 
1103         if (MANDLOCK(vp, va.va_mode)) {
1104                 resp->status = NFS3ERR_ACCES;
1105                 goto out1;


1215         if (error) {
1216                 if (mp)
1217                         freemsg(mp);
1218                 /* check if a monitor detected a delegation conflict */
1219                 if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1220                         resp->status = NFS3ERR_JUKEBOX;
1221                         goto out1;
1222                 }
1223                 goto out;
1224         }
1225 
1226         /* make mblk using zc buffers */
1227         if (loaned_buffers) {
1228                 mp = uio_to_mblk(uiop);
1229                 ASSERT(mp != NULL);
1230         }
1231 
1232         va.va_mask = AT_ALL;
1233         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1234 
1235 #ifdef DEBUG
1236         if (rfs3_do_post_op_attr) {
1237                 if (error)
1238                         vap = NULL;
1239                 else
1240                         vap = &va;
1241         } else
1242                 vap = NULL;
1243 #else
1244         if (error)
1245                 vap = NULL;
1246         else
1247                 vap = &va;
1248 #endif
1249 
1250         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &ct);
1251 
1252         if (in_crit)
1253                 nbl_end_crit(vp);
1254 
1255         resp->status = NFS3_OK;
1256         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
1257         resp->resok.count = args->count - uiop->uio_resid;
1258         if (!error && offset + resp->resok.count == va.va_size)
1259                 resp->resok.eof = TRUE;
1260         else
1261                 resp->resok.eof = FALSE;
1262         resp->resok.data.data_len = resp->resok.count;
1263 
1264         if (mp)
1265                 rfs_rndup_mblks(mp, resp->resok.count, loaned_buffers);
1266 
1267         resp->resok.data.mp = mp;
1268         resp->resok.size = (uint_t)args->count;


1402 
1403         /* check if a monitor detected a delegation conflict */
1404         if (rwlock_ret == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1405                 resp->status = NFS3ERR_JUKEBOX;
1406                 rwlock_ret = -1;
1407                 goto err1;
1408         }
1409 
1410 
1411         bva.va_mask = AT_ALL;
1412         error = VOP_GETATTR(vp, &bva, 0, cr, &ct);
1413 
1414         /*
1415          * If we can't get the attributes, then we can't do the
1416          * right access checking.  So, we'll fail the request.
1417          */
1418         if (error)
1419                 goto err;
1420 
1421         bvap = &bva;
1422 #ifdef DEBUG
1423         if (!rfs3_do_pre_op_attr)
1424                 bvap = NULL;
1425 #endif
1426         avap = bvap;
1427 
1428         if (args->count != args->data.data_len) {
1429                 resp->status = NFS3ERR_INVAL;
1430                 goto err1;
1431         }
1432 
1433         if (rdonly(exi, req)) {
1434                 resp->status = NFS3ERR_ROFS;
1435                 goto err1;
1436         }
1437 
1438         if (vp->v_type != VREG) {
1439                 resp->status = NFS3ERR_INVAL;
1440                 goto err1;
1441         }
1442 
1443         if (crgetuid(cr) != bva.va_uid &&
1444             (error = VOP_ACCESS(vp, VWRITE, 0, cr, &ct)))
1445                 goto err;


1517          * the cred of the current thread to be used if quota
1518          * checking is enabled.
1519          */
1520         savecred = curthread->t_cred;
1521         curthread->t_cred = cr;
1522         error = VOP_WRITE(vp, &uio, ioflag, cr, &ct);
1523         curthread->t_cred = savecred;
1524 
1525         if (iovp != iov)
1526                 kmem_free(iovp, sizeof (*iovp) * iovcnt);
1527 
1528         /* check if a monitor detected a delegation conflict */
1529         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1530                 resp->status = NFS3ERR_JUKEBOX;
1531                 goto err1;
1532         }
1533 
1534         ava.va_mask = AT_ALL;
1535         avap = VOP_GETATTR(vp, &ava, 0, cr, &ct) ? NULL : &ava;
1536 
1537 #ifdef DEBUG
1538         if (!rfs3_do_post_op_attr)
1539                 avap = NULL;
1540 #endif
1541 
1542         if (error)
1543                 goto err;
1544 
1545         /*
1546          * If we were unable to get the V_WRITELOCK_TRUE, then we
1547          * may not have accurate after attrs, so check if
1548          * we have both attributes, they have a non-zero va_seq, and
1549          * va_seq has changed by exactly one,
1550          * if not, turn off the before attr.
1551          */
1552         if (rwlock_ret != V_WRITELOCK_TRUE) {
1553                 if (bvap == NULL || avap == NULL ||
1554                     bvap->va_seq == 0 || avap->va_seq == 0 ||
1555                     avap->va_seq != (bvap->va_seq + 1)) {
1556                         bvap = NULL;
1557                 }
1558         }
1559 
1560         resp->status = NFS3_OK;
1561         vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);


1610         enum vcexcl excl;
1611         nfstime3 *mtime;
1612         len_t reqsize;
1613         bool_t trunc;
1614         struct sockaddr *ca;
1615         char *name = NULL;
1616 
1617         dbvap = NULL;
1618         davap = NULL;
1619 
1620         dvp = nfs3_fhtovp(&args->where.dir, exi);
1621 
1622         DTRACE_NFSV3_4(op__create__start, struct svc_req *, req,
1623             cred_t *, cr, vnode_t *, dvp, CREATE3args *, args);
1624 
1625         if (dvp == NULL) {
1626                 error = ESTALE;
1627                 goto out;
1628         }
1629 
1630 #ifdef DEBUG
1631         if (rfs3_do_pre_op_attr) {
1632                 dbva.va_mask = AT_ALL;
1633                 dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
1634         } else
1635                 dbvap = NULL;
1636 #else
1637         dbva.va_mask = AT_ALL;
1638         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
1639 #endif
1640         davap = dbvap;
1641 
1642         if (args->where.name == nfs3nametoolong) {
1643                 resp->status = NFS3ERR_NAMETOOLONG;
1644                 goto out1;
1645         }
1646 
1647         if (args->where.name == NULL || *(args->where.name) == '\0') {
1648                 resp->status = NFS3ERR_ACCES;
1649                 goto out1;
1650         }
1651 
1652         if (rdonly(exi, req)) {
1653                 resp->status = NFS3ERR_ROFS;
1654                 goto out1;
1655         }
1656 
1657         if (is_system_labeled()) {
1658                 bslabel_t *clabel = req->rq_label;
1659 


1782                 goto out1;
1783         }
1784 
1785         /*
1786          * If the filesystem is exported with nosuid, then mask off
1787          * the setuid and setgid bits.
1788          */
1789         if (va.va_type == VREG && (exi->exi_export.ex_flags & EX_NOSUID))
1790                 va.va_mode &= ~(VSUID | VSGID);
1791 
1792 tryagain:
1793         /*
1794          * The file open mode used is VWRITE.  If the client needs
1795          * some other semantic, then it should do the access checking
1796          * itself.  It would have been nice to have the file open mode
1797          * passed as part of the arguments.
1798          */
1799         error = VOP_CREATE(dvp, name, &va, excl, VWRITE,
1800             &vp, cr, 0, NULL, NULL);
1801 
1802 #ifdef DEBUG
1803         if (rfs3_do_post_op_attr) {
1804                 dava.va_mask = AT_ALL;
1805                 davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
1806         } else
1807                 davap = NULL;
1808 #else
1809         dava.va_mask = AT_ALL;
1810         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
1811 #endif
1812 
1813         if (error) {
1814                 /*
1815                  * If we got something other than file already exists
1816                  * then just return this error.  Otherwise, we got
1817                  * EEXIST.  If we were doing a GUARDED create, then
1818                  * just return this error.  Otherwise, we need to
1819                  * make sure that this wasn't a duplicate of an
1820                  * exclusive create request.
1821                  *
1822                  * The assumption is made that a non-exclusive create
1823                  * request will never return EEXIST.
1824                  */
1825                 if (error != EEXIST || args->how.mode == GUARDED)
1826                         goto out;
1827                 /*
1828                  * Lookup the file so that we can get a vnode for it.
1829                  */
1830                 error = VOP_LOOKUP(dvp, name, &vp, NULL, 0,
1831                     NULL, cr, NULL, NULL, NULL);


1895                  * still recover by checking the size of the file
1896                  * after it has created it and then issue a setattr
1897                  * request of its own to set the size of the file.
1898                  */
1899                 if (vap != NULL &&
1900                     (args->how.mode == UNCHECKED ||
1901                     args->how.mode == GUARDED) &&
1902                     args->how.createhow3_u.obj_attributes.size.set_it &&
1903                     vap->va_size != reqsize) {
1904                         va.va_mask = AT_SIZE;
1905                         va.va_size = reqsize;
1906                         (void) VOP_SETATTR(vp, &va, 0, cr, NULL);
1907                         va.va_mask = AT_ALL;
1908                         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
1909                 }
1910         }
1911 
1912         if (name != args->where.name)
1913                 kmem_free(name, MAXPATHLEN + 1);
1914 
1915 #ifdef DEBUG
1916         if (!rfs3_do_post_op_attr)
1917                 vap = NULL;
1918 #endif
1919 
1920 #ifdef DEBUG
1921         if (!rfs3_do_post_op_fh3)
1922                 resp->resok.obj.handle_follows = FALSE;
1923         else {
1924 #endif
1925         error = makefh3(&resp->resok.obj.handle, vp, exi);
1926         if (error)
1927                 resp->resok.obj.handle_follows = FALSE;
1928         else
1929                 resp->resok.obj.handle_follows = TRUE;
1930 #ifdef DEBUG
1931         }
1932 #endif
1933 
1934         /*
1935          * Force modified data and metadata out to stable storage.
1936          */
1937         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
1938         (void) VOP_FSYNC(dvp, 0, cr, NULL);
1939 
1940         VN_RELE(vp);
1941         if (tvp != NULL) {
1942                 if (in_crit)
1943                         nbl_end_crit(tvp);
1944                 VN_RELE(tvp);
1945         }
1946 
1947         resp->status = NFS3_OK;
1948         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
1949         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
1950 
1951         DTRACE_NFSV3_4(op__create__done, struct svc_req *, req,
1952             cred_t *, cr, vnode_t *, dvp, CREATE3res *, resp);


1996         struct vattr *dbvap;
1997         struct vattr dbva;
1998         struct vattr *davap;
1999         struct vattr dava;
2000         struct sockaddr *ca;
2001         char *name = NULL;
2002 
2003         dbvap = NULL;
2004         davap = NULL;
2005 
2006         dvp = nfs3_fhtovp(&args->where.dir, exi);
2007 
2008         DTRACE_NFSV3_4(op__mkdir__start, struct svc_req *, req,
2009             cred_t *, cr, vnode_t *, dvp, MKDIR3args *, args);
2010 
2011         if (dvp == NULL) {
2012                 error = ESTALE;
2013                 goto out;
2014         }
2015 
2016 #ifdef DEBUG
2017         if (rfs3_do_pre_op_attr) {
2018                 dbva.va_mask = AT_ALL;
2019                 dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2020         } else
2021                 dbvap = NULL;
2022 #else
2023         dbva.va_mask = AT_ALL;
2024         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2025 #endif
2026         davap = dbvap;
2027 
2028         if (args->where.name == nfs3nametoolong) {
2029                 resp->status = NFS3ERR_NAMETOOLONG;
2030                 goto out1;
2031         }
2032 
2033         if (args->where.name == NULL || *(args->where.name) == '\0') {
2034                 resp->status = NFS3ERR_ACCES;
2035                 goto out1;
2036         }
2037 
2038         if (rdonly(exi, req)) {
2039                 resp->status = NFS3ERR_ROFS;
2040                 goto out1;
2041         }
2042 
2043         if (is_system_labeled()) {
2044                 bslabel_t *clabel = req->rq_label;
2045 


2065                 goto out1;
2066         }
2067 
2068         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2069         name = nfscmd_convname(ca, exi, args->where.name,
2070             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2071 
2072         if (name == NULL) {
2073                 resp->status = NFS3ERR_INVAL;
2074                 goto out1;
2075         }
2076 
2077         va.va_mask |= AT_TYPE;
2078         va.va_type = VDIR;
2079 
2080         error = VOP_MKDIR(dvp, name, &va, &vp, cr, NULL, 0, NULL);
2081 
2082         if (name != args->where.name)
2083                 kmem_free(name, MAXPATHLEN + 1);
2084 
2085 #ifdef DEBUG
2086         if (rfs3_do_post_op_attr) {
2087                 dava.va_mask = AT_ALL;
2088                 davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2089         } else
2090                 davap = NULL;
2091 #else
2092         dava.va_mask = AT_ALL;
2093         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2094 #endif
2095 
2096         /*
2097          * Force modified data and metadata out to stable storage.
2098          */
2099         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2100 
2101         if (error)
2102                 goto out;
2103 
2104 #ifdef DEBUG
2105         if (!rfs3_do_post_op_fh3)
2106                 resp->resok.obj.handle_follows = FALSE;
2107         else {
2108 #endif
2109         error = makefh3(&resp->resok.obj.handle, vp, exi);
2110         if (error)
2111                 resp->resok.obj.handle_follows = FALSE;
2112         else
2113                 resp->resok.obj.handle_follows = TRUE;
2114 #ifdef DEBUG
2115         }
2116 #endif
2117 
2118 #ifdef DEBUG
2119         if (rfs3_do_post_op_attr) {
2120                 va.va_mask = AT_ALL;
2121                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2122         } else
2123                 vap = NULL;
2124 #else
2125         va.va_mask = AT_ALL;
2126         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2127 #endif
2128 
2129         /*
2130          * Force modified data and metadata out to stable storage.
2131          */
2132         (void) VOP_FSYNC(vp, 0, cr, NULL);
2133 
2134         VN_RELE(vp);
2135 
2136         resp->status = NFS3_OK;
2137         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2138         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2139 
2140         DTRACE_NFSV3_4(op__mkdir__done, struct svc_req *, req,
2141             cred_t *, cr, vnode_t *, dvp, MKDIR3res *, resp);
2142         VN_RELE(dvp);
2143 
2144         return;
2145 
2146 out:
2147         if (curthread->t_flag & T_WOULDBLOCK) {


2177         struct vattr dbva;
2178         struct vattr *davap;
2179         struct vattr dava;
2180         struct sockaddr *ca;
2181         char *name = NULL;
2182         char *symdata = NULL;
2183 
2184         dbvap = NULL;
2185         davap = NULL;
2186 
2187         dvp = nfs3_fhtovp(&args->where.dir, exi);
2188 
2189         DTRACE_NFSV3_4(op__symlink__start, struct svc_req *, req,
2190             cred_t *, cr, vnode_t *, dvp, SYMLINK3args *, args);
2191 
2192         if (dvp == NULL) {
2193                 error = ESTALE;
2194                 goto err;
2195         }
2196 
2197 #ifdef DEBUG
2198         if (rfs3_do_pre_op_attr) {
2199                 dbva.va_mask = AT_ALL;
2200                 dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2201         } else
2202                 dbvap = NULL;
2203 #else
2204         dbva.va_mask = AT_ALL;
2205         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2206 #endif
2207         davap = dbvap;
2208 
2209         if (args->where.name == nfs3nametoolong) {
2210                 resp->status = NFS3ERR_NAMETOOLONG;
2211                 goto err1;
2212         }
2213 
2214         if (args->where.name == NULL || *(args->where.name) == '\0') {
2215                 resp->status = NFS3ERR_ACCES;
2216                 goto err1;
2217         }
2218 
2219         if (rdonly(exi, req)) {
2220                 resp->status = NFS3ERR_ROFS;
2221                 goto err1;
2222         }
2223 
2224         if (is_system_labeled()) {
2225                 bslabel_t *clabel = req->rq_label;
2226 


2258         if (name == NULL) {
2259                 /* This is really a Solaris EILSEQ */
2260                 resp->status = NFS3ERR_INVAL;
2261                 goto err1;
2262         }
2263 
2264         symdata = nfscmd_convname(ca, exi, args->symlink.symlink_data,
2265             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2266         if (symdata == NULL) {
2267                 /* This is really a Solaris EILSEQ */
2268                 resp->status = NFS3ERR_INVAL;
2269                 goto err1;
2270         }
2271 
2272 
2273         va.va_mask |= AT_TYPE;
2274         va.va_type = VLNK;
2275 
2276         error = VOP_SYMLINK(dvp, name, &va, symdata, cr, NULL, 0);
2277 
2278 #ifdef DEBUG
2279         if (rfs3_do_post_op_attr) {
2280                 dava.va_mask = AT_ALL;
2281                 davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2282         } else
2283                 davap = NULL;
2284 #else
2285         dava.va_mask = AT_ALL;
2286         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2287 #endif
2288 
2289         if (error)
2290                 goto err;
2291 
2292         error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
2293             NULL, NULL, NULL);
2294 
2295         /*
2296          * Force modified data and metadata out to stable storage.
2297          */
2298         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2299 
2300 
2301         resp->status = NFS3_OK;
2302         if (error) {
2303                 resp->resok.obj.handle_follows = FALSE;
2304                 vattr_to_post_op_attr(NULL, &resp->resok.obj_attributes);
2305                 vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2306                 goto out;
2307         }
2308 
2309 #ifdef DEBUG
2310         if (!rfs3_do_post_op_fh3)
2311                 resp->resok.obj.handle_follows = FALSE;
2312         else {
2313 #endif
2314         error = makefh3(&resp->resok.obj.handle, vp, exi);
2315         if (error)
2316                 resp->resok.obj.handle_follows = FALSE;
2317         else
2318                 resp->resok.obj.handle_follows = TRUE;
2319 #ifdef DEBUG
2320         }
2321 #endif
2322 
2323 #ifdef DEBUG
2324         if (rfs3_do_post_op_attr) {
2325                 va.va_mask = AT_ALL;
2326                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2327         } else
2328                 vap = NULL;
2329 #else
2330         va.va_mask = AT_ALL;
2331         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2332 #endif
2333 
2334         /*
2335          * Force modified data and metadata out to stable storage.
2336          */
2337         (void) VOP_FSYNC(vp, 0, cr, NULL);
2338 
2339         VN_RELE(vp);
2340 
2341         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2342         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2343         goto out;
2344 
2345 err:
2346         if (curthread->t_flag & T_WOULDBLOCK) {
2347                 curthread->t_flag &= ~T_WOULDBLOCK;
2348                 resp->status = NFS3ERR_JUKEBOX;
2349         } else
2350                 resp->status = puterrno3(error);
2351 err1:
2352         vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);


2385         struct vattr *davap;
2386         struct vattr dava;
2387         int mode;
2388         enum vcexcl excl;
2389         struct sockaddr *ca;
2390         char *name = NULL;
2391 
2392         dbvap = NULL;
2393         davap = NULL;
2394 
2395         dvp = nfs3_fhtovp(&args->where.dir, exi);
2396 
2397         DTRACE_NFSV3_4(op__mknod__start, struct svc_req *, req,
2398             cred_t *, cr, vnode_t *, dvp, MKNOD3args *, args);
2399 
2400         if (dvp == NULL) {
2401                 error = ESTALE;
2402                 goto out;
2403         }
2404 
2405 #ifdef DEBUG
2406         if (rfs3_do_pre_op_attr) {
2407                 dbva.va_mask = AT_ALL;
2408                 dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2409         } else
2410                 dbvap = NULL;
2411 #else
2412         dbva.va_mask = AT_ALL;
2413         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;
2414 #endif
2415         davap = dbvap;
2416 
2417         if (args->where.name == nfs3nametoolong) {
2418                 resp->status = NFS3ERR_NAMETOOLONG;
2419                 goto out1;
2420         }
2421 
2422         if (args->where.name == NULL || *(args->where.name) == '\0') {
2423                 resp->status = NFS3ERR_ACCES;
2424                 goto out1;
2425         }
2426 
2427         if (rdonly(exi, req)) {
2428                 resp->status = NFS3ERR_ROFS;
2429                 goto out1;
2430         }
2431 
2432         if (is_system_labeled()) {
2433                 bslabel_t *clabel = req->rq_label;
2434 


2496 
2497         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2498         name = nfscmd_convname(ca, exi, args->where.name,
2499             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2500 
2501         if (name == NULL) {
2502                 resp->status = NFS3ERR_INVAL;
2503                 goto out1;
2504         }
2505 
2506         excl = EXCL;
2507 
2508         mode = 0;
2509 
2510         error = VOP_CREATE(dvp, name, &va, excl, mode,
2511             &vp, cr, 0, NULL, NULL);
2512 
2513         if (name != args->where.name)
2514                 kmem_free(name, MAXPATHLEN + 1);
2515 
2516 #ifdef DEBUG
2517         if (rfs3_do_post_op_attr) {
2518                 dava.va_mask = AT_ALL;
2519                 davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2520         } else
2521                 davap = NULL;
2522 #else
2523         dava.va_mask = AT_ALL;
2524         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;
2525 #endif
2526 
2527         /*
2528          * Force modified data and metadata out to stable storage.
2529          */
2530         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2531 
2532         if (error)
2533                 goto out;
2534 
2535         resp->status = NFS3_OK;
2536 
2537 #ifdef DEBUG
2538         if (!rfs3_do_post_op_fh3)
2539                 resp->resok.obj.handle_follows = FALSE;
2540         else {
2541 #endif
2542         error = makefh3(&resp->resok.obj.handle, vp, exi);
2543         if (error)
2544                 resp->resok.obj.handle_follows = FALSE;
2545         else
2546                 resp->resok.obj.handle_follows = TRUE;
2547 #ifdef DEBUG
2548         }
2549 #endif
2550 
2551 #ifdef DEBUG
2552         if (rfs3_do_post_op_attr) {
2553                 va.va_mask = AT_ALL;
2554                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2555         } else
2556                 vap = NULL;
2557 #else
2558         va.va_mask = AT_ALL;
2559         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
2560 #endif
2561 
2562         /*
2563          * Force modified metadata out to stable storage.
2564          *
2565          * if a underlying vp exists, pass it to VOP_FSYNC
2566          */
2567         if (VOP_REALVP(vp, &realvp, NULL) == 0)
2568                 (void) VOP_FSYNC(realvp, FNODSYNC, cr, NULL);
2569         else
2570                 (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
2571 
2572         VN_RELE(vp);
2573 
2574         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2575         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2576         DTRACE_NFSV3_4(op__mknod__done, struct svc_req *, req,
2577             cred_t *, cr, vnode_t *, dvp, MKNOD3res *, resp);
2578         VN_RELE(dvp);
2579         return;
2580 


2609         struct vattr bva;
2610         struct vattr *avap;
2611         struct vattr ava;
2612         vnode_t *targvp = NULL;
2613         struct sockaddr *ca;
2614         char *name = NULL;
2615 
2616         bvap = NULL;
2617         avap = NULL;
2618 
2619         vp = nfs3_fhtovp(&args->object.dir, exi);
2620 
2621         DTRACE_NFSV3_4(op__remove__start, struct svc_req *, req,
2622             cred_t *, cr, vnode_t *, vp, REMOVE3args *, args);
2623 
2624         if (vp == NULL) {
2625                 error = ESTALE;
2626                 goto err;
2627         }
2628 
2629 #ifdef DEBUG
2630         if (rfs3_do_pre_op_attr) {
2631                 bva.va_mask = AT_ALL;
2632                 bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;
2633         } else
2634                 bvap = NULL;
2635 #else
2636         bva.va_mask = AT_ALL;
2637         bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;
2638 #endif
2639         avap = bvap;
2640 
2641         if (vp->v_type != VDIR) {
2642                 resp->status = NFS3ERR_NOTDIR;
2643                 goto err1;
2644         }
2645 
2646         if (args->object.name == nfs3nametoolong) {
2647                 resp->status = NFS3ERR_NAMETOOLONG;
2648                 goto err1;
2649         }
2650 
2651         if (args->object.name == NULL || *(args->object.name) == '\0') {
2652                 resp->status = NFS3ERR_ACCES;
2653                 goto err1;
2654         }
2655 
2656         if (rdonly(exi, req)) {
2657                 resp->status = NFS3ERR_ROFS;
2658                 goto err1;


2694 
2695         if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
2696                 resp->status = NFS3ERR_JUKEBOX;
2697                 goto err1;
2698         }
2699 
2700         if (!nbl_need_check(targvp)) {
2701                 error = VOP_REMOVE(vp, name, cr, NULL, 0);
2702         } else {
2703                 nbl_start_crit(targvp, RW_READER);
2704                 if (nbl_conflict(targvp, NBL_REMOVE, 0, 0, 0, NULL)) {
2705                         error = EACCES;
2706                 } else {
2707                         error = VOP_REMOVE(vp, name, cr, NULL, 0);
2708                 }
2709                 nbl_end_crit(targvp);
2710         }
2711         VN_RELE(targvp);
2712         targvp = NULL;
2713 
2714 #ifdef DEBUG
2715         if (rfs3_do_post_op_attr) {
2716                 ava.va_mask = AT_ALL;
2717                 avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2718         } else
2719                 avap = NULL;
2720 #else
2721         ava.va_mask = AT_ALL;
2722         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2723 #endif
2724 
2725         /*
2726          * Force modified data and metadata out to stable storage.
2727          */
2728         (void) VOP_FSYNC(vp, 0, cr, NULL);
2729 
2730         if (error)
2731                 goto err;
2732 
2733         resp->status = NFS3_OK;
2734         vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);
2735         goto out;
2736 
2737 err:
2738         if (curthread->t_flag & T_WOULDBLOCK) {
2739                 curthread->t_flag &= ~T_WOULDBLOCK;
2740                 resp->status = NFS3ERR_JUKEBOX;
2741         } else
2742                 resp->status = puterrno3(error);
2743 err1:


2769         struct vattr *bvap;
2770         struct vattr bva;
2771         struct vattr *avap;
2772         struct vattr ava;
2773         struct sockaddr *ca;
2774         char *name = NULL;
2775 
2776         bvap = NULL;
2777         avap = NULL;
2778 
2779         vp = nfs3_fhtovp(&args->object.dir, exi);
2780 
2781         DTRACE_NFSV3_4(op__rmdir__start, struct svc_req *, req,
2782             cred_t *, cr, vnode_t *, vp, RMDIR3args *, args);
2783 
2784         if (vp == NULL) {
2785                 error = ESTALE;
2786                 goto err;
2787         }
2788 
2789 #ifdef DEBUG
2790         if (rfs3_do_pre_op_attr) {
2791                 bva.va_mask = AT_ALL;
2792                 bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;
2793         } else
2794                 bvap = NULL;
2795 #else
2796         bva.va_mask = AT_ALL;
2797         bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;
2798 #endif
2799         avap = bvap;
2800 
2801         if (vp->v_type != VDIR) {
2802                 resp->status = NFS3ERR_NOTDIR;
2803                 goto err1;
2804         }
2805 
2806         if (args->object.name == nfs3nametoolong) {
2807                 resp->status = NFS3ERR_NAMETOOLONG;
2808                 goto err1;
2809         }
2810 
2811         if (args->object.name == NULL || *(args->object.name) == '\0') {
2812                 resp->status = NFS3ERR_ACCES;
2813                 goto err1;
2814         }
2815 
2816         if (rdonly(exi, req)) {
2817                 resp->status = NFS3ERR_ROFS;
2818                 goto err1;


2831                                 resp->status = NFS3ERR_ACCES;
2832                                 goto err1;
2833                         }
2834                 }
2835         }
2836 
2837         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2838         name = nfscmd_convname(ca, exi, args->object.name,
2839             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2840 
2841         if (name == NULL) {
2842                 resp->status = NFS3ERR_INVAL;
2843                 goto err1;
2844         }
2845 
2846         error = VOP_RMDIR(vp, name, rootdir, cr, NULL, 0);
2847 
2848         if (name != args->object.name)
2849                 kmem_free(name, MAXPATHLEN + 1);
2850 
2851 #ifdef DEBUG
2852         if (rfs3_do_post_op_attr) {
2853                 ava.va_mask = AT_ALL;
2854                 avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2855         } else
2856                 avap = NULL;
2857 #else
2858         ava.va_mask = AT_ALL;
2859         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
2860 #endif
2861 
2862         /*
2863          * Force modified data and metadata out to stable storage.
2864          */
2865         (void) VOP_FSYNC(vp, 0, cr, NULL);
2866 
2867         if (error) {
2868                 /*
2869                  * System V defines rmdir to return EEXIST, not ENOTEMPTY,
2870                  * if the directory is not empty.  A System V NFS server
2871                  * needs to map NFS3ERR_EXIST to NFS3ERR_NOTEMPTY to transmit
2872                  * over the wire.
2873                  */
2874                 if (error == EEXIST)
2875                         error = ENOTEMPTY;
2876                 goto err;
2877         }
2878 
2879         resp->status = NFS3_OK;
2880         vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);


2941         if (fvp == NULL) {
2942                 error = ESTALE;
2943                 goto err;
2944         }
2945 
2946         if (is_system_labeled()) {
2947                 clabel = req->rq_label;
2948                 ASSERT(clabel != NULL);
2949                 DTRACE_PROBE2(tx__rfs3__log__info__oprename__clabel, char *,
2950                     "got client label from request(1)", struct svc_req *, req);
2951 
2952                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2953                         if (!do_rfs_label_check(clabel, fvp, EQUALITY_CHECK,
2954                             exi)) {
2955                                 resp->status = NFS3ERR_ACCES;
2956                                 goto err1;
2957                         }
2958                 }
2959         }
2960 
2961 #ifdef DEBUG
2962         if (rfs3_do_pre_op_attr) {
2963                 fbva.va_mask = AT_ALL;
2964                 fbvap = VOP_GETATTR(fvp, &fbva, 0, cr, NULL) ? NULL : &fbva;
2965         } else
2966                 fbvap = NULL;
2967 #else
2968         fbva.va_mask = AT_ALL;
2969         fbvap = VOP_GETATTR(fvp, &fbva, 0, cr, NULL) ? NULL : &fbva;
2970 #endif
2971         favap = fbvap;
2972 
2973         fh3 = &args->to.dir;
2974         to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
2975         if (to_exi == NULL) {
2976                 resp->status = NFS3ERR_ACCES;
2977                 goto err1;
2978         }
2979         exi_rele(to_exi);
2980 
2981         if (to_exi != exi) {
2982                 resp->status = NFS3ERR_XDEV;
2983                 goto err1;
2984         }
2985 
2986         tvp = nfs3_fhtovp(&args->to.dir, exi);
2987         if (tvp == NULL) {
2988                 error = ESTALE;
2989                 goto err;
2990         }
2991 
2992 #ifdef DEBUG
2993         if (rfs3_do_pre_op_attr) {
2994                 tbva.va_mask = AT_ALL;
2995                 tbvap = VOP_GETATTR(tvp, &tbva, 0, cr, NULL) ? NULL : &tbva;
2996         } else
2997                 tbvap = NULL;
2998 #else
2999         tbva.va_mask = AT_ALL;
3000         tbvap = VOP_GETATTR(tvp, &tbva, 0, cr, NULL) ? NULL : &tbva;
3001 #endif
3002         tavap = tbvap;
3003 
3004         if (fvp->v_type != VDIR || tvp->v_type != VDIR) {
3005                 resp->status = NFS3ERR_NOTDIR;
3006                 goto err1;
3007         }
3008 
3009         if (args->from.name == nfs3nametoolong ||
3010             args->to.name == nfs3nametoolong) {
3011                 resp->status = NFS3ERR_NAMETOOLONG;
3012                 goto err1;
3013         }
3014         if (args->from.name == NULL || *(args->from.name) == '\0' ||
3015             args->to.name == NULL || *(args->to.name) == '\0') {
3016                 resp->status = NFS3ERR_ACCES;
3017                 goto err1;
3018         }
3019 
3020         if (rdonly(exi, req)) {
3021                 resp->status = NFS3ERR_ROFS;


3083                 }
3084                 VN_RELE(targvp);
3085         }
3086 
3087         if (!nbl_need_check(srcvp)) {
3088                 error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
3089         } else {
3090                 nbl_start_crit(srcvp, RW_READER);
3091                 if (nbl_conflict(srcvp, NBL_RENAME, 0, 0, 0, NULL))
3092                         error = EACCES;
3093                 else
3094                         error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
3095                 nbl_end_crit(srcvp);
3096         }
3097         if (error == 0)
3098                 vn_renamepath(tvp, srcvp, args->to.name,
3099                     strlen(args->to.name));
3100         VN_RELE(srcvp);
3101         srcvp = NULL;
3102 
3103 #ifdef DEBUG
3104         if (rfs3_do_post_op_attr) {
3105                 fava.va_mask = AT_ALL;
3106                 favap = VOP_GETATTR(fvp, &fava, 0, cr, NULL) ? NULL : &fava;
3107                 tava.va_mask = AT_ALL;
3108                 tavap = VOP_GETATTR(tvp, &tava, 0, cr, NULL) ? NULL : &tava;
3109         } else {
3110                 favap = NULL;
3111                 tavap = NULL;
3112         }
3113 #else
3114         fava.va_mask = AT_ALL;
3115         favap = VOP_GETATTR(fvp, &fava, 0, cr, NULL) ? NULL : &fava;
3116         tava.va_mask = AT_ALL;
3117         tavap = VOP_GETATTR(tvp, &tava, 0, cr, NULL) ? NULL : &tava;
3118 #endif
3119 
3120         /*
3121          * Force modified data and metadata out to stable storage.
3122          */
3123         (void) VOP_FSYNC(fvp, 0, cr, NULL);
3124         (void) VOP_FSYNC(tvp, 0, cr, NULL);
3125 
3126         if (error)
3127                 goto err;
3128 
3129         resp->status = NFS3_OK;
3130         vattr_to_wcc_data(fbvap, favap, &resp->resok.fromdir_wcc);
3131         vattr_to_wcc_data(tbvap, tavap, &resp->resok.todir_wcc);
3132         goto out;
3133 
3134 err:
3135         if (curthread->t_flag & T_WOULDBLOCK) {
3136                 curthread->t_flag &= ~T_WOULDBLOCK;
3137                 resp->status = NFS3ERR_JUKEBOX;
3138         } else {


3180         struct exportinfo *to_exi;
3181         bslabel_t *clabel;
3182         struct sockaddr *ca;
3183         char *name = NULL;
3184 
3185         vap = NULL;
3186         bvap = NULL;
3187         avap = NULL;
3188         dvp = NULL;
3189 
3190         vp = nfs3_fhtovp(&args->file, exi);
3191 
3192         DTRACE_NFSV3_4(op__link__start, struct svc_req *, req,
3193             cred_t *, cr, vnode_t *, vp, LINK3args *, args);
3194 
3195         if (vp == NULL) {
3196                 error = ESTALE;
3197                 goto out;
3198         }
3199 
3200 #ifdef DEBUG
3201         if (rfs3_do_pre_op_attr) {
3202                 va.va_mask = AT_ALL;
3203                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3204         } else
3205                 vap = NULL;
3206 #else
3207         va.va_mask = AT_ALL;
3208         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3209 #endif
3210 
3211         fh3 = &args->link.dir;
3212         to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
3213         if (to_exi == NULL) {
3214                 resp->status = NFS3ERR_ACCES;
3215                 goto out1;
3216         }
3217         exi_rele(to_exi);
3218 
3219         if (to_exi != exi) {
3220                 resp->status = NFS3ERR_XDEV;
3221                 goto out1;
3222         }
3223 
3224         if (is_system_labeled()) {
3225                 clabel = req->rq_label;
3226 
3227                 ASSERT(clabel != NULL);
3228                 DTRACE_PROBE2(tx__rfs3__log__info__oplink__clabel, char *,
3229                     "got client label from request(1)", struct svc_req *, req);
3230 
3231                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3232                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3233                             exi)) {
3234                                 resp->status = NFS3ERR_ACCES;
3235                                 goto out1;
3236                         }
3237                 }
3238         }
3239 
3240         dvp = nfs3_fhtovp(&args->link.dir, exi);
3241         if (dvp == NULL) {
3242                 error = ESTALE;
3243                 goto out;
3244         }
3245 
3246 #ifdef DEBUG
3247         if (rfs3_do_pre_op_attr) {
3248                 bva.va_mask = AT_ALL;
3249                 bvap = VOP_GETATTR(dvp, &bva, 0, cr, NULL) ? NULL : &bva;
3250         } else
3251                 bvap = NULL;
3252 #else
3253         bva.va_mask = AT_ALL;
3254         bvap = VOP_GETATTR(dvp, &bva, 0, cr, NULL) ? NULL : &bva;
3255 #endif
3256 
3257         if (dvp->v_type != VDIR) {
3258                 resp->status = NFS3ERR_NOTDIR;
3259                 goto out1;
3260         }
3261 
3262         if (args->link.name == nfs3nametoolong) {
3263                 resp->status = NFS3ERR_NAMETOOLONG;
3264                 goto out1;
3265         }
3266 
3267         if (args->link.name == NULL || *(args->link.name) == '\0') {
3268                 resp->status = NFS3ERR_ACCES;
3269                 goto out1;
3270         }
3271 
3272         if (rdonly(exi, req)) {
3273                 resp->status = NFS3ERR_ROFS;
3274                 goto out1;
3275         }


3281                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3282                         if (!do_rfs_label_check(clabel, dvp, EQUALITY_CHECK,
3283                             exi)) {
3284                                 resp->status = NFS3ERR_ACCES;
3285                                 goto out1;
3286                         }
3287                 }
3288         }
3289 
3290         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
3291         name = nfscmd_convname(ca, exi, args->link.name,
3292             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
3293 
3294         if (name == NULL) {
3295                 resp->status = NFS3ERR_SERVERFAULT;
3296                 goto out1;
3297         }
3298 
3299         error = VOP_LINK(dvp, vp, name, cr, NULL, 0);
3300 
3301 #ifdef DEBUG
3302         if (rfs3_do_post_op_attr) {
3303                 va.va_mask = AT_ALL;
3304                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3305                 ava.va_mask = AT_ALL;
3306                 avap = VOP_GETATTR(dvp, &ava, 0, cr, NULL) ? NULL : &ava;
3307         } else {
3308                 vap = NULL;
3309                 avap = NULL;
3310         }
3311 #else
3312         va.va_mask = AT_ALL;
3313         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3314         ava.va_mask = AT_ALL;
3315         avap = VOP_GETATTR(dvp, &ava, 0, cr, NULL) ? NULL : &ava;
3316 #endif
3317 
3318         /*
3319          * Force modified data and metadata out to stable storage.
3320          */
3321         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
3322         (void) VOP_FSYNC(dvp, 0, cr, NULL);
3323 
3324         if (error)
3325                 goto out;
3326 
3327         VN_RELE(dvp);
3328 
3329         resp->status = NFS3_OK;
3330         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
3331         vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
3332 
3333         DTRACE_NFSV3_4(op__link__done, struct svc_req *, req,
3334             cred_t *, cr, vnode_t *, vp, LINK3res *, resp);
3335 
3336         VN_RELE(vp);


3425         }
3426 
3427         if (is_system_labeled()) {
3428                 bslabel_t *clabel = req->rq_label;
3429 
3430                 ASSERT(clabel != NULL);
3431                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddir__clabel, char *,
3432                     "got client label from request(1)", struct svc_req *, req);
3433 
3434                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3435                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3436                             exi)) {
3437                                 resp->status = NFS3ERR_ACCES;
3438                                 goto out1;
3439                         }
3440                 }
3441         }
3442 
3443         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3444 
3445 #ifdef DEBUG
3446         if (rfs3_do_pre_op_attr) {
3447                 va.va_mask = AT_ALL;
3448                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3449         } else
3450                 vap = NULL;
3451 #else
3452         va.va_mask = AT_ALL;
3453         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3454 #endif
3455 
3456         if (vp->v_type != VDIR) {
3457                 resp->status = NFS3ERR_NOTDIR;
3458                 goto out1;
3459         }
3460 
3461         error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
3462         if (error)
3463                 goto out;
3464 
3465         /*
3466          * Now don't allow arbitrary count to alloc;
3467          * allow the maximum not to exceed rfs3_tsize()
3468          */
3469         if (args->count > rfs3_tsize(req))
3470                 args->count = rfs3_tsize(req);
3471 
3472         /*
3473          * Make sure that there is room to read at least one entry
3474          * if any are available.
3475          */
3476         if (args->count < DIRENT64_RECLEN(MAXNAMELEN))
3477                 count = DIRENT64_RECLEN(MAXNAMELEN);
3478         else
3479                 count = args->count;
3480 
3481         data = kmem_alloc(count, KM_SLEEP);
3482 
3483         iov.iov_base = data;
3484         iov.iov_len = count;
3485         uio.uio_iov = &iov;
3486         uio.uio_iovcnt = 1;
3487         uio.uio_segflg = UIO_SYSSPACE;
3488         uio.uio_extflg = UIO_COPY_CACHED;
3489         uio.uio_loffset = (offset_t)args->cookie;
3490         uio.uio_resid = count;
3491 
3492         error = VOP_READDIR(vp, &uio, cr, &iseof, NULL, 0);
3493 
3494 #ifdef DEBUG
3495         if (rfs3_do_post_op_attr) {
3496                 va.va_mask = AT_ALL;
3497                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3498         } else
3499                 vap = NULL;
3500 #else
3501         va.va_mask = AT_ALL;
3502         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3503 #endif
3504 
3505         if (error) {
3506                 kmem_free(data, count);
3507                 goto out;
3508         }
3509 
3510         /*
3511          * If the count was not large enough to be able to guarantee
3512          * to be able to return at least one entry, then need to
3513          * check to see if NFS3ERR_TOOSMALL should be returned.
3514          */
3515         if (args->count < NFS3_READDIR_MIN_COUNT(MAXNAMELEN)) {
3516                 /*
3517                  * bufsize is used to keep track of the size of the response.
3518                  * It is primed with:
3519                  *      1 for the status +
3520                  *      1 for the dir_attributes.attributes boolean +
3521                  *      2 for the cookie verifier
3522                  * all times BYTES_PER_XDR_UNIT to convert from XDR units
3523                  * to bytes.  If there are directory attributes to be


3713 
3714         if (is_system_labeled()) {
3715                 bslabel_t *clabel = req->rq_label;
3716 
3717                 ASSERT(clabel != NULL);
3718                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddirplus__clabel,
3719                     char *, "got client label from request(1)",
3720                     struct svc_req *, req);
3721 
3722                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3723                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3724                             exi)) {
3725                                 resp->status = NFS3ERR_ACCES;
3726                                 goto out1;
3727                         }
3728                 }
3729         }
3730 
3731         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3732 
3733 #ifdef DEBUG
3734         if (rfs3_do_pre_op_attr) {
3735                 va.va_mask = AT_ALL;
3736                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3737         } else
3738                 vap = NULL;
3739 #else
3740         va.va_mask = AT_ALL;
3741         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3742 #endif
3743 
3744         if (vp->v_type != VDIR) {
3745                 error = ENOTDIR;
3746                 goto out;
3747         }
3748 
3749         error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
3750         if (error)
3751                 goto out;
3752 
3753         /*
3754          * Don't allow arbitrary counts for allocation
3755          */
3756         if (args->maxcount > rfs3_tsize(req))
3757                 args->maxcount = rfs3_tsize(req);
3758 
3759         /*
3760          * Make sure that there is room to read at least one entry
3761          * if any are available
3762          */


3881                         iseof = FALSE;
3882                         goto good;
3883                 }
3884                 bufsize += entrysize;
3885                 nents++;
3886         }
3887 
3888         /*
3889          * If there is enough room to fit at least 1 more entry including
3890          * post op attributes and filehandle in the buffer AND that we haven't
3891          * exceeded dircount then go back and get some more.
3892          */
3893         if (!iseof &&
3894             (args->maxcount - bufsize) >= NFS3_READDIRPLUS_ENTRY(MAXNAMELEN)) {
3895                 space_left -= (prev_len - uio.uio_resid);
3896                 if (space_left >= DIRENT64_RECLEN(MAXNAMELEN))
3897                         goto getmoredents;
3898 
3899                 /* else, fall through */
3900         }
3901 
3902 good:
3903 
3904 #ifdef DEBUG
3905         if (rfs3_do_post_op_attr) {
3906                 va.va_mask = AT_ALL;
3907                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3908         } else
3909                 vap = NULL;
3910 #else
3911         va.va_mask = AT_ALL;
3912         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3913 #endif
3914 
3915         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
3916 
3917         infop = kmem_alloc(nents * sizeof (struct entryplus3_info), KM_SLEEP);
3918         resp->resok.infop = infop;
3919 
3920         dp = (struct dirent64 *)data;
3921         for (i = 0; i < nents; i++) {
3922 
3923                 if (dp->d_ino == 0) {
3924                         infop[i].attr.attributes = FALSE;
3925                         infop[i].fh.handle_follows = FALSE;
3926                         dp = nextdp(dp);
3927                         continue;
3928                 }
3929 
3930                 infop[i].namelen = namlen[i];
3931 
3932                 error = VOP_LOOKUP(vp, dp->d_name, &nvp, NULL, 0, NULL, cr,
3933                     NULL, NULL, NULL);
3934                 if (error) {
3935                         infop[i].attr.attributes = FALSE;
3936                         infop[i].fh.handle_follows = FALSE;
3937                         dp = nextdp(dp);
3938                         continue;
3939                 }
3940 
3941 #ifdef DEBUG
3942                 if (rfs3_do_post_op_attr) {
3943                         nva.va_mask = AT_ALL;
3944                         nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ?
3945                             NULL : &nva;
3946                 } else
3947                         nvap = NULL;
3948 #else
3949                 nva.va_mask = AT_ALL;
3950                 nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ? NULL : &nva;
3951 #endif
3952                 /* Lie about the object type for a referral */
3953                 if (vn_is_nfs_reparse(nvp, cr))
3954                         nvap->va_type = VLNK;
3955 




3956                 vattr_to_post_op_attr(nvap, &infop[i].attr);
3957 
3958 #ifdef DEBUG
3959                 if (!rfs3_do_post_op_fh3)
3960                         infop[i].fh.handle_follows = FALSE;
3961                 else {
3962 #endif
3963                 error = makefh3(&infop[i].fh.handle, nvp, exi);
3964                 if (!error)
3965                         infop[i].fh.handle_follows = TRUE;
3966                 else
3967                         infop[i].fh.handle_follows = FALSE;
3968 #ifdef DEBUG
3969                 }
3970 #endif
3971 
3972                 VN_RELE(nvp);
3973                 dp = nextdp(dp);
3974         }
3975 
3976         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
3977         ret = nfscmd_convdirplus(ca, exi, data, nents, args->dircount, &ndata);
3978         if (ndata == NULL)
3979                 ndata = data;
3980 
3981         if (ret > 0) {
3982                 /*
3983                  * We had to drop one or more entries in order to fit
3984                  * during the character conversion.  We need to patch
3985                  * up the size and eof info.
3986                  */
3987                 if (iseof)
3988                         iseof = FALSE;
3989 
3990                 ret = nfscmd_dropped_entrysize((struct dirent64 *)data,


4089         }
4090 
4091         if (is_system_labeled()) {
4092                 bslabel_t *clabel = req->rq_label;
4093 
4094                 ASSERT(clabel != NULL);
4095                 DTRACE_PROBE2(tx__rfs3__log__info__opfsstat__clabel, char *,
4096                     "got client label from request(1)", struct svc_req *, req);
4097 
4098                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4099                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
4100                             exi)) {
4101                                 resp->status = NFS3ERR_ACCES;
4102                                 goto out1;
4103                         }
4104                 }
4105         }
4106 
4107         error = VFS_STATVFS(vp->v_vfsp, &sb);
4108 
4109 #ifdef DEBUG
4110         if (rfs3_do_post_op_attr) {
4111                 va.va_mask = AT_ALL;
4112                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4113         } else
4114                 vap = NULL;
4115 #else
4116         va.va_mask = AT_ALL;
4117         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4118 #endif
4119 
4120         if (error)
4121                 goto out;
4122 
4123         resp->status = NFS3_OK;
4124         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
4125         if (sb.f_blocks != (fsblkcnt64_t)-1)
4126                 resp->resok.tbytes = (size3)sb.f_frsize * (size3)sb.f_blocks;
4127         else
4128                 resp->resok.tbytes = (size3)sb.f_blocks;
4129         if (sb.f_bfree != (fsblkcnt64_t)-1)
4130                 resp->resok.fbytes = (size3)sb.f_frsize * (size3)sb.f_bfree;
4131         else
4132                 resp->resok.fbytes = (size3)sb.f_bfree;
4133         if (sb.f_bavail != (fsblkcnt64_t)-1)
4134                 resp->resok.abytes = (size3)sb.f_frsize * (size3)sb.f_bavail;
4135         else
4136                 resp->resok.abytes = (size3)sb.f_bavail;
4137         resp->resok.tfiles = (size3)sb.f_files;
4138         resp->resok.ffiles = (size3)sb.f_ffree;


4194         }
4195 
4196         if (is_system_labeled()) {
4197                 bslabel_t *clabel = req->rq_label;
4198 
4199                 ASSERT(clabel != NULL);
4200                 DTRACE_PROBE2(tx__rfs3__log__info__opfsinfo__clabel, char *,
4201                     "got client label from request(1)", struct svc_req *, req);
4202 
4203                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4204                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
4205                             exi)) {
4206                                 resp->status = NFS3ERR_STALE;
4207                                 vattr_to_post_op_attr(NULL,
4208                                     &resp->resfail.obj_attributes);
4209                                 goto out;
4210                         }
4211                 }
4212         }
4213 
4214 #ifdef DEBUG
4215         if (rfs3_do_post_op_attr) {
4216                 va.va_mask = AT_ALL;
4217                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4218         } else
4219                 vap = NULL;
4220 #else
4221         va.va_mask = AT_ALL;
4222         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4223 #endif
4224 
4225         resp->status = NFS3_OK;
4226         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
4227         xfer_size = rfs3_tsize(req);
4228         resp->resok.rtmax = xfer_size;
4229         resp->resok.rtpref = xfer_size;
4230         resp->resok.rtmult = DEV_BSIZE;
4231         resp->resok.wtmax = xfer_size;
4232         resp->resok.wtpref = xfer_size;
4233         resp->resok.wtmult = DEV_BSIZE;
4234         resp->resok.dtpref = MAXBSIZE;
4235 
4236         /*
4237          * Large file spec: want maxfilesize based on limit of
4238          * underlying filesystem.  We can guess 2^31-1 if need be.
4239          */
4240         error = VOP_PATHCONF(vp, _PC_FILESIZEBITS, &l, cr, NULL);
4241         if (error) {
4242                 resp->status = puterrno3(error);
4243                 goto out;


4306                 error = ESTALE;
4307                 goto out;
4308         }
4309 
4310         if (is_system_labeled()) {
4311                 bslabel_t *clabel = req->rq_label;
4312 
4313                 ASSERT(clabel != NULL);
4314                 DTRACE_PROBE2(tx__rfs3__log__info__oppathconf__clabel, char *,
4315                     "got client label from request(1)", struct svc_req *, req);
4316 
4317                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4318                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
4319                             exi)) {
4320                                 resp->status = NFS3ERR_ACCES;
4321                                 goto out1;
4322                         }
4323                 }
4324         }
4325 
4326 #ifdef DEBUG
4327         if (rfs3_do_post_op_attr) {
4328                 va.va_mask = AT_ALL;
4329                 vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4330         } else
4331                 vap = NULL;
4332 #else
4333         va.va_mask = AT_ALL;
4334         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
4335 #endif
4336 
4337         error = VOP_PATHCONF(vp, _PC_LINK_MAX, &val, cr, NULL);
4338         if (error)
4339                 goto out;
4340         resp->resok.info.link_max = (uint32)val;
4341 
4342         error = VOP_PATHCONF(vp, _PC_NAME_MAX, &val, cr, NULL);
4343         if (error)
4344                 goto out;
4345         resp->resok.info.name_max = (uint32)val;
4346 
4347         error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &val, cr, NULL);
4348         if (error)
4349                 goto out;
4350         if (val == 1)
4351                 resp->resok.info.no_trunc = TRUE;
4352         else
4353                 resp->resok.info.no_trunc = FALSE;
4354 
4355         error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &val, cr, NULL);


4407         vp = nfs3_fhtovp(&args->file, exi);
4408 
4409         DTRACE_NFSV3_4(op__commit__start, struct svc_req *, req,
4410             cred_t *, cr, vnode_t *, vp, COMMIT3args *, args);
4411 
4412         if (vp == NULL) {
4413                 error = ESTALE;
4414                 goto out;
4415         }
4416 
4417         bva.va_mask = AT_ALL;
4418         error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4419 
4420         /*
4421          * If we can't get the attributes, then we can't do the
4422          * right access checking.  So, we'll fail the request.
4423          */
4424         if (error)
4425                 goto out;
4426 
4427 #ifdef DEBUG
4428         if (rfs3_do_pre_op_attr)
4429                 bvap = &bva;
4430         else
4431                 bvap = NULL;
4432 #else
4433         bvap = &bva;
4434 #endif
4435 
4436         if (rdonly(exi, req)) {
4437                 resp->status = NFS3ERR_ROFS;
4438                 goto out1;
4439         }
4440 
4441         if (vp->v_type != VREG) {
4442                 resp->status = NFS3ERR_INVAL;
4443                 goto out1;
4444         }
4445 
4446         if (is_system_labeled()) {
4447                 bslabel_t *clabel = req->rq_label;
4448 
4449                 ASSERT(clabel != NULL);
4450                 DTRACE_PROBE2(tx__rfs3__log__info__opcommit__clabel, char *,
4451                     "got client label from request(1)", struct svc_req *, req);
4452 
4453                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4454                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
4455                             exi)) {
4456                                 resp->status = NFS3ERR_ACCES;
4457                                 goto out1;
4458                         }
4459                 }
4460         }
4461 
4462         if (crgetuid(cr) != bva.va_uid &&
4463             (error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL)))
4464                 goto out;
4465 
4466         error = VOP_FSYNC(vp, FSYNC, cr, NULL);
4467 
4468 #ifdef DEBUG
4469         if (rfs3_do_post_op_attr) {
4470                 ava.va_mask = AT_ALL;
4471                 avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
4472         } else
4473                 avap = NULL;
4474 #else
4475         ava.va_mask = AT_ALL;
4476         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;
4477 #endif
4478 
4479         if (error)
4480                 goto out;
4481 
4482         resp->status = NFS3_OK;
4483         vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
4484         resp->resok.verf = write3verf;
4485 
4486         DTRACE_NFSV3_4(op__commit__done, struct svc_req *, req,
4487             cred_t *, cr, vnode_t *, vp, COMMIT3res *, resp);
4488 
4489         VN_RELE(vp);
4490 
4491         return;
4492 
4493 out:
4494         if (curthread->t_flag & T_WOULDBLOCK) {
4495                 curthread->t_flag &= ~T_WOULDBLOCK;
4496                 resp->status = NFS3ERR_JUKEBOX;
4497         } else




  54 #include <nfs/nfs.h>
  55 #include <nfs/export.h>
  56 #include <nfs/nfs_cmd.h>
  57 
  58 #include <sys/strsubr.h>
  59 
  60 #include <sys/tsol/label.h>
  61 #include <sys/tsol/tndb.h>
  62 
  63 #include <sys/zone.h>
  64 
  65 #include <inet/ip.h>
  66 #include <inet/ip6.h>
  67 
  68 /*
  69  * These are the interface routines for the server side of the
  70  * Network File System.  See the NFS version 3 protocol specification
  71  * for a description of this interface.
  72  */
  73 






  74 static writeverf3 write3verf;
  75 
  76 static int      sattr3_to_vattr(sattr3 *, struct vattr *);
  77 static int      vattr_to_fattr3(struct vattr *, fattr3 *);
  78 static int      vattr_to_wcc_attr(struct vattr *, wcc_attr *);
  79 static void     vattr_to_pre_op_attr(struct vattr *, pre_op_attr *);
  80 static void     vattr_to_wcc_data(struct vattr *, struct vattr *, wcc_data *);
  81 static int      rdma_setup_read_data3(READ3args *, READ3resok *);
  82 
  83 extern int nfs_loaned_buffers;
  84 
  85 u_longlong_t nfs3_srv_caller_id;
  86 
  87 /* ARGSUSED */
  88 void
  89 rfs3_getattr(GETATTR3args *args, GETATTR3res *resp, struct exportinfo *exi,
  90         struct svc_req *req, cred_t *cr)
  91 {
  92         int error;
  93         vnode_t *vp;


 204          * delegated this file.  If so, then we return JUKEBOX to
 205          * allow the client to retrasmit its request.
 206          */
 207         if (vp->v_type == VREG && (ava.va_mask & AT_SIZE)) {
 208                 if (nbl_need_check(vp)) {
 209                         nbl_start_crit(vp, RW_READER);
 210                         in_crit = 1;
 211                 }
 212         }
 213 
 214         bva.va_mask = AT_ALL;
 215         error = rfs4_delegated_getattr(vp, &bva, 0, cr);
 216 
 217         /*
 218          * If we can't get the attributes, then we can't do the
 219          * right access checking.  So, we'll fail the request.
 220          */
 221         if (error)
 222                 goto out;
 223 




 224         bvap = &bva;

 225 
 226         if (rdonly(exi, req) || vn_is_readonly(vp)) {
 227                 resp->status = NFS3ERR_ROFS;
 228                 goto out1;
 229         }
 230 
 231         if (args->guard.check &&
 232             (args->guard.obj_ctime.seconds != bva.va_ctime.tv_sec ||
 233             args->guard.obj_ctime.nseconds != bva.va_ctime.tv_nsec)) {
 234                 resp->status = NFS3ERR_NOT_SYNC;
 235                 goto out1;
 236         }
 237 
 238         if (args->new_attributes.mtime.set_it == SET_TO_CLIENT_TIME)
 239                 flag = ATTR_UTIME;
 240         else
 241                 flag = 0;
 242 
 243         /*
 244          * If the filesystem is exported with nosuid, then mask off


 294                         bf.l_type = F_WRLCK;
 295                         bf.l_whence = 0;
 296                         bf.l_start = (off64_t)ava.va_size;
 297                         bf.l_len = 0;
 298                         bf.l_sysid = 0;
 299                         bf.l_pid = 0;
 300                         error = VOP_SPACE(vp, F_FREESP, &bf, FWRITE,
 301                             (offset_t)ava.va_size, cr, &ct);
 302                 }
 303         }
 304 
 305         if (!error && ava.va_mask)
 306                 error = VOP_SETATTR(vp, &ava, flag, cr, &ct);
 307 
 308         /* check if a monitor detected a delegation conflict */
 309         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
 310                 resp->status = NFS3ERR_JUKEBOX;
 311                 goto out1;
 312         }
 313 







 314         ava.va_mask = AT_ALL;
 315         avap = rfs4_delegated_getattr(vp, &ava, 0, cr) ? NULL : &ava;

 316 
 317         /*
 318          * Force modified metadata out to stable storage.
 319          */
 320         (void) VOP_FSYNC(vp, FNODSYNC, cr, &ct);
 321 
 322         if (error)
 323                 goto out;
 324 
 325         if (in_crit)
 326                 nbl_end_crit(vp);
 327 
 328         resp->status = NFS3_OK;
 329         vattr_to_wcc_data(bvap, avap, &resp->resok.obj_wcc);
 330 
 331         DTRACE_NFSV3_4(op__setattr__done, struct svc_req *, req,
 332             cred_t *, cr, vnode_t *, vp, SETATTR3res *, resp);
 333 
 334         VN_RELE(vp);
 335 


 385          * location of the public filehandle.
 386          */
 387         if (exi != NULL && (exi->exi_export.ex_flags & EX_PUBLIC)) {
 388                 dvp = rootdir;
 389                 VN_HOLD(dvp);
 390 
 391                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 392                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 393         } else {
 394                 dvp = nfs3_fhtovp(&args->what.dir, exi);
 395 
 396                 DTRACE_NFSV3_4(op__lookup__start, struct svc_req *, req,
 397                     cred_t *, cr, vnode_t *, dvp, LOOKUP3args *, args);
 398 
 399                 if (dvp == NULL) {
 400                         error = ESTALE;
 401                         goto out;
 402                 }
 403         }
 404 






 405         dva.va_mask = AT_ALL;
 406         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;

 407 
 408         if (args->what.name == nfs3nametoolong) {
 409                 resp->status = NFS3ERR_NAMETOOLONG;
 410                 goto out1;
 411         }
 412 
 413         if (args->what.name == NULL || *(args->what.name) == '\0') {
 414                 resp->status = NFS3ERR_ACCES;
 415                 goto out1;
 416         }
 417 
 418         fhp = &args->what.dir;
 419         if (strcmp(args->what.name, "..") == 0 &&
 420             EQFID(&exi->exi_fid, FH3TOFIDP(fhp))) {
 421                 resp->status = NFS3ERR_NOENT;
 422                 goto out1;
 423         }
 424 
 425         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
 426         name = nfscmd_convname(ca, exi, args->what.name,
 427             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
 428 
 429         if (name == NULL) {
 430                 resp->status = NFS3ERR_ACCES;
 431                 goto out1;
 432         }
 433 
 434         exi_hold(exi);
 435 
 436         /*
 437          * If the public filehandle is used then allow
 438          * a multi-component lookup
 439          */
 440         if (PUBLIC_FH3(&args->what.dir)) {
 441                 struct exportinfo *new;
 442 
 443                 publicfh_flag = TRUE;
 444 
 445                 error = rfs_publicfh_mclookup(name, dvp, cr, &vp,
 446                     &new, &sec);
 447 
 448                 if (error == 0) {
 449                         exi_rele(exi);
 450                         exi = new;
 451                 }
 452 
 453                 /*
 454                  * Since WebNFS may bypass MOUNT, we need to ensure this
 455                  * request didn't come from an unlabeled admin_low client.
 456                  */
 457                 if (is_system_labeled() && error == 0) {
 458                         int             addr_type;
 459                         void            *ipaddr;
 460                         tsol_tpc_t      *tp;
 461 
 462                         if (ca->sa_family == AF_INET) {
 463                                 addr_type = IPV4_VERSION;
 464                                 ipaddr = &((struct sockaddr_in *)ca)->sin_addr;
 465                         } else if (ca->sa_family == AF_INET6) {
 466                                 addr_type = IPV6_VERSION;
 467                                 ipaddr = &((struct sockaddr_in6 *)
 468                                     ca)->sin6_addr;
 469                         }
 470                         tp = find_tpc(ipaddr, addr_type, B_FALSE);
 471                         if (tp == NULL || tp->tpc_tp.tp_doi !=
 472                             l_admin_low->tsl_doi || tp->tpc_tp.host_type !=
 473                             SUN_CIPSO) {


 474                                 VN_RELE(vp);
 475                                 resp->status = NFS3ERR_ACCES;
 476                                 error = 1;
 477                         }
 478                         if (tp != NULL)
 479                                 TPC_RELE(tp);
 480                 }
 481         } else {
 482                 error = VOP_LOOKUP(dvp, name, &vp,
 483                     NULL, 0, NULL, cr, NULL, NULL, NULL);
 484         }
 485 
 486         if (name != args->what.name)
 487                 kmem_free(name, MAXPATHLEN + 1);
 488 
 489         if (error == 0 && vn_ismntpt(vp)) {
 490                 error = rfs_cross_mnt(&vp, &exi);
 491                 if (error)
 492                         VN_RELE(vp);
 493         }
 494 
 495         if (is_system_labeled() && error == 0) {
 496                 bslabel_t *clabel = req->rq_label;
 497 
 498                 ASSERT(clabel != NULL);
 499                 DTRACE_PROBE2(tx__rfs3__log__info__oplookup__clabel, char *,
 500                     "got client label from request(1)", struct svc_req *, req);
 501 
 502                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 503                         if (!do_rfs_label_check(clabel, dvp,
 504                             DOMINANCE_CHECK, exi)) {


 505                                 VN_RELE(vp);
 506                                 resp->status = NFS3ERR_ACCES;
 507                                 error = 1;
 508                         }
 509                 }
 510         }
 511 


 512         dva.va_mask = AT_ALL;
 513         dvap = VOP_GETATTR(dvp, &dva, 0, cr, NULL) ? NULL : &dva;






 514 
 515         if (error)
 516                 goto out;
 517 
 518         if (sec.sec_flags & SEC_QUERY) {
 519                 error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
 520         } else {
 521                 error = makefh3(&resp->resok.object, vp, exi);
 522                 if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
 523                         auth_weak = TRUE;
 524         }
 525 
 526         if (error) {
 527                 VN_RELE(vp);
 528                 goto out;
 529         }
 530 











 531         va.va_mask = AT_ALL;
 532         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;






 533 
 534         exi_rele(exi);
 535         VN_RELE(vp);
 536 
 537         resp->status = NFS3_OK;
 538         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 539         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 540 
 541         /*
 542          * If it's public fh, no 0x81, and client's flavor is
 543          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 544          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 545          */
 546         if (auth_weak)
 547                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 548 
 549         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 550             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 551         VN_RELE(dvp);
 552 
 553         return;
 554 
 555 out:
 556         /*
 557          * The passed argument exportinfo is released by the
 558          * caller, common_dispatch
 559          */
 560         exi_rele(exi);
 561 
 562         if (curthread->t_flag & T_WOULDBLOCK) {
 563                 curthread->t_flag &= ~T_WOULDBLOCK;
 564                 resp->status = NFS3ERR_JUKEBOX;
 565         } else
 566                 resp->status = puterrno3(error);
 567 out1:
 568         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 569             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 570 
 571         if (dvp != NULL)
 572                 VN_RELE(dvp);
 573         vattr_to_post_op_attr(dvap, &resp->resfail.dir_attributes);
 574 
 575 }
 576 
 577 void *
 578 rfs3_lookup_getfh(LOOKUP3args *args)
 579 {
 580 
 581         return (&args->what.dir);


 612          * to check write permissions for regular files and directories.
 613          * Special files are interpreted by the client, so the underlying
 614          * permissions are sent back to the client for interpretation.
 615          */
 616         if (rdonly(exi, req) && (vp->v_type == VREG || vp->v_type == VDIR))
 617                 checkwriteperm = 0;
 618         else
 619                 checkwriteperm = 1;
 620 
 621         /*
 622          * We need the mode so that we can correctly determine access
 623          * permissions relative to a mandatory lock file.  Access to
 624          * mandatory lock files is denied on the server, so it might
 625          * as well be reflected to the server during the open.
 626          */
 627         va.va_mask = AT_MODE;
 628         error = VOP_GETATTR(vp, &va, 0, cr, NULL);
 629         if (error)
 630                 goto out;
 631 




 632         vap = &va;

 633 
 634         resp->resok.access = 0;
 635 
 636         if (is_system_labeled()) {
 637                 bslabel_t *clabel = req->rq_label;
 638 
 639                 ASSERT(clabel != NULL);
 640                 DTRACE_PROBE2(tx__rfs3__log__info__opaccess__clabel, char *,
 641                     "got client label from request(1)", struct svc_req *, req);
 642 
 643                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 644                         if ((equal_label = do_rfs_label_check(clabel, vp,
 645                             EQUALITY_CHECK, exi)) == B_FALSE) {
 646                                 dominant_label = do_rfs_label_check(clabel,
 647                                     vp, DOMINANCE_CHECK, exi);
 648                         } else
 649                                 dominant_label = B_TRUE;
 650                         admin_low_client = B_FALSE;
 651                 } else
 652                         admin_low_client = B_TRUE;


 687             (args->access & ACCESS3_DELETE) && vp->v_type == VDIR) {
 688                 error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
 689                 if (error) {
 690                         if (curthread->t_flag & T_WOULDBLOCK)
 691                                 goto out;
 692                 } else if (!is_system_labeled() || admin_low_client ||
 693                     equal_label)
 694                         resp->resok.access |= ACCESS3_DELETE;
 695         }
 696         if (args->access & ACCESS3_EXECUTE) {
 697                 error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL);
 698                 if (error) {
 699                         if (curthread->t_flag & T_WOULDBLOCK)
 700                                 goto out;
 701                 } else if (!MANDLOCK(vp, va.va_mode) &&
 702                     (!is_system_labeled() || admin_low_client ||
 703                     dominant_label))
 704                         resp->resok.access |= ACCESS3_EXECUTE;
 705         }
 706 







 707         va.va_mask = AT_ALL;
 708         vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va;

 709 
 710         resp->status = NFS3_OK;
 711         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 712 
 713         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 714             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 715 
 716         VN_RELE(vp);
 717 
 718         return;
 719 
 720 out:
 721         if (curthread->t_flag & T_WOULDBLOCK) {
 722                 curthread->t_flag &= ~T_WOULDBLOCK;
 723                 resp->status = NFS3ERR_JUKEBOX;
 724         } else
 725                 resp->status = puterrno3(error);
 726         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 727             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 728         if (vp != NULL)


 753         char *name = NULL;
 754         int is_referral = 0;
 755 
 756         vap = NULL;
 757 
 758         vp = nfs3_fhtovp(&args->symlink, exi);
 759 
 760         DTRACE_NFSV3_4(op__readlink__start, struct svc_req *, req,
 761             cred_t *, cr, vnode_t *, vp, READLINK3args *, args);
 762 
 763         if (vp == NULL) {
 764                 error = ESTALE;
 765                 goto out;
 766         }
 767 
 768         va.va_mask = AT_ALL;
 769         error = VOP_GETATTR(vp, &va, 0, cr, NULL);
 770         if (error)
 771                 goto out;
 772 


 773         vap = &va;



 774 
 775         /* We lied about the object type for a referral */
 776         if (vn_is_nfs_reparse(vp, cr))
 777                 is_referral = 1;
 778 
 779         if (vp->v_type != VLNK && !is_referral) {
 780                 resp->status = NFS3ERR_INVAL;
 781                 goto out1;
 782         }
 783 
 784         if (MANDLOCK(vp, va.va_mode)) {
 785                 resp->status = NFS3ERR_ACCES;
 786                 goto out1;
 787         }
 788 
 789         if (is_system_labeled()) {
 790                 bslabel_t *clabel = req->rq_label;
 791 
 792                 ASSERT(clabel != NULL);
 793                 DTRACE_PROBE2(tx__rfs3__log__info__opreadlink__clabel, char *,


 821                         kmem_free(s, strsz);
 822                 }
 823 
 824         } else {
 825 
 826                 iov.iov_base = data;
 827                 iov.iov_len = MAXPATHLEN;
 828                 uio.uio_iov = &iov;
 829                 uio.uio_iovcnt = 1;
 830                 uio.uio_segflg = UIO_SYSSPACE;
 831                 uio.uio_extflg = UIO_COPY_CACHED;
 832                 uio.uio_loffset = 0;
 833                 uio.uio_resid = MAXPATHLEN;
 834 
 835                 error = VOP_READLINK(vp, &uio, cr, NULL);
 836 
 837                 if (!error)
 838                         *(data + MAXPATHLEN - uio.uio_resid) = '\0';
 839         }
 840 







 841         va.va_mask = AT_ALL;
 842         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
 843 
 844         /* Lie about object type again just to be consistent */
 845         if (is_referral && vap != NULL)
 846                 vap->va_type = VLNK;
 847 
 848 #if 0 /* notyet */
 849         /*
 850          * Don't do this.  It causes local disk writes when just
 851          * reading the file and the overhead is deemed larger
 852          * than the benefit.
 853          */
 854         /*
 855          * Force modified metadata out to stable storage.
 856          */
 857         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
 858 #endif
 859 
 860         if (error) {
 861                 kmem_free(data, MAXPATHLEN + 1);
 862                 goto out;
 863         }


1002         error = VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &ct);
1003 
1004         /* check if a monitor detected a delegation conflict */
1005         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1006                 resp->status = NFS3ERR_JUKEBOX;
1007                 goto out1;
1008         }
1009 
1010         need_rwunlock = 1;
1011 
1012         va.va_mask = AT_ALL;
1013         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1014 
1015         /*
1016          * If we can't get the attributes, then we can't do the
1017          * right access checking.  So, we'll fail the request.
1018          */
1019         if (error)
1020                 goto out;
1021 


1022         vap = &va;



1023 
1024         if (vp->v_type != VREG) {
1025                 resp->status = NFS3ERR_INVAL;
1026                 goto out1;
1027         }
1028 
1029         if (crgetuid(cr) != va.va_uid) {
1030                 error = VOP_ACCESS(vp, VREAD, 0, cr, &ct);
1031                 if (error) {
1032                         if (curthread->t_flag & T_WOULDBLOCK)
1033                                 goto out;
1034                         error = VOP_ACCESS(vp, VEXEC, 0, cr, &ct);
1035                         if (error)
1036                                 goto out;
1037                 }
1038         }
1039 
1040         if (MANDLOCK(vp, va.va_mode)) {
1041                 resp->status = NFS3ERR_ACCES;
1042                 goto out1;


1152         if (error) {
1153                 if (mp)
1154                         freemsg(mp);
1155                 /* check if a monitor detected a delegation conflict */
1156                 if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1157                         resp->status = NFS3ERR_JUKEBOX;
1158                         goto out1;
1159                 }
1160                 goto out;
1161         }
1162 
1163         /* make mblk using zc buffers */
1164         if (loaned_buffers) {
1165                 mp = uio_to_mblk(uiop);
1166                 ASSERT(mp != NULL);
1167         }
1168 
1169         va.va_mask = AT_ALL;
1170         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1171 









1172         if (error)
1173                 vap = NULL;
1174         else
1175                 vap = &va;

1176 
1177         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &ct);
1178 
1179         if (in_crit)
1180                 nbl_end_crit(vp);
1181 
1182         resp->status = NFS3_OK;
1183         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
1184         resp->resok.count = args->count - uiop->uio_resid;
1185         if (!error && offset + resp->resok.count == va.va_size)
1186                 resp->resok.eof = TRUE;
1187         else
1188                 resp->resok.eof = FALSE;
1189         resp->resok.data.data_len = resp->resok.count;
1190 
1191         if (mp)
1192                 rfs_rndup_mblks(mp, resp->resok.count, loaned_buffers);
1193 
1194         resp->resok.data.mp = mp;
1195         resp->resok.size = (uint_t)args->count;


1329 
1330         /* check if a monitor detected a delegation conflict */
1331         if (rwlock_ret == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1332                 resp->status = NFS3ERR_JUKEBOX;
1333                 rwlock_ret = -1;
1334                 goto err1;
1335         }
1336 
1337 
1338         bva.va_mask = AT_ALL;
1339         error = VOP_GETATTR(vp, &bva, 0, cr, &ct);
1340 
1341         /*
1342          * If we can't get the attributes, then we can't do the
1343          * right access checking.  So, we'll fail the request.
1344          */
1345         if (error)
1346                 goto err;
1347 
1348         bvap = &bva;




1349         avap = bvap;
1350 
1351         if (args->count != args->data.data_len) {
1352                 resp->status = NFS3ERR_INVAL;
1353                 goto err1;
1354         }
1355 
1356         if (rdonly(exi, req)) {
1357                 resp->status = NFS3ERR_ROFS;
1358                 goto err1;
1359         }
1360 
1361         if (vp->v_type != VREG) {
1362                 resp->status = NFS3ERR_INVAL;
1363                 goto err1;
1364         }
1365 
1366         if (crgetuid(cr) != bva.va_uid &&
1367             (error = VOP_ACCESS(vp, VWRITE, 0, cr, &ct)))
1368                 goto err;


1440          * the cred of the current thread to be used if quota
1441          * checking is enabled.
1442          */
1443         savecred = curthread->t_cred;
1444         curthread->t_cred = cr;
1445         error = VOP_WRITE(vp, &uio, ioflag, cr, &ct);
1446         curthread->t_cred = savecred;
1447 
1448         if (iovp != iov)
1449                 kmem_free(iovp, sizeof (*iovp) * iovcnt);
1450 
1451         /* check if a monitor detected a delegation conflict */
1452         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1453                 resp->status = NFS3ERR_JUKEBOX;
1454                 goto err1;
1455         }
1456 
1457         ava.va_mask = AT_ALL;
1458         avap = VOP_GETATTR(vp, &ava, 0, cr, &ct) ? NULL : &ava;
1459 





1460         if (error)
1461                 goto err;
1462 
1463         /*
1464          * If we were unable to get the V_WRITELOCK_TRUE, then we
1465          * may not have accurate after attrs, so check if
1466          * we have both attributes, they have a non-zero va_seq, and
1467          * va_seq has changed by exactly one,
1468          * if not, turn off the before attr.
1469          */
1470         if (rwlock_ret != V_WRITELOCK_TRUE) {
1471                 if (bvap == NULL || avap == NULL ||
1472                     bvap->va_seq == 0 || avap->va_seq == 0 ||
1473                     avap->va_seq != (bvap->va_seq + 1)) {
1474                         bvap = NULL;
1475                 }
1476         }
1477 
1478         resp->status = NFS3_OK;
1479         vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);


1528         enum vcexcl excl;
1529         nfstime3 *mtime;
1530         len_t reqsize;
1531         bool_t trunc;
1532         struct sockaddr *ca;
1533         char *name = NULL;
1534 
1535         dbvap = NULL;
1536         davap = NULL;
1537 
1538         dvp = nfs3_fhtovp(&args->where.dir, exi);
1539 
1540         DTRACE_NFSV3_4(op__create__start, struct svc_req *, req,
1541             cred_t *, cr, vnode_t *, dvp, CREATE3args *, args);
1542 
1543         if (dvp == NULL) {
1544                 error = ESTALE;
1545                 goto out;
1546         }
1547 


1548         dbva.va_mask = AT_ALL;
1549         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;






1550         davap = dbvap;
1551 
1552         if (args->where.name == nfs3nametoolong) {
1553                 resp->status = NFS3ERR_NAMETOOLONG;
1554                 goto out1;
1555         }
1556 
1557         if (args->where.name == NULL || *(args->where.name) == '\0') {
1558                 resp->status = NFS3ERR_ACCES;
1559                 goto out1;
1560         }
1561 
1562         if (rdonly(exi, req)) {
1563                 resp->status = NFS3ERR_ROFS;
1564                 goto out1;
1565         }
1566 
1567         if (is_system_labeled()) {
1568                 bslabel_t *clabel = req->rq_label;
1569 


1692                 goto out1;
1693         }
1694 
1695         /*
1696          * If the filesystem is exported with nosuid, then mask off
1697          * the setuid and setgid bits.
1698          */
1699         if (va.va_type == VREG && (exi->exi_export.ex_flags & EX_NOSUID))
1700                 va.va_mode &= ~(VSUID | VSGID);
1701 
1702 tryagain:
1703         /*
1704          * The file open mode used is VWRITE.  If the client needs
1705          * some other semantic, then it should do the access checking
1706          * itself.  It would have been nice to have the file open mode
1707          * passed as part of the arguments.
1708          */
1709         error = VOP_CREATE(dvp, name, &va, excl, VWRITE,
1710             &vp, cr, 0, NULL, NULL);
1711 







1712         dava.va_mask = AT_ALL;
1713         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;

1714 
1715         if (error) {
1716                 /*
1717                  * If we got something other than file already exists
1718                  * then just return this error.  Otherwise, we got
1719                  * EEXIST.  If we were doing a GUARDED create, then
1720                  * just return this error.  Otherwise, we need to
1721                  * make sure that this wasn't a duplicate of an
1722                  * exclusive create request.
1723                  *
1724                  * The assumption is made that a non-exclusive create
1725                  * request will never return EEXIST.
1726                  */
1727                 if (error != EEXIST || args->how.mode == GUARDED)
1728                         goto out;
1729                 /*
1730                  * Lookup the file so that we can get a vnode for it.
1731                  */
1732                 error = VOP_LOOKUP(dvp, name, &vp, NULL, 0,
1733                     NULL, cr, NULL, NULL, NULL);


1797                  * still recover by checking the size of the file
1798                  * after it has created it and then issue a setattr
1799                  * request of its own to set the size of the file.
1800                  */
1801                 if (vap != NULL &&
1802                     (args->how.mode == UNCHECKED ||
1803                     args->how.mode == GUARDED) &&
1804                     args->how.createhow3_u.obj_attributes.size.set_it &&
1805                     vap->va_size != reqsize) {
1806                         va.va_mask = AT_SIZE;
1807                         va.va_size = reqsize;
1808                         (void) VOP_SETATTR(vp, &va, 0, cr, NULL);
1809                         va.va_mask = AT_ALL;
1810                         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
1811                 }
1812         }
1813 
1814         if (name != args->where.name)
1815                 kmem_free(name, MAXPATHLEN + 1);
1816 










1817         error = makefh3(&resp->resok.obj.handle, vp, exi);
1818         if (error)
1819                 resp->resok.obj.handle_follows = FALSE;
1820         else
1821                 resp->resok.obj.handle_follows = TRUE;



1822 
1823         /*
1824          * Force modified data and metadata out to stable storage.
1825          */
1826         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
1827         (void) VOP_FSYNC(dvp, 0, cr, NULL);
1828 
1829         VN_RELE(vp);
1830         if (tvp != NULL) {
1831                 if (in_crit)
1832                         nbl_end_crit(tvp);
1833                 VN_RELE(tvp);
1834         }
1835 
1836         resp->status = NFS3_OK;
1837         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
1838         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
1839 
1840         DTRACE_NFSV3_4(op__create__done, struct svc_req *, req,
1841             cred_t *, cr, vnode_t *, dvp, CREATE3res *, resp);


1885         struct vattr *dbvap;
1886         struct vattr dbva;
1887         struct vattr *davap;
1888         struct vattr dava;
1889         struct sockaddr *ca;
1890         char *name = NULL;
1891 
1892         dbvap = NULL;
1893         davap = NULL;
1894 
1895         dvp = nfs3_fhtovp(&args->where.dir, exi);
1896 
1897         DTRACE_NFSV3_4(op__mkdir__start, struct svc_req *, req,
1898             cred_t *, cr, vnode_t *, dvp, MKDIR3args *, args);
1899 
1900         if (dvp == NULL) {
1901                 error = ESTALE;
1902                 goto out;
1903         }
1904 


1905         dbva.va_mask = AT_ALL;
1906         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;






1907         davap = dbvap;
1908 
1909         if (args->where.name == nfs3nametoolong) {
1910                 resp->status = NFS3ERR_NAMETOOLONG;
1911                 goto out1;
1912         }
1913 
1914         if (args->where.name == NULL || *(args->where.name) == '\0') {
1915                 resp->status = NFS3ERR_ACCES;
1916                 goto out1;
1917         }
1918 
1919         if (rdonly(exi, req)) {
1920                 resp->status = NFS3ERR_ROFS;
1921                 goto out1;
1922         }
1923 
1924         if (is_system_labeled()) {
1925                 bslabel_t *clabel = req->rq_label;
1926 


1946                 goto out1;
1947         }
1948 
1949         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
1950         name = nfscmd_convname(ca, exi, args->where.name,
1951             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
1952 
1953         if (name == NULL) {
1954                 resp->status = NFS3ERR_INVAL;
1955                 goto out1;
1956         }
1957 
1958         va.va_mask |= AT_TYPE;
1959         va.va_type = VDIR;
1960 
1961         error = VOP_MKDIR(dvp, name, &va, &vp, cr, NULL, 0, NULL);
1962 
1963         if (name != args->where.name)
1964                 kmem_free(name, MAXPATHLEN + 1);
1965 







1966         dava.va_mask = AT_ALL;
1967         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;

1968 
1969         /*
1970          * Force modified data and metadata out to stable storage.
1971          */
1972         (void) VOP_FSYNC(dvp, 0, cr, NULL);
1973 
1974         if (error)
1975                 goto out;
1976 





1977         error = makefh3(&resp->resok.obj.handle, vp, exi);
1978         if (error)
1979                 resp->resok.obj.handle_follows = FALSE;
1980         else
1981                 resp->resok.obj.handle_follows = TRUE;



1982 







1983         va.va_mask = AT_ALL;
1984         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

1985 
1986         /*
1987          * Force modified data and metadata out to stable storage.
1988          */
1989         (void) VOP_FSYNC(vp, 0, cr, NULL);
1990 
1991         VN_RELE(vp);
1992 
1993         resp->status = NFS3_OK;
1994         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
1995         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
1996 
1997         DTRACE_NFSV3_4(op__mkdir__done, struct svc_req *, req,
1998             cred_t *, cr, vnode_t *, dvp, MKDIR3res *, resp);
1999         VN_RELE(dvp);
2000 
2001         return;
2002 
2003 out:
2004         if (curthread->t_flag & T_WOULDBLOCK) {


2034         struct vattr dbva;
2035         struct vattr *davap;
2036         struct vattr dava;
2037         struct sockaddr *ca;
2038         char *name = NULL;
2039         char *symdata = NULL;
2040 
2041         dbvap = NULL;
2042         davap = NULL;
2043 
2044         dvp = nfs3_fhtovp(&args->where.dir, exi);
2045 
2046         DTRACE_NFSV3_4(op__symlink__start, struct svc_req *, req,
2047             cred_t *, cr, vnode_t *, dvp, SYMLINK3args *, args);
2048 
2049         if (dvp == NULL) {
2050                 error = ESTALE;
2051                 goto err;
2052         }
2053 


2054         dbva.va_mask = AT_ALL;
2055         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;






2056         davap = dbvap;
2057 
2058         if (args->where.name == nfs3nametoolong) {
2059                 resp->status = NFS3ERR_NAMETOOLONG;
2060                 goto err1;
2061         }
2062 
2063         if (args->where.name == NULL || *(args->where.name) == '\0') {
2064                 resp->status = NFS3ERR_ACCES;
2065                 goto err1;
2066         }
2067 
2068         if (rdonly(exi, req)) {
2069                 resp->status = NFS3ERR_ROFS;
2070                 goto err1;
2071         }
2072 
2073         if (is_system_labeled()) {
2074                 bslabel_t *clabel = req->rq_label;
2075 


2107         if (name == NULL) {
2108                 /* This is really a Solaris EILSEQ */
2109                 resp->status = NFS3ERR_INVAL;
2110                 goto err1;
2111         }
2112 
2113         symdata = nfscmd_convname(ca, exi, args->symlink.symlink_data,
2114             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2115         if (symdata == NULL) {
2116                 /* This is really a Solaris EILSEQ */
2117                 resp->status = NFS3ERR_INVAL;
2118                 goto err1;
2119         }
2120 
2121 
2122         va.va_mask |= AT_TYPE;
2123         va.va_type = VLNK;
2124 
2125         error = VOP_SYMLINK(dvp, name, &va, symdata, cr, NULL, 0);
2126 







2127         dava.va_mask = AT_ALL;
2128         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;

2129 
2130         if (error)
2131                 goto err;
2132 
2133         error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
2134             NULL, NULL, NULL);
2135 
2136         /*
2137          * Force modified data and metadata out to stable storage.
2138          */
2139         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2140 
2141 
2142         resp->status = NFS3_OK;
2143         if (error) {
2144                 resp->resok.obj.handle_follows = FALSE;
2145                 vattr_to_post_op_attr(NULL, &resp->resok.obj_attributes);
2146                 vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2147                 goto out;
2148         }
2149 





2150         error = makefh3(&resp->resok.obj.handle, vp, exi);
2151         if (error)
2152                 resp->resok.obj.handle_follows = FALSE;
2153         else
2154                 resp->resok.obj.handle_follows = TRUE;



2155 







2156         va.va_mask = AT_ALL;
2157         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

2158 
2159         /*
2160          * Force modified data and metadata out to stable storage.
2161          */
2162         (void) VOP_FSYNC(vp, 0, cr, NULL);
2163 
2164         VN_RELE(vp);
2165 
2166         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2167         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2168         goto out;
2169 
2170 err:
2171         if (curthread->t_flag & T_WOULDBLOCK) {
2172                 curthread->t_flag &= ~T_WOULDBLOCK;
2173                 resp->status = NFS3ERR_JUKEBOX;
2174         } else
2175                 resp->status = puterrno3(error);
2176 err1:
2177         vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);


2210         struct vattr *davap;
2211         struct vattr dava;
2212         int mode;
2213         enum vcexcl excl;
2214         struct sockaddr *ca;
2215         char *name = NULL;
2216 
2217         dbvap = NULL;
2218         davap = NULL;
2219 
2220         dvp = nfs3_fhtovp(&args->where.dir, exi);
2221 
2222         DTRACE_NFSV3_4(op__mknod__start, struct svc_req *, req,
2223             cred_t *, cr, vnode_t *, dvp, MKNOD3args *, args);
2224 
2225         if (dvp == NULL) {
2226                 error = ESTALE;
2227                 goto out;
2228         }
2229 


2230         dbva.va_mask = AT_ALL;
2231         dbvap = VOP_GETATTR(dvp, &dbva, 0, cr, NULL) ? NULL : &dbva;






2232         davap = dbvap;
2233 
2234         if (args->where.name == nfs3nametoolong) {
2235                 resp->status = NFS3ERR_NAMETOOLONG;
2236                 goto out1;
2237         }
2238 
2239         if (args->where.name == NULL || *(args->where.name) == '\0') {
2240                 resp->status = NFS3ERR_ACCES;
2241                 goto out1;
2242         }
2243 
2244         if (rdonly(exi, req)) {
2245                 resp->status = NFS3ERR_ROFS;
2246                 goto out1;
2247         }
2248 
2249         if (is_system_labeled()) {
2250                 bslabel_t *clabel = req->rq_label;
2251 


2313 
2314         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2315         name = nfscmd_convname(ca, exi, args->where.name,
2316             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2317 
2318         if (name == NULL) {
2319                 resp->status = NFS3ERR_INVAL;
2320                 goto out1;
2321         }
2322 
2323         excl = EXCL;
2324 
2325         mode = 0;
2326 
2327         error = VOP_CREATE(dvp, name, &va, excl, mode,
2328             &vp, cr, 0, NULL, NULL);
2329 
2330         if (name != args->where.name)
2331                 kmem_free(name, MAXPATHLEN + 1);
2332 


2333         dava.va_mask = AT_ALL;
2334         davap = VOP_GETATTR(dvp, &dava, 0, cr, NULL) ? NULL : &dava;






2335 
2336         /*
2337          * Force modified data and metadata out to stable storage.
2338          */
2339         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2340 
2341         if (error)
2342                 goto out;
2343 
2344         resp->status = NFS3_OK;
2345 





2346         error = makefh3(&resp->resok.obj.handle, vp, exi);
2347         if (error)
2348                 resp->resok.obj.handle_follows = FALSE;
2349         else
2350                 resp->resok.obj.handle_follows = TRUE;



2351 


2352         va.va_mask = AT_ALL;
2353         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;






2354 
2355         /*
2356          * Force modified metadata out to stable storage.
2357          *
2358          * if a underlying vp exists, pass it to VOP_FSYNC
2359          */
2360         if (VOP_REALVP(vp, &realvp, NULL) == 0)
2361                 (void) VOP_FSYNC(realvp, FNODSYNC, cr, NULL);
2362         else
2363                 (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
2364 
2365         VN_RELE(vp);
2366 
2367         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2368         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2369         DTRACE_NFSV3_4(op__mknod__done, struct svc_req *, req,
2370             cred_t *, cr, vnode_t *, dvp, MKNOD3res *, resp);
2371         VN_RELE(dvp);
2372         return;
2373 


2402         struct vattr bva;
2403         struct vattr *avap;
2404         struct vattr ava;
2405         vnode_t *targvp = NULL;
2406         struct sockaddr *ca;
2407         char *name = NULL;
2408 
2409         bvap = NULL;
2410         avap = NULL;
2411 
2412         vp = nfs3_fhtovp(&args->object.dir, exi);
2413 
2414         DTRACE_NFSV3_4(op__remove__start, struct svc_req *, req,
2415             cred_t *, cr, vnode_t *, vp, REMOVE3args *, args);
2416 
2417         if (vp == NULL) {
2418                 error = ESTALE;
2419                 goto err;
2420         }
2421 







2422         bva.va_mask = AT_ALL;
2423         bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;

2424         avap = bvap;
2425 
2426         if (vp->v_type != VDIR) {
2427                 resp->status = NFS3ERR_NOTDIR;
2428                 goto err1;
2429         }
2430 
2431         if (args->object.name == nfs3nametoolong) {
2432                 resp->status = NFS3ERR_NAMETOOLONG;
2433                 goto err1;
2434         }
2435 
2436         if (args->object.name == NULL || *(args->object.name) == '\0') {
2437                 resp->status = NFS3ERR_ACCES;
2438                 goto err1;
2439         }
2440 
2441         if (rdonly(exi, req)) {
2442                 resp->status = NFS3ERR_ROFS;
2443                 goto err1;


2479 
2480         if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
2481                 resp->status = NFS3ERR_JUKEBOX;
2482                 goto err1;
2483         }
2484 
2485         if (!nbl_need_check(targvp)) {
2486                 error = VOP_REMOVE(vp, name, cr, NULL, 0);
2487         } else {
2488                 nbl_start_crit(targvp, RW_READER);
2489                 if (nbl_conflict(targvp, NBL_REMOVE, 0, 0, 0, NULL)) {
2490                         error = EACCES;
2491                 } else {
2492                         error = VOP_REMOVE(vp, name, cr, NULL, 0);
2493                 }
2494                 nbl_end_crit(targvp);
2495         }
2496         VN_RELE(targvp);
2497         targvp = NULL;
2498 


2499         ava.va_mask = AT_ALL;
2500         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;






2501 
2502         /*
2503          * Force modified data and metadata out to stable storage.
2504          */
2505         (void) VOP_FSYNC(vp, 0, cr, NULL);
2506 
2507         if (error)
2508                 goto err;
2509 
2510         resp->status = NFS3_OK;
2511         vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);
2512         goto out;
2513 
2514 err:
2515         if (curthread->t_flag & T_WOULDBLOCK) {
2516                 curthread->t_flag &= ~T_WOULDBLOCK;
2517                 resp->status = NFS3ERR_JUKEBOX;
2518         } else
2519                 resp->status = puterrno3(error);
2520 err1:


2546         struct vattr *bvap;
2547         struct vattr bva;
2548         struct vattr *avap;
2549         struct vattr ava;
2550         struct sockaddr *ca;
2551         char *name = NULL;
2552 
2553         bvap = NULL;
2554         avap = NULL;
2555 
2556         vp = nfs3_fhtovp(&args->object.dir, exi);
2557 
2558         DTRACE_NFSV3_4(op__rmdir__start, struct svc_req *, req,
2559             cred_t *, cr, vnode_t *, vp, RMDIR3args *, args);
2560 
2561         if (vp == NULL) {
2562                 error = ESTALE;
2563                 goto err;
2564         }
2565 







2566         bva.va_mask = AT_ALL;
2567         bvap = VOP_GETATTR(vp, &bva, 0, cr, NULL) ? NULL : &bva;

2568         avap = bvap;
2569 
2570         if (vp->v_type != VDIR) {
2571                 resp->status = NFS3ERR_NOTDIR;
2572                 goto err1;
2573         }
2574 
2575         if (args->object.name == nfs3nametoolong) {
2576                 resp->status = NFS3ERR_NAMETOOLONG;
2577                 goto err1;
2578         }
2579 
2580         if (args->object.name == NULL || *(args->object.name) == '\0') {
2581                 resp->status = NFS3ERR_ACCES;
2582                 goto err1;
2583         }
2584 
2585         if (rdonly(exi, req)) {
2586                 resp->status = NFS3ERR_ROFS;
2587                 goto err1;


2600                                 resp->status = NFS3ERR_ACCES;
2601                                 goto err1;
2602                         }
2603                 }
2604         }
2605 
2606         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2607         name = nfscmd_convname(ca, exi, args->object.name,
2608             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2609 
2610         if (name == NULL) {
2611                 resp->status = NFS3ERR_INVAL;
2612                 goto err1;
2613         }
2614 
2615         error = VOP_RMDIR(vp, name, rootdir, cr, NULL, 0);
2616 
2617         if (name != args->object.name)
2618                 kmem_free(name, MAXPATHLEN + 1);
2619 







2620         ava.va_mask = AT_ALL;
2621         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;

2622 
2623         /*
2624          * Force modified data and metadata out to stable storage.
2625          */
2626         (void) VOP_FSYNC(vp, 0, cr, NULL);
2627 
2628         if (error) {
2629                 /*
2630                  * System V defines rmdir to return EEXIST, not ENOTEMPTY,
2631                  * if the directory is not empty.  A System V NFS server
2632                  * needs to map NFS3ERR_EXIST to NFS3ERR_NOTEMPTY to transmit
2633                  * over the wire.
2634                  */
2635                 if (error == EEXIST)
2636                         error = ENOTEMPTY;
2637                 goto err;
2638         }
2639 
2640         resp->status = NFS3_OK;
2641         vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);


2702         if (fvp == NULL) {
2703                 error = ESTALE;
2704                 goto err;
2705         }
2706 
2707         if (is_system_labeled()) {
2708                 clabel = req->rq_label;
2709                 ASSERT(clabel != NULL);
2710                 DTRACE_PROBE2(tx__rfs3__log__info__oprename__clabel, char *,
2711                     "got client label from request(1)", struct svc_req *, req);
2712 
2713                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2714                         if (!do_rfs_label_check(clabel, fvp, EQUALITY_CHECK,
2715                             exi)) {
2716                                 resp->status = NFS3ERR_ACCES;
2717                                 goto err1;
2718                         }
2719                 }
2720         }
2721 







2722         fbva.va_mask = AT_ALL;
2723         fbvap = VOP_GETATTR(fvp, &fbva, 0, cr, NULL) ? NULL : &fbva;

2724         favap = fbvap;
2725 
2726         fh3 = &args->to.dir;
2727         to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
2728         if (to_exi == NULL) {
2729                 resp->status = NFS3ERR_ACCES;
2730                 goto err1;
2731         }
2732         exi_rele(to_exi);
2733 
2734         if (to_exi != exi) {
2735                 resp->status = NFS3ERR_XDEV;
2736                 goto err1;
2737         }
2738 
2739         tvp = nfs3_fhtovp(&args->to.dir, exi);
2740         if (tvp == NULL) {
2741                 error = ESTALE;
2742                 goto err;
2743         }
2744 







2745         tbva.va_mask = AT_ALL;
2746         tbvap = VOP_GETATTR(tvp, &tbva, 0, cr, NULL) ? NULL : &tbva;

2747         tavap = tbvap;
2748 
2749         if (fvp->v_type != VDIR || tvp->v_type != VDIR) {
2750                 resp->status = NFS3ERR_NOTDIR;
2751                 goto err1;
2752         }
2753 
2754         if (args->from.name == nfs3nametoolong ||
2755             args->to.name == nfs3nametoolong) {
2756                 resp->status = NFS3ERR_NAMETOOLONG;
2757                 goto err1;
2758         }
2759         if (args->from.name == NULL || *(args->from.name) == '\0' ||
2760             args->to.name == NULL || *(args->to.name) == '\0') {
2761                 resp->status = NFS3ERR_ACCES;
2762                 goto err1;
2763         }
2764 
2765         if (rdonly(exi, req)) {
2766                 resp->status = NFS3ERR_ROFS;


2828                 }
2829                 VN_RELE(targvp);
2830         }
2831 
2832         if (!nbl_need_check(srcvp)) {
2833                 error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
2834         } else {
2835                 nbl_start_crit(srcvp, RW_READER);
2836                 if (nbl_conflict(srcvp, NBL_RENAME, 0, 0, 0, NULL))
2837                         error = EACCES;
2838                 else
2839                         error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
2840                 nbl_end_crit(srcvp);
2841         }
2842         if (error == 0)
2843                 vn_renamepath(tvp, srcvp, args->to.name,
2844                     strlen(args->to.name));
2845         VN_RELE(srcvp);
2846         srcvp = NULL;
2847 


2848         fava.va_mask = AT_ALL;
2849         favap = VOP_GETATTR(fvp, &fava, 0, cr, NULL) ? NULL : &fava;
2850         tava.va_mask = AT_ALL;
2851         tavap = VOP_GETATTR(tvp, &tava, 0, cr, NULL) ? NULL : &tava;










2852 
2853         /*
2854          * Force modified data and metadata out to stable storage.
2855          */
2856         (void) VOP_FSYNC(fvp, 0, cr, NULL);
2857         (void) VOP_FSYNC(tvp, 0, cr, NULL);
2858 
2859         if (error)
2860                 goto err;
2861 
2862         resp->status = NFS3_OK;
2863         vattr_to_wcc_data(fbvap, favap, &resp->resok.fromdir_wcc);
2864         vattr_to_wcc_data(tbvap, tavap, &resp->resok.todir_wcc);
2865         goto out;
2866 
2867 err:
2868         if (curthread->t_flag & T_WOULDBLOCK) {
2869                 curthread->t_flag &= ~T_WOULDBLOCK;
2870                 resp->status = NFS3ERR_JUKEBOX;
2871         } else {


2913         struct exportinfo *to_exi;
2914         bslabel_t *clabel;
2915         struct sockaddr *ca;
2916         char *name = NULL;
2917 
2918         vap = NULL;
2919         bvap = NULL;
2920         avap = NULL;
2921         dvp = NULL;
2922 
2923         vp = nfs3_fhtovp(&args->file, exi);
2924 
2925         DTRACE_NFSV3_4(op__link__start, struct svc_req *, req,
2926             cred_t *, cr, vnode_t *, vp, LINK3args *, args);
2927 
2928         if (vp == NULL) {
2929                 error = ESTALE;
2930                 goto out;
2931         }
2932 


2933         va.va_mask = AT_ALL;
2934         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;






2935 
2936         fh3 = &args->link.dir;
2937         to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
2938         if (to_exi == NULL) {
2939                 resp->status = NFS3ERR_ACCES;
2940                 goto out1;
2941         }
2942         exi_rele(to_exi);
2943 
2944         if (to_exi != exi) {
2945                 resp->status = NFS3ERR_XDEV;
2946                 goto out1;
2947         }
2948 
2949         if (is_system_labeled()) {
2950                 clabel = req->rq_label;
2951 
2952                 ASSERT(clabel != NULL);
2953                 DTRACE_PROBE2(tx__rfs3__log__info__oplink__clabel, char *,
2954                     "got client label from request(1)", struct svc_req *, req);
2955 
2956                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2957                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
2958                             exi)) {
2959                                 resp->status = NFS3ERR_ACCES;
2960                                 goto out1;
2961                         }
2962                 }
2963         }
2964 
2965         dvp = nfs3_fhtovp(&args->link.dir, exi);
2966         if (dvp == NULL) {
2967                 error = ESTALE;
2968                 goto out;
2969         }
2970 







2971         bva.va_mask = AT_ALL;
2972         bvap = VOP_GETATTR(dvp, &bva, 0, cr, NULL) ? NULL : &bva;

2973 
2974         if (dvp->v_type != VDIR) {
2975                 resp->status = NFS3ERR_NOTDIR;
2976                 goto out1;
2977         }
2978 
2979         if (args->link.name == nfs3nametoolong) {
2980                 resp->status = NFS3ERR_NAMETOOLONG;
2981                 goto out1;
2982         }
2983 
2984         if (args->link.name == NULL || *(args->link.name) == '\0') {
2985                 resp->status = NFS3ERR_ACCES;
2986                 goto out1;
2987         }
2988 
2989         if (rdonly(exi, req)) {
2990                 resp->status = NFS3ERR_ROFS;
2991                 goto out1;
2992         }


2998                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2999                         if (!do_rfs_label_check(clabel, dvp, EQUALITY_CHECK,
3000                             exi)) {
3001                                 resp->status = NFS3ERR_ACCES;
3002                                 goto out1;
3003                         }
3004                 }
3005         }
3006 
3007         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
3008         name = nfscmd_convname(ca, exi, args->link.name,
3009             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
3010 
3011         if (name == NULL) {
3012                 resp->status = NFS3ERR_SERVERFAULT;
3013                 goto out1;
3014         }
3015 
3016         error = VOP_LINK(dvp, vp, name, cr, NULL, 0);
3017 











3018         va.va_mask = AT_ALL;
3019         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3020         ava.va_mask = AT_ALL;
3021         avap = VOP_GETATTR(dvp, &ava, 0, cr, NULL) ? NULL : &ava;

3022 
3023         /*
3024          * Force modified data and metadata out to stable storage.
3025          */
3026         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
3027         (void) VOP_FSYNC(dvp, 0, cr, NULL);
3028 
3029         if (error)
3030                 goto out;
3031 
3032         VN_RELE(dvp);
3033 
3034         resp->status = NFS3_OK;
3035         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
3036         vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
3037 
3038         DTRACE_NFSV3_4(op__link__done, struct svc_req *, req,
3039             cred_t *, cr, vnode_t *, vp, LINK3res *, resp);
3040 
3041         VN_RELE(vp);


3130         }
3131 
3132         if (is_system_labeled()) {
3133                 bslabel_t *clabel = req->rq_label;
3134 
3135                 ASSERT(clabel != NULL);
3136                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddir__clabel, char *,
3137                     "got client label from request(1)", struct svc_req *, req);
3138 
3139                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3140                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3141                             exi)) {
3142                                 resp->status = NFS3ERR_ACCES;
3143                                 goto out1;
3144                         }
3145                 }
3146         }
3147 
3148         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3149 







3150         va.va_mask = AT_ALL;
3151         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3152 
3153         if (vp->v_type != VDIR) {
3154                 resp->status = NFS3ERR_NOTDIR;
3155                 goto out1;
3156         }
3157 
3158         error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
3159         if (error)
3160                 goto out;
3161 
3162         /*
3163          * Now don't allow arbitrary count to alloc;
3164          * allow the maximum not to exceed rfs3_tsize()
3165          */
3166         if (args->count > rfs3_tsize(req))
3167                 args->count = rfs3_tsize(req);
3168 
3169         /*
3170          * Make sure that there is room to read at least one entry
3171          * if any are available.
3172          */
3173         if (args->count < DIRENT64_RECLEN(MAXNAMELEN))
3174                 count = DIRENT64_RECLEN(MAXNAMELEN);
3175         else
3176                 count = args->count;
3177 
3178         data = kmem_alloc(count, KM_SLEEP);
3179 
3180         iov.iov_base = data;
3181         iov.iov_len = count;
3182         uio.uio_iov = &iov;
3183         uio.uio_iovcnt = 1;
3184         uio.uio_segflg = UIO_SYSSPACE;
3185         uio.uio_extflg = UIO_COPY_CACHED;
3186         uio.uio_loffset = (offset_t)args->cookie;
3187         uio.uio_resid = count;
3188 
3189         error = VOP_READDIR(vp, &uio, cr, &iseof, NULL, 0);
3190 







3191         va.va_mask = AT_ALL;
3192         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3193 
3194         if (error) {
3195                 kmem_free(data, count);
3196                 goto out;
3197         }
3198 
3199         /*
3200          * If the count was not large enough to be able to guarantee
3201          * to be able to return at least one entry, then need to
3202          * check to see if NFS3ERR_TOOSMALL should be returned.
3203          */
3204         if (args->count < NFS3_READDIR_MIN_COUNT(MAXNAMELEN)) {
3205                 /*
3206                  * bufsize is used to keep track of the size of the response.
3207                  * It is primed with:
3208                  *      1 for the status +
3209                  *      1 for the dir_attributes.attributes boolean +
3210                  *      2 for the cookie verifier
3211                  * all times BYTES_PER_XDR_UNIT to convert from XDR units
3212                  * to bytes.  If there are directory attributes to be


3402 
3403         if (is_system_labeled()) {
3404                 bslabel_t *clabel = req->rq_label;
3405 
3406                 ASSERT(clabel != NULL);
3407                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddirplus__clabel,
3408                     char *, "got client label from request(1)",
3409                     struct svc_req *, req);
3410 
3411                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3412                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3413                             exi)) {
3414                                 resp->status = NFS3ERR_ACCES;
3415                                 goto out1;
3416                         }
3417                 }
3418         }
3419 
3420         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3421 







3422         va.va_mask = AT_ALL;
3423         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3424 
3425         if (vp->v_type != VDIR) {
3426                 error = ENOTDIR;
3427                 goto out;
3428         }
3429 
3430         error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
3431         if (error)
3432                 goto out;
3433 
3434         /*
3435          * Don't allow arbitrary counts for allocation
3436          */
3437         if (args->maxcount > rfs3_tsize(req))
3438                 args->maxcount = rfs3_tsize(req);
3439 
3440         /*
3441          * Make sure that there is room to read at least one entry
3442          * if any are available
3443          */


3562                         iseof = FALSE;
3563                         goto good;
3564                 }
3565                 bufsize += entrysize;
3566                 nents++;
3567         }
3568 
3569         /*
3570          * If there is enough room to fit at least 1 more entry including
3571          * post op attributes and filehandle in the buffer AND that we haven't
3572          * exceeded dircount then go back and get some more.
3573          */
3574         if (!iseof &&
3575             (args->maxcount - bufsize) >= NFS3_READDIRPLUS_ENTRY(MAXNAMELEN)) {
3576                 space_left -= (prev_len - uio.uio_resid);
3577                 if (space_left >= DIRENT64_RECLEN(MAXNAMELEN))
3578                         goto getmoredents;
3579 
3580                 /* else, fall through */
3581         }

3582 good:








3583         va.va_mask = AT_ALL;
3584         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3585 
3586         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
3587 
3588         infop = kmem_alloc(nents * sizeof (struct entryplus3_info), KM_SLEEP);
3589         resp->resok.infop = infop;
3590 
3591         dp = (struct dirent64 *)data;
3592         for (i = 0; i < nents; i++) {
3593 
3594                 if (dp->d_ino == 0) {
3595                         infop[i].attr.attributes = FALSE;
3596                         infop[i].fh.handle_follows = FALSE;
3597                         dp = nextdp(dp);
3598                         continue;
3599                 }
3600 
3601                 infop[i].namelen = namlen[i];
3602 
3603                 error = VOP_LOOKUP(vp, dp->d_name, &nvp, NULL, 0, NULL, cr,
3604                     NULL, NULL, NULL);
3605                 if (error) {
3606                         infop[i].attr.attributes = FALSE;
3607                         infop[i].fh.handle_follows = FALSE;
3608                         dp = nextdp(dp);
3609                         continue;
3610                 }
3611 








3612                 nva.va_mask = AT_ALL;
3613                 nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ? NULL : &nva;
3614 
3615                 /* Lie about the object type for a referral */
3616                 if (vn_is_nfs_reparse(nvp, cr))
3617                         nvap->va_type = VLNK;
3618 
3619                 if (vn_ismntpt(nvp)) {
3620                         infop[i].attr.attributes = FALSE;
3621                         infop[i].fh.handle_follows = FALSE;
3622                 } else {
3623                         vattr_to_post_op_attr(nvap, &infop[i].attr);
3624 





3625                         error = makefh3(&infop[i].fh.handle, nvp, exi);
3626                         if (!error)
3627                                 infop[i].fh.handle_follows = TRUE;
3628                         else
3629                                 infop[i].fh.handle_follows = FALSE;

3630                 }

3631 
3632                 VN_RELE(nvp);
3633                 dp = nextdp(dp);
3634         }
3635 
3636         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
3637         ret = nfscmd_convdirplus(ca, exi, data, nents, args->dircount, &ndata);
3638         if (ndata == NULL)
3639                 ndata = data;
3640 
3641         if (ret > 0) {
3642                 /*
3643                  * We had to drop one or more entries in order to fit
3644                  * during the character conversion.  We need to patch
3645                  * up the size and eof info.
3646                  */
3647                 if (iseof)
3648                         iseof = FALSE;
3649 
3650                 ret = nfscmd_dropped_entrysize((struct dirent64 *)data,


3749         }
3750 
3751         if (is_system_labeled()) {
3752                 bslabel_t *clabel = req->rq_label;
3753 
3754                 ASSERT(clabel != NULL);
3755                 DTRACE_PROBE2(tx__rfs3__log__info__opfsstat__clabel, char *,
3756                     "got client label from request(1)", struct svc_req *, req);
3757 
3758                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3759                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3760                             exi)) {
3761                                 resp->status = NFS3ERR_ACCES;
3762                                 goto out1;
3763                         }
3764                 }
3765         }
3766 
3767         error = VFS_STATVFS(vp->v_vfsp, &sb);
3768 







3769         va.va_mask = AT_ALL;
3770         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3771 
3772         if (error)
3773                 goto out;
3774 
3775         resp->status = NFS3_OK;
3776         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
3777         if (sb.f_blocks != (fsblkcnt64_t)-1)
3778                 resp->resok.tbytes = (size3)sb.f_frsize * (size3)sb.f_blocks;
3779         else
3780                 resp->resok.tbytes = (size3)sb.f_blocks;
3781         if (sb.f_bfree != (fsblkcnt64_t)-1)
3782                 resp->resok.fbytes = (size3)sb.f_frsize * (size3)sb.f_bfree;
3783         else
3784                 resp->resok.fbytes = (size3)sb.f_bfree;
3785         if (sb.f_bavail != (fsblkcnt64_t)-1)
3786                 resp->resok.abytes = (size3)sb.f_frsize * (size3)sb.f_bavail;
3787         else
3788                 resp->resok.abytes = (size3)sb.f_bavail;
3789         resp->resok.tfiles = (size3)sb.f_files;
3790         resp->resok.ffiles = (size3)sb.f_ffree;


3846         }
3847 
3848         if (is_system_labeled()) {
3849                 bslabel_t *clabel = req->rq_label;
3850 
3851                 ASSERT(clabel != NULL);
3852                 DTRACE_PROBE2(tx__rfs3__log__info__opfsinfo__clabel, char *,
3853                     "got client label from request(1)", struct svc_req *, req);
3854 
3855                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3856                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3857                             exi)) {
3858                                 resp->status = NFS3ERR_STALE;
3859                                 vattr_to_post_op_attr(NULL,
3860                                     &resp->resfail.obj_attributes);
3861                                 goto out;
3862                         }
3863                 }
3864         }
3865 







3866         va.va_mask = AT_ALL;
3867         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3868 
3869         resp->status = NFS3_OK;
3870         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
3871         xfer_size = rfs3_tsize(req);
3872         resp->resok.rtmax = xfer_size;
3873         resp->resok.rtpref = xfer_size;
3874         resp->resok.rtmult = DEV_BSIZE;
3875         resp->resok.wtmax = xfer_size;
3876         resp->resok.wtpref = xfer_size;
3877         resp->resok.wtmult = DEV_BSIZE;
3878         resp->resok.dtpref = MAXBSIZE;
3879 
3880         /*
3881          * Large file spec: want maxfilesize based on limit of
3882          * underlying filesystem.  We can guess 2^31-1 if need be.
3883          */
3884         error = VOP_PATHCONF(vp, _PC_FILESIZEBITS, &l, cr, NULL);
3885         if (error) {
3886                 resp->status = puterrno3(error);
3887                 goto out;


3950                 error = ESTALE;
3951                 goto out;
3952         }
3953 
3954         if (is_system_labeled()) {
3955                 bslabel_t *clabel = req->rq_label;
3956 
3957                 ASSERT(clabel != NULL);
3958                 DTRACE_PROBE2(tx__rfs3__log__info__oppathconf__clabel, char *,
3959                     "got client label from request(1)", struct svc_req *, req);
3960 
3961                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3962                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3963                             exi)) {
3964                                 resp->status = NFS3ERR_ACCES;
3965                                 goto out1;
3966                         }
3967                 }
3968         }
3969 







3970         va.va_mask = AT_ALL;
3971         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;

3972 
3973         error = VOP_PATHCONF(vp, _PC_LINK_MAX, &val, cr, NULL);
3974         if (error)
3975                 goto out;
3976         resp->resok.info.link_max = (uint32)val;
3977 
3978         error = VOP_PATHCONF(vp, _PC_NAME_MAX, &val, cr, NULL);
3979         if (error)
3980                 goto out;
3981         resp->resok.info.name_max = (uint32)val;
3982 
3983         error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &val, cr, NULL);
3984         if (error)
3985                 goto out;
3986         if (val == 1)
3987                 resp->resok.info.no_trunc = TRUE;
3988         else
3989                 resp->resok.info.no_trunc = FALSE;
3990 
3991         error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &val, cr, NULL);


4043         vp = nfs3_fhtovp(&args->file, exi);
4044 
4045         DTRACE_NFSV3_4(op__commit__start, struct svc_req *, req,
4046             cred_t *, cr, vnode_t *, vp, COMMIT3args *, args);
4047 
4048         if (vp == NULL) {
4049                 error = ESTALE;
4050                 goto out;
4051         }
4052 
4053         bva.va_mask = AT_ALL;
4054         error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4055 
4056         /*
4057          * If we can't get the attributes, then we can't do the
4058          * right access checking.  So, we'll fail the request.
4059          */
4060         if (error)
4061                 goto out;
4062 


4063         bvap = &bva;





4064 
4065         if (rdonly(exi, req)) {
4066                 resp->status = NFS3ERR_ROFS;
4067                 goto out1;
4068         }
4069 
4070         if (vp->v_type != VREG) {
4071                 resp->status = NFS3ERR_INVAL;
4072                 goto out1;
4073         }
4074 
4075         if (is_system_labeled()) {
4076                 bslabel_t *clabel = req->rq_label;
4077 
4078                 ASSERT(clabel != NULL);
4079                 DTRACE_PROBE2(tx__rfs3__log__info__opcommit__clabel, char *,
4080                     "got client label from request(1)", struct svc_req *, req);
4081 
4082                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4083                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
4084                             exi)) {
4085                                 resp->status = NFS3ERR_ACCES;
4086                                 goto out1;
4087                         }
4088                 }
4089         }
4090 
4091         if (crgetuid(cr) != bva.va_uid &&
4092             (error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL)))
4093                 goto out;
4094 
4095         error = VOP_FSYNC(vp, FSYNC, cr, NULL);
4096 


4097         ava.va_mask = AT_ALL;
4098         avap = VOP_GETATTR(vp, &ava, 0, cr, NULL) ? NULL : &ava;






4099 
4100         if (error)
4101                 goto out;
4102 
4103         resp->status = NFS3_OK;
4104         vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
4105         resp->resok.verf = write3verf;
4106 
4107         DTRACE_NFSV3_4(op__commit__done, struct svc_req *, req,
4108             cred_t *, cr, vnode_t *, vp, COMMIT3res *, resp);
4109 
4110         VN_RELE(vp);
4111 
4112         return;
4113 
4114 out:
4115         if (curthread->t_flag & T_WOULDBLOCK) {
4116                 curthread->t_flag &= ~T_WOULDBLOCK;
4117                 resp->status = NFS3ERR_JUKEBOX;
4118         } else