|
24 | 24 | #include <sys/vdev_impl.h> |
25 | 25 | #include <sys/spa.h> |
26 | 26 | #include <zfs_comutil.h> |
| 27 | +#include <sys/metaslab_impl.h> |
27 | 28 |
|
28 | 29 | /* |
29 | 30 | * Keeps stats on last N reads per spa_t, disabled by default. |
@@ -302,6 +303,69 @@ spa_txg_history_init(spa_t *spa) |
302 | 303 | offsetof(spa_txg_history_t, sth_node)); |
303 | 304 | } |
304 | 305 |
|
| 306 | +static void * |
| 307 | +spa_frag_addr(kstat_t *ksp, loff_t n) |
| 308 | +{ |
| 309 | + if (n == 0) |
| 310 | + return ksp->ks_private; |
| 311 | + return NULL; |
| 312 | +} |
| 313 | + |
| 314 | +static int |
| 315 | +spa_frag_data(char *buf, size_t size, void *data) { |
| 316 | + spa_t *spa = (spa_t *)data; |
| 317 | + size_t offset = 0; |
| 318 | + const char *name = spa_name(spa); |
| 319 | + |
| 320 | + metaslab_class_t *mc = spa_normal_class(spa); |
| 321 | + for (int i=0; i<RANGE_TREE_HISTOGRAM_SIZE; i++) { |
| 322 | + if (mc->mc_histogram[i] > 0) { |
| 323 | + int res = snprintf(buf + offset, size, "zfs_fragmentation_normal{power=\"%d\",pool=\"%s\"} %llu\n", i, name, (u_longlong_t)mc->mc_histogram[i]); |
| 324 | + offset += res; |
| 325 | + size -= res; |
| 326 | + } |
| 327 | + } |
| 328 | + |
| 329 | + metaslab_class_t *smc = spa_special_class(spa); |
| 330 | + for (int i=0; i<RANGE_TREE_HISTOGRAM_SIZE; i++) { |
| 331 | + if (smc->mc_histogram[i] > 0) { |
| 332 | + int res = snprintf(buf + offset, size, "zfs_fragmentation_special{power=\"%d\",pool=\"%s\"} %llu\n", i, name, (u_longlong_t)smc->mc_histogram[i]); |
| 333 | + offset += res; |
| 334 | + size -= res; |
| 335 | + } |
| 336 | + } |
| 337 | + return 0; |
| 338 | +} |
| 339 | + |
| 340 | +static void |
| 341 | +spa_fragmentation_init(spa_t *spa) |
| 342 | +{ |
| 343 | + char *name; |
| 344 | + spa_history_kstat_t *shk = &spa->spa_stats.fragmentation; |
| 345 | + kstat_t *ksp; |
| 346 | + |
| 347 | + name = kmem_asprintf("zfs/%s", spa_name(spa)); |
| 348 | + ksp = kstat_create(name, 0, "fragmentation", "misc", KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL); |
| 349 | + |
| 350 | + shk->kstat = ksp; |
| 351 | + if (ksp) { |
| 352 | + ksp->ks_private = spa; |
| 353 | + ksp->ks_flags |= KSTAT_FLAG_NO_HEADERS; |
| 354 | + kstat_set_raw_ops(ksp, NULL, spa_frag_data, spa_frag_addr); |
| 355 | + kstat_install(ksp); |
| 356 | + } |
| 357 | + kmem_strfree(name); |
| 358 | +} |
| 359 | + |
| 360 | +static void |
| 361 | +spa_fragmentation_destroy(spa_t *spa) |
| 362 | +{ |
| 363 | + spa_history_kstat_t *shk = &spa->spa_stats.fragmentation; |
| 364 | + kstat_t *ksp = shk->kstat; |
| 365 | + if (ksp) |
| 366 | + kstat_delete(ksp); |
| 367 | +} |
| 368 | + |
305 | 369 | static void |
306 | 370 | spa_txg_history_destroy(spa_t *spa) |
307 | 371 | { |
@@ -855,7 +919,7 @@ spa_guid_init(spa_t *spa) |
855 | 919 | } |
856 | 920 |
|
857 | 921 | static void |
858 | | -spa_health_destroy(spa_t *spa) |
| 922 | +spa_state_destroy(spa_t *spa) |
859 | 923 | { |
860 | 924 | spa_history_kstat_t *shk = &spa->spa_stats.state; |
861 | 925 | kstat_t *ksp = shk->kstat; |
@@ -998,18 +1062,20 @@ spa_stats_init(spa_t *spa) |
998 | 1062 | spa_state_init(spa); |
999 | 1063 | spa_guid_init(spa); |
1000 | 1064 | spa_iostats_init(spa); |
| 1065 | + spa_fragmentation_init(spa); |
1001 | 1066 | } |
1002 | 1067 |
|
1003 | 1068 | void |
1004 | 1069 | spa_stats_destroy(spa_t *spa) |
1005 | 1070 | { |
1006 | 1071 | spa_iostats_destroy(spa); |
1007 | | - spa_health_destroy(spa); |
| 1072 | + spa_state_destroy(spa); |
1008 | 1073 | spa_tx_assign_destroy(spa); |
1009 | 1074 | spa_txg_history_destroy(spa); |
1010 | 1075 | spa_read_history_destroy(spa); |
1011 | 1076 | spa_mmp_history_destroy(spa); |
1012 | 1077 | spa_guid_destroy(spa); |
| 1078 | + spa_fragmentation_destroy(spa); |
1013 | 1079 | } |
1014 | 1080 |
|
1015 | 1081 | ZFS_MODULE_PARAM(zfs, zfs_, read_history, UINT, ZMOD_RW, |
|
0 commit comments