blob: 54c9e89470bf1b921e45a280131e29321fe54650 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ftl.h"
#include "ftlnp.h"
// flush_bstat: Flush buffered statistics counts
//
// Inputs: ftl = pointer to FTL control block
// b = block number of current block
// type = "FREE", "MAP", or "VOLUME"
// In/Outputs: *blk0 = first consecutive block number or -1
// *blke = end consecutive block number
//
static void flush_bstat(CFTLN ftl, int* blk0, int* blke, int b, const char* type) {
if (*blk0 == -1)
*blk0 = *blke = b;
else if (*blke + 1 == b)
*blke = b;
else {
printf("B = %4u", *blk0);
if (*blk0 == *blke) {
printf(" - used = %2u, wc lag = %3d, rc = %8u", NUM_USED(ftl->bdata[*blk0]),
ftl->blk_wc_lag[*blk0], GET_RC(ftl->bdata[*blk0]));
printf(" - %s BLOCK\n", type);
} else {
printf("-%-4u", *blke);
printf("%*s", 37, " ");
printf("- %s BLOCKS\n", type);
}
*blk0 = *blke = b;
}
}
// FtlnBlkStats: Debug function to display blocks statistics
//
// Input: ftl = pointer to FTL control block
//
void FtlnBlkStats(CFTLN ftl) {
int free0 = -1, freee, vol0 = -1, vole;
ui32 b;
printf(
"\nBLOCK STATS: %u blocks, %u pages per block, curr free "
"blocks = %u\n",
ftl->num_blks, ftl->pgs_per_blk, ftl->num_free_blks);
// Loop over FTL blocks.
for (b = 0; b < ftl->num_blks; ++b) {
// Check if block is free.
if (IS_FREE(ftl->bdata[b])) {
flush_bstat(ftl, &vol0, &vole, -1, "VOLUME");
flush_bstat(ftl, &free0, &freee, b, "FREE");
}
// Else check if map block.
else if (IS_MAP_BLK(ftl->bdata[b])) {
flush_bstat(ftl, &free0, &freee, -1, "FREE");
flush_bstat(ftl, &vol0, &vole, -1, "VOLUME");
printf("B = %4u - used = %2u, wc lag = %3d, rc = %8u - ", b, NUM_USED(ftl->bdata[b]),
ftl->blk_wc_lag[b], GET_RC(ftl->bdata[b]));
printf("MAP BLOCK\n");
}
// Else is volume block.
else {
flush_bstat(ftl, &free0, &freee, -1, "FREE");
if (ftln_debug() <= 1) {
flush_bstat(ftl, &vol0, &vole, b, "VOLUME");
} else {
printf("B = %4u - used = %2u, wc lag = %3d, rc = %8u - ", b, NUM_USED(ftl->bdata[b]),
ftl->blk_wc_lag[b], GET_RC(ftl->bdata[b]));
printf("VOLUME BLOCK\n");
}
}
}
flush_bstat(ftl, &free0, &freee, -1, "FREE");
flush_bstat(ftl, &vol0, &vole, -1, "VOLUME");
}
// FtlnStats: Display FTL statistics
//
// Input: ftl = pointer to FTL control block
//
void FtlnStats(FTLN ftl) {
ui32 b, n;
printf("\nFTL STATS:\n");
printf(" - # vol pages = %d\n", ftl->num_vpages);
printf(" - # map pages = %d\n", ftl->num_map_pgs);
printf(" - # free blocks = %d\n", ftl->num_free_blks);
for (n = b = 0; b < ftl->num_blks; ++b)
if (IS_ERASED(ftl->bdata[b]))
++n;
printf(" - # erased blks = %d\n", n);
printf(" - flags =");
if (ftl->flags & FTLN_FATAL_ERR)
printf(" FTLN_FATAL_ERR");
if (ftl->flags & FTLN_MOUNTED)
printf(" FTLN_MOUNTED");
putchar('\n');
}