From 37954a275fce612f60406bc79f5bc0b07b4b6558 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Tue, 8 Oct 2019 18:45:29 -0400 Subject: [PATCH] bcachefs: Limit pointers to being in only one stripe This make the disk accounting code saner, and it's not clear why we'd ever want the same data to be in multiple stripes simultaneously. Signed-off-by: Kent Overstreet --- fs/bcachefs/buckets.c | 28 +++++++++++----------------- fs/bcachefs/ec.c | 5 ++--- fs/bcachefs/extents.c | 21 ++++++++++----------- fs/bcachefs/extents.h | 5 +++-- fs/bcachefs/extents_types.h | 4 ++-- fs/bcachefs/replicas.c | 4 +--- 6 files changed, 29 insertions(+), 38 deletions(-) diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 9beb4d4cf85da..dc184de053ee4 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1027,7 +1027,6 @@ static int bch2_mark_extent(struct bch_fs *c, struct bkey_s_c k, struct extent_ptr_decoded p; struct bch_replicas_padded r; s64 dirty_sectors = 0; - unsigned i; int ret; r.e.data_type = data_type; @@ -1047,17 +1046,15 @@ static int bch2_mark_extent(struct bch_fs *c, struct bkey_s_c k, if (!stale) update_cached_sectors(c, fs_usage, p.ptr.dev, disk_sectors); - } else if (!p.ec_nr) { + } else if (!p.has_ec) { dirty_sectors += disk_sectors; r.e.devs[r.e.nr_devs++] = p.ptr.dev; } else { - for (i = 0; i < p.ec_nr; i++) { - ret = bch2_mark_stripe_ptr(c, p.ec[i], - data_type, fs_usage, - disk_sectors, flags); - if (ret) - return ret; - } + ret = bch2_mark_stripe_ptr(c, p.ec, + data_type, fs_usage, + disk_sectors, flags); + if (ret) + return ret; r.e.nr_required = 0; } @@ -1564,7 +1561,6 @@ static int bch2_trans_mark_extent(struct btree_trans *trans, struct bch_replicas_padded r; s64 dirty_sectors = 0; bool stale; - unsigned i; int ret; r.e.data_type = data_type; @@ -1589,16 +1585,14 @@ static int bch2_trans_mark_extent(struct btree_trans *trans, if (!stale) update_cached_sectors_list(trans, p.ptr.dev, disk_sectors); - } else if (!p.ec_nr) { + } else if (!p.has_ec) { dirty_sectors += disk_sectors; r.e.devs[r.e.nr_devs++] = p.ptr.dev; } else { - for (i = 0; i < p.ec_nr; i++) { - ret = bch2_trans_mark_stripe_ptr(trans, p.ec[i], - disk_sectors, data_type); - if (ret) - return ret; - } + ret = bch2_trans_mark_stripe_ptr(trans, p.ec, + disk_sectors, data_type); + if (ret) + return ret; r.e.nr_required = 0; } diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index 424d5cf48893a..316dd82809ffc 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -433,10 +433,9 @@ int bch2_ec_read_extent(struct bch_fs *c, struct bch_read_bio *rbio) closure_init_stack(&cl); - BUG_ON(!rbio->pick.idx || - rbio->pick.idx - 1 >= rbio->pick.ec_nr); + BUG_ON(!rbio->pick.has_ec); - stripe_idx = rbio->pick.ec[rbio->pick.idx - 1].idx; + stripe_idx = rbio->pick.ec.idx; buf = kzalloc(sizeof(*buf), GFP_NOIO); if (!buf) diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index a8c2081cdd250..50cad6725c1b6 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -66,7 +66,7 @@ unsigned bch2_bkey_nr_dirty_ptrs(struct bkey_s_c k) static unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded p) { - unsigned i, durability = 0; + unsigned durability = 0; struct bch_dev *ca; if (p.ptr.cached) @@ -77,16 +77,16 @@ static unsigned bch2_extent_ptr_durability(struct bch_fs *c, if (ca->mi.state != BCH_MEMBER_STATE_FAILED) durability = max_t(unsigned, durability, ca->mi.durability); - for (i = 0; i < p.ec_nr; i++) { + if (p.has_ec) { struct stripe *s = - genradix_ptr(&c->stripes[0], p.ec[i].idx); + genradix_ptr(&c->stripes[0], p.ec.idx); if (WARN_ON(!s)) - continue; + goto out; durability = max_t(unsigned, durability, s->nr_redundant); } - +out: return durability; } @@ -205,10 +205,10 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k, p.idx++; if (force_reconstruct_read(c) && - !p.idx && p.ec_nr) + !p.idx && p.has_ec) p.idx++; - if (p.idx >= p.ec_nr + 1) + if (p.idx >= (unsigned) p.has_ec + 1) continue; if (ret > 0 && !ptr_better(c, p, *pick)) @@ -1543,7 +1543,6 @@ void bch2_extent_ptr_decoded_append(struct bkey_i *k, struct bch_extent_crc_unpacked crc = bch2_extent_crc_unpack(&k->k, NULL); union bch_extent_entry *pos; - unsigned i; if (!bch2_crc_unpacked_cmp(crc, p->crc)) { pos = ptrs.start; @@ -1562,9 +1561,9 @@ found: p->ptr.type = 1 << BCH_EXTENT_ENTRY_ptr; __extent_entry_insert(k, pos, to_entry(&p->ptr)); - for (i = 0; i < p->ec_nr; i++) { - p->ec[i].type = 1 << BCH_EXTENT_ENTRY_stripe_ptr; - __extent_entry_insert(k, pos, to_entry(&p->ec[i])); + if (p->has_ec) { + p->ec.type = 1 << BCH_EXTENT_ENTRY_stripe_ptr; + __extent_entry_insert(k, pos, to_entry(&p->ec)); } } diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index 7253cd01db6ae..cc7ee9067b50a 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -228,7 +228,7 @@ struct bkey_ptrs { __label__ out; \ \ (_ptr).idx = 0; \ - (_ptr).ec_nr = 0; \ + (_ptr).has_ec = false; \ \ __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ switch (extent_entry_type(_entry)) { \ @@ -242,7 +242,8 @@ struct bkey_ptrs { entry_to_crc(_entry)); \ break; \ case BCH_EXTENT_ENTRY_stripe_ptr: \ - (_ptr).ec[(_ptr).ec_nr++] = _entry->stripe_ptr; \ + (_ptr).ec = _entry->stripe_ptr; \ + (_ptr).has_ec = true; \ break; \ } \ out: \ diff --git a/fs/bcachefs/extents_types.h b/fs/bcachefs/extents_types.h index a8dd6952d9895..43d6c341eccab 100644 --- a/fs/bcachefs/extents_types.h +++ b/fs/bcachefs/extents_types.h @@ -21,10 +21,10 @@ struct bch_extent_crc_unpacked { struct extent_ptr_decoded { unsigned idx; - unsigned ec_nr; + bool has_ec; struct bch_extent_crc_unpacked crc; struct bch_extent_ptr ptr; - struct bch_extent_stripe_ptr ec[4]; + struct bch_extent_stripe_ptr ec; }; struct bch_io_failures { diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index afd226f3c8e7d..eef9f54808fb1 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -84,10 +84,8 @@ static void extent_to_replicas(struct bkey_s_c k, if (p.ptr.cached) continue; - if (p.ec_nr) { + if (p.has_ec) r->nr_required = 0; - break; - } r->devs[r->nr_devs++] = p.ptr.dev; } -- 2.30.2