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,


 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;


 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,


 481 
 482         if (is_system_labeled() && error == 0) {
 483                 bslabel_t *clabel = req->rq_label;
 484 
 485                 ASSERT(clabel != NULL);
 486                 DTRACE_PROBE2(tx__rfs3__log__info__oplookup__clabel, char *,
 487                     "got client label from request(1)", struct svc_req *, req);
 488 
 489                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 490                         if (!do_rfs_label_check(clabel, dvp,
 491                             DOMINANCE_CHECK, exi)) {
 492                                 if (publicfh_flag && exi != NULL)
 493                                         exi_rele(exi);
 494                                 VN_RELE(vp);
 495                                 resp->status = NFS3ERR_ACCES;
 496                                 error = 1;
 497                         }
 498                 }
 499         }
 500 







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

 503 
 504         if (error)
 505                 goto out;
 506 
 507         if (sec.sec_flags & SEC_QUERY) {
 508                 error = makefh3_ol(&resp->resok.object, exi, sec.sec_index);
 509         } else {
 510                 error = makefh3(&resp->resok.object, vp, exi);
 511                 if (!error && publicfh_flag && !chk_clnt_sec(exi, req))
 512                         auth_weak = TRUE;
 513         }
 514 
 515         if (error) {
 516                 VN_RELE(vp);
 517                 goto out;
 518         }
 519 
 520         /*
 521          * If publicfh_flag is true then we have called rfs_publicfh_mclookup
 522          * and have obtained a new exportinfo in exi which needs to be
 523          * released. Note the the original exportinfo pointed to by exi
 524          * will be released by the caller, common_dispatch.
 525          */
 526         if (publicfh_flag)
 527                 exi_rele(exi);
 528 


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






 531 
 532         VN_RELE(vp);
 533 
 534         resp->status = NFS3_OK;
 535         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 536         vattr_to_post_op_attr(dvap, &resp->resok.dir_attributes);
 537 
 538         /*
 539          * If it's public fh, no 0x81, and client's flavor is
 540          * invalid, set WebNFS status to WNFSERR_CLNT_FLAVOR now.
 541          * Then set RPC status to AUTH_TOOWEAK in common_dispatch.
 542          */
 543         if (auth_weak)
 544                 resp->status = (enum nfsstat3)WNFSERR_CLNT_FLAVOR;
 545 
 546         DTRACE_NFSV3_4(op__lookup__done, struct svc_req *, req,
 547             cred_t *, cr, vnode_t *, dvp, LOOKUP3res *, resp);
 548         VN_RELE(dvp);
 549 
 550         return;


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




 623         vap = &va;

 624 
 625         resp->resok.access = 0;
 626 
 627         if (is_system_labeled()) {
 628                 bslabel_t *clabel = req->rq_label;
 629 
 630                 ASSERT(clabel != NULL);
 631                 DTRACE_PROBE2(tx__rfs3__log__info__opaccess__clabel, char *,
 632                     "got client label from request(1)", struct svc_req *, req);
 633 
 634                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
 635                         if ((equal_label = do_rfs_label_check(clabel, vp,
 636                             EQUALITY_CHECK, exi)) == B_FALSE) {
 637                                 dominant_label = do_rfs_label_check(clabel,
 638                                     vp, DOMINANCE_CHECK, exi);
 639                         } else
 640                                 dominant_label = B_TRUE;
 641                         admin_low_client = B_FALSE;
 642                 } else
 643                         admin_low_client = B_TRUE;


 678             (args->access & ACCESS3_DELETE) && vp->v_type == VDIR) {
 679                 error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL);
 680                 if (error) {
 681                         if (curthread->t_flag & T_WOULDBLOCK)
 682                                 goto out;
 683                 } else if (!is_system_labeled() || admin_low_client ||
 684                     equal_label)
 685                         resp->resok.access |= ACCESS3_DELETE;
 686         }
 687         if (args->access & ACCESS3_EXECUTE) {
 688                 error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL);
 689                 if (error) {
 690                         if (curthread->t_flag & T_WOULDBLOCK)
 691                                 goto out;
 692                 } else if (!MANDLOCK(vp, va.va_mode) &&
 693                     (!is_system_labeled() || admin_low_client ||
 694                     dominant_label))
 695                         resp->resok.access |= ACCESS3_EXECUTE;
 696         }
 697 


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






 700 
 701         resp->status = NFS3_OK;
 702         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
 703 
 704         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 705             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 706 
 707         VN_RELE(vp);
 708 
 709         return;
 710 
 711 out:
 712         if (curthread->t_flag & T_WOULDBLOCK) {
 713                 curthread->t_flag &= ~T_WOULDBLOCK;
 714                 resp->status = NFS3ERR_JUKEBOX;
 715         } else
 716                 resp->status = puterrno3(error);
 717         DTRACE_NFSV3_4(op__access__done, struct svc_req *, req,
 718             cred_t *, cr, vnode_t *, vp, ACCESS3res *, resp);
 719         if (vp != NULL)


 744         char *name = NULL;
 745         int is_referral = 0;
 746 
 747         vap = NULL;
 748 
 749         vp = nfs3_fhtovp(&args->symlink, exi);
 750 
 751         DTRACE_NFSV3_4(op__readlink__start, struct svc_req *, req,
 752             cred_t *, cr, vnode_t *, vp, READLINK3args *, args);
 753 
 754         if (vp == NULL) {
 755                 error = ESTALE;
 756                 goto out;
 757         }
 758 
 759         va.va_mask = AT_ALL;
 760         error = VOP_GETATTR(vp, &va, 0, cr, NULL);
 761         if (error)
 762                 goto out;
 763 




 764         vap = &va;

 765 
 766         /* We lied about the object type for a referral */
 767         if (vn_is_nfs_reparse(vp, cr))
 768                 is_referral = 1;
 769 
 770         if (vp->v_type != VLNK && !is_referral) {
 771                 resp->status = NFS3ERR_INVAL;
 772                 goto out1;
 773         }
 774 
 775         if (MANDLOCK(vp, va.va_mode)) {
 776                 resp->status = NFS3ERR_ACCES;
 777                 goto out1;
 778         }
 779 
 780         if (is_system_labeled()) {
 781                 bslabel_t *clabel = req->rq_label;
 782 
 783                 ASSERT(clabel != NULL);
 784                 DTRACE_PROBE2(tx__rfs3__log__info__opreadlink__clabel, char *,


 812                         kmem_free(s, strsz);
 813                 }
 814 
 815         } else {
 816 
 817                 iov.iov_base = data;
 818                 iov.iov_len = MAXPATHLEN;
 819                 uio.uio_iov = &iov;
 820                 uio.uio_iovcnt = 1;
 821                 uio.uio_segflg = UIO_SYSSPACE;
 822                 uio.uio_extflg = UIO_COPY_CACHED;
 823                 uio.uio_loffset = 0;
 824                 uio.uio_resid = MAXPATHLEN;
 825 
 826                 error = VOP_READLINK(vp, &uio, cr, NULL);
 827 
 828                 if (!error)
 829                         *(data + MAXPATHLEN - uio.uio_resid) = '\0';
 830         }
 831 







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


 993         error = VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &ct);
 994 
 995         /* check if a monitor detected a delegation conflict */
 996         if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
 997                 resp->status = NFS3ERR_JUKEBOX;
 998                 goto out1;
 999         }
1000 
1001         need_rwunlock = 1;
1002 
1003         va.va_mask = AT_ALL;
1004         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1005 
1006         /*
1007          * If we can't get the attributes, then we can't do the
1008          * right access checking.  So, we'll fail the request.
1009          */
1010         if (error)
1011                 goto out;
1012 




1013         vap = &va;

1014 
1015         if (vp->v_type != VREG) {
1016                 resp->status = NFS3ERR_INVAL;
1017                 goto out1;
1018         }
1019 
1020         if (crgetuid(cr) != va.va_uid) {
1021                 error = VOP_ACCESS(vp, VREAD, 0, cr, &ct);
1022                 if (error) {
1023                         if (curthread->t_flag & T_WOULDBLOCK)
1024                                 goto out;
1025                         error = VOP_ACCESS(vp, VEXEC, 0, cr, &ct);
1026                         if (error)
1027                                 goto out;
1028                 }
1029         }
1030 
1031         if (MANDLOCK(vp, va.va_mode)) {
1032                 resp->status = NFS3ERR_ACCES;
1033                 goto out1;


1143         if (error) {
1144                 if (mp)
1145                         freemsg(mp);
1146                 /* check if a monitor detected a delegation conflict */
1147                 if (error == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1148                         resp->status = NFS3ERR_JUKEBOX;
1149                         goto out1;
1150                 }
1151                 goto out;
1152         }
1153 
1154         /* make mblk using zc buffers */
1155         if (loaned_buffers) {
1156                 mp = uio_to_mblk(uiop);
1157                 ASSERT(mp != NULL);
1158         }
1159 
1160         va.va_mask = AT_ALL;
1161         error = VOP_GETATTR(vp, &va, 0, cr, &ct);
1162 


1163         if (error)
1164                 vap = NULL;
1165         else
1166                 vap = &va;








1167 
1168         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &ct);
1169 
1170         if (in_crit)
1171                 nbl_end_crit(vp);
1172 
1173         resp->status = NFS3_OK;
1174         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
1175         resp->resok.count = args->count - uiop->uio_resid;
1176         if (!error && offset + resp->resok.count == va.va_size)
1177                 resp->resok.eof = TRUE;
1178         else
1179                 resp->resok.eof = FALSE;
1180         resp->resok.data.data_len = resp->resok.count;
1181 
1182         if (mp)
1183                 rfs_rndup_mblks(mp, resp->resok.count, loaned_buffers);
1184 
1185         resp->resok.data.mp = mp;
1186         resp->resok.size = (uint_t)args->count;


1320 
1321         /* check if a monitor detected a delegation conflict */
1322         if (rwlock_ret == EAGAIN && (ct.cc_flags & CC_WOULDBLOCK)) {
1323                 resp->status = NFS3ERR_JUKEBOX;
1324                 rwlock_ret = -1;
1325                 goto err1;
1326         }
1327 
1328 
1329         bva.va_mask = AT_ALL;
1330         error = VOP_GETATTR(vp, &bva, 0, cr, &ct);
1331 
1332         /*
1333          * If we can't get the attributes, then we can't do the
1334          * right access checking.  So, we'll fail the request.
1335          */
1336         if (error)
1337                 goto err;
1338 
1339         bvap = &bva;




1340         avap = bvap;
1341 
1342         if (args->count != args->data.data_len) {
1343                 resp->status = NFS3ERR_INVAL;
1344                 goto err1;
1345         }
1346 
1347         if (rdonly(exi, req)) {
1348                 resp->status = NFS3ERR_ROFS;
1349                 goto err1;
1350         }
1351 
1352         if (vp->v_type != VREG) {
1353                 resp->status = NFS3ERR_INVAL;
1354                 goto err1;
1355         }
1356 
1357         if (crgetuid(cr) != bva.va_uid &&
1358             (error = VOP_ACCESS(vp, VWRITE, 0, cr, &ct)))
1359                 goto err;


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





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


1519         enum vcexcl excl;
1520         nfstime3 *mtime;
1521         len_t reqsize;
1522         bool_t trunc;
1523         struct sockaddr *ca;
1524         char *name = NULL;
1525 
1526         dbvap = NULL;
1527         davap = NULL;
1528 
1529         dvp = nfs3_fhtovp(&args->where.dir, exi);
1530 
1531         DTRACE_NFSV3_4(op__create__start, struct svc_req *, req,
1532             cred_t *, cr, vnode_t *, dvp, CREATE3args *, args);
1533 
1534         if (dvp == NULL) {
1535                 error = ESTALE;
1536                 goto out;
1537         }
1538 







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

1541         davap = dbvap;
1542 
1543         if (args->where.name == nfs3nametoolong) {
1544                 resp->status = NFS3ERR_NAMETOOLONG;
1545                 goto out1;
1546         }
1547 
1548         if (args->where.name == NULL || *(args->where.name) == '\0') {
1549                 resp->status = NFS3ERR_ACCES;
1550                 goto out1;
1551         }
1552 
1553         if (rdonly(exi, req)) {
1554                 resp->status = NFS3ERR_ROFS;
1555                 goto out1;
1556         }
1557 
1558         if (is_system_labeled()) {
1559                 bslabel_t *clabel = req->rq_label;
1560 


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







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

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


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










1808         error = makefh3(&resp->resok.obj.handle, vp, exi);
1809         if (error)
1810                 resp->resok.obj.handle_follows = FALSE;
1811         else
1812                 resp->resok.obj.handle_follows = TRUE;



1813 
1814         /*
1815          * Force modified data and metadata out to stable storage.
1816          */
1817         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
1818         (void) VOP_FSYNC(dvp, 0, cr, NULL);
1819 
1820         VN_RELE(vp);
1821         if (tvp != NULL) {
1822                 if (in_crit)
1823                         nbl_end_crit(tvp);
1824                 VN_RELE(tvp);
1825         }
1826 
1827         resp->status = NFS3_OK;
1828         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
1829         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
1830 
1831         DTRACE_NFSV3_4(op__create__done, struct svc_req *, req,
1832             cred_t *, cr, vnode_t *, dvp, CREATE3res *, resp);


1876         struct vattr *dbvap;
1877         struct vattr dbva;
1878         struct vattr *davap;
1879         struct vattr dava;
1880         struct sockaddr *ca;
1881         char *name = NULL;
1882 
1883         dbvap = NULL;
1884         davap = NULL;
1885 
1886         dvp = nfs3_fhtovp(&args->where.dir, exi);
1887 
1888         DTRACE_NFSV3_4(op__mkdir__start, struct svc_req *, req,
1889             cred_t *, cr, vnode_t *, dvp, MKDIR3args *, args);
1890 
1891         if (dvp == NULL) {
1892                 error = ESTALE;
1893                 goto out;
1894         }
1895 







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

1898         davap = dbvap;
1899 
1900         if (args->where.name == nfs3nametoolong) {
1901                 resp->status = NFS3ERR_NAMETOOLONG;
1902                 goto out1;
1903         }
1904 
1905         if (args->where.name == NULL || *(args->where.name) == '\0') {
1906                 resp->status = NFS3ERR_ACCES;
1907                 goto out1;
1908         }
1909 
1910         if (rdonly(exi, req)) {
1911                 resp->status = NFS3ERR_ROFS;
1912                 goto out1;
1913         }
1914 
1915         if (is_system_labeled()) {
1916                 bslabel_t *clabel = req->rq_label;
1917 


1937                 goto out1;
1938         }
1939 
1940         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
1941         name = nfscmd_convname(ca, exi, args->where.name,
1942             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
1943 
1944         if (name == NULL) {
1945                 resp->status = NFS3ERR_INVAL;
1946                 goto out1;
1947         }
1948 
1949         va.va_mask |= AT_TYPE;
1950         va.va_type = VDIR;
1951 
1952         error = VOP_MKDIR(dvp, name, &va, &vp, cr, NULL, 0, NULL);
1953 
1954         if (name != args->where.name)
1955                 kmem_free(name, MAXPATHLEN + 1);
1956 







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

1959 
1960         /*
1961          * Force modified data and metadata out to stable storage.
1962          */
1963         (void) VOP_FSYNC(dvp, 0, cr, NULL);
1964 
1965         if (error)
1966                 goto out;
1967 





1968         error = makefh3(&resp->resok.obj.handle, vp, exi);
1969         if (error)
1970                 resp->resok.obj.handle_follows = FALSE;
1971         else
1972                 resp->resok.obj.handle_follows = TRUE;



1973 







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

1976 
1977         /*
1978          * Force modified data and metadata out to stable storage.
1979          */
1980         (void) VOP_FSYNC(vp, 0, cr, NULL);
1981 
1982         VN_RELE(vp);
1983 
1984         resp->status = NFS3_OK;
1985         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
1986         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
1987 
1988         DTRACE_NFSV3_4(op__mkdir__done, struct svc_req *, req,
1989             cred_t *, cr, vnode_t *, dvp, MKDIR3res *, resp);
1990         VN_RELE(dvp);
1991 
1992         return;
1993 
1994 out:
1995         if (curthread->t_flag & T_WOULDBLOCK) {


2025         struct vattr dbva;
2026         struct vattr *davap;
2027         struct vattr dava;
2028         struct sockaddr *ca;
2029         char *name = NULL;
2030         char *symdata = NULL;
2031 
2032         dbvap = NULL;
2033         davap = NULL;
2034 
2035         dvp = nfs3_fhtovp(&args->where.dir, exi);
2036 
2037         DTRACE_NFSV3_4(op__symlink__start, struct svc_req *, req,
2038             cred_t *, cr, vnode_t *, dvp, SYMLINK3args *, args);
2039 
2040         if (dvp == NULL) {
2041                 error = ESTALE;
2042                 goto err;
2043         }
2044 







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

2047         davap = dbvap;
2048 
2049         if (args->where.name == nfs3nametoolong) {
2050                 resp->status = NFS3ERR_NAMETOOLONG;
2051                 goto err1;
2052         }
2053 
2054         if (args->where.name == NULL || *(args->where.name) == '\0') {
2055                 resp->status = NFS3ERR_ACCES;
2056                 goto err1;
2057         }
2058 
2059         if (rdonly(exi, req)) {
2060                 resp->status = NFS3ERR_ROFS;
2061                 goto err1;
2062         }
2063 
2064         if (is_system_labeled()) {
2065                 bslabel_t *clabel = req->rq_label;
2066 


2098         if (name == NULL) {
2099                 /* This is really a Solaris EILSEQ */
2100                 resp->status = NFS3ERR_INVAL;
2101                 goto err1;
2102         }
2103 
2104         symdata = nfscmd_convname(ca, exi, args->symlink.symlink_data,
2105             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2106         if (symdata == NULL) {
2107                 /* This is really a Solaris EILSEQ */
2108                 resp->status = NFS3ERR_INVAL;
2109                 goto err1;
2110         }
2111 
2112 
2113         va.va_mask |= AT_TYPE;
2114         va.va_type = VLNK;
2115 
2116         error = VOP_SYMLINK(dvp, name, &va, symdata, cr, NULL, 0);
2117 


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






2120 
2121         if (error)
2122                 goto err;
2123 
2124         error = VOP_LOOKUP(dvp, name, &vp, NULL, 0, NULL, cr,
2125             NULL, NULL, NULL);
2126 
2127         /*
2128          * Force modified data and metadata out to stable storage.
2129          */
2130         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2131 
2132 
2133         resp->status = NFS3_OK;
2134         if (error) {
2135                 resp->resok.obj.handle_follows = FALSE;
2136                 vattr_to_post_op_attr(NULL, &resp->resok.obj_attributes);
2137                 vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2138                 goto out;
2139         }
2140 





2141         error = makefh3(&resp->resok.obj.handle, vp, exi);
2142         if (error)
2143                 resp->resok.obj.handle_follows = FALSE;
2144         else
2145                 resp->resok.obj.handle_follows = TRUE;



2146 


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






2149 
2150         /*
2151          * Force modified data and metadata out to stable storage.
2152          */
2153         (void) VOP_FSYNC(vp, 0, cr, NULL);
2154 
2155         VN_RELE(vp);
2156 
2157         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2158         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2159         goto out;
2160 
2161 err:
2162         if (curthread->t_flag & T_WOULDBLOCK) {
2163                 curthread->t_flag &= ~T_WOULDBLOCK;
2164                 resp->status = NFS3ERR_JUKEBOX;
2165         } else
2166                 resp->status = puterrno3(error);
2167 err1:
2168         vattr_to_wcc_data(dbvap, davap, &resp->resfail.dir_wcc);


2201         struct vattr *davap;
2202         struct vattr dava;
2203         int mode;
2204         enum vcexcl excl;
2205         struct sockaddr *ca;
2206         char *name = NULL;
2207 
2208         dbvap = NULL;
2209         davap = NULL;
2210 
2211         dvp = nfs3_fhtovp(&args->where.dir, exi);
2212 
2213         DTRACE_NFSV3_4(op__mknod__start, struct svc_req *, req,
2214             cred_t *, cr, vnode_t *, dvp, MKNOD3args *, args);
2215 
2216         if (dvp == NULL) {
2217                 error = ESTALE;
2218                 goto out;
2219         }
2220 







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

2223         davap = dbvap;
2224 
2225         if (args->where.name == nfs3nametoolong) {
2226                 resp->status = NFS3ERR_NAMETOOLONG;
2227                 goto out1;
2228         }
2229 
2230         if (args->where.name == NULL || *(args->where.name) == '\0') {
2231                 resp->status = NFS3ERR_ACCES;
2232                 goto out1;
2233         }
2234 
2235         if (rdonly(exi, req)) {
2236                 resp->status = NFS3ERR_ROFS;
2237                 goto out1;
2238         }
2239 
2240         if (is_system_labeled()) {
2241                 bslabel_t *clabel = req->rq_label;
2242 


2304 
2305         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2306         name = nfscmd_convname(ca, exi, args->where.name,
2307             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2308 
2309         if (name == NULL) {
2310                 resp->status = NFS3ERR_INVAL;
2311                 goto out1;
2312         }
2313 
2314         excl = EXCL;
2315 
2316         mode = 0;
2317 
2318         error = VOP_CREATE(dvp, name, &va, excl, mode,
2319             &vp, cr, 0, NULL, NULL);
2320 
2321         if (name != args->where.name)
2322                 kmem_free(name, MAXPATHLEN + 1);
2323 







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

2326 
2327         /*
2328          * Force modified data and metadata out to stable storage.
2329          */
2330         (void) VOP_FSYNC(dvp, 0, cr, NULL);
2331 
2332         if (error)
2333                 goto out;
2334 
2335         resp->status = NFS3_OK;
2336 





2337         error = makefh3(&resp->resok.obj.handle, vp, exi);
2338         if (error)
2339                 resp->resok.obj.handle_follows = FALSE;
2340         else
2341                 resp->resok.obj.handle_follows = TRUE;



2342 


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






2345 
2346         /*
2347          * Force modified metadata out to stable storage.
2348          *
2349          * if a underlying vp exists, pass it to VOP_FSYNC
2350          */
2351         if (VOP_REALVP(vp, &realvp, NULL) == 0)
2352                 (void) VOP_FSYNC(realvp, FNODSYNC, cr, NULL);
2353         else
2354                 (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
2355 
2356         VN_RELE(vp);
2357 
2358         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
2359         vattr_to_wcc_data(dbvap, davap, &resp->resok.dir_wcc);
2360         DTRACE_NFSV3_4(op__mknod__done, struct svc_req *, req,
2361             cred_t *, cr, vnode_t *, dvp, MKNOD3res *, resp);
2362         VN_RELE(dvp);
2363         return;
2364 


2393         struct vattr bva;
2394         struct vattr *avap;
2395         struct vattr ava;
2396         vnode_t *targvp = NULL;
2397         struct sockaddr *ca;
2398         char *name = NULL;
2399 
2400         bvap = NULL;
2401         avap = NULL;
2402 
2403         vp = nfs3_fhtovp(&args->object.dir, exi);
2404 
2405         DTRACE_NFSV3_4(op__remove__start, struct svc_req *, req,
2406             cred_t *, cr, vnode_t *, vp, REMOVE3args *, args);
2407 
2408         if (vp == NULL) {
2409                 error = ESTALE;
2410                 goto err;
2411         }
2412 







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

2415         avap = bvap;
2416 
2417         if (vp->v_type != VDIR) {
2418                 resp->status = NFS3ERR_NOTDIR;
2419                 goto err1;
2420         }
2421 
2422         if (args->object.name == nfs3nametoolong) {
2423                 resp->status = NFS3ERR_NAMETOOLONG;
2424                 goto err1;
2425         }
2426 
2427         if (args->object.name == NULL || *(args->object.name) == '\0') {
2428                 resp->status = NFS3ERR_ACCES;
2429                 goto err1;
2430         }
2431 
2432         if (rdonly(exi, req)) {
2433                 resp->status = NFS3ERR_ROFS;
2434                 goto err1;


2470 
2471         if (rfs4_check_delegated(FWRITE, targvp, TRUE)) {
2472                 resp->status = NFS3ERR_JUKEBOX;
2473                 goto err1;
2474         }
2475 
2476         if (!nbl_need_check(targvp)) {
2477                 error = VOP_REMOVE(vp, name, cr, NULL, 0);
2478         } else {
2479                 nbl_start_crit(targvp, RW_READER);
2480                 if (nbl_conflict(targvp, NBL_REMOVE, 0, 0, 0, NULL)) {
2481                         error = EACCES;
2482                 } else {
2483                         error = VOP_REMOVE(vp, name, cr, NULL, 0);
2484                 }
2485                 nbl_end_crit(targvp);
2486         }
2487         VN_RELE(targvp);
2488         targvp = NULL;
2489 







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

2492 
2493         /*
2494          * Force modified data and metadata out to stable storage.
2495          */
2496         (void) VOP_FSYNC(vp, 0, cr, NULL);
2497 
2498         if (error)
2499                 goto err;
2500 
2501         resp->status = NFS3_OK;
2502         vattr_to_wcc_data(bvap, avap, &resp->resok.dir_wcc);
2503         goto out;
2504 
2505 err:
2506         if (curthread->t_flag & T_WOULDBLOCK) {
2507                 curthread->t_flag &= ~T_WOULDBLOCK;
2508                 resp->status = NFS3ERR_JUKEBOX;
2509         } else
2510                 resp->status = puterrno3(error);
2511 err1:


2537         struct vattr *bvap;
2538         struct vattr bva;
2539         struct vattr *avap;
2540         struct vattr ava;
2541         struct sockaddr *ca;
2542         char *name = NULL;
2543 
2544         bvap = NULL;
2545         avap = NULL;
2546 
2547         vp = nfs3_fhtovp(&args->object.dir, exi);
2548 
2549         DTRACE_NFSV3_4(op__rmdir__start, struct svc_req *, req,
2550             cred_t *, cr, vnode_t *, vp, RMDIR3args *, args);
2551 
2552         if (vp == NULL) {
2553                 error = ESTALE;
2554                 goto err;
2555         }
2556 


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






2559         avap = bvap;
2560 
2561         if (vp->v_type != VDIR) {
2562                 resp->status = NFS3ERR_NOTDIR;
2563                 goto err1;
2564         }
2565 
2566         if (args->object.name == nfs3nametoolong) {
2567                 resp->status = NFS3ERR_NAMETOOLONG;
2568                 goto err1;
2569         }
2570 
2571         if (args->object.name == NULL || *(args->object.name) == '\0') {
2572                 resp->status = NFS3ERR_ACCES;
2573                 goto err1;
2574         }
2575 
2576         if (rdonly(exi, req)) {
2577                 resp->status = NFS3ERR_ROFS;
2578                 goto err1;


2591                                 resp->status = NFS3ERR_ACCES;
2592                                 goto err1;
2593                         }
2594                 }
2595         }
2596 
2597         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2598         name = nfscmd_convname(ca, exi, args->object.name,
2599             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
2600 
2601         if (name == NULL) {
2602                 resp->status = NFS3ERR_INVAL;
2603                 goto err1;
2604         }
2605 
2606         error = VOP_RMDIR(vp, name, rootdir, cr, NULL, 0);
2607 
2608         if (name != args->object.name)
2609                 kmem_free(name, MAXPATHLEN + 1);
2610 


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






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


2693         if (fvp == NULL) {
2694                 error = ESTALE;
2695                 goto err;
2696         }
2697 
2698         if (is_system_labeled()) {
2699                 clabel = req->rq_label;
2700                 ASSERT(clabel != NULL);
2701                 DTRACE_PROBE2(tx__rfs3__log__info__oprename__clabel, char *,
2702                     "got client label from request(1)", struct svc_req *, req);
2703 
2704                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2705                         if (!do_rfs_label_check(clabel, fvp, EQUALITY_CHECK,
2706                             exi)) {
2707                                 resp->status = NFS3ERR_ACCES;
2708                                 goto err1;
2709                         }
2710                 }
2711         }
2712 







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

2715         favap = fbvap;
2716 
2717         fh3 = &args->to.dir;
2718         to_exi = checkexport(&fh3->fh3_fsid, FH3TOXFIDP(fh3));
2719         if (to_exi == NULL) {
2720                 resp->status = NFS3ERR_ACCES;
2721                 goto err1;
2722         }
2723         exi_rele(to_exi);
2724 
2725         if (to_exi != exi) {
2726                 resp->status = NFS3ERR_XDEV;
2727                 goto err1;
2728         }
2729 
2730         tvp = nfs3_fhtovp(&args->to.dir, exi);
2731         if (tvp == NULL) {
2732                 error = ESTALE;
2733                 goto err;
2734         }
2735 


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






2738         tavap = tbvap;
2739 
2740         if (fvp->v_type != VDIR || tvp->v_type != VDIR) {
2741                 resp->status = NFS3ERR_NOTDIR;
2742                 goto err1;
2743         }
2744 
2745         if (args->from.name == nfs3nametoolong ||
2746             args->to.name == nfs3nametoolong) {
2747                 resp->status = NFS3ERR_NAMETOOLONG;
2748                 goto err1;
2749         }
2750         if (args->from.name == NULL || *(args->from.name) == '\0' ||
2751             args->to.name == NULL || *(args->to.name) == '\0') {
2752                 resp->status = NFS3ERR_ACCES;
2753                 goto err1;
2754         }
2755 
2756         if (rdonly(exi, req)) {
2757                 resp->status = NFS3ERR_ROFS;


2819                 }
2820                 VN_RELE(targvp);
2821         }
2822 
2823         if (!nbl_need_check(srcvp)) {
2824                 error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
2825         } else {
2826                 nbl_start_crit(srcvp, RW_READER);
2827                 if (nbl_conflict(srcvp, NBL_RENAME, 0, 0, 0, NULL))
2828                         error = EACCES;
2829                 else
2830                         error = VOP_RENAME(fvp, name, tvp, toname, cr, NULL, 0);
2831                 nbl_end_crit(srcvp);
2832         }
2833         if (error == 0)
2834                 vn_renamepath(tvp, srcvp, args->to.name,
2835                     strlen(args->to.name));
2836         VN_RELE(srcvp);
2837         srcvp = NULL;
2838 


2839         fava.va_mask = AT_ALL;
2840         favap = VOP_GETATTR(fvp, &fava, 0, cr, NULL) ? NULL : &fava;
2841         tava.va_mask = AT_ALL;
2842         tavap = VOP_GETATTR(tvp, &tava, 0, cr, NULL) ? NULL : &tava;










2843 
2844         /*
2845          * Force modified data and metadata out to stable storage.
2846          */
2847         (void) VOP_FSYNC(fvp, 0, cr, NULL);
2848         (void) VOP_FSYNC(tvp, 0, cr, NULL);
2849 
2850         if (error)
2851                 goto err;
2852 
2853         resp->status = NFS3_OK;
2854         vattr_to_wcc_data(fbvap, favap, &resp->resok.fromdir_wcc);
2855         vattr_to_wcc_data(tbvap, tavap, &resp->resok.todir_wcc);
2856         goto out;
2857 
2858 err:
2859         if (curthread->t_flag & T_WOULDBLOCK) {
2860                 curthread->t_flag &= ~T_WOULDBLOCK;
2861                 resp->status = NFS3ERR_JUKEBOX;
2862         } else {


2904         struct exportinfo *to_exi;
2905         bslabel_t *clabel;
2906         struct sockaddr *ca;
2907         char *name = NULL;
2908 
2909         vap = NULL;
2910         bvap = NULL;
2911         avap = NULL;
2912         dvp = NULL;
2913 
2914         vp = nfs3_fhtovp(&args->file, exi);
2915 
2916         DTRACE_NFSV3_4(op__link__start, struct svc_req *, req,
2917             cred_t *, cr, vnode_t *, vp, LINK3args *, args);
2918 
2919         if (vp == NULL) {
2920                 error = ESTALE;
2921                 goto out;
2922         }
2923 


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






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







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

2964 
2965         if (dvp->v_type != VDIR) {
2966                 resp->status = NFS3ERR_NOTDIR;
2967                 goto out1;
2968         }
2969 
2970         if (args->link.name == nfs3nametoolong) {
2971                 resp->status = NFS3ERR_NAMETOOLONG;
2972                 goto out1;
2973         }
2974 
2975         if (args->link.name == NULL || *(args->link.name) == '\0') {
2976                 resp->status = NFS3ERR_ACCES;
2977                 goto out1;
2978         }
2979 
2980         if (rdonly(exi, req)) {
2981                 resp->status = NFS3ERR_ROFS;
2982                 goto out1;
2983         }


2989                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
2990                         if (!do_rfs_label_check(clabel, dvp, EQUALITY_CHECK,
2991                             exi)) {
2992                                 resp->status = NFS3ERR_ACCES;
2993                                 goto out1;
2994                         }
2995                 }
2996         }
2997 
2998         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
2999         name = nfscmd_convname(ca, exi, args->link.name,
3000             NFSCMD_CONV_INBOUND, MAXPATHLEN + 1);
3001 
3002         if (name == NULL) {
3003                 resp->status = NFS3ERR_SERVERFAULT;
3004                 goto out1;
3005         }
3006 
3007         error = VOP_LINK(dvp, vp, name, cr, NULL, 0);
3008 


3009         va.va_mask = AT_ALL;
3010         vap = VOP_GETATTR(vp, &va, 0, cr, NULL) ? NULL : &va;
3011         ava.va_mask = AT_ALL;
3012         avap = VOP_GETATTR(dvp, &ava, 0, cr, NULL) ? NULL : &ava;










3013 
3014         /*
3015          * Force modified data and metadata out to stable storage.
3016          */
3017         (void) VOP_FSYNC(vp, FNODSYNC, cr, NULL);
3018         (void) VOP_FSYNC(dvp, 0, cr, NULL);
3019 
3020         if (error)
3021                 goto out;
3022 
3023         VN_RELE(dvp);
3024 
3025         resp->status = NFS3_OK;
3026         vattr_to_post_op_attr(vap, &resp->resok.file_attributes);
3027         vattr_to_wcc_data(bvap, avap, &resp->resok.linkdir_wcc);
3028 
3029         DTRACE_NFSV3_4(op__link__done, struct svc_req *, req,
3030             cred_t *, cr, vnode_t *, vp, LINK3res *, resp);
3031 
3032         VN_RELE(vp);


3121         }
3122 
3123         if (is_system_labeled()) {
3124                 bslabel_t *clabel = req->rq_label;
3125 
3126                 ASSERT(clabel != NULL);
3127                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddir__clabel, char *,
3128                     "got client label from request(1)", struct svc_req *, req);
3129 
3130                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3131                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3132                             exi)) {
3133                                 resp->status = NFS3ERR_ACCES;
3134                                 goto out1;
3135                         }
3136                 }
3137         }
3138 
3139         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3140 


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






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


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






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


3393 
3394         if (is_system_labeled()) {
3395                 bslabel_t *clabel = req->rq_label;
3396 
3397                 ASSERT(clabel != NULL);
3398                 DTRACE_PROBE2(tx__rfs3__log__info__opreaddirplus__clabel,
3399                     char *, "got client label from request(1)",
3400                     struct svc_req *, req);
3401 
3402                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3403                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3404                             exi)) {
3405                                 resp->status = NFS3ERR_ACCES;
3406                                 goto out1;
3407                         }
3408                 }
3409         }
3410 
3411         (void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
3412 







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

3415 
3416         if (vp->v_type != VDIR) {
3417                 error = ENOTDIR;
3418                 goto out;
3419         }
3420 
3421         error = VOP_ACCESS(vp, VREAD, 0, cr, NULL);
3422         if (error)
3423                 goto out;
3424 
3425         /*
3426          * Don't allow arbitrary counts for allocation
3427          */
3428         if (args->maxcount > rfs3_tsize(req))
3429                 args->maxcount = rfs3_tsize(req);
3430 
3431         /*
3432          * Make sure that there is room to read at least one entry
3433          * if any are available
3434          */


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

3573 good:



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






3576 
3577         VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
3578 
3579         infop = kmem_alloc(nents * sizeof (struct entryplus3_info), KM_SLEEP);
3580         resp->resok.infop = infop;
3581 
3582         dp = (struct dirent64 *)data;
3583         for (i = 0; i < nents; i++) {
3584 
3585                 if (dp->d_ino == 0) {
3586                         infop[i].attr.attributes = FALSE;
3587                         infop[i].fh.handle_follows = FALSE;
3588                         dp = nextdp(dp);
3589                         continue;
3590                 }
3591 
3592                 infop[i].namelen = namlen[i];
3593 
3594                 error = VOP_LOOKUP(vp, dp->d_name, &nvp, NULL, 0, NULL, cr,
3595                     NULL, NULL, NULL);
3596                 if (error) {
3597                         infop[i].attr.attributes = FALSE;
3598                         infop[i].fh.handle_follows = FALSE;
3599                         dp = nextdp(dp);
3600                         continue;
3601                 }
3602 








3603                 nva.va_mask = AT_ALL;
3604                 nvap = rfs4_delegated_getattr(nvp, &nva, 0, cr) ? NULL : &nva;
3605 
3606                 /* Lie about the object type for a referral */
3607                 if (vn_is_nfs_reparse(nvp, cr))
3608                         nvap->va_type = VLNK;
3609 
3610                 vattr_to_post_op_attr(nvap, &infop[i].attr);
3611 





3612                 error = makefh3(&infop[i].fh.handle, nvp, exi);
3613                 if (!error)
3614                         infop[i].fh.handle_follows = TRUE;
3615                 else
3616                         infop[i].fh.handle_follows = FALSE;



3617 
3618                 VN_RELE(nvp);
3619                 dp = nextdp(dp);
3620         }
3621 
3622         ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
3623         ret = nfscmd_convdirplus(ca, exi, data, nents, args->dircount, &ndata);
3624         if (ndata == NULL)
3625                 ndata = data;
3626 
3627         if (ret > 0) {
3628                 /*
3629                  * We had to drop one or more entries in order to fit
3630                  * during the character conversion.  We need to patch
3631                  * up the size and eof info.
3632                  */
3633                 if (iseof)
3634                         iseof = FALSE;
3635 
3636                 ret = nfscmd_dropped_entrysize((struct dirent64 *)data,


3735         }
3736 
3737         if (is_system_labeled()) {
3738                 bslabel_t *clabel = req->rq_label;
3739 
3740                 ASSERT(clabel != NULL);
3741                 DTRACE_PROBE2(tx__rfs3__log__info__opfsstat__clabel, char *,
3742                     "got client label from request(1)", struct svc_req *, req);
3743 
3744                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3745                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3746                             exi)) {
3747                                 resp->status = NFS3ERR_ACCES;
3748                                 goto out1;
3749                         }
3750                 }
3751         }
3752 
3753         error = VFS_STATVFS(vp->v_vfsp, &sb);
3754 


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






3757 
3758         if (error)
3759                 goto out;
3760 
3761         resp->status = NFS3_OK;
3762         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
3763         if (sb.f_blocks != (fsblkcnt64_t)-1)
3764                 resp->resok.tbytes = (size3)sb.f_frsize * (size3)sb.f_blocks;
3765         else
3766                 resp->resok.tbytes = (size3)sb.f_blocks;
3767         if (sb.f_bfree != (fsblkcnt64_t)-1)
3768                 resp->resok.fbytes = (size3)sb.f_frsize * (size3)sb.f_bfree;
3769         else
3770                 resp->resok.fbytes = (size3)sb.f_bfree;
3771         if (sb.f_bavail != (fsblkcnt64_t)-1)
3772                 resp->resok.abytes = (size3)sb.f_frsize * (size3)sb.f_bavail;
3773         else
3774                 resp->resok.abytes = (size3)sb.f_bavail;
3775         resp->resok.tfiles = (size3)sb.f_files;
3776         resp->resok.ffiles = (size3)sb.f_ffree;


3832         }
3833 
3834         if (is_system_labeled()) {
3835                 bslabel_t *clabel = req->rq_label;
3836 
3837                 ASSERT(clabel != NULL);
3838                 DTRACE_PROBE2(tx__rfs3__log__info__opfsinfo__clabel, char *,
3839                     "got client label from request(1)", struct svc_req *, req);
3840 
3841                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3842                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3843                             exi)) {
3844                                 resp->status = NFS3ERR_STALE;
3845                                 vattr_to_post_op_attr(NULL,
3846                                     &resp->resfail.obj_attributes);
3847                                 goto out;
3848                         }
3849                 }
3850         }
3851 







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

3854 
3855         resp->status = NFS3_OK;
3856         vattr_to_post_op_attr(vap, &resp->resok.obj_attributes);
3857         xfer_size = rfs3_tsize(req);
3858         resp->resok.rtmax = xfer_size;
3859         resp->resok.rtpref = xfer_size;
3860         resp->resok.rtmult = DEV_BSIZE;
3861         resp->resok.wtmax = xfer_size;
3862         resp->resok.wtpref = xfer_size;
3863         resp->resok.wtmult = DEV_BSIZE;
3864         resp->resok.dtpref = MAXBSIZE;
3865 
3866         /*
3867          * Large file spec: want maxfilesize based on limit of
3868          * underlying filesystem.  We can guess 2^31-1 if need be.
3869          */
3870         error = VOP_PATHCONF(vp, _PC_FILESIZEBITS, &l, cr, NULL);
3871         if (error) {
3872                 resp->status = puterrno3(error);
3873                 goto out;


3936                 error = ESTALE;
3937                 goto out;
3938         }
3939 
3940         if (is_system_labeled()) {
3941                 bslabel_t *clabel = req->rq_label;
3942 
3943                 ASSERT(clabel != NULL);
3944                 DTRACE_PROBE2(tx__rfs3__log__info__oppathconf__clabel, char *,
3945                     "got client label from request(1)", struct svc_req *, req);
3946 
3947                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
3948                         if (!do_rfs_label_check(clabel, vp, DOMINANCE_CHECK,
3949                             exi)) {
3950                                 resp->status = NFS3ERR_ACCES;
3951                                 goto out1;
3952                         }
3953                 }
3954         }
3955 


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






3958 
3959         error = VOP_PATHCONF(vp, _PC_LINK_MAX, &val, cr, NULL);
3960         if (error)
3961                 goto out;
3962         resp->resok.info.link_max = (uint32)val;
3963 
3964         error = VOP_PATHCONF(vp, _PC_NAME_MAX, &val, cr, NULL);
3965         if (error)
3966                 goto out;
3967         resp->resok.info.name_max = (uint32)val;
3968 
3969         error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &val, cr, NULL);
3970         if (error)
3971                 goto out;
3972         if (val == 1)
3973                 resp->resok.info.no_trunc = TRUE;
3974         else
3975                 resp->resok.info.no_trunc = FALSE;
3976 
3977         error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &val, cr, NULL);


4029         vp = nfs3_fhtovp(&args->file, exi);
4030 
4031         DTRACE_NFSV3_4(op__commit__start, struct svc_req *, req,
4032             cred_t *, cr, vnode_t *, vp, COMMIT3args *, args);
4033 
4034         if (vp == NULL) {
4035                 error = ESTALE;
4036                 goto out;
4037         }
4038 
4039         bva.va_mask = AT_ALL;
4040         error = VOP_GETATTR(vp, &bva, 0, cr, NULL);
4041 
4042         /*
4043          * If we can't get the attributes, then we can't do the
4044          * right access checking.  So, we'll fail the request.
4045          */
4046         if (error)
4047                 goto out;
4048 






4049         bvap = &bva;

4050 
4051         if (rdonly(exi, req)) {
4052                 resp->status = NFS3ERR_ROFS;
4053                 goto out1;
4054         }
4055 
4056         if (vp->v_type != VREG) {
4057                 resp->status = NFS3ERR_INVAL;
4058                 goto out1;
4059         }
4060 
4061         if (is_system_labeled()) {
4062                 bslabel_t *clabel = req->rq_label;
4063 
4064                 ASSERT(clabel != NULL);
4065                 DTRACE_PROBE2(tx__rfs3__log__info__opcommit__clabel, char *,
4066                     "got client label from request(1)", struct svc_req *, req);
4067 
4068                 if (!blequal(&l_admin_low->tsl_label, clabel)) {
4069                         if (!do_rfs_label_check(clabel, vp, EQUALITY_CHECK,
4070                             exi)) {
4071                                 resp->status = NFS3ERR_ACCES;
4072                                 goto out1;
4073                         }
4074                 }
4075         }
4076 
4077         if (crgetuid(cr) != bva.va_uid &&
4078             (error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL)))
4079                 goto out;
4080 
4081         error = VOP_FSYNC(vp, FSYNC, cr, NULL);
4082 


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






4085 
4086         if (error)
4087                 goto out;
4088 
4089         resp->status = NFS3_OK;
4090         vattr_to_wcc_data(bvap, avap, &resp->resok.file_wcc);
4091         resp->resok.verf = write3verf;
4092 
4093         DTRACE_NFSV3_4(op__commit__done, struct svc_req *, req,
4094             cred_t *, cr, vnode_t *, vp, COMMIT3res *, resp);
4095 
4096         VN_RELE(vp);
4097 
4098         return;
4099 
4100 out:
4101         if (curthread->t_flag & T_WOULDBLOCK) {
4102                 curthread->t_flag &= ~T_WOULDBLOCK;
4103                 resp->status = NFS3ERR_JUKEBOX;
4104         } else