bcachefs: Kill bch2_bkey_ptr_data_type()
Remove some duplication, and inconsistency between check_fix_ptrs and the main ptr marking paths Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
dcc1c04587
commit
47d2080e30
|
@ -29,8 +29,7 @@ static bool extent_matches_bp(struct bch_fs *c,
|
||||||
if (p.ptr.cached)
|
if (p.ptr.cached)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bch2_extent_ptr_to_bp(c, btree_id, level, k, p,
|
bch2_extent_ptr_to_bp(c, btree_id, level, k, p, entry, &bucket2, &bp2);
|
||||||
&bucket2, &bp2);
|
|
||||||
if (bpos_eq(bucket, bucket2) &&
|
if (bpos_eq(bucket, bucket2) &&
|
||||||
!memcmp(&bp, &bp2, sizeof(bp)))
|
!memcmp(&bp, &bp2, sizeof(bp)))
|
||||||
return true;
|
return true;
|
||||||
|
@ -507,8 +506,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
|
||||||
if (p.ptr.cached)
|
if (p.ptr.cached)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bch2_extent_ptr_to_bp(c, btree, level,
|
bch2_extent_ptr_to_bp(c, btree, level, k, p, entry, &bucket_pos, &bp);
|
||||||
k, p, &bucket_pos, &bp);
|
|
||||||
|
|
||||||
ret = check_bp_exists(trans, s, bucket_pos, bp, k);
|
ret = check_bp_exists(trans, s, bucket_pos, bp, k);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -90,20 +90,40 @@ static inline int bch2_bucket_backpointer_mod(struct btree_trans *trans,
|
||||||
return bch2_trans_update_buffered(trans, BTREE_ID_backpointers, &bp_k.k_i);
|
return bch2_trans_update_buffered(trans, BTREE_ID_backpointers, &bp_k.k_i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline enum bch_data_type bkey_ptr_data_type(enum btree_id btree_id, unsigned level,
|
static inline enum bch_data_type bch2_bkey_ptr_data_type(struct bkey_s_c k,
|
||||||
struct bkey_s_c k, struct extent_ptr_decoded p)
|
struct extent_ptr_decoded p,
|
||||||
|
const union bch_extent_entry *entry)
|
||||||
{
|
{
|
||||||
return level ? BCH_DATA_btree :
|
switch (k.k->type) {
|
||||||
p.has_ec ? BCH_DATA_stripe :
|
case KEY_TYPE_btree_ptr:
|
||||||
BCH_DATA_user;
|
case KEY_TYPE_btree_ptr_v2:
|
||||||
|
return BCH_DATA_btree;
|
||||||
|
case KEY_TYPE_extent:
|
||||||
|
case KEY_TYPE_reflink_v:
|
||||||
|
return p.has_ec ? BCH_DATA_stripe : BCH_DATA_user;
|
||||||
|
case KEY_TYPE_stripe: {
|
||||||
|
const struct bch_extent_ptr *ptr = &entry->ptr;
|
||||||
|
struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
|
||||||
|
|
||||||
|
BUG_ON(ptr < s.v->ptrs ||
|
||||||
|
ptr >= s.v->ptrs + s.v->nr_blocks);
|
||||||
|
|
||||||
|
return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
|
||||||
|
? BCH_DATA_parity
|
||||||
|
: BCH_DATA_user;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
|
static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
|
||||||
enum btree_id btree_id, unsigned level,
|
enum btree_id btree_id, unsigned level,
|
||||||
struct bkey_s_c k, struct extent_ptr_decoded p,
|
struct bkey_s_c k, struct extent_ptr_decoded p,
|
||||||
|
const union bch_extent_entry *entry,
|
||||||
struct bpos *bucket_pos, struct bch_backpointer *bp)
|
struct bpos *bucket_pos, struct bch_backpointer *bp)
|
||||||
{
|
{
|
||||||
enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p);
|
enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);
|
||||||
s64 sectors = level ? btree_sectors(c) : k.k->size;
|
s64 sectors = level ? btree_sectors(c) : k.k->size;
|
||||||
u32 bucket_offset;
|
u32 bucket_offset;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "bcachefs.h"
|
#include "bcachefs.h"
|
||||||
#include "alloc_background.h"
|
#include "alloc_background.h"
|
||||||
#include "alloc_foreground.h"
|
#include "alloc_foreground.h"
|
||||||
|
#include "backpointers.h"
|
||||||
#include "bkey_methods.h"
|
#include "bkey_methods.h"
|
||||||
#include "bkey_buf.h"
|
#include "bkey_buf.h"
|
||||||
#include "btree_journal_iter.h"
|
#include "btree_journal_iter.h"
|
||||||
|
@ -508,7 +509,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
|
||||||
bkey_for_each_ptr_decode(k->k, ptrs_c, p, entry_c) {
|
bkey_for_each_ptr_decode(k->k, ptrs_c, p, entry_c) {
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
||||||
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
|
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
|
||||||
enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, &entry_c->ptr);
|
enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, p, entry_c);
|
||||||
|
|
||||||
if (fsck_err_on(!g->gen_valid,
|
if (fsck_err_on(!g->gen_valid,
|
||||||
c, ptr_to_missing_alloc_key,
|
c, ptr_to_missing_alloc_key,
|
||||||
|
@ -574,7 +575,8 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fsck_err_on(bucket_data_type(g->data_type) &&
|
if (fsck_err_on(bucket_data_type(g->data_type) &&
|
||||||
bucket_data_type(g->data_type) != data_type, c,
|
bucket_data_type(g->data_type) !=
|
||||||
|
bucket_data_type(data_type), c,
|
||||||
ptr_bucket_data_type_mismatch,
|
ptr_bucket_data_type_mismatch,
|
||||||
"bucket %u:%zu different types of data in same bucket: %s, %s\n"
|
"bucket %u:%zu different types of data in same bucket: %s, %s\n"
|
||||||
"while marking %s",
|
"while marking %s",
|
||||||
|
@ -615,18 +617,13 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_update) {
|
if (do_update) {
|
||||||
struct bkey_ptrs ptrs;
|
|
||||||
union bch_extent_entry *entry;
|
|
||||||
struct bch_extent_ptr *ptr;
|
|
||||||
struct bkey_i *new;
|
|
||||||
|
|
||||||
if (is_root) {
|
if (is_root) {
|
||||||
bch_err(c, "cannot update btree roots yet");
|
bch_err(c, "cannot update btree roots yet");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
|
struct bkey_i *new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
|
||||||
if (!new) {
|
if (!new) {
|
||||||
ret = -BCH_ERR_ENOMEM_gc_repair_key;
|
ret = -BCH_ERR_ENOMEM_gc_repair_key;
|
||||||
bch_err_msg(c, ret, "allocating new key");
|
bch_err_msg(c, ret, "allocating new key");
|
||||||
|
@ -641,7 +638,7 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
|
||||||
* btree node isn't there anymore, the read path will
|
* btree node isn't there anymore, the read path will
|
||||||
* sort it out:
|
* sort it out:
|
||||||
*/
|
*/
|
||||||
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
|
struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
|
||||||
bkey_for_each_ptr(ptrs, ptr) {
|
bkey_for_each_ptr(ptrs, ptr) {
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
|
struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
|
||||||
struct bucket *g = PTR_GC_BUCKET(ca, ptr);
|
struct bucket *g = PTR_GC_BUCKET(ca, ptr);
|
||||||
|
@ -649,19 +646,26 @@ static int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree_id
|
||||||
ptr->gen = g->gen;
|
ptr->gen = g->gen;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, ({
|
struct bkey_ptrs ptrs;
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
|
union bch_extent_entry *entry;
|
||||||
struct bucket *g = PTR_GC_BUCKET(ca, ptr);
|
restart_drop_ptrs:
|
||||||
enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, ptr);
|
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
|
||||||
|
bkey_for_each_ptr_decode(bkey_i_to_s(new).k, ptrs, p, entry) {
|
||||||
|
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
||||||
|
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
|
||||||
|
enum bch_data_type data_type = bch2_bkey_ptr_data_type(bkey_i_to_s_c(new), p, entry);
|
||||||
|
|
||||||
(ptr->cached &&
|
if ((p.ptr.cached &&
|
||||||
(!g->gen_valid || gen_cmp(ptr->gen, g->gen) > 0)) ||
|
(!g->gen_valid || gen_cmp(p.ptr.gen, g->gen) > 0)) ||
|
||||||
(!ptr->cached &&
|
(!p.ptr.cached &&
|
||||||
gen_cmp(ptr->gen, g->gen) < 0) ||
|
gen_cmp(p.ptr.gen, g->gen) < 0) ||
|
||||||
gen_cmp(g->gen, ptr->gen) > BUCKET_GC_GEN_MAX ||
|
gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX ||
|
||||||
(g->data_type &&
|
(g->data_type &&
|
||||||
g->data_type != data_type);
|
g->data_type != data_type)) {
|
||||||
}));
|
bch2_bkey_drop_ptr(bkey_i_to_s(new), &entry->ptr);
|
||||||
|
goto restart_drop_ptrs;
|
||||||
|
}
|
||||||
|
}
|
||||||
again:
|
again:
|
||||||
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
|
ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
|
||||||
bkey_extent_entry_for_each(ptrs, entry) {
|
bkey_extent_entry_for_each(ptrs, entry) {
|
||||||
|
@ -736,10 +740,6 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
|
||||||
BUG_ON(bch2_journal_seq_verify &&
|
BUG_ON(bch2_journal_seq_verify &&
|
||||||
k->k->version.lo > atomic64_read(&c->journal.seq));
|
k->k->version.lo > atomic64_read(&c->journal.seq));
|
||||||
|
|
||||||
ret = bch2_check_fix_ptrs(trans, btree_id, level, is_root, k);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (fsck_err_on(k->k->version.lo > atomic64_read(&c->key_version), c,
|
if (fsck_err_on(k->k->version.lo > atomic64_read(&c->key_version), c,
|
||||||
bkey_version_in_future,
|
bkey_version_in_future,
|
||||||
"key version number higher than recorded: %llu > %llu",
|
"key version number higher than recorded: %llu > %llu",
|
||||||
|
@ -748,8 +748,13 @@ static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
|
||||||
atomic64_set(&c->key_version, k->k->version.lo);
|
atomic64_set(&c->key_version, k->k->version.lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = bch2_check_fix_ptrs(trans, btree_id, level, is_root, k);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
ret = commit_do(trans, NULL, NULL, 0,
|
ret = commit_do(trans, NULL, NULL, 0,
|
||||||
bch2_key_trigger(trans, btree_id, level, old, unsafe_bkey_s_c_to_s(*k), BTREE_TRIGGER_GC));
|
bch2_key_trigger(trans, btree_id, level, old,
|
||||||
|
unsafe_bkey_s_c_to_s(*k), BTREE_TRIGGER_GC));
|
||||||
fsck_err:
|
fsck_err:
|
||||||
err:
|
err:
|
||||||
bch_err_fn(c, ret);
|
bch_err_fn(c, ret);
|
||||||
|
|
|
@ -525,6 +525,7 @@ int bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
|
||||||
"different types of data in same bucket: %s, %s",
|
"different types of data in same bucket: %s, %s",
|
||||||
bch2_data_type_str(g->data_type),
|
bch2_data_type_str(g->data_type),
|
||||||
bch2_data_type_str(data_type))) {
|
bch2_data_type_str(data_type))) {
|
||||||
|
BUG();
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -628,6 +629,7 @@ int bch2_check_bucket_ref(struct btree_trans *trans,
|
||||||
bch2_data_type_str(ptr_data_type),
|
bch2_data_type_str(ptr_data_type),
|
||||||
(printbuf_reset(&buf),
|
(printbuf_reset(&buf),
|
||||||
bch2_bkey_val_to_text(&buf, c, k), buf.buf));
|
bch2_bkey_val_to_text(&buf, c, k), buf.buf));
|
||||||
|
BUG();
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -815,14 +817,14 @@ static int __mark_pointer(struct btree_trans *trans,
|
||||||
static int bch2_trigger_pointer(struct btree_trans *trans,
|
static int bch2_trigger_pointer(struct btree_trans *trans,
|
||||||
enum btree_id btree_id, unsigned level,
|
enum btree_id btree_id, unsigned level,
|
||||||
struct bkey_s_c k, struct extent_ptr_decoded p,
|
struct bkey_s_c k, struct extent_ptr_decoded p,
|
||||||
s64 *sectors,
|
const union bch_extent_entry *entry,
|
||||||
unsigned flags)
|
s64 *sectors, unsigned flags)
|
||||||
{
|
{
|
||||||
bool insert = !(flags & BTREE_TRIGGER_OVERWRITE);
|
bool insert = !(flags & BTREE_TRIGGER_OVERWRITE);
|
||||||
struct bpos bucket;
|
struct bpos bucket;
|
||||||
struct bch_backpointer bp;
|
struct bch_backpointer bp;
|
||||||
|
|
||||||
bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, &bucket, &bp);
|
bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp);
|
||||||
*sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
|
*sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
|
||||||
|
|
||||||
if (flags & BTREE_TRIGGER_TRANSACTIONAL) {
|
if (flags & BTREE_TRIGGER_TRANSACTIONAL) {
|
||||||
|
@ -851,7 +853,7 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
|
||||||
if (flags & BTREE_TRIGGER_GC) {
|
if (flags & BTREE_TRIGGER_GC) {
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
||||||
enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p);
|
enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);
|
||||||
|
|
||||||
percpu_down_read(&c->mark_lock);
|
percpu_down_read(&c->mark_lock);
|
||||||
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
|
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
|
||||||
|
@ -979,7 +981,7 @@ static int __trigger_extent(struct btree_trans *trans,
|
||||||
|
|
||||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
|
||||||
s64 disk_sectors;
|
s64 disk_sectors;
|
||||||
ret = bch2_trigger_pointer(trans, btree_id, level, k, p, &disk_sectors, flags);
|
ret = bch2_trigger_pointer(trans, btree_id, level, k, p, entry, &disk_sectors, flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -596,30 +596,6 @@ static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned bch2_bkey_ptr_data_type(struct bkey_s_c k, const struct bch_extent_ptr *ptr)
|
|
||||||
{
|
|
||||||
switch (k.k->type) {
|
|
||||||
case KEY_TYPE_btree_ptr:
|
|
||||||
case KEY_TYPE_btree_ptr_v2:
|
|
||||||
return BCH_DATA_btree;
|
|
||||||
case KEY_TYPE_extent:
|
|
||||||
case KEY_TYPE_reflink_v:
|
|
||||||
return BCH_DATA_user;
|
|
||||||
case KEY_TYPE_stripe: {
|
|
||||||
struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
|
|
||||||
|
|
||||||
BUG_ON(ptr < s.v->ptrs ||
|
|
||||||
ptr >= s.v->ptrs + s.v->nr_blocks);
|
|
||||||
|
|
||||||
return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
|
|
||||||
? BCH_DATA_parity
|
|
||||||
: BCH_DATA_user;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned bch2_bkey_nr_ptrs(struct bkey_s_c);
|
unsigned bch2_bkey_nr_ptrs(struct bkey_s_c);
|
||||||
unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c);
|
unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c);
|
||||||
unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c);
|
unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c);
|
||||||
|
|
Loading…
Reference in New Issue