diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/backpointers.c | 72 | ||||
-rw-r--r-- | fs/bcachefs/bcachefs_format.h | 11 | ||||
-rw-r--r-- | fs/bcachefs/bkey_methods.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/bkey_types.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.c | 68 | ||||
-rw-r--r-- | fs/bcachefs/btree_key_cache.c | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 18 | ||||
-rw-r--r-- | fs/bcachefs/btree_update.c | 45 |
8 files changed, 47 insertions, 179 deletions
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c index afdfe991e4dd..bd26ab3e6812 100644 --- a/fs/bcachefs/backpointers.c +++ b/fs/bcachefs/backpointers.c @@ -872,27 +872,13 @@ static int check_bucket_backpointers_to_extents(struct btree_trans *, struct bch static int check_bucket_backpointer_mismatch(struct btree_trans *trans, struct bkey_s_c alloc_k, bool *had_mismatch, - struct bkey_buf *last_flushed, - struct bpos *last_pos, - unsigned *nr_iters) + struct bkey_buf *last_flushed) { struct bch_fs *c = trans->c; struct bch_alloc_v4 a_convert; const struct bch_alloc_v4 *a = bch2_alloc_to_v4(alloc_k, &a_convert); bool need_commit = false; - if (!bpos_eq(*last_pos, alloc_k.k->p)) - *nr_iters = 0; - - *last_pos = alloc_k.k->p; - *nr_iters += 1; - - if (*nr_iters > 2) { - bch_err(c, "%s: looping at %llu:%llu", __func__, - last_pos->inode, last_pos->offset); - return 0; - } - *had_mismatch = false; if (a->data_type == BCH_DATA_sb || @@ -951,52 +937,19 @@ static int check_bucket_backpointer_mismatch(struct btree_trans *trans, struct b if (sectors[ALLOC_dirty] != a->dirty_sectors || sectors[ALLOC_cached] != a->cached_sectors || sectors[ALLOC_stripe] != a->stripe_sectors) { + if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_backpointer_bucket_gen) { + ret = bch2_backpointers_maybe_flush(trans, alloc_k, last_flushed); + if (ret) + return ret; + } + if (sectors[ALLOC_dirty] > a->dirty_sectors || sectors[ALLOC_cached] > a->cached_sectors || sectors[ALLOC_stripe] > a->stripe_sectors) { - if (*nr_iters > 1) { - ret = 0; - - CLASS(printbuf, buf)(); - bch2_log_msg_start(c, &buf); - - prt_printf(&buf, "backpointer sectors > bucket sectors, but found no bad backpointers\n" - "bucket %llu:%llu data type %s, counters\n", - alloc_k.k->p.inode, - alloc_k.k->p.offset, - __bch2_data_types[a->data_type]); - if (sectors[ALLOC_dirty] > a->dirty_sectors) - prt_printf(&buf, "dirty: %u > %u\n", - sectors[ALLOC_dirty], a->dirty_sectors); - if (sectors[ALLOC_cached] > a->cached_sectors) - prt_printf(&buf, "cached: %u > %u\n", - sectors[ALLOC_cached], a->cached_sectors); - if (sectors[ALLOC_stripe] > a->stripe_sectors) - prt_printf(&buf, "stripe: %u > %u\n", - sectors[ALLOC_stripe], a->stripe_sectors); - - for_each_btree_key_max_norestart(trans, iter, BTREE_ID_backpointers, - bucket_pos_to_bp_start(ca, alloc_k.k->p), - bucket_pos_to_bp_end(ca, alloc_k.k->p), 0, bp_k, ret) { - bch2_bkey_val_to_text(&buf, c, bp_k); - prt_newline(&buf); - } - bch2_trans_iter_exit(trans, &iter); - - bch2_print_str(c, KERN_ERR, buf.buf); - return ret; - } - return check_bucket_backpointers_to_extents(trans, ca, alloc_k.k->p) ?: bch_err_throw(c, transaction_restart_nested); } - if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_backpointer_bucket_gen) { - ret = bch2_backpointers_maybe_flush(trans, alloc_k, last_flushed); - if (ret) - return ret; - } - bool empty = (sectors[ALLOC_dirty] + sectors[ALLOC_stripe] + sectors[ALLOC_cached]) == 0; @@ -1148,8 +1101,6 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c) CLASS(btree_trans, trans)(c); struct extents_to_bp_state s = { .bp_start = POS_MIN }; - struct bpos last_pos = POS_MIN; - unsigned nr_iters = 0; bch2_bkey_buf_init(&s.last_flushed); bkey_init(&s.last_flushed.k->k); @@ -1158,8 +1109,7 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c) POS_MIN, BTREE_ITER_prefetch, k, ({ bool had_mismatch; bch2_fs_going_ro(c) ?: - check_bucket_backpointer_mismatch(trans, k, &had_mismatch, &s.last_flushed, - &last_pos, &nr_iters); + check_bucket_backpointer_mismatch(trans, k, &had_mismatch, &s.last_flushed); })); if (ret) goto err; @@ -1228,11 +1178,7 @@ static int check_bucket_backpointer_pos_mismatch(struct btree_trans *trans, if (ret) return ret; - struct bpos last_pos = POS_MIN; - unsigned nr_iters = 0; - ret = check_bucket_backpointer_mismatch(trans, k, had_mismatch, - last_flushed, - &last_pos, &nr_iters); + ret = check_bucket_backpointer_mismatch(trans, k, had_mismatch, last_flushed); bch2_trans_iter_exit(trans, &alloc_iter); return ret; } diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index a8f59522e258..b4a04df5ea95 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -423,8 +423,7 @@ enum bch_bkey_type_flags { x(logged_op_truncate, 32, BKEY_TYPE_strict_btree_checks) \ x(logged_op_finsert, 33, BKEY_TYPE_strict_btree_checks) \ x(accounting, 34, BKEY_TYPE_strict_btree_checks) \ - x(inode_alloc_cursor, 35, BKEY_TYPE_strict_btree_checks) \ - x(extent_whiteout, 36, BKEY_TYPE_strict_btree_checks) + x(inode_alloc_cursor, 35, BKEY_TYPE_strict_btree_checks) enum bch_bkey_type { #define x(name, nr, ...) KEY_TYPE_##name = nr, @@ -441,10 +440,6 @@ struct bch_whiteout { struct bch_val v; }; -struct bch_extent_whiteout { - struct bch_val v; -}; - struct bch_error { struct bch_val v; }; @@ -705,8 +700,7 @@ struct bch_sb_field_ext { x(extent_flags, BCH_VERSION(1, 25)) \ x(snapshot_deletion_v2, BCH_VERSION(1, 26)) \ x(fast_device_removal, BCH_VERSION(1, 27)) \ - x(inode_has_case_insensitive, BCH_VERSION(1, 28)) \ - x(extent_snapshot_whiteouts, BCH_VERSION(1, 29)) + x(inode_has_case_insensitive, BCH_VERSION(1, 28)) enum bcachefs_metadata_version { bcachefs_metadata_version_min = 9, @@ -1346,7 +1340,6 @@ enum btree_id_flags { BTREE_IS_snapshots| \ BTREE_IS_data, \ BIT_ULL(KEY_TYPE_whiteout)| \ - BIT_ULL(KEY_TYPE_extent_whiteout)| \ BIT_ULL(KEY_TYPE_error)| \ BIT_ULL(KEY_TYPE_cookie)| \ BIT_ULL(KEY_TYPE_extent)| \ diff --git a/fs/bcachefs/bkey_methods.c b/fs/bcachefs/bkey_methods.c index 75d73677c4d8..fcd8c82cba4f 100644 --- a/fs/bcachefs/bkey_methods.c +++ b/fs/bcachefs/bkey_methods.c @@ -41,10 +41,6 @@ static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k, .key_validate = deleted_key_validate, \ }) -#define bch2_bkey_ops_extent_whiteout ((struct bkey_ops) { \ - .key_validate = deleted_key_validate, \ -}) - static int empty_val_key_validate(struct bch_fs *c, struct bkey_s_c k, struct bkey_validate_context from) { @@ -207,7 +203,7 @@ int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k, ? bch2_bkey_types[k.k->type] : "(unknown)"); - if (btree_node_type_is_extents(type) && !bkey_extent_whiteout(k.k)) { + if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) { bkey_fsck_err_on(k.k->size == 0, c, bkey_extent_size_zero, "size == 0"); diff --git a/fs/bcachefs/bkey_types.h b/fs/bcachefs/bkey_types.h index 88a48ce63656..b4f328f9853c 100644 --- a/fs/bcachefs/bkey_types.h +++ b/fs/bcachefs/bkey_types.h @@ -44,11 +44,6 @@ static inline void set_bkey_val_bytes(struct bkey *k, unsigned bytes) #define bkey_whiteout(_k) \ ((_k)->type == KEY_TYPE_deleted || (_k)->type == KEY_TYPE_whiteout) -#define bkey_extent_whiteout(_k) \ - ((_k)->type == KEY_TYPE_deleted || \ - (_k)->type == KEY_TYPE_whiteout || \ - (_k)->type == KEY_TYPE_extent_whiteout) - /* bkey with split value, const */ struct bkey_s_c { const struct bkey *k; diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 45ddfb54188a..dd716b35a11d 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -2448,27 +2448,10 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_trans *trans, struct btree continue; } - if (!(iter->flags & BTREE_ITER_nofilter_whiteouts)) { - /* - * KEY_TYPE_extent_whiteout indicates that there - * are no extents that overlap with this - * whiteout - meaning bkey_start_pos() is - * monotonically increasing when including - * KEY_TYPE_extent_whiteout (not - * KEY_TYPE_whiteout). - * - * Without this @end wouldn't be able to - * terminate searches and we'd have to scan - * through tons of whiteouts: - */ - if (k.k->type == KEY_TYPE_extent_whiteout && - bkey_ge(k.k->p, end)) - goto end; - - if (bkey_extent_whiteout(k.k)) { - search_key = bkey_successor(iter, k.k->p); - continue; - } + if (bkey_whiteout(k.k) && + !(iter->flags & BTREE_ITER_key_cache_fill)) { + search_key = bkey_successor(iter, k.k->p); + continue; } } @@ -2728,7 +2711,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_trans *trans, struct saved_path = 0; } - if (!bkey_extent_whiteout(k.k)) { + if (!bkey_whiteout(k.k)) { saved_path = btree_path_clone(trans, iter->path, iter->flags & BTREE_ITER_intent, _THIS_IP_); @@ -2741,7 +2724,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_trans *trans, struct continue; } - if (bkey_extent_whiteout(k.k)) { + if (bkey_whiteout(k.k)) { search_key = bkey_predecessor(iter, k.k->p); search_key.snapshot = U32_MAX; continue; @@ -2882,9 +2865,9 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre iter->k = *k.k; } - if (unlikely(bkey_extent_whiteout(k.k) && + if (unlikely(k.k->type == KEY_TYPE_whiteout && (iter->flags & BTREE_ITER_filter_snapshots) && - !(iter->flags & BTREE_ITER_nofilter_whiteouts))) + !(iter->flags & BTREE_ITER_key_cache_fill))) iter->k.type = KEY_TYPE_deleted; } else { struct bpos next; @@ -2895,30 +2878,27 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_trans *trans, struct btre EBUG_ON(btree_iter_path(trans, iter)->level); - struct btree_iter iter2; - - bch2_trans_copy_iter(trans, &iter2, iter); - iter2.flags |= BTREE_ITER_nofilter_whiteouts; + if (iter->flags & BTREE_ITER_intent) { + struct btree_iter iter2; - while (1) { + bch2_trans_copy_iter(trans, &iter2, iter); k = bch2_btree_iter_peek_max(trans, &iter2, end); - if ((iter2.flags & BTREE_ITER_is_extents) && - k.k && - !bkey_err(k) && - k.k->type == KEY_TYPE_whiteout) { - bch2_btree_iter_set_pos(trans, &iter2, k.k->p); - continue; - } - break; - } + if (k.k && !bkey_err(k)) { + swap(iter->key_cache_path, iter2.key_cache_path); + iter->k = iter2.k; + k.k = &iter->k; + } + bch2_trans_iter_exit(trans, &iter2); + } else { + struct bpos pos = iter->pos; - if (k.k && !bkey_err(k)) { - swap(iter->key_cache_path, iter2.key_cache_path); - iter->k = iter2.k; - k.k = &iter->k; + k = bch2_btree_iter_peek_max(trans, iter, end); + if (unlikely(bkey_err(k))) + bch2_btree_iter_set_pos(trans, iter, pos); + else + iter->pos = pos; } - bch2_trans_iter_exit(trans, &iter2); if (unlikely(bkey_err(k))) goto out; diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index 2317fe5b3c23..d61b782087ce 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -329,7 +329,6 @@ static noinline int btree_key_cache_fill(struct btree_trans *trans, bch2_trans_iter_init(trans, &iter, ck_path->btree_id, ck_path->pos, BTREE_ITER_intent| - BTREE_ITER_nofilter_whiteouts| BTREE_ITER_key_cache_fill| BTREE_ITER_cached_nofill); iter.flags &= ~BTREE_ITER_with_journal; diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 1d5611bc9a50..e4870fbc11d0 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -229,7 +229,6 @@ struct btree_node_iter { x(snapshot_field) \ x(all_snapshots) \ x(filter_snapshots) \ - x(nofilter_whiteouts) \ x(nopreserve) \ x(cached_nofill) \ x(key_cache_fill) \ @@ -839,15 +838,15 @@ static inline bool btree_node_type_has_triggers(enum btree_node_type type) return BIT_ULL(type) & BTREE_NODE_TYPE_HAS_TRIGGERS; } -static const u64 btree_is_extents_mask = 0 +static inline bool btree_id_is_extents(enum btree_id btree) +{ + const u64 mask = 0 #define x(name, nr, flags, ...) |((!!((flags) & BTREE_IS_extents)) << nr) -BCH_BTREE_IDS() + BCH_BTREE_IDS() #undef x -; + ; -static inline bool btree_id_is_extents(enum btree_id btree) -{ - return BIT_ULL(btree) & btree_is_extents_mask; + return BIT_ULL(btree) & mask; } static inline bool btree_node_type_is_extents(enum btree_node_type type) @@ -866,11 +865,6 @@ static inline bool btree_type_has_snapshots(enum btree_id btree) return BIT_ULL(btree) & btree_has_snapshots_mask; } -static inline bool btree_id_is_extents_snapshots(enum btree_id btree) -{ - return BIT_ULL(btree) & btree_has_snapshots_mask & btree_is_extents_mask; -} - static inline bool btree_type_has_snapshot_field(enum btree_id btree) { const u64 mask = 0 diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c index ff7b53c6b0fb..f514a8ad7a89 100644 --- a/fs/bcachefs/btree_update.c +++ b/fs/bcachefs/btree_update.c @@ -164,19 +164,6 @@ int __bch2_insert_snapshot_whiteouts(struct btree_trans *trans, return ret; } -static inline enum bch_bkey_type extent_whiteout_type(enum btree_id btree, const struct bkey *k) -{ - /* - * KEY_TYPE_extent_whiteout indicates that there isn't a real extent - * present at that position: key start positions inclusive of - * KEY_TYPE_extent_whiteout (but not KEY_TYPE_whiteout) are - * monotonically increasing - */ - return btree_id_is_extents_snapshots(btree) && bkey_deleted(k) - ? KEY_TYPE_extent_whiteout - : KEY_TYPE_whiteout; -} - int bch2_trans_update_extent_overwrite(struct btree_trans *trans, struct btree_iter *iter, enum btree_iter_update_trigger_flags flags, @@ -244,13 +231,13 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, update->k.p.snapshot = new.k->p.snapshot; if (new.k->p.snapshot != old.k->p.snapshot) { - update->k.type = extent_whiteout_type(iter->btree_id, new.k); + update->k.type = KEY_TYPE_whiteout; } else if (btree_type_has_snapshots(btree_id)) { ret = need_whiteout_for_snapshot(trans, btree_id, update->k.p); if (ret < 0) return ret; if (ret) - update->k.type = extent_whiteout_type(iter->btree_id, new.k); + update->k.type = KEY_TYPE_whiteout; } ret = bch2_btree_insert_nonextent(trans, btree_id, update, @@ -289,8 +276,7 @@ static int bch2_trans_update_extent(struct btree_trans *trans, bch2_trans_iter_init(trans, &iter, btree_id, bkey_start_pos(&insert->k), BTREE_ITER_intent| BTREE_ITER_with_updates| - BTREE_ITER_not_extents| - BTREE_ITER_nofilter_whiteouts); + BTREE_ITER_not_extents); k = bch2_btree_iter_peek_max(trans, &iter, POS(insert->k.p.inode, U64_MAX)); if ((ret = bkey_err(k))) goto err; @@ -307,28 +293,7 @@ static int bch2_trans_update_extent(struct btree_trans *trans, goto next; } - while (true) { - if (k.k->type == KEY_TYPE_whiteout && - bkey_lt(insert->k.p, k.k->p)) - continue; - - if (bkey_le(insert->k.p, bkey_start_pos(k.k))) - break; - - if (bkey_extent_whiteout(k.k)) { - enum bch_bkey_type whiteout_type = extent_whiteout_type(btree_id, &insert->k); - if (k.k->type != whiteout_type) { - struct bkey_i *update = bch2_bkey_make_mut(trans, &iter, &k, 0); - ret = PTR_ERR_OR_ZERO(update); - if (ret) - goto err; - - update->k.type = whiteout_type; - } - - goto next; - } - + while (bkey_gt(insert->k.p, bkey_start_pos(k.k))) { bool done = bkey_lt(insert->k.p, k.k->p); ret = bch2_trans_update_extent_overwrite(trans, &iter, flags, k, bkey_i_to_s_c(insert)); @@ -560,7 +525,7 @@ int __must_check bch2_trans_update_ip(struct btree_trans *trans, struct btree_it return ret; if (ret) - k->k.type = extent_whiteout_type(iter->btree_id, &k->k); + k->k.type = KEY_TYPE_whiteout; } /* |