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>

*** 16,27 **** --- 16,29 ---- * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ + /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h>
*** 52,71 **** #include <sys/zio_checksum.h> #include <sys/zio_compress.h> #include <sys/zfs_fuid.h> #include <sys/arc.h> #include <sys/ddt.h> #undef ZFS_MAXNAMELEN #undef verify #include <libzfs.h> #define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \ zio_compress_table[(idx)].ci_name : "UNKNOWN") #define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \ zio_checksum_table[(idx)].ci_name : "UNKNOWN") #define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \ ! dmu_ot[(idx)].ot_name : "UNKNOWN") #define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES) #ifndef lint extern int zfs_recover; #else --- 54,75 ---- #include <sys/zio_checksum.h> #include <sys/zio_compress.h> #include <sys/zfs_fuid.h> #include <sys/arc.h> #include <sys/ddt.h> + #include <sys/zfeature.h> #undef ZFS_MAXNAMELEN #undef verify #include <libzfs.h> #define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \ zio_compress_table[(idx)].ci_name : "UNKNOWN") #define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \ zio_checksum_table[(idx)].ci_name : "UNKNOWN") #define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \ ! dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \ ! dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN") #define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES) #ifndef lint extern int zfs_recover; #else
*** 1086,1096 **** if (ds == NULL) return; ASSERT(size == sizeof (*ds)); crtime = ds->ds_creation_time; ! zdb_nicenum(ds->ds_used_bytes, used); zdb_nicenum(ds->ds_compressed_bytes, compressed); zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed); zdb_nicenum(ds->ds_unique_bytes, unique); sprintf_blkptr(blkbuf, &ds->ds_bp); --- 1090,1100 ---- if (ds == NULL) return; ASSERT(size == sizeof (*ds)); crtime = ds->ds_creation_time; ! zdb_nicenum(ds->ds_referenced_bytes, used); zdb_nicenum(ds->ds_compressed_bytes, compressed); zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed); zdb_nicenum(ds->ds_unique_bytes, unique); sprintf_blkptr(blkbuf, &ds->ds_bp);
*** 1130,1139 **** --- 1134,1181 ---- (void) printf("\t\tbp = %s\n", blkbuf); } /* ARGSUSED */ static int + dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) + { + char blkbuf[BP_SPRINTF_LEN]; + + if (bp->blk_birth != 0) { + sprintf_blkptr(blkbuf, bp); + (void) printf("\t%s\n", blkbuf); + } + return (0); + } + + static void + dump_bptree(objset_t *os, uint64_t obj, char *name) + { + char bytes[32]; + bptree_phys_t *bt; + dmu_buf_t *db; + + if (dump_opt['d'] < 3) + return; + + VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db)); + bt = db->db_data; + zdb_nicenum(bt->bt_bytes, bytes); + (void) printf("\n %s: %llu datasets, %s\n", + name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes); + dmu_buf_rele(db, FTAG); + + if (dump_opt['d'] < 5) + return; + + (void) printf("\n"); + + (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL); + } + + /* ARGSUSED */ + static int dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) { char blkbuf[BP_SPRINTF_LEN]; ASSERT(bp->blk_birth != 0);
*** 1881,1895 **** /* * Extended object types to report deferred frees and dedup auto-ditto blocks. */ #define ZDB_OT_DEFERRED (DMU_OT_NUMTYPES + 0) #define ZDB_OT_DITTO (DMU_OT_NUMTYPES + 1) ! #define ZDB_OT_TOTAL (DMU_OT_NUMTYPES + 2) static char *zdb_ot_extname[] = { "deferred free", "dedup ditto", "Total", }; #define ZB_TOTAL DN_MAX_LEVELS --- 1923,1939 ---- /* * Extended object types to report deferred frees and dedup auto-ditto blocks. */ #define ZDB_OT_DEFERRED (DMU_OT_NUMTYPES + 0) #define ZDB_OT_DITTO (DMU_OT_NUMTYPES + 1) ! #define ZDB_OT_OTHER (DMU_OT_NUMTYPES + 2) ! #define ZDB_OT_TOTAL (DMU_OT_NUMTYPES + 3) static char *zdb_ot_extname[] = { "deferred free", "dedup ditto", + "other", "Total", }; #define ZB_TOTAL DN_MAX_LEVELS
*** 1966,1978 **** if (bp == NULL) return (0); type = BP_GET_TYPE(bp); ! zdb_count_block(zcb, zilog, bp, type); ! is_metadata = (BP_GET_LEVEL(bp) != 0 || dmu_ot[type].ot_metadata); if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) { int ioerr; size_t size = BP_GET_PSIZE(bp); void *data = malloc(size); --- 2010,2023 ---- if (bp == NULL) return (0); type = BP_GET_TYPE(bp); ! zdb_count_block(zcb, zilog, bp, ! (type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type); ! is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type)); if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) { int ioerr; size_t size = BP_GET_PSIZE(bp); void *data = malloc(size);
*** 2193,2202 **** --- 2238,2253 ---- */ (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj, count_block_cb, &zcb, NULL); (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj, count_block_cb, &zcb, NULL); + if (spa_feature_is_active(spa, + &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset, + spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb, + &zcb, NULL)); + } if (dump_opt['c'] > 1) flags |= TRAVERSE_PREFETCH_DATA; zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
*** 2369,2379 **** (u_longlong_t)bp->blk_fill, avl_numnodes(t)); } if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF || ! BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) return (0); ddt_key_fill(&zdde_search.zdde_key, bp); zdde = avl_find(t, &zdde_search, &where); --- 2420,2430 ---- (u_longlong_t)bp->blk_fill, avl_numnodes(t)); } if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF || ! BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp))) return (0); ddt_key_fill(&zdde_search.zdde_key, bp); zdde = avl_find(t, &zdde_search, &where);
*** 2474,2485 **** dump_dir(dp->dp_meta_objset); if (dump_opt['d'] >= 3) { dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees"); if (spa_version(spa) >= SPA_VERSION_DEADLISTS) { dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj, ! "Pool frees"); } dump_dtl(spa->spa_root_vdev, 0); } (void) dmu_objset_find(spa_name(spa), dump_one_dir, NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN); } --- 2525,2543 ---- dump_dir(dp->dp_meta_objset); if (dump_opt['d'] >= 3) { dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees"); if (spa_version(spa) >= SPA_VERSION_DEADLISTS) { dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj, ! "Pool snapshot frees"); } + + if (spa_feature_is_active(spa, + &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + dump_bptree(spa->spa_meta_objset, + spa->spa_dsl_pool->dp_bptree_obj, + "Pool dataset frees"); + } dump_dtl(spa->spa_root_vdev, 0); } (void) dmu_objset_find(spa_name(spa), dump_one_dir, NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN); }