diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-10-30 14:32:21 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-03 16:26:39 -0400 |
commit | f72e5f065538d369176c736f1d1dda9861d86304 (patch) | |
tree | 3bc1f87167e1bb9585b569ddbeb140929b3f7314 | |
parent | 6a009941dde743cc49797fd67c7c04e2caeab103 (diff) |
bcachefs: replicas: prep work for stripes
-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 9f38f00f5238..1d464450c6da 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -152,10 +152,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 6d3fab8e767e..89b032ab9ebf 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -550,7 +550,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; @@ -2062,7 +2062,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 e5dc4cfa88de..3ce2f9ebdff4 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 e49118313dc3..930c18065885 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -320,7 +320,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 f5cbf44d7b8c..c0dfe1c641e2 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -50,7 +50,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); @@ -71,7 +71,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; @@ -134,7 +134,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 a6b044de0dab..c9495ab78cf0 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; @@ -601,7 +601,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; } @@ -625,7 +625,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 b6bcd4a61942..b0cef995e9e6 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -73,6 +73,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) @@ -188,13 +224,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; @@ -205,31 +256,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) @@ -506,18 +557,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 dfea0c052a86..640fe5b26975 100644 --- a/fs/bcachefs/replicas.h +++ b/fs/bcachefs/replicas.h @@ -5,11 +5,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); |