Check one block_ref struct in block core

Each of the different block types had a reading function that read a
block and then checked their reference struct for their block type.

This gets rid of each block reference type and has a single block_ref
type which is then checked by a single ref reading function in the block
core.  By putting ref checking in the core we no longer have to export
checking the block header crc, verifying headers, invalidating blocks,
or even reading raw blocks themseves.  Everyone reads refs and leaves
the checking up to the core.

The changes don't have a significant functional effect.  This is mostly
just changing types and moving code around.  (There are some changes to
visible counters.)

This shares code, which is nice, but this is putting the block reference
checking in one place in the block core so that in a few patches we can
fix problems with writers dirtying blocks that are being read.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2021-03-01 09:49:17 -08:00
parent b1b75cbe9f
commit 0969a94bfc
9 changed files with 129 additions and 207 deletions
+18 -25
View File
@@ -358,31 +358,24 @@ static void list_block_sort(struct scoutfs_alloc_list_block *lblk)
/*
* We're always reading blocks that we own, so we shouldn't see stale
* references. But the cached block can be stale and we can need to
* invalidate it.
* references but we could retry reads after dropping stale cached
* blocks. If we do see a stale error then we've hit persistent
* corruption.
*/
static int read_list_block(struct super_block *sb,
struct scoutfs_alloc_list_ref *ref,
static int read_list_block(struct super_block *sb, struct scoutfs_block_ref *ref,
struct scoutfs_block **bl_ret)
{
struct scoutfs_block *bl = NULL;
int ret;
bl = scoutfs_block_read(sb, le64_to_cpu(ref->blkno));
if (!IS_ERR_OR_NULL(bl) &&
!scoutfs_block_consistent_ref(sb, bl, ref->seq, ref->blkno,
SCOUTFS_BLOCK_MAGIC_ALLOC_LIST)) {
scoutfs_inc_counter(sb, alloc_stale_cached_list_block);
scoutfs_block_invalidate(sb, bl);
scoutfs_block_put(sb, bl);
bl = scoutfs_block_read(sb, le64_to_cpu(ref->blkno));
}
if (IS_ERR(bl)) {
*bl_ret = NULL;
return PTR_ERR(bl);
}
ret = scoutfs_block_read_ref(sb, ref, SCOUTFS_BLOCK_MAGIC_ALLOC_LIST, bl_ret);
if (ret < 0) {
if (ret == -ESTALE) {
scoutfs_inc_counter(sb, alloc_stale_list_block);
ret = -EIO;
}
};
*bl_ret = bl;
return 0;
return ret;
}
/*
@@ -396,7 +389,7 @@ static int read_list_block(struct super_block *sb,
static int dirty_list_block(struct super_block *sb,
struct scoutfs_alloc *alloc,
struct scoutfs_block_writer *wri,
struct scoutfs_alloc_list_ref *ref,
struct scoutfs_block_ref *ref,
u64 dirty, u64 *old,
struct scoutfs_block **bl_ret)
{
@@ -497,7 +490,7 @@ static int dirty_alloc_blocks(struct super_block *sb,
struct scoutfs_alloc *alloc,
struct scoutfs_block_writer *wri)
{
struct scoutfs_alloc_list_ref orig_freed;
struct scoutfs_block_ref orig_freed;
struct scoutfs_alloc_list_block *lblk;
struct scoutfs_block *av_bl = NULL;
struct scoutfs_block *fr_bl = NULL;
@@ -1106,7 +1099,7 @@ int scoutfs_alloc_splice_list(struct super_block *sb,
struct scoutfs_alloc_list_head *src)
{
struct scoutfs_alloc_list_block *lblk;
struct scoutfs_alloc_list_ref *ref;
struct scoutfs_block_ref *ref;
struct scoutfs_block *prev = NULL;
struct scoutfs_block *bl = NULL;
int ret = 0;
@@ -1169,8 +1162,8 @@ bool scoutfs_alloc_meta_low(struct super_block *sb,
int scoutfs_alloc_foreach(struct super_block *sb,
scoutfs_alloc_foreach_cb_t cb, void *arg)
{
struct scoutfs_btree_ref stale_refs[2] = {{0,}};
struct scoutfs_btree_ref refs[2] = {{0,}};
struct scoutfs_block_ref stale_refs[2] = {{0,}};
struct scoutfs_block_ref refs[2] = {{0,}};
struct scoutfs_super_block *super = NULL;
struct scoutfs_srch_compact *sc;
struct scoutfs_log_trees lt;