Print this page
Hyperaggressive asserts pt 2/N
Be far more judicious in the use of curzone-using macros.
(Merge and extra asserts by danmcd.)
dss_paths[] entries need cleanup too
Try to remove assumption that zone's root vnode is marked VROOT

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs4_srv.c
          +++ new/usr/src/uts/common/fs/nfs/nfs4_srv.c
↓ open down ↓ 810 lines elided ↑ open up ↑
 811  811          oldstate->next = oldstate;
 812  812          oldstate->prev = oldstate;
 813  813          sip->oldstate = oldstate;
 814  814  
 815  815  
 816  816          sip->dss_npaths = dss_npaths;
 817  817          sip->dss_paths = kmem_alloc(dss_npaths *
 818  818              sizeof (rfs4_dss_path_t *), KM_SLEEP);
 819  819  
 820  820          for (i = 0; i < dss_npaths; i++) {
 821      -                /* CSTYLED */
 822      -                sip->dss_paths[i] = rfs4_dss_newpath(nsrv4, sip, dss_paths[i], i);
      821 +                sip->dss_paths[i] =
      822 +                    rfs4_dss_newpath(nsrv4, sip, dss_paths[i], i);
 823  823          }
 824  824  
 825  825          mutex_enter(&nsrv4->servinst_lock);
 826  826          if (nsrv4->nfs4_cur_servinst != NULL) {
 827  827                  /* add to linked list */
 828  828                  sip->prev = nsrv4->nfs4_cur_servinst;
 829  829                  nsrv4->nfs4_cur_servinst->next = sip;
 830  830          }
 831  831          if (start_grace)
 832  832                  rfs4_grace_start(sip);
↓ open down ↓ 17 lines elided ↑ open up ↑
 850  850  
 851  851          mutex_enter(&nsrv4->servinst_lock);
 852  852          ASSERT(nsrv4->nfs4_cur_servinst != NULL);
 853  853          current = nsrv4->nfs4_cur_servinst;
 854  854          nsrv4->nfs4_cur_servinst = NULL;
 855  855          for (sip = current; sip != NULL; sip = prev) {
 856  856                  prev = sip->prev;
 857  857                  rw_destroy(&sip->rwlock);
 858  858                  if (sip->oldstate)
 859  859                          kmem_free(sip->oldstate, sizeof (rfs4_oldstate_t));
 860      -                if (sip->dss_paths)
      860 +                if (sip->dss_paths) {
      861 +                        int i = sip->dss_npaths;
      862 +
      863 +                        while (i > 0) {
      864 +                                i--;
      865 +                                if (sip->dss_paths[i] != NULL) {
      866 +                                        char *path = sip->dss_paths[i]->path;
      867 +
      868 +                                        if (path != NULL) {
      869 +                                                kmem_free(path,
      870 +                                                    strlen(path) + 1);
      871 +                                        }
      872 +                                        kmem_free(sip->dss_paths[i],
      873 +                                            sizeof (rfs4_dss_path_t));
      874 +                                }
      875 +                        }
 861  876                          kmem_free(sip->dss_paths,
 862  877                              sip->dss_npaths * sizeof (rfs4_dss_path_t *));
      878 +                }
 863  879                  kmem_free(sip, sizeof (rfs4_servinst_t));
 864  880  #ifdef DEBUG
 865  881                  n++;
 866  882  #endif
 867  883          }
 868  884          mutex_exit(&nsrv4->servinst_lock);
 869  885  }
 870  886  
 871  887  /*
 872  888   * Assign the current server instance to a client_t.
↓ open down ↓ 57 lines elided ↑ open up ↑
 930  946  /*
 931  947   * Used by rfs4_op_secinfo to get the security information from the
 932  948   * export structure associated with the component.
 933  949   */
 934  950  /* ARGSUSED */
 935  951  static nfsstat4
 936  952  do_rfs4_op_secinfo(struct compound_state *cs, char *nm, SECINFO4res *resp)
 937  953  {
 938  954          int error, different_export = 0;
 939  955          vnode_t *dvp, *vp;
 940      -        struct exportinfo *exi = NULL;
      956 +        struct exportinfo *exi;
 941  957          fid_t fid;
 942  958          uint_t count, i;
 943  959          secinfo4 *resok_val;
 944  960          struct secinfo *secp;
 945  961          seconfig_t *si;
 946  962          bool_t did_traverse = FALSE;
 947  963          int dotdot, walk;
 948  964          nfs_export_t *ne = nfs_get_export();
 949  965  
 950  966          dvp = cs->vp;
      967 +        exi = cs->exi;
      968 +        ASSERT(exi != NULL);
 951  969          dotdot = (nm[0] == '.' && nm[1] == '.' && nm[2] == '\0');
 952  970  
 953  971          /*
 954  972           * If dotdotting, then need to check whether it's above the
 955  973           * root of a filesystem, or above an export point.
 956  974           */
 957  975          if (dotdot) {
 958      -
      976 +                ASSERT3U(exi->exi_zoneid, ==, curzone->zone_id);
 959  977                  /*
 960  978                   * If dotdotting at the root of a filesystem, then
 961  979                   * need to traverse back to the mounted-on filesystem
 962  980                   * and do the dotdot lookup there.
 963  981                   */
 964      -                if (cs->vp->v_flag & VROOT) {
      982 +                if ((dvp->v_flag & VROOT) || VN_IS_CURZONEROOT(dvp)) {
 965  983  
 966  984                          /*
 967  985                           * If at the system root, then can
 968  986                           * go up no further.
 969  987                           */
 970  988                          if (VN_CMP(dvp, ZONE_ROOTVP()))
 971  989                                  return (puterrno4(ENOENT));
 972  990  
 973  991                          /*
 974  992                           * Traverse back to the mounted-on filesystem
 975  993                           */
 976      -                        dvp = untraverse(cs->vp);
      994 +                        dvp = untraverse(dvp);
 977  995  
 978  996                          /*
 979  997                           * Set the different_export flag so we remember
 980  998                           * to pick up a new exportinfo entry for
 981  999                           * this new filesystem.
 982 1000                           */
 983 1001                          different_export = 1;
 984 1002                  } else {
 985 1003  
 986 1004                          /*
 987 1005                           * If dotdotting above an export point then set
 988 1006                           * the different_export to get new export info.
 989 1007                           */
 990      -                        different_export = nfs_exported(cs->exi, cs->vp);
     1008 +                        different_export = nfs_exported(exi, dvp);
 991 1009                  }
 992 1010          }
 993 1011  
 994 1012          /*
 995 1013           * Get the vnode for the component "nm".
 996 1014           */
 997 1015          error = VOP_LOOKUP(dvp, nm, &vp, NULL, 0, NULL, cs->cr,
 998 1016              NULL, NULL, NULL);
 999 1017          if (error)
1000 1018                  return (puterrno4(error));
1001 1019  
1002 1020          /*
1003 1021           * If the vnode is in a pseudo filesystem, or if the security flavor
1004 1022           * used in the request is valid but not an explicitly shared flavor,
1005 1023           * or the access bit indicates that this is a limited access,
1006 1024           * check whether this vnode is visible.
1007 1025           */
1008 1026          if (!different_export &&
1009      -            (PSEUDO(cs->exi) || ! is_exported_sec(cs->nfsflavor, cs->exi) ||
     1027 +            (PSEUDO(exi) || !is_exported_sec(cs->nfsflavor, exi) ||
1010 1028              cs->access & CS_ACCESS_LIMITED)) {
1011      -                if (! nfs_visible(cs->exi, vp, &different_export)) {
     1029 +                if (! nfs_visible(exi, vp, &different_export)) {
1012 1030                          VN_RELE(vp);
1013 1031                          return (puterrno4(ENOENT));
1014 1032                  }
1015 1033          }
1016 1034  
1017 1035          /*
1018 1036           * If it's a mountpoint, then traverse it.
1019 1037           */
1020 1038          if (vn_ismntpt(vp)) {
1021 1039                  if ((error = traverse(&vp)) != 0) {
↓ open down ↓ 21 lines elided ↑ open up ↑
1043 1061          if (different_export) {
1044 1062  
1045 1063                  bzero(&fid, sizeof (fid));
1046 1064                  fid.fid_len = MAXFIDSZ;
1047 1065                  error = vop_fid_pseudo(vp, &fid);
1048 1066                  if (error) {
1049 1067                          VN_RELE(vp);
1050 1068                          return (puterrno4(error));
1051 1069                  }
1052 1070  
     1071 +                /* We'll need to reassign "exi". */
1053 1072                  if (dotdot)
1054 1073                          exi = nfs_vptoexi(NULL, vp, cs->cr, &walk, NULL, TRUE);
1055 1074                  else
1056 1075                          exi = checkexport4(&vp->v_vfsp->vfs_fsid, &fid, vp);
1057 1076  
1058 1077                  if (exi == NULL) {
1059 1078                          if (did_traverse == TRUE) {
1060 1079                                  /*
1061 1080                                   * If this vnode is a mounted-on vnode,
1062 1081                                   * but the mounted-on file system is not
1063 1082                                   * exported, send back the secinfo for
1064 1083                                   * the exported node that the mounted-on
1065 1084                                   * vnode lives in.
1066 1085                                   */
1067 1086                                  exi = cs->exi;
1068 1087                          } else {
1069 1088                                  VN_RELE(vp);
1070 1089                                  return (puterrno4(EACCES));
1071 1090                          }
1072 1091                  }
1073      -        } else {
1074      -                exi = cs->exi;
1075 1092          }
1076 1093          ASSERT(exi != NULL);
1077 1094  
1078 1095  
1079 1096          /*
1080 1097           * Create the secinfo result based on the security information
1081 1098           * from the exportinfo structure (exi).
1082 1099           *
1083 1100           * Return all flavors for a pseudo node.
1084 1101           * For a real export node, return the flavor that the client
↓ open down ↓ 1610 lines elided ↑ open up ↑
2695 2712          }
2696 2713  
2697 2714          dotdot = (nm[0] == '.' && nm[1] == '.' && nm[2] == '\0');
2698 2715  
2699 2716          /*
2700 2717           * If dotdotting, then need to check whether it's
2701 2718           * above the root of a filesystem, or above an
2702 2719           * export point.
2703 2720           */
2704 2721          if (dotdot) {
2705      -
     2722 +                ASSERT(cs->exi != NULL);
     2723 +                ASSERT3U(cs->exi->exi_zoneid, ==, curzone->zone_id);
2706 2724                  /*
2707 2725                   * If dotdotting at the root of a filesystem, then
2708 2726                   * need to traverse back to the mounted-on filesystem
2709 2727                   * and do the dotdot lookup there.
2710 2728                   */
2711      -                if (cs->vp->v_flag & VROOT) {
     2729 +                if ((cs->vp->v_flag & VROOT) || VN_IS_CURZONEROOT(cs->vp)) {
2712 2730  
2713 2731                          /*
2714 2732                           * If at the system root, then can
2715 2733                           * go up no further.
2716 2734                           */
2717 2735                          if (VN_CMP(cs->vp, ZONE_ROOTVP()))
2718 2736                                  return (puterrno4(ENOENT));
2719 2737  
2720 2738                          /*
2721 2739                           * Traverse back to the mounted-on filesystem
↓ open down ↓ 7368 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX