@@ -109,6 +109,7 @@ extern uint_t zfs_btree_verify_intensity;
109
109
enum {
110
110
ARG_ALLOCATED = 256 ,
111
111
ARG_BLOCK_BIN_MODE ,
112
+ ARG_BLOCK_CLASSES ,
112
113
};
113
114
114
115
static const char cmdname [] = "zdb" ;
@@ -141,6 +142,13 @@ static enum {
141
142
BIN_ASIZE ,
142
143
} block_bin_mode = BIN_AUTO ;
143
144
145
+ static enum {
146
+ CLASS_NORMAL = 1 << 1 ,
147
+ CLASS_SPECIAL = 1 << 2 ,
148
+ CLASS_DEDUP = 1 << 3 ,
149
+ CLASS_OTHER = 1 << 4 ,
150
+ } block_classes = 0 ;
151
+
144
152
static void snprintf_blkptr_compact (char * , size_t , const blkptr_t * ,
145
153
boolean_t );
146
154
static void mos_obj_refd (uint64_t );
@@ -761,6 +769,10 @@ usage(void)
761
769
"block statistics\n" );
762
770
(void ) fprintf (stderr , " --bin=(lsize|psize|asize) "
763
771
"bin blocks based on this size in all three columns\n" );
772
+ (void ) fprintf (stderr ,
773
+ " --class=(normal|special|dedup|other)[,...]\n"
774
+ " only consider blocks from "
775
+ "these allocation classes\n" );
764
776
(void ) fprintf (stderr , " -B --backup "
765
777
"backup stream\n" );
766
778
(void ) fprintf (stderr , " -c --checksum "
@@ -5840,6 +5852,20 @@ dump_size_histograms(zdb_cb_t *zcb)
5840
5852
printf ("(note: all categories are binned separately)\n" );
5841
5853
break ;
5842
5854
}
5855
+ if (block_classes != 0 ) {
5856
+ char buf [256 ] = "" ;
5857
+ if (block_classes & CLASS_NORMAL )
5858
+ strlcat (buf , "\"normal\", " , sizeof (buf ));
5859
+ if (block_classes & CLASS_SPECIAL )
5860
+ strlcat (buf , "\"special\", " , sizeof (buf ));
5861
+ if (block_classes & CLASS_DEDUP )
5862
+ strlcat (buf , "\"dedup\", " , sizeof (buf ));
5863
+ if (block_classes & CLASS_OTHER )
5864
+ strlcat (buf , "\"other\", " , sizeof (buf ));
5865
+ buf [strlen (buf )- 2 ] = '\0' ;
5866
+ printf ("(note: only blocks in these classes are counted: %s)\n" ,
5867
+ buf );
5868
+ }
5843
5869
/*
5844
5870
* Print the first line titles
5845
5871
*/
@@ -6189,6 +6215,38 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
6189
6215
return ;
6190
6216
}
6191
6217
6218
+ if (block_classes != 0 ) {
6219
+ spa_config_enter (zcb -> zcb_spa , SCL_CONFIG , FTAG , RW_READER );
6220
+
6221
+ uint64_t vdev = DVA_GET_VDEV (& bp -> blk_dva [0 ]);
6222
+ uint64_t offset = DVA_GET_OFFSET (& bp -> blk_dva [0 ]);
6223
+ vdev_t * vd = vdev_lookup_top (zcb -> zcb_spa , vdev );
6224
+ ASSERT (vd != NULL );
6225
+ metaslab_t * ms = vd -> vdev_ms [offset >> vd -> vdev_ms_shift ];
6226
+ ASSERT (ms != NULL );
6227
+ metaslab_group_t * mg = ms -> ms_group ;
6228
+ ASSERT (mg != NULL );
6229
+ metaslab_class_t * mc = mg -> mg_class ;
6230
+ ASSERT (mc != NULL );
6231
+
6232
+ spa_config_exit (zcb -> zcb_spa , SCL_CONFIG , FTAG );
6233
+
6234
+ int class ;
6235
+ if (mc == spa_normal_class (zcb -> zcb_spa )) {
6236
+ class = CLASS_NORMAL ;
6237
+ } else if (mc == spa_special_class (zcb -> zcb_spa )) {
6238
+ class = CLASS_SPECIAL ;
6239
+ } else if (mc == spa_dedup_class (zcb -> zcb_spa )) {
6240
+ class = CLASS_DEDUP ;
6241
+ } else {
6242
+ class = CLASS_OTHER ;
6243
+ }
6244
+
6245
+ if (!(block_classes & class )) {
6246
+ goto hist_skipped ;
6247
+ }
6248
+ }
6249
+
6192
6250
/*
6193
6251
* The binning histogram bins by powers of two up to
6194
6252
* SPA_MAXBLOCKSIZE rather than creating bins for
@@ -6225,6 +6283,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
6225
6283
zcb -> zcb_asize_len [bin ] += BP_GET_ASIZE (bp );
6226
6284
zcb -> zcb_asize_total += BP_GET_ASIZE (bp );
6227
6285
6286
+ hist_skipped :
6228
6287
if (!do_claim )
6229
6288
return ;
6230
6289
@@ -9469,6 +9528,8 @@ main(int argc, char **argv)
9469
9528
ARG_ALLOCATED },
9470
9529
{"bin" , required_argument , NULL ,
9471
9530
ARG_BLOCK_BIN_MODE },
9531
+ {"class" , required_argument , NULL ,
9532
+ ARG_BLOCK_CLASSES },
9472
9533
{0 , 0 , 0 , 0 }
9473
9534
};
9474
9535
@@ -9596,6 +9657,45 @@ main(int argc, char **argv)
9596
9657
usage ();
9597
9658
}
9598
9659
break ;
9660
+
9661
+ case ARG_BLOCK_CLASSES : {
9662
+ char * buf = strdup (optarg ), * tok = buf , * next ,
9663
+ * save = NULL ;
9664
+
9665
+ while ((next = strtok_r (tok , "," , & save )) != NULL ) {
9666
+ tok = NULL ;
9667
+
9668
+ if (strcmp (next , "normal" ) == 0 ) {
9669
+ block_classes |= CLASS_NORMAL ;
9670
+ } else if (strcmp (next , "special" ) == 0 ) {
9671
+ block_classes |= CLASS_SPECIAL ;
9672
+ } else if (strcmp (next , "dedup" ) == 0 ) {
9673
+ block_classes |= CLASS_DEDUP ;
9674
+ } else if (strcmp (next , "other" ) == 0 ) {
9675
+ block_classes |= CLASS_OTHER ;
9676
+ } else {
9677
+ (void ) fprintf (stderr ,
9678
+ "--class=\"%s\" must be a "
9679
+ "comma-separated list of either "
9680
+ "\"normal\", \"special\", "
9681
+ "\"asize\" or \"other\"; "
9682
+ "got \"%s\"\n" ,
9683
+ optarg , next );
9684
+ usage ();
9685
+ }
9686
+ }
9687
+
9688
+ if (block_classes == 0 ) {
9689
+ (void ) fprintf (stderr ,
9690
+ "--class= must be a comma-separated "
9691
+ "list of either \"normal\", \"special\", "
9692
+ "\"asize\" or \"other\"; got empty\n" );
9693
+ usage ();
9694
+ }
9695
+
9696
+ free (buf );
9697
+ break ;
9698
+ }
9599
9699
default :
9600
9700
usage ();
9601
9701
break ;
0 commit comments