Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zdb/zdb.c
          +++ new/usr/src/cmd/zdb/zdb.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
       21 +
  21   22  /*
  22   23   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright (c) 2012 by Delphix. All rights reserved.
  23   25   */
  24   26  
  25   27  #include <stdio.h>
  26   28  #include <stdio_ext.h>
  27   29  #include <stdlib.h>
  28   30  #include <ctype.h>
  29   31  #include <sys/zfs_context.h>
  30   32  #include <sys/spa.h>
  31   33  #include <sys/spa_impl.h>
  32   34  #include <sys/dmu.h>
↓ open down ↓ 14 lines elided ↑ open up ↑
  47   49  #include <sys/zil.h>
  48   50  #include <sys/zil_impl.h>
  49   51  #include <sys/stat.h>
  50   52  #include <sys/resource.h>
  51   53  #include <sys/dmu_traverse.h>
  52   54  #include <sys/zio_checksum.h>
  53   55  #include <sys/zio_compress.h>
  54   56  #include <sys/zfs_fuid.h>
  55   57  #include <sys/arc.h>
  56   58  #include <sys/ddt.h>
       59 +#include <sys/zfeature.h>
  57   60  #undef ZFS_MAXNAMELEN
  58   61  #undef verify
  59   62  #include <libzfs.h>
  60   63  
  61   64  #define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \
  62   65      zio_compress_table[(idx)].ci_name : "UNKNOWN")
  63   66  #define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
  64   67      zio_checksum_table[(idx)].ci_name : "UNKNOWN")
  65   68  #define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
  66      -    dmu_ot[(idx)].ot_name : "UNKNOWN")
       69 +    dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \
       70 +    dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
  67   71  #define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES)
  68   72  
  69   73  #ifndef lint
  70   74  extern int zfs_recover;
  71   75  #else
  72   76  int zfs_recover;
  73   77  #endif
  74   78  
  75   79  const char cmdname[] = "zdb";
  76   80  uint8_t dump_opt[256];
↓ open down ↓ 1004 lines elided ↑ open up ↑
1081 1085          dsl_dataset_phys_t *ds = data;
1082 1086          time_t crtime;
1083 1087          char used[32], compressed[32], uncompressed[32], unique[32];
1084 1088          char blkbuf[BP_SPRINTF_LEN];
1085 1089  
1086 1090          if (ds == NULL)
1087 1091                  return;
1088 1092  
1089 1093          ASSERT(size == sizeof (*ds));
1090 1094          crtime = ds->ds_creation_time;
1091      -        zdb_nicenum(ds->ds_used_bytes, used);
     1095 +        zdb_nicenum(ds->ds_referenced_bytes, used);
1092 1096          zdb_nicenum(ds->ds_compressed_bytes, compressed);
1093 1097          zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
1094 1098          zdb_nicenum(ds->ds_unique_bytes, unique);
1095 1099          sprintf_blkptr(blkbuf, &ds->ds_bp);
1096 1100  
1097 1101          (void) printf("\t\tdir_obj = %llu\n",
1098 1102              (u_longlong_t)ds->ds_dir_obj);
1099 1103          (void) printf("\t\tprev_snap_obj = %llu\n",
1100 1104              (u_longlong_t)ds->ds_prev_snap_obj);
1101 1105          (void) printf("\t\tprev_snap_txg = %llu\n",
↓ open down ↓ 23 lines elided ↑ open up ↑
1125 1129              (u_longlong_t)ds->ds_flags);
1126 1130          (void) printf("\t\tnext_clones_obj = %llu\n",
1127 1131              (u_longlong_t)ds->ds_next_clones_obj);
1128 1132          (void) printf("\t\tprops_obj = %llu\n",
1129 1133              (u_longlong_t)ds->ds_props_obj);
1130 1134          (void) printf("\t\tbp = %s\n", blkbuf);
1131 1135  }
1132 1136  
1133 1137  /* ARGSUSED */
1134 1138  static int
     1139 +dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
     1140 +{
     1141 +        char blkbuf[BP_SPRINTF_LEN];
     1142 +
     1143 +        if (bp->blk_birth != 0) {
     1144 +                sprintf_blkptr(blkbuf, bp);
     1145 +                (void) printf("\t%s\n", blkbuf);
     1146 +        }
     1147 +        return (0);
     1148 +}
     1149 +
     1150 +static void
     1151 +dump_bptree(objset_t *os, uint64_t obj, char *name)
     1152 +{
     1153 +        char bytes[32];
     1154 +        bptree_phys_t *bt;
     1155 +        dmu_buf_t *db;
     1156 +
     1157 +        if (dump_opt['d'] < 3)
     1158 +                return;
     1159 +
     1160 +        VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
     1161 +        bt = db->db_data;
     1162 +        zdb_nicenum(bt->bt_bytes, bytes);
     1163 +        (void) printf("\n    %s: %llu datasets, %s\n",
     1164 +            name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes);
     1165 +        dmu_buf_rele(db, FTAG);
     1166 +
     1167 +        if (dump_opt['d'] < 5)
     1168 +                return;
     1169 +
     1170 +        (void) printf("\n");
     1171 +
     1172 +        (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL);
     1173 +}
     1174 +
     1175 +/* ARGSUSED */
     1176 +static int
1135 1177  dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
1136 1178  {
1137 1179          char blkbuf[BP_SPRINTF_LEN];
1138 1180  
1139 1181          ASSERT(bp->blk_birth != 0);
1140 1182          sprintf_blkptr_compact(blkbuf, bp);
1141 1183          (void) printf("\t%s\n", blkbuf);
1142 1184          return (0);
1143 1185  }
1144 1186  
↓ open down ↓ 731 lines elided ↑ open up ↑
1876 1918          uint64_t        zb_lsize;
1877 1919          uint64_t        zb_psize;
1878 1920          uint64_t        zb_count;
1879 1921  } zdb_blkstats_t;
1880 1922  
1881 1923  /*
1882 1924   * Extended object types to report deferred frees and dedup auto-ditto blocks.
1883 1925   */
1884 1926  #define ZDB_OT_DEFERRED (DMU_OT_NUMTYPES + 0)
1885 1927  #define ZDB_OT_DITTO    (DMU_OT_NUMTYPES + 1)
1886      -#define ZDB_OT_TOTAL    (DMU_OT_NUMTYPES + 2)
     1928 +#define ZDB_OT_OTHER    (DMU_OT_NUMTYPES + 2)
     1929 +#define ZDB_OT_TOTAL    (DMU_OT_NUMTYPES + 3)
1887 1930  
1888 1931  static char *zdb_ot_extname[] = {
1889 1932          "deferred free",
1890 1933          "dedup ditto",
     1934 +        "other",
1891 1935          "Total",
1892 1936  };
1893 1937  
1894 1938  #define ZB_TOTAL        DN_MAX_LEVELS
1895 1939  
1896 1940  typedef struct zdb_cb {
1897 1941          zdb_blkstats_t  zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1];
1898 1942          uint64_t        zcb_dedup_asize;
1899 1943          uint64_t        zcb_dedup_blocks;
1900 1944          uint64_t        zcb_errors[256];
↓ open down ↓ 60 lines elided ↑ open up ↑
1961 2005          zdb_cb_t *zcb = arg;
1962 2006          char blkbuf[BP_SPRINTF_LEN];
1963 2007          dmu_object_type_t type;
1964 2008          boolean_t is_metadata;
1965 2009  
1966 2010          if (bp == NULL)
1967 2011                  return (0);
1968 2012  
1969 2013          type = BP_GET_TYPE(bp);
1970 2014  
1971      -        zdb_count_block(zcb, zilog, bp, type);
     2015 +        zdb_count_block(zcb, zilog, bp,
     2016 +            (type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type);
1972 2017  
1973      -        is_metadata = (BP_GET_LEVEL(bp) != 0 || dmu_ot[type].ot_metadata);
     2018 +        is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type));
1974 2019  
1975 2020          if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) {
1976 2021                  int ioerr;
1977 2022                  size_t size = BP_GET_PSIZE(bp);
1978 2023                  void *data = malloc(size);
1979 2024                  int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;
1980 2025  
1981 2026                  /* If it's an intent log block, failure is expected. */
1982 2027                  if (zb->zb_level == ZB_ZIL_LEVEL)
1983 2028                          flags |= ZIO_FLAG_SPECULATIVE;
↓ open down ↓ 204 lines elided ↑ open up ↑
2188 2233           */
2189 2234          zdb_leak_init(spa, &zcb);
2190 2235  
2191 2236          /*
2192 2237           * If there's a deferred-free bplist, process that first.
2193 2238           */
2194 2239          (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2195 2240              count_block_cb, &zcb, NULL);
2196 2241          (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2197 2242              count_block_cb, &zcb, NULL);
     2243 +        if (spa_feature_is_active(spa,
     2244 +            &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
     2245 +                VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
     2246 +                    spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
     2247 +                    &zcb, NULL));
     2248 +        }
2198 2249  
2199 2250          if (dump_opt['c'] > 1)
2200 2251                  flags |= TRAVERSE_PREFETCH_DATA;
2201 2252  
2202 2253          zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2203 2254  
2204 2255          if (zcb.zcb_haderrors) {
2205 2256                  (void) printf("\nError counts:\n\n");
2206 2257                  (void) printf("\t%5s  %s\n", "errno", "count");
2207 2258                  for (int e = 0; e < 256; e++) {
↓ open down ↓ 156 lines elided ↑ open up ↑
2364 2415  
2365 2416          if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
2366 2417                  (void) printf("traversing objset %llu, %llu objects, "
2367 2418                      "%lu blocks so far\n",
2368 2419                      (u_longlong_t)zb->zb_objset,
2369 2420                      (u_longlong_t)bp->blk_fill,
2370 2421                      avl_numnodes(t));
2371 2422          }
2372 2423  
2373 2424          if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF ||
2374      -            BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata)
     2425 +            BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))
2375 2426                  return (0);
2376 2427  
2377 2428          ddt_key_fill(&zdde_search.zdde_key, bp);
2378 2429  
2379 2430          zdde = avl_find(t, &zdde_search, &where);
2380 2431  
2381 2432          if (zdde == NULL) {
2382 2433                  zdde = umem_zalloc(sizeof (*zdde), UMEM_NOFAIL);
2383 2434                  zdde->zdde_key = zdde_search.zdde_key;
2384 2435                  avl_insert(t, zdde, where);
↓ open down ↓ 84 lines elided ↑ open up ↑
2469 2520  
2470 2521          if (dump_opt['d'] > 2 || dump_opt['m'])
2471 2522                  dump_metaslabs(spa);
2472 2523  
2473 2524          if (dump_opt['d'] || dump_opt['i']) {
2474 2525                  dump_dir(dp->dp_meta_objset);
2475 2526                  if (dump_opt['d'] >= 3) {
2476 2527                          dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees");
2477 2528                          if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2478 2529                                  dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2479      -                                    "Pool frees");
     2530 +                                    "Pool snapshot frees");
2480 2531                          }
     2532 +
     2533 +                        if (spa_feature_is_active(spa,
     2534 +                            &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
     2535 +                                dump_bptree(spa->spa_meta_objset,
     2536 +                                    spa->spa_dsl_pool->dp_bptree_obj,
     2537 +                                    "Pool dataset frees");
     2538 +                        }
2481 2539                          dump_dtl(spa->spa_root_vdev, 0);
2482 2540                  }
2483 2541                  (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2484 2542                      NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2485 2543          }
2486 2544          if (dump_opt['b'] || dump_opt['c'])
2487 2545                  rc = dump_block_stats(spa);
2488 2546  
2489 2547          if (dump_opt['s'])
2490 2548                  show_pool_stats(spa);
↓ open down ↓ 671 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX