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_scan.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_scan.c
↓ open down ↓ 367 lines elided ↑ open up ↑
 368  368  dsl_free_sync(zio_t *pio, dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp)
 369  369  {
 370  370          ASSERT(dsl_pool_sync_context(dp));
 371  371          zio_nowait(zio_free_sync(pio, dp->dp_spa, txg, bpp, pio->io_flags));
 372  372  }
 373  373  
 374  374  static uint64_t
 375  375  dsl_scan_ds_maxtxg(dsl_dataset_t *ds)
 376  376  {
 377  377          uint64_t smt = ds->ds_dir->dd_pool->dp_scan->scn_phys.scn_max_txg;
 378      -        if (dsl_dataset_is_snapshot(ds))
      378 +        if (ds->ds_is_snapshot)
 379  379                  return (MIN(smt, dsl_dataset_phys(ds)->ds_creation_txg));
 380  380          return (smt);
 381  381  }
 382  382  
 383  383  static void
 384  384  dsl_scan_sync_state(dsl_scan_t *scn, dmu_tx_t *tx)
 385  385  {
 386  386          VERIFY0(zap_update(scn->scn_dp->dp_meta_objset,
 387  387              DMU_POOL_DIRECTORY_OBJECT,
 388  388              DMU_POOL_SCAN, sizeof (uint64_t), SCAN_PHYS_NUMINTS,
↓ open down ↓ 415 lines elided ↑ open up ↑
 804  804  dsl_scan_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx)
 805  805  {
 806  806          dsl_pool_t *dp = ds->ds_dir->dd_pool;
 807  807          dsl_scan_t *scn = dp->dp_scan;
 808  808          uint64_t mintxg;
 809  809  
 810  810          if (scn->scn_phys.scn_state != DSS_SCANNING)
 811  811                  return;
 812  812  
 813  813          if (scn->scn_phys.scn_bookmark.zb_objset == ds->ds_object) {
 814      -                if (dsl_dataset_is_snapshot(ds)) {
      814 +                if (ds->ds_is_snapshot) {
 815  815                          /* Note, scn_cur_{min,max}_txg stays the same. */
 816  816                          scn->scn_phys.scn_bookmark.zb_objset =
 817  817                              dsl_dataset_phys(ds)->ds_next_snap_obj;
 818  818                          zfs_dbgmsg("destroying ds %llu; currently traversing; "
 819  819                              "reset zb_objset to %llu",
 820  820                              (u_longlong_t)ds->ds_object,
 821  821                              (u_longlong_t)dsl_dataset_phys(ds)->
 822  822                              ds_next_snap_obj);
 823  823                          scn->scn_phys.scn_flags |= DSF_VISIT_DS_AGAIN;
 824  824                  } else {
↓ open down ↓ 1 lines elided ↑ open up ↑
 826  826                              ZB_DESTROYED_OBJSET, 0, 0, 0);
 827  827                          zfs_dbgmsg("destroying ds %llu; currently traversing; "
 828  828                              "reset bookmark to -1,0,0,0",
 829  829                              (u_longlong_t)ds->ds_object);
 830  830                  }
 831  831          } else if (zap_lookup_int_key(dp->dp_meta_objset,
 832  832              scn->scn_phys.scn_queue_obj, ds->ds_object, &mintxg) == 0) {
 833  833                  ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
 834  834                  VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
 835  835                      scn->scn_phys.scn_queue_obj, ds->ds_object, tx));
 836      -                if (dsl_dataset_is_snapshot(ds)) {
      836 +                if (ds->ds_is_snapshot) {
 837  837                          /*
 838  838                           * We keep the same mintxg; it could be >
 839  839                           * ds_creation_txg if the previous snapshot was
 840  840                           * deleted too.
 841  841                           */
 842  842                          VERIFY(zap_add_int_key(dp->dp_meta_objset,
 843  843                              scn->scn_phys.scn_queue_obj,
 844  844                              dsl_dataset_phys(ds)->ds_next_snap_obj,
 845  845                              mintxg, tx) == 0);
 846  846                          zfs_dbgmsg("destroying ds %llu; in queue; "
↓ open down ↓ 163 lines elided ↑ open up ↑
1010 1010          if (dmu_objset_from_ds(ds, &os))
1011 1011                  goto out;
1012 1012  
1013 1013          /*
1014 1014           * Only the ZIL in the head (non-snapshot) is valid.  Even though
1015 1015           * snapshots can have ZIL block pointers (which may be the same
1016 1016           * BP as in the head), they must be ignored.  So we traverse the
1017 1017           * ZIL here, rather than in scan_recurse(), because the regular
1018 1018           * snapshot block-sharing rules don't apply to it.
1019 1019           */
1020      -        if (DSL_SCAN_IS_SCRUB_RESILVER(scn) && !dsl_dataset_is_snapshot(ds))
     1020 +        if (DSL_SCAN_IS_SCRUB_RESILVER(scn) && !ds->ds_is_snapshot)
1021 1021                  dsl_scan_zil(dp, &os->os_zil_header);
1022 1022  
1023 1023          /*
1024 1024           * Iterate over the bps in this ds.
1025 1025           */
1026 1026          dmu_buf_will_dirty(ds->ds_dbuf, tx);
1027 1027          dsl_scan_visit_rootbp(scn, ds, &dsl_dataset_phys(ds)->ds_bp, tx);
1028 1028  
1029 1029          char *dsname = kmem_alloc(ZFS_MAXNAMELEN, KM_SLEEP);
1030 1030          dsl_dataset_name(ds, dsname);
↓ open down ↓ 779 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX