提交 480a8ec8 编写于 作者: Q Qu Wenruo 提交者: David Sterba

btrfs: scrub: refactor scrub_find_csum()

Function scrub_find_csum() is to locate the csum for bytenr @logical
from sctx->csum_list.

However it lacks a lot of comments to explain things like how the
csum_list is organized and why we need to drop csum range which is
before us.

Refactor the function by:

- Add more comments explaining the behavior
- Add comment explaining why we need to drop the csum range
- Put the csum copy in the main loop
  This is mostly for the incoming patches to make scrub_find_csum() able
  to find multiple checksums.
Signed-off-by: NQu Wenruo <wqu@suse.com>
Signed-off-by: NDavid Sterba <dsterba@suse.com>
上级 96e63a45
...@@ -2362,38 +2362,65 @@ static void scrub_block_complete(struct scrub_block *sblock) ...@@ -2362,38 +2362,65 @@ static void scrub_block_complete(struct scrub_block *sblock)
} }
} }
static void drop_csum_range(struct scrub_ctx *sctx, struct btrfs_ordered_sum *sum)
{
sctx->stat.csum_discards += sum->len >> sctx->fs_info->sectorsize_bits;
list_del(&sum->list);
kfree(sum);
}
/*
* Find the desired csum for range [logical, logical + sectorsize), and store
* the csum into @csum.
*
* The search source is sctx->csum_list, which is a pre-populated list
* storing bytenr ordered csum ranges. We're reponsible to cleanup any range
* that is before @logical.
*
* Return 0 if there is no csum for the range.
* Return 1 if there is csum for the range and copied to @csum.
*/
static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum) static int scrub_find_csum(struct scrub_ctx *sctx, u64 logical, u8 *csum)
{ {
struct btrfs_ordered_sum *sum = NULL; bool found = false;
unsigned long index;
unsigned long num_sectors;
while (!list_empty(&sctx->csum_list)) { while (!list_empty(&sctx->csum_list)) {
struct btrfs_ordered_sum *sum = NULL;
unsigned long index;
unsigned long num_sectors;
sum = list_first_entry(&sctx->csum_list, sum = list_first_entry(&sctx->csum_list,
struct btrfs_ordered_sum, list); struct btrfs_ordered_sum, list);
/* The current csum range is beyond our range, no csum found */
if (sum->bytenr > logical) if (sum->bytenr > logical)
return 0;
if (sum->bytenr + sum->len > logical)
break; break;
++sctx->stat.csum_discards; /*
list_del(&sum->list); * The current sum is before our bytenr, since scrub is always
kfree(sum); * done in bytenr order, the csum will never be used anymore,
sum = NULL; * clean it up so that later calls won't bother with the range,
} * and continue search the next range.
if (!sum) */
return 0; if (sum->bytenr + sum->len <= logical) {
drop_csum_range(sctx, sum);
continue;
}
index = (logical - sum->bytenr) >> sctx->fs_info->sectorsize_bits; /* Now the csum range covers our bytenr, copy the csum */
ASSERT(index < UINT_MAX); found = true;
index = (logical - sum->bytenr) >> sctx->fs_info->sectorsize_bits;
num_sectors = sum->len >> sctx->fs_info->sectorsize_bits;
num_sectors = sum->len >> sctx->fs_info->sectorsize_bits; memcpy(csum, sum->sums + index * sctx->fs_info->csum_size,
memcpy(csum, sum->sums + index * sctx->fs_info->csum_size, sctx->fs_info->csum_size);
sctx->fs_info->csum_size);
if (index == num_sectors - 1) { /* Cleanup the range if we're at the end of the csum range */
list_del(&sum->list); if (index == num_sectors - 1)
kfree(sum); drop_csum_range(sctx, sum);
break;
} }
if (!found)
return 0;
return 1; return 1;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册