Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions src/libprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -242,13 +248,46 @@ 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)
{
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++) {
Expand All @@ -258,13 +297,12 @@ 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));
cb_bad_block_info(cb, indent, &x_blocks[i], &xbf, dev, rwi);
}
return false;
}
Expand Down Expand Up @@ -629,7 +667,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");

Expand Down Expand Up @@ -681,13 +719,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;
}
Expand Down
Loading