diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-10-30 14:32:21 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:10 -0400 |
commit | 103e212785561df4ee3f29024868d8e3468f1f40 (patch) | |
tree | c3da2e733f7c45022d4a366eedfdd3f969f5c8c5 /fs | |
parent | 7a920560d727701c4397a5448085f99bf9f060d5 (diff) |
bcachefs: replicas: prep work for stripes
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/btree_gc.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/replicas.c | 119 | ||||
-rw-r--r-- | fs/bcachefs/replicas.h | 4 |
8 files changed, 108 insertions, 43 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 757a170e7508..c9a013f43374 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -155,10 +155,10 @@ static int bch2_btree_mark_ptrs_initial(struct bch_fs *c, enum bkey_type type, k.k->version.lo > journal_cur_seq(&c->journal)); if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || - fsck_err_on(!bch2_bkey_replicas_marked(c, data_type, k), c, + fsck_err_on(!bch2_bkey_replicas_marked(c, type, k), c, "superblock not marked as containing replicas (type %u)", data_type)) { - ret = bch2_mark_bkey_replicas(c, data_type, k); + ret = bch2_mark_bkey_replicas(c, type, k); if (ret) return ret; } diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 26721c5a871c..c9facec494ef 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -551,7 +551,7 @@ static struct btree_reserve *bch2_btree_reserve_get(struct bch_fs *c, goto err_free; } - ret = bch2_mark_bkey_replicas(c, BCH_DATA_BTREE, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_BTREE, bkey_i_to_s_c(&b->key)); if (ret) goto err_free; @@ -2063,7 +2063,7 @@ int bch2_btree_node_update_key(struct bch_fs *c, struct btree_iter *iter, goto err; } - ret = bch2_mark_bkey_replicas(c, BCH_DATA_BTREE, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_BTREE, extent_i_to_s_c(new_key).s_c); if (ret) goto err_free_update; diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 5dd552bf1d1b..4e4918524a77 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -648,7 +648,7 @@ void bch2_btree_ptr_debugcheck(struct bch_fs *c, struct btree *b, goto err; } - if (!bch2_bkey_replicas_marked(c, BCH_DATA_BTREE, e.s_c)) { + if (!bch2_bkey_replicas_marked(c, btree_node_type(b), e.s_c)) { bch2_bkey_val_to_text(c, btree_node_type(b), buf, sizeof(buf), k); bch2_fs_bug(c, @@ -1681,8 +1681,7 @@ static void bch2_extent_debugcheck_extent(struct bch_fs *c, struct btree *b, return; } - if (!bkey_extent_is_cached(e.k) && - !bch2_bkey_replicas_marked(c, BCH_DATA_USER, e.s_c)) { + if (!bch2_bkey_replicas_marked(c, btree_node_type(b), e.s_c)) { bch2_bkey_val_to_text(c, btree_node_type(b), buf, sizeof(buf), e.s_c); bch2_fs_bug(c, diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 549a179b85e6..a4660746be0d 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -337,7 +337,8 @@ static void __bch2_write_index(struct bch_write_op *op) } if (!(op->flags & BCH_WRITE_NOMARK_REPLICAS)) { - ret = bch2_mark_bkey_replicas(c, BCH_DATA_USER, e.s_c); + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_EXTENTS, + e.s_c); if (ret) goto err; } diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c index 9337a8729a5b..38b392472521 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -51,7 +51,7 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) !(ret = btree_iter_err(k))) { if (!bkey_extent_is_data(k.k) || !bch2_extent_has_device(bkey_s_c_to_extent(k), dev_idx)) { - ret = bch2_mark_bkey_replicas(c, BCH_DATA_USER, k); + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_EXTENTS, k); if (ret) break; bch2_btree_iter_next(&iter); @@ -72,7 +72,7 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) */ bch2_extent_normalize(c, e.s); - ret = bch2_mark_bkey_replicas(c, BCH_DATA_USER, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_EXTENTS, bkey_i_to_s_c(&tmp.key)); if (ret) break; @@ -135,7 +135,7 @@ retry: */ bch2_btree_iter_downgrade(&iter); - ret = bch2_mark_bkey_replicas(c, BCH_DATA_BTREE, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_BTREE, bkey_i_to_s_c(&b->key)); if (ret) goto err; diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index c7132a65566b..b2bf0944d59d 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -149,7 +149,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op) goto next; } - ret = bch2_mark_bkey_replicas(c, BCH_DATA_USER, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_EXTENTS, extent_i_to_s_c(insert).s_c); if (ret) break; @@ -600,7 +600,7 @@ static int bch2_gc_data_replicas(struct bch_fs *c) for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, POS_MIN, BTREE_ITER_PREFETCH, k) { - ret = bch2_mark_bkey_replicas(c, BCH_DATA_USER, k); + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_EXTENTS, k); if (ret) break; } @@ -624,7 +624,7 @@ static int bch2_gc_btree_replicas(struct bch_fs *c) for (id = 0; id < BTREE_ID_NR; id++) { for_each_btree_node(&iter, c, id, POS_MIN, BTREE_ITER_PREFETCH, b) { - ret = bch2_mark_bkey_replicas(c, BCH_DATA_BTREE, + ret = bch2_mark_bkey_replicas(c, BKEY_TYPE_BTREE, bkey_i_to_s_c(&b->key)); bch2_btree_iter_cond_resched(&iter); diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index a1ece679954c..72dd70b00abb 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -74,6 +74,42 @@ int bch2_cpu_replicas_to_text(struct bch_replicas_cpu *r, return out - buf; } +static void extent_to_replicas(struct bkey_s_c k, + struct bch_replicas_entry *r) +{ + if (bkey_extent_is_data(k.k)) { + struct bkey_s_c_extent e = bkey_s_c_to_extent(k); + const union bch_extent_entry *entry; + struct extent_ptr_decoded p; + + extent_for_each_ptr_decode(e, p, entry) + if (!p.ptr.cached) + r->devs[r->nr_devs++] = p.ptr.dev; + } +} + +static void bkey_to_replicas(enum bkey_type type, + struct bkey_s_c k, + struct bch_replicas_entry *e) +{ + e->nr_devs = 0; + + switch (type) { + case BKEY_TYPE_BTREE: + e->data_type = BCH_DATA_BTREE; + extent_to_replicas(k, e); + break; + case BKEY_TYPE_EXTENTS: + e->data_type = BCH_DATA_USER; + extent_to_replicas(k, e); + break; + default: + break; + } + + replicas_entry_sort(e); +} + static inline void devlist_to_replicas(struct bch_devs_list devs, enum bch_data_type data_type, struct bch_replicas_entry *e) @@ -189,13 +225,28 @@ err: return ret; } +static int __bch2_mark_replicas(struct bch_fs *c, + struct bch_replicas_entry *devs) +{ + struct bch_replicas_cpu *r, *gc_r; + bool marked; + + rcu_read_lock(); + r = rcu_dereference(c->replicas); + gc_r = rcu_dereference(c->replicas_gc); + marked = replicas_has_entry(r, devs) && + (!likely(gc_r) || replicas_has_entry(gc_r, devs)); + rcu_read_unlock(); + + return likely(marked) ? 0 + : bch2_mark_replicas_slowpath(c, devs); +} + int bch2_mark_replicas(struct bch_fs *c, enum bch_data_type data_type, struct bch_devs_list devs) { struct bch_replicas_entry_padded search; - struct bch_replicas_cpu *r, *gc_r; - bool marked; if (!devs.nr) return 0; @@ -206,31 +257,31 @@ int bch2_mark_replicas(struct bch_fs *c, devlist_to_replicas(devs, data_type, &search.e); - rcu_read_lock(); - r = rcu_dereference(c->replicas); - gc_r = rcu_dereference(c->replicas_gc); - marked = replicas_has_entry(r, &search.e) && - (!likely(gc_r) || replicas_has_entry(gc_r, &search.e)); - rcu_read_unlock(); - - return likely(marked) ? 0 - : bch2_mark_replicas_slowpath(c, &search.e); + return __bch2_mark_replicas(c, &search.e); } int bch2_mark_bkey_replicas(struct bch_fs *c, - enum bch_data_type data_type, + enum bkey_type type, struct bkey_s_c k) { - struct bch_devs_list cached = bch2_bkey_cached_devs(k); - unsigned i; + struct bch_replicas_entry_padded search; int ret; - for (i = 0; i < cached.nr; i++) - if ((ret = bch2_mark_replicas(c, BCH_DATA_CACHED, - bch2_dev_list_single(cached.devs[i])))) - return ret; + if (type == BKEY_TYPE_EXTENTS) { + struct bch_devs_list cached = bch2_bkey_cached_devs(k); + unsigned i; + + for (i = 0; i < cached.nr; i++) + if ((ret = bch2_mark_replicas(c, BCH_DATA_CACHED, + bch2_dev_list_single(cached.devs[i])))) + return ret; + } + + bkey_to_replicas(type, k, &search.e); - return bch2_mark_replicas(c, data_type, bch2_bkey_dirty_devs(k)); + return search.e.nr_devs + ? __bch2_mark_replicas(c, &search.e) + : 0; } int bch2_replicas_gc_end(struct bch_fs *c, int ret) @@ -507,18 +558,32 @@ bool bch2_replicas_marked(struct bch_fs *c, } bool bch2_bkey_replicas_marked(struct bch_fs *c, - enum bch_data_type data_type, + enum bkey_type type, struct bkey_s_c k) { - struct bch_devs_list cached = bch2_bkey_cached_devs(k); - unsigned i; + struct bch_replicas_entry_padded search; + bool ret; + + if (type == BKEY_TYPE_EXTENTS) { + struct bch_devs_list cached = bch2_bkey_cached_devs(k); + unsigned i; + + for (i = 0; i < cached.nr; i++) + if (!bch2_replicas_marked(c, BCH_DATA_CACHED, + bch2_dev_list_single(cached.devs[i]))) + return false; + } + + bkey_to_replicas(type, k, &search.e); - for (i = 0; i < cached.nr; i++) - if (!bch2_replicas_marked(c, BCH_DATA_CACHED, - bch2_dev_list_single(cached.devs[i]))) - return false; + if (!search.e.nr_devs) + return true; + + rcu_read_lock(); + ret = replicas_has_entry(rcu_dereference(c->replicas), &search.e); + rcu_read_unlock(); - return bch2_replicas_marked(c, data_type, bch2_bkey_dirty_devs(k)); + return ret; } struct replicas_status __bch2_replicas_status(struct bch_fs *c, diff --git a/fs/bcachefs/replicas.h b/fs/bcachefs/replicas.h index 6c01f35296e7..ebbb1334cc2c 100644 --- a/fs/bcachefs/replicas.h +++ b/fs/bcachefs/replicas.h @@ -6,11 +6,11 @@ bool bch2_replicas_marked(struct bch_fs *, enum bch_data_type, struct bch_devs_list); -bool bch2_bkey_replicas_marked(struct bch_fs *, enum bch_data_type, +bool bch2_bkey_replicas_marked(struct bch_fs *, enum bkey_type, struct bkey_s_c); int bch2_mark_replicas(struct bch_fs *, enum bch_data_type, struct bch_devs_list); -int bch2_mark_bkey_replicas(struct bch_fs *, enum bch_data_type, +int bch2_mark_bkey_replicas(struct bch_fs *, enum bkey_type, struct bkey_s_c); int bch2_cpu_replicas_to_text(struct bch_replicas_cpu *, char *, size_t); |