diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-01-03 23:53:28 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-22 00:44:18 -0400 |
commit | a74233222b463dd3fcd4f665d0c3a79f892741eb (patch) | |
tree | 2466d6604ff5de0276cbc6bfdca1cbcf6f94e62f | |
parent | 4f0536621c20dd3c2af13633f4e140afe2c2cbde (diff) |
bcachefs; check_mark_super() now takes devlist
-rw-r--r-- | fs/bcachefs/btree_gc.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 7 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 11 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/journal.c | 20 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 39 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/super-io.c | 77 | ||||
-rw-r--r-- | fs/bcachefs/super-io.h | 12 |
10 files changed, 80 insertions, 116 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 7d1be86f41cb..01694f9f02e0 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -148,23 +148,24 @@ int bch2_btree_mark_key_initial(struct bch_fs *c, enum bkey_type type, { enum bch_data_type data_type = type == BKEY_TYPE_BTREE ? BCH_DATA_BTREE : BCH_DATA_USER; + struct bch_devs_list devs = bch2_bkey_devs(k); int ret = 0; + if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || + fsck_err_on(!bch2_sb_has_replicas(c, data_type, devs), c, + "superblock not marked as containing replicas (type %u)", + data_type)) { + ret = bch2_check_mark_super(c, data_type, devs); + if (ret) + return ret; + } + switch (k.k->type) { case BCH_EXTENT: case BCH_EXTENT_CACHED: { struct bkey_s_c_extent e = bkey_s_c_to_extent(k); const struct bch_extent_ptr *ptr; - if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || - fsck_err_on(!bch2_sb_has_replicas(c, e, data_type), c, - "superblock not marked as containing replicas (type %u)", - data_type)) { - ret = bch2_check_mark_super(c, e, data_type); - if (ret) - return ret; - } - extent_for_each_ptr(e, ptr) { struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); size_t b = PTR_BUCKET_NR(ca, ptr); diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 04854532b8b4..62d1faa3f7a2 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -546,8 +546,8 @@ static struct btree_reserve *bch2_btree_reserve_get(struct bch_fs *c, goto err_free; } - ret = bch2_check_mark_super(c, bkey_i_to_s_c_extent(&b->key), - BCH_DATA_BTREE); + ret = bch2_check_mark_super(c, BCH_DATA_BTREE, + bch2_bkey_devs(bkey_i_to_s_c(&b->key))); if (ret) goto err_free; @@ -1957,7 +1957,8 @@ int bch2_btree_node_update_key(struct bch_fs *c, struct btree_iter *iter, goto err; } - ret = bch2_check_mark_super(c, extent_i_to_s_c(new_key), BCH_DATA_BTREE); + ret = bch2_check_mark_super(c, BCH_DATA_BTREE, + bch2_extent_devs(extent_i_to_s_c(new_key))); if (ret) goto err_free_update; diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 2b4a2dc2339e..bceea486c5b6 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -666,7 +666,7 @@ static void btree_ptr_debugcheck(struct bch_fs *c, struct btree *b, goto err; } - if (!bch2_sb_has_replicas(c, e, BCH_DATA_BTREE)) { + if (!bch2_sb_has_replicas(c, BCH_DATA_BTREE, bch2_extent_devs(e))) { bch2_bkey_val_to_text(c, btree_node_type(b), buf, sizeof(buf), k); bch2_fs_bug(c, @@ -1803,7 +1803,7 @@ static void bch2_extent_debugcheck_extent(struct bch_fs *c, struct btree *b, } if (!bkey_extent_is_cached(e.k) && - !bch2_sb_has_replicas(c, e, BCH_DATA_USER)) { + !bch2_sb_has_replicas(c, BCH_DATA_USER, bch2_extent_devs(e))) { 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/extents.h b/fs/bcachefs/extents.h index aeae361d9e28..eda34381001e 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -426,6 +426,17 @@ static inline struct bch_devs_list bch2_extent_dirty_devs(struct bkey_s_c_extent return ret; } +static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k) +{ + switch (k.k->type) { + case BCH_EXTENT: + case BCH_EXTENT_CACHED: + return bch2_extent_devs(bkey_s_c_to_extent(k)); + default: + return (struct bch_devs_list) { .nr = 0 }; + } +} + bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent, struct bch_extent_crc_unpacked); bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked); diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 9d7b6c4ea846..3553fa4d3cd2 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -268,7 +268,8 @@ static void bch2_write_index(struct closure *cl) } if (!(op->flags & BCH_WRITE_NOMARK_REPLICAS)) { - ret = bch2_check_mark_super(c, e.c, BCH_DATA_USER); + ret = bch2_check_mark_super(c, BCH_DATA_USER, + bch2_extent_devs(e.c)); if (ret) goto err; } diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index e8756cd8e01b..b60bdb0932dd 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -996,12 +996,12 @@ int bch2_journal_read(struct bch_fs *c, struct list_head *list) goto fsck_err; if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || - fsck_err_on(!bch2_sb_has_replicas_devlist(c, &i->devs, - BCH_DATA_JOURNAL), c, + fsck_err_on(!bch2_sb_has_replicas(c, BCH_DATA_JOURNAL, + i->devs), c, "superblock not marked as containing replicas (type %u)", BCH_DATA_JOURNAL)) { - ret = bch2_check_mark_super_devlist(c, &i->devs, - BCH_DATA_JOURNAL); + ret = bch2_check_mark_super(c, BCH_DATA_JOURNAL, + i->devs); if (ret) return ret; } @@ -2197,14 +2197,15 @@ static void journal_write_done(struct closure *cl) struct journal *j = container_of(cl, struct journal, io); struct bch_fs *c = container_of(j, struct bch_fs, journal); struct journal_buf *w = journal_prev_buf(j); - struct bkey_s_c_extent e = bkey_i_to_s_c_extent(&w->key); + struct bch_devs_list devs = + bch2_extent_devs(bkey_i_to_s_c_extent(&w->key)); - if (!bch2_extent_nr_ptrs(e)) { + if (!devs.nr) { bch_err(c, "unable to write journal to sufficient devices"); goto err; } - if (bch2_check_mark_super(c, e, BCH_DATA_JOURNAL)) + if (bch2_check_mark_super(c, BCH_DATA_JOURNAL, devs)) goto err; out: __bch2_time_stats_update(j->write_time, j->write_start_time); @@ -2212,8 +2213,7 @@ out: spin_lock(&j->lock); j->last_seq_ondisk = le64_to_cpu(w->data->last_seq); - journal_seq_pin(j, le64_to_cpu(w->data->seq))->devs = - bch2_extent_devs(bkey_i_to_s_c_extent(&w->key)); + journal_seq_pin(j, le64_to_cpu(w->data->seq))->devs = devs; /* * Updating last_seq_ondisk may let journal_reclaim_work() discard more @@ -2771,7 +2771,7 @@ int bch2_journal_flush_device(struct journal *j, unsigned dev_idx) seq++; spin_unlock(&j->lock); - ret = bch2_check_mark_super_devlist(c, &devs, BCH_DATA_JOURNAL); + ret = bch2_check_mark_super(c, BCH_DATA_JOURNAL, devs); spin_lock(&j->lock); } spin_unlock(&j->lock); diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c index abfbb15ce538..35f12f60b2df 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -65,11 +65,7 @@ static int bch2_dev_usrdata_migrate(struct bch_fs *c, struct bch_dev *ca, bch2_replicas_gc_start(c, 1 << BCH_DATA_USER); for_each_btree_key(&iter, c, BTREE_ID_EXTENTS, POS_MIN, BTREE_ITER_PREFETCH, k) { - if (!bkey_extent_is_data(k.k)) - continue; - - ret = bch2_check_mark_super(c, bkey_s_c_to_extent(k), - BCH_DATA_USER); + ret = bch2_check_mark_super(c, BCH_DATA_USER, bch2_bkey_devs(k)); if (ret) { bch_err(c, "error migrating data %i from check_mark_super()", ret); break; @@ -161,11 +157,15 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) while ((k = bch2_btree_iter_peek(&iter)).k && !(ret = btree_iter_err(k))) { - if (!bkey_extent_is_data(k.k)) - goto advance; - - if (!bch2_extent_has_device(bkey_s_c_to_extent(k), dev_idx)) - goto advance; + if (!bkey_extent_is_data(k.k) || + !bch2_extent_has_device(bkey_s_c_to_extent(k), dev_idx)) { + ret = bch2_check_mark_super(c, BCH_DATA_USER, + bch2_bkey_devs(k)); + if (ret) + break; + bch2_btree_iter_advance_pos(&iter); + continue; + } bkey_reassemble(&tmp.key, k); e = bkey_i_to_s_extent(&tmp.key); @@ -181,8 +181,9 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) */ bch2_extent_normalize(c, e.s); - if (bkey_extent_is_data(e.k) && - (ret = bch2_check_mark_super(c, e.c, BCH_DATA_USER))) + ret = bch2_check_mark_super(c, BCH_DATA_USER, + bch2_bkey_devs(bkey_i_to_s_c(&tmp.key))); + if (ret) break; iter.pos = bkey_start_pos(&tmp.key.k); @@ -201,16 +202,6 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) ret = 0; if (ret) break; - - continue; -advance: - if (bkey_extent_is_data(k.k)) { - ret = bch2_check_mark_super(c, bkey_s_c_to_extent(k), - BCH_DATA_USER); - if (ret) - break; - } - bch2_btree_iter_advance_pos(&iter); } bch2_btree_iter_unlock(&iter); @@ -247,8 +238,8 @@ retry: dev_idx)) { bch2_btree_iter_set_locks_want(&iter, 0); - ret = bch2_check_mark_super(c, bkey_i_to_s_c_extent(&b->key), - BCH_DATA_BTREE); + ret = bch2_check_mark_super(c, BCH_DATA_BTREE, + bch2_bkey_devs(bkey_i_to_s_c(&b->key))); if (ret) goto err; } else { diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 038d9fd630ff..1df7ceed6875 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -116,8 +116,8 @@ static int bch2_migrate_index_update(struct bch_write_op *op) bch2_extent_normalize(c, extent_i_to_s(insert).s); bch2_extent_mark_replicas_cached(c, extent_i_to_s(insert)); - ret = bch2_check_mark_super(c, extent_i_to_s_c(insert), - BCH_DATA_USER); + ret = bch2_check_mark_super(c, BCH_DATA_USER, + bch2_extent_devs(extent_i_to_s_c(insert))); if (ret) break; diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 16aee91bda16..e3c319fc5390 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -1099,13 +1099,20 @@ err: return ret; } -static inline int __bch2_check_mark_super(struct bch_fs *c, - struct bch_replicas_cpu_entry search, - unsigned max_dev) +int bch2_check_mark_super(struct bch_fs *c, + enum bch_data_type data_type, + struct bch_devs_list devs) { + struct bch_replicas_cpu_entry search; struct bch_replicas_cpu *r, *gc_r; + unsigned max_dev; bool marked; + if (!devs.nr) + return 0; + + devlist_to_replicas(devs, data_type, &search, &max_dev); + rcu_read_lock(); r = rcu_dereference(c->replicas); gc_r = rcu_dereference(c->replicas_gc); @@ -1117,32 +1124,6 @@ static inline int __bch2_check_mark_super(struct bch_fs *c, : bch2_check_mark_super_slowpath(c, search, max_dev); } -int bch2_check_mark_super(struct bch_fs *c, struct bkey_s_c_extent e, - enum bch_data_type data_type) -{ - struct bch_replicas_cpu_entry search; - unsigned max_dev; - - if (!bkey_to_replicas(e, data_type, &search, &max_dev)) - return 0; - - return __bch2_check_mark_super(c, search, max_dev); -} - -int bch2_check_mark_super_devlist(struct bch_fs *c, - struct bch_devs_list *devs, - enum bch_data_type data_type) -{ - struct bch_replicas_cpu_entry search; - unsigned max_dev; - - if (!devs->nr) - return 0; - - devlist_to_replicas(*devs, data_type, &search, &max_dev); - return __bch2_check_mark_super(c, search, max_dev); -} - int bch2_replicas_gc_end(struct bch_fs *c, int err) { struct bch_replicas_cpu *new_r, *old_r; @@ -1426,12 +1407,19 @@ int bch2_sb_replicas_to_text(struct bch_sb_field_replicas *r, char *buf, size_t /* Query replicas: */ -static bool __bch2_sb_has_replicas(struct bch_fs *c, - struct bch_replicas_cpu_entry search, - unsigned max_dev) +bool bch2_sb_has_replicas(struct bch_fs *c, + enum bch_data_type data_type, + struct bch_devs_list devs) { + struct bch_replicas_cpu_entry search; + unsigned max_dev; bool ret; + if (!devs.nr) + return true; + + devlist_to_replicas(devs, data_type, &search, &max_dev); + rcu_read_lock(); ret = replicas_has_entry(rcu_dereference(c->replicas), search, max_dev); @@ -1440,31 +1428,6 @@ static bool __bch2_sb_has_replicas(struct bch_fs *c, return ret; } -bool bch2_sb_has_replicas(struct bch_fs *c, struct bkey_s_c_extent e, - enum bch_data_type data_type) -{ - struct bch_replicas_cpu_entry search; - unsigned max_dev; - - if (!bkey_to_replicas(e, data_type, &search, &max_dev)) - return true; - - return __bch2_sb_has_replicas(c, search, max_dev); -} - -bool bch2_sb_has_replicas_devlist(struct bch_fs *c, struct bch_devs_list *devs, - enum bch_data_type data_type) -{ - struct bch_replicas_cpu_entry search; - unsigned max_dev; - - if (!devs->nr) - return true; - - devlist_to_replicas(*devs, data_type, &search, &max_dev); - return __bch2_sb_has_replicas(c, search, max_dev); -} - struct replicas_status __bch2_replicas_status(struct bch_fs *c, struct bch_devs_mask online_devs) { diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h index 69366a6f9581..59a8b816c467 100644 --- a/fs/bcachefs/super-io.h +++ b/fs/bcachefs/super-io.h @@ -138,14 +138,10 @@ static inline struct bch_member_cpu bch2_mi_to_cpu(struct bch_member *mi) /* BCH_SB_FIELD_replicas: */ -bool bch2_sb_has_replicas(struct bch_fs *, struct bkey_s_c_extent, - enum bch_data_type); -bool bch2_sb_has_replicas_devlist(struct bch_fs *, struct bch_devs_list *, - enum bch_data_type); -int bch2_check_mark_super(struct bch_fs *, struct bkey_s_c_extent, - enum bch_data_type); -int bch2_check_mark_super_devlist(struct bch_fs *, struct bch_devs_list *, - enum bch_data_type); +bool bch2_sb_has_replicas(struct bch_fs *, enum bch_data_type, + struct bch_devs_list); +int bch2_check_mark_super(struct bch_fs *, enum bch_data_type, + struct bch_devs_list); int bch2_cpu_replicas_to_text(struct bch_replicas_cpu *, char *, size_t); int bch2_sb_replicas_to_text(struct bch_sb_field_replicas *, char *, size_t); |