Commit 702ffea2 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Extent helper improvements

 - __bch2_bkey_drop_ptr() -> bch2_bkey_drop_ptr_noerror(), now available
   outside extents.

 - Split bch2_bkey_has_device() and bch2_bkey_has_device_c(), const and
   non const versions

 - bch2_extent_has_ptr() now returns the pointer it found
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 3f5d3fb4
...@@ -170,13 +170,13 @@ static int __bch2_data_update_index_update(struct btree_trans *trans, ...@@ -170,13 +170,13 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
i = 0; i = 0;
bkey_for_each_ptr_decode(old.k, bch2_bkey_ptrs_c(old), p, entry) { bkey_for_each_ptr_decode(old.k, bch2_bkey_ptrs_c(old), p, entry) {
if (((1U << i) & m->data_opts.rewrite_ptrs) && if (((1U << i) & m->data_opts.rewrite_ptrs) &&
bch2_extent_has_ptr(old, p, bkey_i_to_s_c(insert))) { bch2_extent_has_ptr(old, p, bkey_i_to_s(insert))) {
/* /*
* If we're going to be adding a pointer to the * If we're going to be adding a pointer to the
* same device, we have to drop the old one - * same device, we have to drop the old one -
* otherwise, we can just mark it cached: * otherwise, we can just mark it cached:
*/ */
if (bch2_bkey_has_device(bkey_i_to_s_c(&new->k_i), p.ptr.dev)) if (bch2_bkey_has_device_c(bkey_i_to_s_c(&new->k_i), p.ptr.dev))
bch2_bkey_drop_device_noerror(bkey_i_to_s(insert), p.ptr.dev); bch2_bkey_drop_device_noerror(bkey_i_to_s(insert), p.ptr.dev);
else else
bch2_bkey_mark_dev_cached(bkey_i_to_s(insert), p.ptr.dev); bch2_bkey_mark_dev_cached(bkey_i_to_s(insert), p.ptr.dev);
...@@ -188,7 +188,7 @@ static int __bch2_data_update_index_update(struct btree_trans *trans, ...@@ -188,7 +188,7 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
/* Add new ptrs: */ /* Add new ptrs: */
extent_for_each_ptr_decode(extent_i_to_s(new), p, entry) { extent_for_each_ptr_decode(extent_i_to_s(new), p, entry) {
const struct bch_extent_ptr *existing_ptr = const struct bch_extent_ptr *existing_ptr =
bch2_bkey_has_device(bkey_i_to_s_c(insert), p.ptr.dev); bch2_bkey_has_device_c(bkey_i_to_s_c(insert), p.ptr.dev);
if (existing_ptr && existing_ptr->cached) { if (existing_ptr && existing_ptr->cached) {
/* /*
......
...@@ -959,7 +959,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans, ...@@ -959,7 +959,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
bkey_reassemble(n, k); bkey_reassemble(n, k);
bch2_bkey_drop_ptrs(bkey_i_to_s(n), ptr, ptr->dev != dev); bch2_bkey_drop_ptrs(bkey_i_to_s(n), ptr, ptr->dev != dev);
ec_ptr = (void *) bch2_bkey_has_device(bkey_i_to_s_c(n), dev); ec_ptr = bch2_bkey_has_device(bkey_i_to_s(n), dev);
BUG_ON(!ec_ptr); BUG_ON(!ec_ptr);
stripe_ptr = (struct bch_extent_stripe_ptr) { stripe_ptr = (struct bch_extent_stripe_ptr) {
......
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
#include "trace.h" #include "trace.h"
#include "util.h" #include "util.h"
static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *);
static unsigned bch2_crc_field_size_max[] = { static unsigned bch2_crc_field_size_max[] = {
[BCH_EXTENT_ENTRY_crc32] = CRC32_SIZE_MAX, [BCH_EXTENT_ENTRY_crc32] = CRC32_SIZE_MAX,
[BCH_EXTENT_ENTRY_crc64] = CRC64_SIZE_MAX, [BCH_EXTENT_ENTRY_crc64] = CRC64_SIZE_MAX,
...@@ -511,7 +509,7 @@ bool bch2_bkey_narrow_crcs(struct bkey_i *k, struct bch_extent_crc_unpacked n) ...@@ -511,7 +509,7 @@ bool bch2_bkey_narrow_crcs(struct bkey_i *k, struct bch_extent_crc_unpacked n)
bkey_for_each_ptr_decode(&k->k, ptrs, p, i) bkey_for_each_ptr_decode(&k->k, ptrs, p, i)
if (can_narrow_crc(p.crc, n)) { if (can_narrow_crc(p.crc, n)) {
__bch2_bkey_drop_ptr(bkey_i_to_s(k), &i->ptr); bch2_bkey_drop_ptr_noerror(bkey_i_to_s(k), &i->ptr);
p.ptr.offset += p.crc.offset; p.ptr.offset += p.crc.offset;
p.crc = n; p.crc = n;
bch2_extent_ptr_decoded_append(k, &p); bch2_extent_ptr_decoded_append(k, &p);
...@@ -691,7 +689,21 @@ unsigned bch2_bkey_durability(struct bch_fs *c, struct bkey_s_c k) ...@@ -691,7 +689,21 @@ unsigned bch2_bkey_durability(struct bch_fs *c, struct bkey_s_c k)
unsigned durability = 0; unsigned durability = 0;
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
durability += bch2_extent_ptr_durability(c,& p); durability += bch2_extent_ptr_durability(c, &p);
return durability;
}
static unsigned bch2_bkey_durability_safe(struct bch_fs *c, struct bkey_s_c k)
{
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
const union bch_extent_entry *entry;
struct extent_ptr_decoded p;
unsigned durability = 0;
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
if (p.ptr.dev < c->sb.nr_devices && c->devs[p.ptr.dev])
durability += bch2_extent_ptr_durability(c, &p);
return durability; return durability;
} }
...@@ -764,8 +776,8 @@ static void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry) ...@@ -764,8 +776,8 @@ static void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry)
/* /*
* Returns pointer to the next entry after the one being dropped: * Returns pointer to the next entry after the one being dropped:
*/ */
static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s k, union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s k,
struct bch_extent_ptr *ptr) struct bch_extent_ptr *ptr)
{ {
struct bkey_ptrs ptrs = bch2_bkey_ptrs(k); struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
union bch_extent_entry *entry = to_entry(ptr), *next; union bch_extent_entry *entry = to_entry(ptr), *next;
...@@ -808,7 +820,7 @@ union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s k, ...@@ -808,7 +820,7 @@ union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s k,
{ {
bool have_dirty = bch2_bkey_dirty_devs(k.s_c).nr; bool have_dirty = bch2_bkey_dirty_devs(k.s_c).nr;
union bch_extent_entry *ret = union bch_extent_entry *ret =
__bch2_bkey_drop_ptr(k, ptr); bch2_bkey_drop_ptr_noerror(k, ptr);
/* /*
* If we deleted all the dirty pointers and there's still cached * If we deleted all the dirty pointers and there's still cached
...@@ -839,14 +851,13 @@ void bch2_bkey_drop_device(struct bkey_s k, unsigned dev) ...@@ -839,14 +851,13 @@ void bch2_bkey_drop_device(struct bkey_s k, unsigned dev)
void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev) void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev)
{ {
struct bch_extent_ptr *ptr = (void *) bch2_bkey_has_device(k.s_c, dev); struct bch_extent_ptr *ptr = bch2_bkey_has_device(k, dev);
if (ptr) if (ptr)
__bch2_bkey_drop_ptr(k, ptr); bch2_bkey_drop_ptr_noerror(k, ptr);
} }
const struct bch_extent_ptr * const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c k, unsigned dev)
bch2_bkey_has_device(struct bkey_s_c k, unsigned dev)
{ {
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
const struct bch_extent_ptr *ptr; const struct bch_extent_ptr *ptr;
...@@ -921,11 +932,11 @@ bool bch2_extents_match(struct bkey_s_c k1, struct bkey_s_c k2) ...@@ -921,11 +932,11 @@ bool bch2_extents_match(struct bkey_s_c k1, struct bkey_s_c k2)
} }
} }
bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1, struct bch_extent_ptr *
struct bkey_s_c k2) bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1, struct bkey_s k2)
{ {
struct bkey_ptrs_c ptrs2 = bch2_bkey_ptrs_c(k2); struct bkey_ptrs ptrs2 = bch2_bkey_ptrs(k2);
const union bch_extent_entry *entry2; union bch_extent_entry *entry2;
struct extent_ptr_decoded p2; struct extent_ptr_decoded p2;
bkey_for_each_ptr_decode(k2.k, ptrs2, p2, entry2) bkey_for_each_ptr_decode(k2.k, ptrs2, p2, entry2)
...@@ -933,9 +944,9 @@ bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1, ...@@ -933,9 +944,9 @@ bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1,
p1.ptr.gen == p2.ptr.gen && p1.ptr.gen == p2.ptr.gen &&
(s64) p1.ptr.offset + p1.crc.offset - bkey_start_offset(k1.k) == (s64) p1.ptr.offset + p1.crc.offset - bkey_start_offset(k1.k) ==
(s64) p2.ptr.offset + p2.crc.offset - bkey_start_offset(k2.k)) (s64) p2.ptr.offset + p2.crc.offset - bkey_start_offset(k2.k))
return true; return &entry2->ptr;
return false; return NULL;
} }
void bch2_extent_ptr_set_cached(struct bkey_s k, struct bch_extent_ptr *ptr) void bch2_extent_ptr_set_cached(struct bkey_s k, struct bch_extent_ptr *ptr)
...@@ -991,6 +1002,9 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c, ...@@ -991,6 +1002,9 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
struct bch_dev *ca; struct bch_dev *ca;
bool first = true; bool first = true;
if (c)
prt_printf(out, "durability: %u ", bch2_bkey_durability_safe(c, k));
bkey_extent_entry_for_each(ptrs, entry) { bkey_extent_entry_for_each(ptrs, entry) {
if (!first) if (!first)
prt_printf(out, " "); prt_printf(out, " ");
......
...@@ -613,14 +613,21 @@ unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); ...@@ -613,14 +613,21 @@ unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c);
void bch2_bkey_drop_device(struct bkey_s, unsigned); void bch2_bkey_drop_device(struct bkey_s, unsigned);
void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned);
const struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s_c, unsigned);
const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned);
static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev)
{
return (void *) bch2_bkey_has_device_c(k.s_c, dev);
}
bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned);
void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *);
static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr) static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr)
{ {
EBUG_ON(bch2_bkey_has_device(bkey_i_to_s_c(k), ptr.dev)); EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev));
switch (k->k.type) { switch (k->k.type) {
case KEY_TYPE_btree_ptr: case KEY_TYPE_btree_ptr:
...@@ -642,6 +649,8 @@ static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ...@@ -642,6 +649,8 @@ static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr
void bch2_extent_ptr_decoded_append(struct bkey_i *, void bch2_extent_ptr_decoded_append(struct bkey_i *,
struct extent_ptr_decoded *); struct extent_ptr_decoded *);
union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s,
struct bch_extent_ptr *);
union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s,
struct bch_extent_ptr *); struct bch_extent_ptr *);
...@@ -665,7 +674,8 @@ do { \ ...@@ -665,7 +674,8 @@ do { \
bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c,
struct bch_extent_ptr, u64); struct bch_extent_ptr, u64);
bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c); bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c);
bool bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s_c); struct bch_extent_ptr *
bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s);
void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *); void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *);
......
...@@ -971,7 +971,7 @@ static bool bch2_journal_writing_to_device(struct journal *j, unsigned dev_idx) ...@@ -971,7 +971,7 @@ static bool bch2_journal_writing_to_device(struct journal *j, unsigned dev_idx)
seq++) { seq++) {
struct journal_buf *buf = journal_seq_to_buf(j, seq); struct journal_buf *buf = journal_seq_to_buf(j, seq);
if (bch2_bkey_has_device(bkey_i_to_s_c(&buf->key), dev_idx)) if (bch2_bkey_has_device_c(bkey_i_to_s_c(&buf->key), dev_idx))
ret = true; ret = true;
} }
spin_unlock(&j->lock); spin_unlock(&j->lock);
......
...@@ -1338,8 +1338,7 @@ static void __journal_write_alloc(struct journal *j, ...@@ -1338,8 +1338,7 @@ static void __journal_write_alloc(struct journal *j,
if (!ca->mi.durability || if (!ca->mi.durability ||
ca->mi.state != BCH_MEMBER_STATE_rw || ca->mi.state != BCH_MEMBER_STATE_rw ||
!ja->nr || !ja->nr ||
bch2_bkey_has_device(bkey_i_to_s_c(&w->key), bch2_bkey_has_device_c(bkey_i_to_s_c(&w->key), ca->dev_idx) ||
ca->dev_idx) ||
sectors > ja->sectors_free) sectors > ja->sectors_free)
continue; continue;
......
...@@ -46,7 +46,7 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans, ...@@ -46,7 +46,7 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,
struct bkey_i *n; struct bkey_i *n;
int ret; int ret;
if (!bch2_bkey_has_device(k, dev_idx)) if (!bch2_bkey_has_device_c(k, dev_idx))
return 0; return 0;
n = bch2_bkey_make_mut(trans, k); n = bch2_bkey_make_mut(trans, k);
...@@ -130,8 +130,7 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) ...@@ -130,8 +130,7 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
while (bch2_trans_begin(&trans), while (bch2_trans_begin(&trans),
(b = bch2_btree_iter_peek_node(&iter)) && (b = bch2_btree_iter_peek_node(&iter)) &&
!(ret = PTR_ERR_OR_ZERO(b))) { !(ret = PTR_ERR_OR_ZERO(b))) {
if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key), if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx))
dev_idx))
goto next; goto next;
bch2_bkey_buf_copy(&k, c, &b->key); bch2_bkey_buf_copy(&k, c, &b->key);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment