Print this page
5056 ZFS deadlock on db_mtx and dn_holds
Reviewed by: Will Andrews <willa@spectralogic.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_prop.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_prop.c
↓ open down ↓ 155 lines elided ↑ open up ↑
 156  156  
 157  157          return (err);
 158  158  }
 159  159  
 160  160  int
 161  161  dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
 162  162      int intsz, int numints, void *buf, char *setpoint)
 163  163  {
 164  164          zfs_prop_t prop = zfs_name_to_prop(propname);
 165  165          boolean_t inheritable;
 166      -        boolean_t snapshot;
 167  166          uint64_t zapobj;
 168  167  
 169  168          ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
 170  169          inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
 171      -        snapshot = dsl_dataset_is_snapshot(ds);
 172  170          zapobj = dsl_dataset_phys(ds)->ds_props_obj;
 173  171  
 174  172          if (zapobj != 0) {
 175  173                  objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
 176  174                  int err;
 177  175  
 178      -                ASSERT(snapshot);
      176 +                ASSERT(ds->ds_is_snapshot);
 179  177  
 180  178                  /* Check for a local value. */
 181  179                  err = zap_lookup(mos, zapobj, propname, intsz, numints, buf);
 182  180                  if (err != ENOENT) {
 183  181                          if (setpoint != NULL && err == 0)
 184  182                                  dsl_dataset_name(ds, setpoint);
 185  183                          return (err);
 186  184                  }
 187  185  
 188  186                  /*
↓ open down ↓ 19 lines elided ↑ open up ↑
 208  206                          if (err != ENOENT) {
 209  207                                  if (setpoint != NULL && err == 0)
 210  208                                          (void) strcpy(setpoint,
 211  209                                              ZPROP_SOURCE_VAL_RECVD);
 212  210                                  return (err);
 213  211                          }
 214  212                  }
 215  213          }
 216  214  
 217  215          return (dsl_prop_get_dd(ds->ds_dir, propname,
 218      -            intsz, numints, buf, setpoint, snapshot));
      216 +            intsz, numints, buf, setpoint, ds->ds_is_snapshot));
 219  217  }
 220  218  
 221  219  /*
 222  220   * Register interest in the named property.  We'll call the callback
 223  221   * once to notify it of the current property value, and again each time
 224  222   * the property changes, until this callback is unregistered.
 225  223   *
 226  224   * Return 0 on success, errno if the prop is not an integer value.
 227  225   */
 228  226  int
↓ open down ↓ 309 lines elided ↑ open up ↑
 538  536          char valbuf[32];
 539  537          const char *valstr = NULL;
 540  538          char *inheritstr;
 541  539          char *recvdstr;
 542  540          char *tbuf = NULL;
 543  541          int err;
 544  542          uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
 545  543  
 546  544          isint = (dodefault(propname, 8, 1, &intval) == 0);
 547  545  
 548      -        if (dsl_dataset_is_snapshot(ds)) {
      546 +        if (ds->ds_is_snapshot) {
 549  547                  ASSERT(version >= SPA_VERSION_SNAP_PROPS);
 550  548                  if (dsl_dataset_phys(ds)->ds_props_obj == 0) {
 551  549                          dmu_buf_will_dirty(ds->ds_dbuf, tx);
 552  550                          dsl_dataset_phys(ds)->ds_props_obj =
 553  551                              zap_create(mos,
 554  552                              DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
 555  553                  }
 556  554                  zapobj = dsl_dataset_phys(ds)->ds_props_obj;
 557  555          } else {
 558  556                  zapobj = dsl_dir_phys(ds->ds_dir)->dd_props_zapobj;
↓ open down ↓ 76 lines elided ↑ open up ↑
 635  633          default:
 636  634                  cmn_err(CE_PANIC, "unexpected property source: %d", source);
 637  635          }
 638  636  
 639  637          strfree(inheritstr);
 640  638          strfree(recvdstr);
 641  639  
 642  640          if (isint) {
 643  641                  VERIFY0(dsl_prop_get_int_ds(ds, propname, &intval));
 644  642  
 645      -                if (dsl_dataset_is_snapshot(ds)) {
      643 +                if (ds->ds_is_snapshot) {
 646  644                          dsl_prop_cb_record_t *cbr;
 647  645                          /*
 648  646                           * It's a snapshot; nothing can inherit this
 649  647                           * property, so just look for callbacks on this
 650  648                           * ds here.
 651  649                           */
 652  650                          mutex_enter(&ds->ds_dir->dd_lock);
 653  651                          for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr;
 654  652                              cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) {
 655  653                                  if (cbr->cbr_ds == ds &&
↓ open down ↓ 97 lines elided ↑ open up ↑
 753  751                          char *valstr = fnvpair_value_string(elem);
 754  752                          if (strlen(valstr) >= (version <
 755  753                              SPA_VERSION_STMF_PROP ?
 756  754                              ZAP_OLDMAXVALUELEN : ZAP_MAXVALUELEN)) {
 757  755                                  dsl_dataset_rele(ds, FTAG);
 758  756                                  return (E2BIG);
 759  757                          }
 760  758                  }
 761  759          }
 762  760  
 763      -        if (dsl_dataset_is_snapshot(ds) && version < SPA_VERSION_SNAP_PROPS) {
      761 +        if (ds->ds_is_snapshot && version < SPA_VERSION_SNAP_PROPS) {
 764  762                  dsl_dataset_rele(ds, FTAG);
 765  763                  return (SET_ERROR(ENOTSUP));
 766  764          }
 767  765          dsl_dataset_rele(ds, FTAG);
 768  766          return (0);
 769  767  }
 770  768  
 771  769  void
 772  770  dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
 773  771      nvlist_t *props, dmu_tx_t *tx)
↓ open down ↓ 202 lines elided ↑ open up ↑
 976  974      dsl_prop_getflags_t flags)
 977  975  {
 978  976          dsl_dir_t *dd = ds->ds_dir;
 979  977          dsl_pool_t *dp = dd->dd_pool;
 980  978          objset_t *mos = dp->dp_meta_objset;
 981  979          int err = 0;
 982  980          char setpoint[MAXNAMELEN];
 983  981  
 984  982          VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
 985  983  
 986      -        if (dsl_dataset_is_snapshot(ds))
      984 +        if (ds->ds_is_snapshot)
 987  985                  flags |= DSL_PROP_GET_SNAPSHOT;
 988  986  
 989  987          ASSERT(dsl_pool_config_held(dp));
 990  988  
 991  989          if (dsl_dataset_phys(ds)->ds_props_obj != 0) {
 992  990                  ASSERT(flags & DSL_PROP_GET_SNAPSHOT);
 993  991                  dsl_dataset_name(ds, setpoint);
 994  992                  err = dsl_prop_get_all_impl(mos,
 995  993                      dsl_dataset_phys(ds)->ds_props_obj, setpoint, flags, *nvp);
 996  994                  if (err)
↓ open down ↓ 131 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX