summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-01-03 23:53:28 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-05-22 00:44:18 -0400
commita74233222b463dd3fcd4f665d0c3a79f892741eb (patch)
tree2466d6604ff5de0276cbc6bfdca1cbcf6f94e62f
parent4f0536621c20dd3c2af13633f4e140afe2c2cbde (diff)
bcachefs; check_mark_super() now takes devlist
-rw-r--r--fs/bcachefs/btree_gc.c19
-rw-r--r--fs/bcachefs/btree_update_interior.c7
-rw-r--r--fs/bcachefs/extents.c4
-rw-r--r--fs/bcachefs/extents.h11
-rw-r--r--fs/bcachefs/io.c3
-rw-r--r--fs/bcachefs/journal.c20
-rw-r--r--fs/bcachefs/migrate.c39
-rw-r--r--fs/bcachefs/move.c4
-rw-r--r--fs/bcachefs/super-io.c77
-rw-r--r--fs/bcachefs/super-io.h12
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);