From 82ee97055514f1efd44e80f37662bbe7d61a9c26 Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Fri, 12 Jun 2026 10:08:30 -0400 Subject: [PATCH 1/2] libprobe: add found_offset to the return of find_first_x_block() Adding found_offset to the return of find_first_x_block() enables callers to issue more informative logs. --- src/libprobe.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/libprobe.c b/src/libprobe.c index 45156ad..d19c8ad 100644 --- a/src/libprobe.c +++ b/src/libprobe.c @@ -197,10 +197,15 @@ struct def_x_block { uint64_t expected_offset; }; +struct x_block_found { + enum block_state state; + uint64_t found_offset; +}; + static int find_first_x_block(struct device *dev, const struct def_x_block x_blocks[], uint32_t n_blocks, uint64_t bs_set, uint32_t *pfirst_x_block_idx, - enum block_state *pstate, struct rdwr_info *rwi, + struct x_block_found *xbf, struct rdwr_info *rwi, progress_cb cb, unsigned int indent) { const unsigned int block_order = dev_get_block_order(dev); @@ -230,7 +235,8 @@ static int find_first_x_block(struct device *dev, if (in_bs_set(bs_set, bs)) { /* Found the first x_block. */ *pfirst_x_block_idx = i; - *pstate = bs; + xbf->state = bs; + xbf->found_offset = found_offset; end_measurement(&rwi->randr_fw); return false; } @@ -248,7 +254,7 @@ static int find_first_bad_block(struct device *dev, const uint64_t pos[], { const unsigned int block_order = dev_get_block_order(dev); struct def_x_block x_blocks[n_pos]; - enum block_state bs; + struct x_block_found xbf; uint32_t i; for (i = 0; i < n_pos; i++) { @@ -258,13 +264,13 @@ static int find_first_bad_block(struct device *dev, const uint64_t pos[], if (find_first_x_block(dev, x_blocks, n_pos, neg_bs_set(bs_to_set(bs_good)), - &i, &bs, rwi, cb, indent)) + &i, &xbf, rwi, cb, indent)) return true; *pany_bad = i < n_pos; if (*pany_bad) { *pbad_pos = x_blocks[i].pos; cb(indent, "INFO: Block %" PRIu64 " is %s!\n", - *pbad_pos, block_state_to_str(bs)); + *pbad_pos, block_state_to_str(xbf.state)); } return false; } @@ -629,7 +635,7 @@ static int find_wrap(struct device *dev, unsigned int block_order; uint64_t expected_offset, high_bit; uint32_t i; - enum block_state bs; + struct x_block_found xbf; cb(indent, "## Find module\n"); @@ -681,13 +687,14 @@ static int find_wrap(struct device *dev, assert(high_bit + good_block >= *pright_pos); if (find_first_x_block(dev, x_blocks, n_samples, - bss_to_set(bss, DIM(bss)), &i, &bs, rwi, + bss_to_set(bss, DIM(bss)), &i, &xbf, rwi, cb, indent + 1)) return true; if (i < n_samples) { *pright_pos = x_blocks[i].pos - good_block; /* = high_bit */ cb(indent + 1, "INFO: Block %" PRIu64 " overwrites %s block %" PRIu64 "\n", - x_blocks[i].pos, block_state_to_str(bs), good_block); + x_blocks[i].pos, block_state_to_str(xbf.state), + good_block); } return false; } From 35e62dea8637b09a186a5f087a375d7b0cbcc57f Mon Sep 17 00:00:00 2001 From: Michel Machado Date: Fri, 12 Jun 2026 10:53:23 -0400 Subject: [PATCH 2/2] libprobe: make find_first_bad_block() report more information When the bad block is bs_overwritten, it's helpful to identify if it comes from the drive cache and which block overwrites it. --- src/libprobe.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/libprobe.c b/src/libprobe.c index d19c8ad..2ce6bae 100644 --- a/src/libprobe.c +++ b/src/libprobe.c @@ -248,6 +248,39 @@ static int find_first_x_block(struct device *dev, return false; } +static bool is_block_from_cache(const struct rdwr_info *rwi, uint64_t block) +{ + if (rwi->cache_size_block == 0) + return false; + assert(block < rwi->cache_pos + rwi->cache_size_block); + return block >= rwi->cache_pos; +} + +static void cb_bad_block_info(const progress_cb cb, const unsigned int indent, + const struct def_x_block *x_block, const struct x_block_found *xbf, + const struct device *dev, const struct rdwr_info *rwi) +{ + if (xbf->state == bs_overwritten) { + const unsigned int block_order = dev_get_block_order(dev); + const unsigned int block_size = dev_get_block_size(dev); + const uint64_t found_block = xbf->found_offset >> block_order; + + assert((xbf->found_offset & (block_size - 1)) == 0); + + if (is_block_from_cache(rwi, found_block)) { + cb(indent, "INFO: Block %" PRIu64 " comes from the cache block %" PRIu64 "\n", + x_block->pos, found_block); + } else { + cb(indent, "INFO: Block %" PRIu64 " overwrites block %" PRIu64 "\n", + found_block, x_block->pos); + } + return; + } + + cb(indent, "INFO: Block %" PRIu64 " is %s\n", + x_block->pos, block_state_to_str(xbf->state)); +} + static int find_first_bad_block(struct device *dev, const uint64_t pos[], uint32_t n_pos, bool *pany_bad, uint64_t *pbad_pos, struct rdwr_info *rwi, progress_cb cb, unsigned int indent) @@ -269,8 +302,7 @@ static int find_first_bad_block(struct device *dev, const uint64_t pos[], *pany_bad = i < n_pos; if (*pany_bad) { *pbad_pos = x_blocks[i].pos; - cb(indent, "INFO: Block %" PRIu64 " is %s!\n", - *pbad_pos, block_state_to_str(xbf.state)); + cb_bad_block_info(cb, indent, &x_blocks[i], &xbf, dev, rwi); } return false; }