From 0969a94bfc8dcd2ab9a969aed75617c6d63efdda Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Sun, 21 Feb 2021 10:49:07 -0800 Subject: [PATCH] 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 --- kmod/src/alloc.c | 43 +++++++-------- kmod/src/block.c | 112 ++++++++++++++++++++------------------- kmod/src/block.h | 13 +---- kmod/src/btree.c | 53 +++++------------- kmod/src/counters.h | 7 ++- kmod/src/forest.c | 24 ++++----- kmod/src/format.h | 38 ++++++------- kmod/src/scoutfs_trace.h | 8 +-- kmod/src/srch.c | 38 +++---------- 9 files changed, 129 insertions(+), 207 deletions(-) diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index 530e261f..53965eec 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -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; diff --git a/kmod/src/block.c b/kmod/src/block.c index 1c2e4ae8..8e0ed42f 100644 --- a/kmod/src/block.c +++ b/kmod/src/block.c @@ -114,12 +114,7 @@ do { \ #define BLOCK_PRIVATE(_bl) \ container_of((_bl), struct block_private, bl) -/* - * These _block_header helpers are from a previous generation and may - * be refactored away. - */ - -__le32 scoutfs_block_calc_crc(struct scoutfs_block_header *hdr, u32 size) +static __le32 block_calc_crc(struct scoutfs_block_header *hdr, u32 size) { int off = offsetof(struct scoutfs_block_header, crc) + FIELD_SIZEOF(struct scoutfs_block_header, crc); @@ -128,21 +123,6 @@ __le32 scoutfs_block_calc_crc(struct scoutfs_block_header *hdr, u32 size) return cpu_to_le32(calc); } -bool scoutfs_block_valid_crc(struct scoutfs_block_header *hdr, u32 size) -{ - return hdr->crc == scoutfs_block_calc_crc(hdr, size); -} - -bool scoutfs_block_valid_ref(struct super_block *sb, - struct scoutfs_block_header *hdr, - __le64 seq, __le64 blkno) -{ - struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; - - return hdr->fsid == super->hdr.fsid && hdr->seq == seq && - hdr->blkno == blkno; -} - static struct block_private *block_alloc(struct super_block *sb, u64 blkno) { struct block_private *bp; @@ -625,7 +605,7 @@ static bool uptodate_or_error(struct block_private *bp) test_bit(BLOCK_BIT_ERROR, &bp->bits); } -struct scoutfs_block *scoutfs_block_read(struct super_block *sb, u64 blkno) +static struct block_private *block_read(struct super_block *sb, u64 blkno) { DECLARE_BLOCK_INFO(sb, binf); struct block_private *bp = NULL; @@ -654,45 +634,69 @@ out: return ERR_PTR(ret); } - return &bp->bl; + return bp; } /* - * Drop a stale cached read block from the cache. A future read will - * re-read the block from the device. This doesn't drop the caller's reference, - * they still have to call _put. + * Btree blocks don't have rigid cache consistency. We can be following + * block references into cached blocks that are now stale or can be + * following a stale root into blocks that have been overwritten. If we + * hit a block that looks stale we first invalidate the cache and retry, + * returning -ESTALE if it still looks wrong. The caller can retry the + * read from a more current root or decide that this is a persistent + * error. */ -void scoutfs_block_invalidate(struct super_block *sb, struct scoutfs_block *bl) -{ - struct block_private *bp = BLOCK_PRIVATE(bl); - - if (!WARN_ON_ONCE(test_bit(BLOCK_BIT_DIRTY, &bp->bits))) { - scoutfs_inc_counter(sb, block_cache_invalidate); - block_remove(sb, bp); - TRACE_BLOCK(invalidate, bp); - } -} - -/* This is only used for large metadata blocks */ -bool scoutfs_block_consistent_ref(struct super_block *sb, - struct scoutfs_block *bl, - __le64 seq, __le64 blkno, u32 magic) +int scoutfs_block_read_ref(struct super_block *sb, struct scoutfs_block_ref *ref, u32 magic, + struct scoutfs_block **bl_ret) { struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; - struct block_private *bp = BLOCK_PRIVATE(bl); - struct scoutfs_block_header *hdr = bl->data; + struct scoutfs_block_header *hdr; + struct block_private *bp = NULL; + bool retried = false; + int ret; +retry: + bp = block_read(sb, le64_to_cpu(ref->blkno)); + if (IS_ERR(bp)) { + ret = PTR_ERR(bp); + goto out; + } + hdr = bp->bl.data; + + /* corrupted writes might be a sign of a stale reference */ if (!test_bit(BLOCK_BIT_CRC_VALID, &bp->bits)) { - if (hdr->crc != - scoutfs_block_calc_crc(hdr, SCOUTFS_BLOCK_LG_SIZE)) - return false; + if (hdr->crc != block_calc_crc(hdr, SCOUTFS_BLOCK_LG_SIZE)) { + ret = -ESTALE; + goto out; + } + set_bit(BLOCK_BIT_CRC_VALID, &bp->bits); } - return hdr->magic == cpu_to_le32(magic) && - hdr->fsid == super->hdr.fsid && - hdr->seq == seq && - hdr->blkno == blkno; + if (hdr->magic != cpu_to_le32(magic) || hdr->fsid != super->hdr.fsid || + hdr->seq != ref->seq || hdr->blkno != ref->blkno) { + ret = -ESTALE; + goto out; + } + + ret = 0; +out: + if (ret == -ESTALE && !retried) { + retried = true; + scoutfs_inc_counter(sb, block_cache_remove_stale); + block_remove(sb, bp); + block_put(sb, bp); + bp = NULL; + goto retry; + } + + if (ret < 0) { + block_put(sb, bp); + bp = NULL; + } + + *bl_ret = bp ? &bp->bl : NULL; + return ret; } void scoutfs_block_put(struct super_block *sb, struct scoutfs_block *bl) @@ -762,7 +766,7 @@ int scoutfs_block_writer_write(struct super_block *sb, /* checksum everything to reduce time between io submission merging */ list_for_each_entry(bp, &wri->dirty_list, dirty_entry) { hdr = bp->bl.data; - hdr->crc = scoutfs_block_calc_crc(hdr, SCOUTFS_BLOCK_LG_SIZE); + hdr->crc = block_calc_crc(hdr, SCOUTFS_BLOCK_LG_SIZE); } blk_start_plug(&plug); @@ -1013,8 +1017,7 @@ static int sm_block_io(struct block_device *bdev, int rw, u64 blkno, if (len < SCOUTFS_BLOCK_SM_SIZE) memset((char *)pg_hdr + len, 0, SCOUTFS_BLOCK_SM_SIZE - len); - pg_hdr->crc = scoutfs_block_calc_crc(pg_hdr, - SCOUTFS_BLOCK_SM_SIZE); + pg_hdr->crc = block_calc_crc(pg_hdr, SCOUTFS_BLOCK_SM_SIZE); } bio = bio_alloc(GFP_NOFS, 1); @@ -1039,8 +1042,7 @@ static int sm_block_io(struct block_device *bdev, int rw, u64 blkno, if (ret == 0 && !(rw & WRITE)) { memcpy(hdr, pg_hdr, len); - *blk_crc = scoutfs_block_calc_crc(pg_hdr, - SCOUTFS_BLOCK_SM_SIZE); + *blk_crc = block_calc_crc(pg_hdr, SCOUTFS_BLOCK_SM_SIZE); } out: __free_page(page); diff --git a/kmod/src/block.h b/kmod/src/block.h index 79a859d7..7276a61c 100644 --- a/kmod/src/block.h +++ b/kmod/src/block.h @@ -13,18 +13,9 @@ struct scoutfs_block { void *priv; }; -__le32 scoutfs_block_calc_crc(struct scoutfs_block_header *hdr, u32 size); -bool scoutfs_block_valid_crc(struct scoutfs_block_header *hdr, u32 size); -bool scoutfs_block_valid_ref(struct super_block *sb, - struct scoutfs_block_header *hdr, - __le64 seq, __le64 blkno); - struct scoutfs_block *scoutfs_block_create(struct super_block *sb, u64 blkno); -struct scoutfs_block *scoutfs_block_read(struct super_block *sb, u64 blkno); -void scoutfs_block_invalidate(struct super_block *sb, struct scoutfs_block *bl); -bool scoutfs_block_consistent_ref(struct super_block *sb, - struct scoutfs_block *bl, - __le64 seq, __le64 blkno, u32 magic); +int scoutfs_block_read_ref(struct super_block *sb, struct scoutfs_block_ref *ref, u32 magic, + struct scoutfs_block **bl_ret); void scoutfs_block_put(struct super_block *sb, struct scoutfs_block *bl); void scoutfs_block_writer_init(struct super_block *sb, diff --git a/kmod/src/btree.c b/kmod/src/btree.c index d4eee1cc..78643961 100644 --- a/kmod/src/btree.c +++ b/kmod/src/btree.c @@ -619,18 +619,13 @@ static void move_items(struct scoutfs_btree_block *dst, * This is used to lookup cached blocks, read blocks, cow blocks for * dirtying, and allocate new blocks. * - * Btree blocks don't have rigid cache consistency. We can be following - * block references into cached blocks that are now stale or can be - * following a stale root into blocks that have been overwritten. If we - * hit a block that looks stale we first invalidate the cache and retry, - * returning -ESTALE if it still looks wrong. The caller can retry the - * read from a more current root or decide that this is a persistent - * error. + * If we read a stale block we return stale so the caller can retry with + * a newer root or return an error. */ static int get_ref_block(struct super_block *sb, struct scoutfs_alloc *alloc, struct scoutfs_block_writer *wri, int flags, - struct scoutfs_btree_ref *ref, + struct scoutfs_block_ref *ref, struct scoutfs_block **bl_ret) { struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super; @@ -638,40 +633,16 @@ static int get_ref_block(struct super_block *sb, struct scoutfs_btree_block *new; struct scoutfs_block *new_bl = NULL; struct scoutfs_block *bl = NULL; - bool retried = false; u64 blkno; u64 seq; int ret; /* always get the current block, either to return or cow from */ if (ref && ref->blkno) { -retry: - - bl = scoutfs_block_read(sb, le64_to_cpu(ref->blkno)); - if (IS_ERR(bl)) { - trace_scoutfs_btree_read_error(sb, ref); - scoutfs_inc_counter(sb, btree_read_error); - ret = PTR_ERR(bl); - goto out; - } - bt = (void *)bl->data; - - if (!scoutfs_block_consistent_ref(sb, bl, ref->seq, ref->blkno, - SCOUTFS_BLOCK_MAGIC_BTREE) || - scoutfs_trigger(sb, BTREE_STALE_READ)) { - - scoutfs_inc_counter(sb, btree_stale_read); - - scoutfs_block_invalidate(sb, bl); - scoutfs_block_put(sb, bl); - bl = NULL; - - if (!retried) { - retried = true; - goto retry; - } - - ret = -ESTALE; + ret = scoutfs_block_read_ref(sb, ref, SCOUTFS_BLOCK_MAGIC_BTREE, &bl); + if (ret < 0) { + if (ret == -ESTALE) + scoutfs_inc_counter(sb, btree_stale_read); goto out; } @@ -766,7 +737,7 @@ static void create_parent_item(struct scoutfs_btree_block *parent, { struct scoutfs_avl_node *par; int cmp; - struct scoutfs_btree_ref ref = { + struct scoutfs_block_ref ref = { .blkno = child->hdr.blkno, .seq = child->hdr.seq, }; @@ -784,7 +755,7 @@ static void update_parent_item(struct scoutfs_btree_block *parent, struct scoutfs_btree_item *par_item, struct scoutfs_btree_block *child) { - struct scoutfs_btree_ref *ref = item_val(parent, par_item); + struct scoutfs_block_ref *ref = item_val(parent, par_item); par_item->key = *item_key(last_item(child)); ref->blkno = child->hdr.blkno; @@ -837,7 +808,7 @@ static int try_split(struct super_block *sb, /* parents need to leave room for child references */ if (right->level) - val_len = sizeof(struct scoutfs_btree_ref); + val_len = sizeof(struct scoutfs_block_ref); /* don't need to split if there's enough space for the item */ if (mid_free_item_room(right, val_len)) @@ -905,7 +876,7 @@ static int try_join(struct super_block *sb, struct scoutfs_btree_item *sib_par_item; struct scoutfs_btree_block *sib; struct scoutfs_block *sib_bl; - struct scoutfs_btree_ref *ref; + struct scoutfs_block_ref *ref; unsigned int sib_tot; bool move_right; int to_move; @@ -1194,7 +1165,7 @@ static int btree_walk(struct super_block *sb, struct scoutfs_btree_item *prev; struct scoutfs_avl_node *next_node; struct scoutfs_avl_node *node; - struct scoutfs_btree_ref *ref; + struct scoutfs_block_ref *ref; unsigned int level; unsigned int nr; int ret; diff --git a/kmod/src/counters.h b/kmod/src/counters.h index 37d08191..7cb5a331 100644 --- a/kmod/src/counters.h +++ b/kmod/src/counters.h @@ -20,7 +20,7 @@ EXPAND_COUNTER(alloc_list_freed_hi) \ EXPAND_COUNTER(alloc_move) \ EXPAND_COUNTER(alloc_moved_extent) \ - EXPAND_COUNTER(alloc_stale_cached_list_block) \ + EXPAND_COUNTER(alloc_stale_list_block) \ EXPAND_COUNTER(block_cache_access_update) \ EXPAND_COUNTER(block_cache_alloc_failure) \ EXPAND_COUNTER(block_cache_alloc_page_order) \ @@ -29,7 +29,7 @@ EXPAND_COUNTER(block_cache_forget) \ EXPAND_COUNTER(block_cache_free) \ EXPAND_COUNTER(block_cache_free_work) \ - EXPAND_COUNTER(block_cache_invalidate) \ + EXPAND_COUNTER(block_cache_remove_stale) \ EXPAND_COUNTER(block_cache_shrink) \ EXPAND_COUNTER(block_cache_shrink_next) \ EXPAND_COUNTER(block_cache_shrink_recent) \ @@ -46,7 +46,6 @@ EXPAND_COUNTER(btree_lookup) \ EXPAND_COUNTER(btree_next) \ EXPAND_COUNTER(btree_prev) \ - EXPAND_COUNTER(btree_read_error) \ EXPAND_COUNTER(btree_split) \ EXPAND_COUNTER(btree_stale_read) \ EXPAND_COUNTER(btree_update) \ @@ -77,6 +76,7 @@ EXPAND_COUNTER(ext_op_remove) \ EXPAND_COUNTER(forest_bloom_fail) \ EXPAND_COUNTER(forest_bloom_pass) \ + EXPAND_COUNTER(forest_bloom_stale) \ EXPAND_COUNTER(forest_read_items) \ EXPAND_COUNTER(forest_roots_next_hint) \ EXPAND_COUNTER(forest_set_bloom_bits) \ @@ -167,7 +167,6 @@ EXPAND_COUNTER(srch_compact_flush) \ EXPAND_COUNTER(srch_compact_log_page) \ EXPAND_COUNTER(srch_compact_removed_entry) \ - EXPAND_COUNTER(srch_inconsistent_ref) \ EXPAND_COUNTER(srch_rotate_log) \ EXPAND_COUNTER(srch_search_log) \ EXPAND_COUNTER(srch_search_log_block) \ diff --git a/kmod/src/forest.c b/kmod/src/forest.c index f5f259c0..a832b2dd 100644 --- a/kmod/src/forest.c +++ b/kmod/src/forest.c @@ -66,8 +66,8 @@ struct forest_info { struct forest_info *name = SCOUTFS_SB(sb)->forest_info struct forest_refs { - struct scoutfs_btree_ref fs_ref; - struct scoutfs_btree_ref logs_ref; + struct scoutfs_block_ref fs_ref; + struct scoutfs_block_ref logs_ref; }; /* initialize some refs that initially aren't equal */ @@ -96,20 +96,16 @@ static void calc_bloom_nrs(struct forest_bloom_nrs *bloom, } } -static struct scoutfs_block *read_bloom_ref(struct super_block *sb, - struct scoutfs_btree_ref *ref) +static struct scoutfs_block *read_bloom_ref(struct super_block *sb, struct scoutfs_block_ref *ref) { struct scoutfs_block *bl; + int ret; - bl = scoutfs_block_read(sb, le64_to_cpu(ref->blkno)); - if (IS_ERR(bl)) - return bl; - - if (!scoutfs_block_consistent_ref(sb, bl, ref->seq, ref->blkno, - SCOUTFS_BLOCK_MAGIC_BLOOM)) { - scoutfs_block_invalidate(sb, bl); - scoutfs_block_put(sb, bl); - return ERR_PTR(-ESTALE); + ret = scoutfs_block_read_ref(sb, ref, SCOUTFS_BLOCK_MAGIC_BLOOM, &bl); + if (ret < 0) { + if (ret == -ESTALE) + scoutfs_inc_counter(sb, forest_bloom_stale); + bl = ERR_PTR(ret); } return bl; @@ -386,7 +382,7 @@ int scoutfs_forest_set_bloom_bits(struct super_block *sb, struct scoutfs_block *new_bl = NULL; struct scoutfs_block *bl = NULL; struct scoutfs_bloom_block *bb; - struct scoutfs_btree_ref *ref; + struct scoutfs_block_ref *ref; struct forest_bloom_nrs bloom; int nr_set = 0; u64 blkno; diff --git a/kmod/src/format.h b/kmod/src/format.h index 9578586f..28a15175 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -106,6 +106,15 @@ struct scoutfs_block_header { __le64 blkno; }; +/* + * A reference to a block. The corresponding fields in the block_header + * must match after having read the block contents. + */ +struct scoutfs_block_ref { + __le64 blkno; + __le64 seq; +}; + /* * scoutfs identifies all file system metadata items by a small key * struct. @@ -202,17 +211,12 @@ struct scoutfs_avl_node { */ #define SCOUTFS_BTREE_MAX_HEIGHT 20 -struct scoutfs_btree_ref { - __le64 blkno; - __le64 seq; -}; - /* * A height of X means that the first block read will have level X-1 and * the leaves will have level 0. */ struct scoutfs_btree_root { - struct scoutfs_btree_ref ref; + struct scoutfs_block_ref ref; __u8 height; __u8 __pad[7]; }; @@ -253,18 +257,13 @@ struct scoutfs_btree_block { #define SCOUTFS_BTREE_LEAF_ITEM_HASH_BYTES \ (SCOUTFS_BTREE_LEAF_ITEM_HASH_NR * sizeof(__le16)) -struct scoutfs_alloc_list_ref { - __le64 blkno; - __le64 seq; -}; - /* * first_nr tracks the nr of the first block in the list and is used for * allocation sizing. total_nr is the sum of the nr of all the blocks in * the list and is used for calculating total free block counts. */ struct scoutfs_alloc_list_head { - struct scoutfs_alloc_list_ref ref; + struct scoutfs_block_ref ref; __le64 total_nr; __le32 first_nr; __u8 __pad[4]; @@ -283,7 +282,7 @@ struct scoutfs_alloc_list_head { */ struct scoutfs_alloc_list_block { struct scoutfs_block_header hdr; - struct scoutfs_alloc_list_ref next; + struct scoutfs_block_ref next; __le32 start; __le32 nr; __le64 blknos[0]; /* naturally aligned for sorting */ @@ -329,15 +328,10 @@ struct scoutfs_srch_entry { #define SCOUTFS_SRCH_ENTRY_MAX_BYTES (2 + (sizeof(__u64) * 3)) -struct scoutfs_srch_ref { - __le64 blkno; - __le64 seq; -}; - struct scoutfs_srch_file { struct scoutfs_srch_entry first; struct scoutfs_srch_entry last; - struct scoutfs_srch_ref ref; + struct scoutfs_block_ref ref; __le64 blocks; __le64 entries; __u8 height; @@ -346,13 +340,13 @@ struct scoutfs_srch_file { struct scoutfs_srch_parent { struct scoutfs_block_header hdr; - struct scoutfs_srch_ref refs[0]; + struct scoutfs_block_ref refs[0]; }; #define SCOUTFS_SRCH_PARENT_REFS \ ((SCOUTFS_BLOCK_LG_SIZE - \ offsetof(struct scoutfs_srch_parent, refs)) / \ - sizeof(struct scoutfs_srch_ref)) + sizeof(struct scoutfs_block_ref)) struct scoutfs_srch_block { struct scoutfs_block_header hdr; @@ -423,7 +417,7 @@ struct scoutfs_log_trees { struct scoutfs_alloc_list_head meta_avail; struct scoutfs_alloc_list_head meta_freed; struct scoutfs_btree_root item_root; - struct scoutfs_btree_ref bloom_ref; + struct scoutfs_block_ref bloom_ref; struct scoutfs_alloc_root data_avail; struct scoutfs_alloc_root data_freed; struct scoutfs_srch_file srch_file; diff --git a/kmod/src/scoutfs_trace.h b/kmod/src/scoutfs_trace.h index 563f95e3..ecd2080f 100644 --- a/kmod/src/scoutfs_trace.h +++ b/kmod/src/scoutfs_trace.h @@ -1611,7 +1611,7 @@ TRACE_EVENT(scoutfs_get_name, ); TRACE_EVENT(scoutfs_btree_read_error, - TP_PROTO(struct super_block *sb, struct scoutfs_btree_ref *ref), + TP_PROTO(struct super_block *sb, struct scoutfs_block_ref *ref), TP_ARGS(sb, ref), @@ -1661,7 +1661,7 @@ TRACE_EVENT(scoutfs_btree_dirty_block, TRACE_EVENT(scoutfs_btree_walk, TP_PROTO(struct super_block *sb, struct scoutfs_btree_root *root, struct scoutfs_key *key, int flags, int level, - struct scoutfs_btree_ref *ref), + struct scoutfs_block_ref *ref), TP_ARGS(sb, root, key, flags, level, ref), @@ -1989,8 +1989,8 @@ DEFINE_EVENT(scoutfs_forest_bloom_class, scoutfs_forest_bloom_search, ); TRACE_EVENT(scoutfs_forest_prepare_commit, - TP_PROTO(struct super_block *sb, struct scoutfs_btree_ref *item_ref, - struct scoutfs_btree_ref *bloom_ref), + TP_PROTO(struct super_block *sb, struct scoutfs_block_ref *item_ref, + struct scoutfs_block_ref *bloom_ref), TP_ARGS(sb, item_ref, bloom_ref), TP_STRUCT__entry( SCSB_TRACE_FIELDS diff --git a/kmod/src/srch.c b/kmod/src/srch.c index 00c4f0fd..41cb11b1 100644 --- a/kmod/src/srch.c +++ b/kmod/src/srch.c @@ -284,39 +284,15 @@ static void init_file_block(struct super_block *sb, struct scoutfs_block *bl, */ static int read_srch_block(struct super_block *sb, struct scoutfs_block_writer *wri, int level, - struct scoutfs_srch_ref *ref, + struct scoutfs_block_ref *ref, struct scoutfs_block **bl_ret) { - struct scoutfs_block *bl; - int retries = 0; - int ret = 0; - int mag; + u32 magic = level ? SCOUTFS_BLOCK_MAGIC_SRCH_PARENT : SCOUTFS_BLOCK_MAGIC_SRCH_BLOCK; + int ret; - mag = level ? SCOUTFS_BLOCK_MAGIC_SRCH_PARENT : - SCOUTFS_BLOCK_MAGIC_SRCH_BLOCK; -retry: - 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, mag)) { - - scoutfs_inc_counter(sb, srch_inconsistent_ref); - scoutfs_block_writer_forget(sb, wri, bl); - scoutfs_block_invalidate(sb, bl); - scoutfs_block_put(sb, bl); - bl = NULL; - - if (retries++ == 0) - goto retry; - - bl = ERR_PTR(-ESTALE); + ret = scoutfs_block_read_ref(sb, ref, magic, bl_ret); + if (ret == -ESTALE) scoutfs_inc_counter(sb, srch_read_stale); - } - if (IS_ERR(bl)) { - ret = PTR_ERR(bl); - bl = NULL; - } - - *bl_ret = bl; return ret; } @@ -333,7 +309,7 @@ static int read_path_block(struct super_block *sb, { struct scoutfs_block *bl = NULL; struct scoutfs_srch_parent *srp; - struct scoutfs_srch_ref ref; + struct scoutfs_block_ref ref; int level; int ind; int ret; @@ -393,7 +369,7 @@ static int get_file_block(struct super_block *sb, struct scoutfs_block *bl = NULL; struct scoutfs_srch_parent *srp; struct scoutfs_block *new_bl; - struct scoutfs_srch_ref *ref; + struct scoutfs_block_ref *ref; u64 blkno = 0; int level; int ind;