mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-09 00:00:17 +03:00
Update bcachefs sources to dca6a42b7467 bcachefs: bch2_member_to_text()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
6eda7d1831
commit
4174fe0bae
@ -1 +1 @@
|
||||
86a9bf9142f7ff7c097951508b7662a8818492e1
|
||||
dca6a42b74674732d1d7683c282f6002752b2bda
|
||||
|
||||
@ -215,7 +215,7 @@ void bch2_node_pin(struct bch_fs *c, struct btree *b)
|
||||
struct btree_cache *bc = &c->btree_cache;
|
||||
|
||||
guard(mutex)(&bc->lock);
|
||||
if (b != btree_node_root(c, b) && !btree_node_pinned(b)) {
|
||||
if (!btree_node_is_root(c, b) && !btree_node_pinned(b)) {
|
||||
set_btree_node_pinned(b);
|
||||
list_move(&b->list, &bc->live[1].list);
|
||||
bc->live[0].nr--;
|
||||
|
||||
@ -144,6 +144,14 @@ static inline struct btree *btree_node_root(struct bch_fs *c, struct btree *b)
|
||||
return r ? r->b : NULL;
|
||||
}
|
||||
|
||||
static inline bool btree_node_is_root(struct bch_fs *c, struct btree *b)
|
||||
{
|
||||
struct btree *root = btree_node_root(c, b);
|
||||
|
||||
BUG_ON(b != root && b->c.level >= root->c.level);
|
||||
return b == root;
|
||||
}
|
||||
|
||||
const char *bch2_btree_id_str(enum btree_id); /* avoid */
|
||||
void bch2_btree_id_to_text(struct printbuf *, enum btree_id);
|
||||
void bch2_btree_id_level_to_text(struct printbuf *, enum btree_id, unsigned);
|
||||
|
||||
@ -282,6 +282,41 @@ fsck_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btree_check_root_boundaries(struct btree_trans *trans, struct btree *b)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct printbuf buf = PRINTBUF;
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 &&
|
||||
!bpos_eq(bkey_i_to_btree_ptr_v2(&b->key)->v.min_key,
|
||||
b->data->min_key));
|
||||
|
||||
prt_str(&buf, " at ");
|
||||
bch2_btree_pos_to_text(&buf, c, b);
|
||||
|
||||
if (mustfix_fsck_err_on(!bpos_eq(b->data->min_key, POS_MIN),
|
||||
trans, btree_node_topology_bad_root_min_key,
|
||||
"btree root with incorrect min_key%s", buf.buf)) {
|
||||
ret = set_node_min(c, b, POS_MIN);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mustfix_fsck_err_on(!bpos_eq(b->data->max_key, SPOS_MAX),
|
||||
trans, btree_node_topology_bad_root_max_key,
|
||||
"btree root with incorrect min_key%s", buf.buf)) {
|
||||
ret = set_node_max(c, b, SPOS_MAX);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
fsck_err:
|
||||
printbuf_exit(&buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btree_repair_node_end(struct btree_trans *trans, struct btree *b,
|
||||
struct btree *child, struct bpos *pulled_from_scan)
|
||||
{
|
||||
@ -586,7 +621,8 @@ recover:
|
||||
struct btree *b = r->b;
|
||||
|
||||
btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
|
||||
ret = bch2_btree_repair_topology_recurse(trans, b, &pulled_from_scan);
|
||||
ret = btree_check_root_boundaries(trans, b) ?:
|
||||
bch2_btree_repair_topology_recurse(trans, b, &pulled_from_scan);
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_topology_repair_drop_this_node)) {
|
||||
|
||||
@ -215,7 +215,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (bkey_le(old.k->p, new.k->p)) {
|
||||
if (!back_split) {
|
||||
update = bch2_trans_kmalloc(trans, sizeof(*update));
|
||||
if ((ret = PTR_ERR_OR_ZERO(update)))
|
||||
return ret;
|
||||
@ -238,9 +238,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
|
||||
BTREE_UPDATE_internal_snapshot_node|flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (back_split) {
|
||||
} else {
|
||||
update = bch2_bkey_make_mut_noupdate(trans, old);
|
||||
if ((ret = PTR_ERR_OR_ZERO(update)))
|
||||
return ret;
|
||||
|
||||
@ -66,6 +66,10 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
|
||||
bkey_init(&prev.k->k);
|
||||
bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b);
|
||||
|
||||
/*
|
||||
* Don't use btree_node_is_root(): we're called by btree split, after
|
||||
* creating a new root but before setting it
|
||||
*/
|
||||
if (b == btree_node_root(c, b)) {
|
||||
if (!bpos_eq(b->data->min_key, POS_MIN)) {
|
||||
bch2_log_msg_start(c, &buf);
|
||||
@ -1655,7 +1659,7 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
|
||||
int ret = 0;
|
||||
|
||||
bch2_verify_btree_nr_keys(b);
|
||||
BUG_ON(!parent && (b != btree_node_root(c, b)));
|
||||
BUG_ON(!parent && !btree_node_is_root(c, b));
|
||||
BUG_ON(parent && !btree_node_intent_locked(trans->paths + path, b->c.level + 1));
|
||||
|
||||
ret = bch2_btree_node_check_topology(trans, b);
|
||||
@ -2527,7 +2531,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans,
|
||||
if (ret)
|
||||
goto err;
|
||||
} else {
|
||||
BUG_ON(btree_node_root(c, b) != b);
|
||||
BUG_ON(!btree_node_is_root(c, b));
|
||||
|
||||
struct jset_entry *e = bch2_trans_jset_entry_alloc(trans,
|
||||
jset_u64s(new_key->k.u64s));
|
||||
|
||||
@ -119,6 +119,7 @@
|
||||
x(ENOENT, ENOENT_not_directory) \
|
||||
x(ENOENT, ENOENT_directory_dead) \
|
||||
x(ENOENT, ENOENT_subvolume) \
|
||||
x(ENOENT, ENOENT_snapshot) \
|
||||
x(ENOENT, ENOENT_snapshot_tree) \
|
||||
x(ENOENT, ENOENT_dirent_doesnt_match_inode) \
|
||||
x(ENOENT, ENOENT_dev_not_found) \
|
||||
|
||||
@ -511,8 +511,8 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
|
||||
struct bch_subvolume subvol;
|
||||
int ret = lockrestart_do(trans,
|
||||
bch2_subvolume_get(trans, inum.subvol, true, &subvol) ?:
|
||||
bch2_inode_find_by_inum_trans(trans, inum, &inode_u)) ?:
|
||||
PTR_ERR_OR_ZERO(inode = bch2_inode_hash_init_insert(trans, inum, &inode_u, &subvol));
|
||||
bch2_inode_find_by_inum_trans(trans, inum, &inode_u) ?:
|
||||
PTR_ERR_OR_ZERO(inode = bch2_inode_hash_init_insert(trans, inum, &inode_u, &subvol)));
|
||||
|
||||
return ret ? ERR_PTR(ret) : &inode->v;
|
||||
}
|
||||
|
||||
@ -923,9 +923,10 @@ lookup_inode_for_snapshot(struct btree_trans *trans, struct inode_walker *w, str
|
||||
bkey_init(&whiteout.k);
|
||||
whiteout.k.type = KEY_TYPE_whiteout;
|
||||
whiteout.k.p = SPOS(0, i->inode.bi_inum, k.k->p.snapshot);
|
||||
ret = bch2_btree_insert_nonextent(trans, BTREE_ID_inodes,
|
||||
&whiteout,
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
ret = bch2_btree_insert_trans(trans, BTREE_ID_inodes,
|
||||
&whiteout,
|
||||
BTREE_ITER_cached|
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
||||
@ -463,9 +463,10 @@ int __bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked
|
||||
bch2_inode_pack(inode_p, inode);
|
||||
inode_p->inode.k.p.snapshot = inode->bi_snapshot;
|
||||
|
||||
return bch2_btree_insert_nonextent(trans, BTREE_ID_inodes,
|
||||
&inode_p->inode.k_i,
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
return bch2_btree_insert_trans(trans, BTREE_ID_inodes,
|
||||
&inode_p->inode.k_i,
|
||||
BTREE_ITER_cached|
|
||||
BTREE_UPDATE_internal_snapshot_node);
|
||||
}
|
||||
|
||||
int bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode)
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
static inline int bch2_logged_op_update(struct btree_trans *trans, struct bkey_i *op)
|
||||
{
|
||||
return bch2_btree_insert_nonextent(trans, BTREE_ID_logged_ops, op, 0);
|
||||
return bch2_btree_insert_trans(trans, BTREE_ID_logged_ops, op, BTREE_ITER_cached);
|
||||
}
|
||||
|
||||
int bch2_resume_logged_ops(struct bch_fs *);
|
||||
|
||||
@ -76,6 +76,8 @@ enum bch_fsck_flags {
|
||||
x(btree_node_read_error, 62, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_bad_min_key, 63, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_bad_max_key, 64, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_bad_root_min_key, 323, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_bad_root_max_key, 324, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_overwritten_by_prev_node, 65, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_overwritten_by_next_node, 66, FSCK_AUTOFIX) \
|
||||
x(btree_node_topology_interior_node_empty, 67, FSCK_AUTOFIX) \
|
||||
@ -334,7 +336,7 @@ enum bch_fsck_flags {
|
||||
x(dirent_stray_data_after_cf_name, 305, 0) \
|
||||
x(rebalance_work_incorrectly_set, 309, FSCK_AUTOFIX) \
|
||||
x(rebalance_work_incorrectly_unset, 310, FSCK_AUTOFIX) \
|
||||
x(MAX, 323, 0)
|
||||
x(MAX, 325, 0)
|
||||
|
||||
enum bch_sb_error_id {
|
||||
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,
|
||||
|
||||
@ -68,34 +68,13 @@ struct bch_member *bch2_members_v2_get_mut(struct bch_sb *sb, int i)
|
||||
return __bch2_members_v2_get_mut(bch2_sb_field_get(sb, members_v2), i);
|
||||
}
|
||||
|
||||
static struct bch_member members_v2_get(struct bch_sb_field_members_v2 *mi, int i)
|
||||
{
|
||||
struct bch_member ret, *p = __bch2_members_v2_get_mut(mi, i);
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
memcpy(&ret, p, min_t(size_t, le16_to_cpu(mi->member_bytes), sizeof(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct bch_member *members_v1_get_mut(struct bch_sb_field_members_v1 *mi, int i)
|
||||
{
|
||||
return (void *) mi->_members + (i * BCH_MEMBER_V1_BYTES);
|
||||
}
|
||||
|
||||
static struct bch_member members_v1_get(struct bch_sb_field_members_v1 *mi, int i)
|
||||
{
|
||||
struct bch_member ret, *p = members_v1_get_mut(mi, i);
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
memcpy(&ret, p, min_t(size_t, BCH_MEMBER_V1_BYTES, sizeof(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i)
|
||||
{
|
||||
struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(sb, members_v2);
|
||||
if (mi2)
|
||||
return members_v2_get(mi2, i);
|
||||
return bch2_members_v2_get(mi2, i);
|
||||
struct bch_sb_field_members_v1 *mi1 = bch2_sb_field_get(sb, members_v1);
|
||||
return members_v1_get(mi1, i);
|
||||
return bch2_members_v1_get(mi1, i);
|
||||
}
|
||||
|
||||
static int sb_members_v2_resize_entries(struct bch_fs *c)
|
||||
@ -211,33 +190,25 @@ static int validate_member(struct printbuf *err,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void member_to_text(struct printbuf *out,
|
||||
struct bch_member m,
|
||||
struct bch_sb_field_disk_groups *gi,
|
||||
struct bch_sb *sb,
|
||||
int i)
|
||||
void bch2_member_to_text(struct printbuf *out,
|
||||
struct bch_member *m,
|
||||
struct bch_sb_field_disk_groups *gi,
|
||||
struct bch_sb *sb,
|
||||
unsigned idx)
|
||||
{
|
||||
unsigned data_have = bch2_sb_dev_has_data(sb, i);
|
||||
u64 bucket_size = le16_to_cpu(m.bucket_size);
|
||||
u64 device_size = le64_to_cpu(m.nbuckets) * bucket_size;
|
||||
|
||||
if (!bch2_member_alive(&m))
|
||||
return;
|
||||
|
||||
prt_printf(out, "Device:\t%u\n", i);
|
||||
|
||||
printbuf_indent_add(out, 2);
|
||||
u64 bucket_size = le16_to_cpu(m->bucket_size);
|
||||
u64 device_size = le64_to_cpu(m->nbuckets) * bucket_size;
|
||||
|
||||
prt_printf(out, "Label:\t");
|
||||
if (BCH_MEMBER_GROUP(&m))
|
||||
if (BCH_MEMBER_GROUP(m))
|
||||
bch2_disk_path_to_text_sb(out, sb,
|
||||
BCH_MEMBER_GROUP(&m) - 1);
|
||||
BCH_MEMBER_GROUP(m) - 1);
|
||||
else
|
||||
prt_printf(out, "(none)");
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "UUID:\t");
|
||||
pr_uuid(out, m.uuid.b);
|
||||
pr_uuid(out, m->uuid.b);
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Size:\t");
|
||||
@ -245,40 +216,41 @@ static void member_to_text(struct printbuf *out,
|
||||
prt_newline(out);
|
||||
|
||||
for (unsigned i = 0; i < BCH_MEMBER_ERROR_NR; i++)
|
||||
prt_printf(out, "%s errors:\t%llu\n", bch2_member_error_strs[i], le64_to_cpu(m.errors[i]));
|
||||
prt_printf(out, "%s errors:\t%llu\n", bch2_member_error_strs[i], le64_to_cpu(m->errors[i]));
|
||||
|
||||
for (unsigned i = 0; i < BCH_IOPS_NR; i++)
|
||||
prt_printf(out, "%s iops:\t%u\n", bch2_iops_measurements[i], le32_to_cpu(m.iops[i]));
|
||||
prt_printf(out, "%s iops:\t%u\n", bch2_iops_measurements[i], le32_to_cpu(m->iops[i]));
|
||||
|
||||
prt_printf(out, "Bucket size:\t");
|
||||
prt_units_u64(out, bucket_size << 9);
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "First bucket:\t%u\n", le16_to_cpu(m.first_bucket));
|
||||
prt_printf(out, "Buckets:\t%llu\n", le64_to_cpu(m.nbuckets));
|
||||
prt_printf(out, "First bucket:\t%u\n", le16_to_cpu(m->first_bucket));
|
||||
prt_printf(out, "Buckets:\t%llu\n", le64_to_cpu(m->nbuckets));
|
||||
|
||||
prt_printf(out, "Last mount:\t");
|
||||
if (m.last_mount)
|
||||
bch2_prt_datetime(out, le64_to_cpu(m.last_mount));
|
||||
if (m->last_mount)
|
||||
bch2_prt_datetime(out, le64_to_cpu(m->last_mount));
|
||||
else
|
||||
prt_printf(out, "(never)");
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Last superblock write:\t%llu\n", le64_to_cpu(m.seq));
|
||||
prt_printf(out, "Last superblock write:\t%llu\n", le64_to_cpu(m->seq));
|
||||
|
||||
prt_printf(out, "State:\t%s\n",
|
||||
BCH_MEMBER_STATE(&m) < BCH_MEMBER_STATE_NR
|
||||
? bch2_member_states[BCH_MEMBER_STATE(&m)]
|
||||
BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR
|
||||
? bch2_member_states[BCH_MEMBER_STATE(m)]
|
||||
: "unknown");
|
||||
|
||||
prt_printf(out, "Data allowed:\t");
|
||||
if (BCH_MEMBER_DATA_ALLOWED(&m))
|
||||
prt_bitflags(out, __bch2_data_types, BCH_MEMBER_DATA_ALLOWED(&m));
|
||||
if (BCH_MEMBER_DATA_ALLOWED(m))
|
||||
prt_bitflags(out, __bch2_data_types, BCH_MEMBER_DATA_ALLOWED(m));
|
||||
else
|
||||
prt_printf(out, "(none)");
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Has data:\t");
|
||||
unsigned data_have = bch2_sb_dev_has_data(sb, idx);
|
||||
if (data_have)
|
||||
prt_bitflags(out, __bch2_data_types, data_have);
|
||||
else
|
||||
@ -286,22 +258,36 @@ static void member_to_text(struct printbuf *out,
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Btree allocated bitmap blocksize:\t");
|
||||
if (m.btree_bitmap_shift < 64)
|
||||
prt_units_u64(out, 1ULL << m.btree_bitmap_shift);
|
||||
if (m->btree_bitmap_shift < 64)
|
||||
prt_units_u64(out, 1ULL << m->btree_bitmap_shift);
|
||||
else
|
||||
prt_printf(out, "(invalid shift %u)", m.btree_bitmap_shift);
|
||||
prt_printf(out, "(invalid shift %u)", m->btree_bitmap_shift);
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Btree allocated bitmap:\t");
|
||||
bch2_prt_u64_base2_nbits(out, le64_to_cpu(m.btree_allocated_bitmap), 64);
|
||||
bch2_prt_u64_base2_nbits(out, le64_to_cpu(m->btree_allocated_bitmap), 64);
|
||||
prt_newline(out);
|
||||
|
||||
prt_printf(out, "Durability:\t%llu\n", BCH_MEMBER_DURABILITY(&m) ? BCH_MEMBER_DURABILITY(&m) - 1 : 1);
|
||||
prt_printf(out, "Durability:\t%llu\n", BCH_MEMBER_DURABILITY(m) ? BCH_MEMBER_DURABILITY(m) - 1 : 1);
|
||||
|
||||
prt_printf(out, "Discard:\t%llu\n", BCH_MEMBER_DISCARD(&m));
|
||||
prt_printf(out, "Freespace initialized:\t%llu\n", BCH_MEMBER_FREESPACE_INITIALIZED(&m));
|
||||
prt_printf(out, "Resize on mount:\t%llu\n", BCH_MEMBER_RESIZE_ON_MOUNT(&m));
|
||||
prt_printf(out, "Discard:\t%llu\n", BCH_MEMBER_DISCARD(m));
|
||||
prt_printf(out, "Freespace initialized:\t%llu\n", BCH_MEMBER_FREESPACE_INITIALIZED(m));
|
||||
prt_printf(out, "Resize on mount:\t%llu\n", BCH_MEMBER_RESIZE_ON_MOUNT(m));
|
||||
}
|
||||
|
||||
static void member_to_text(struct printbuf *out,
|
||||
struct bch_member m,
|
||||
struct bch_sb_field_disk_groups *gi,
|
||||
struct bch_sb *sb,
|
||||
unsigned idx)
|
||||
{
|
||||
if (!bch2_member_alive(&m))
|
||||
return;
|
||||
|
||||
prt_printf(out, "Device:\t%u\n", idx);
|
||||
|
||||
printbuf_indent_add(out, 2);
|
||||
bch2_member_to_text(out, &m, gi, sb, idx);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
@ -317,7 +303,7 @@ static int bch2_sb_members_v1_validate(struct bch_sb *sb, struct bch_sb_field *f
|
||||
}
|
||||
|
||||
for (i = 0; i < sb->nr_devices; i++) {
|
||||
struct bch_member m = members_v1_get(mi, i);
|
||||
struct bch_member m = bch2_members_v1_get(mi, i);
|
||||
|
||||
int ret = validate_member(err, m, sb, i);
|
||||
if (ret)
|
||||
@ -343,7 +329,7 @@ static void bch2_sb_members_v1_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
prt_printf(out, "nr_devices mismatch: have %i entries, should be %u", nr, sb->nr_devices);
|
||||
|
||||
for (unsigned i = 0; i < min(sb->nr_devices, nr); i++)
|
||||
member_to_text(out, members_v1_get(mi, i), gi, sb, i);
|
||||
member_to_text(out, bch2_members_v1_get(mi, i), gi, sb, i);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_members_v1 = {
|
||||
@ -377,7 +363,7 @@ static void bch2_sb_members_v2_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
*/
|
||||
|
||||
for (unsigned i = 0; i < min(sb->nr_devices, nr); i++)
|
||||
member_to_text(out, members_v2_get(mi, i), gi, sb, i);
|
||||
member_to_text(out, bch2_members_v2_get(mi, i), gi, sb, i);
|
||||
}
|
||||
|
||||
static int bch2_sb_members_v2_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||
@ -394,7 +380,7 @@ static int bch2_sb_members_v2_validate(struct bch_sb *sb, struct bch_sb_field *f
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sb->nr_devices; i++) {
|
||||
int ret = validate_member(err, members_v2_get(mi, i), sb, i);
|
||||
int ret = validate_member(err, bch2_members_v2_get(mi, i), sb, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -430,7 +416,7 @@ void bch2_sb_members_to_cpu(struct bch_fs *c)
|
||||
struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(c->disk_sb.sb, members_v2);
|
||||
if (mi2)
|
||||
for (unsigned i = 0; i < c->sb.nr_devices; i++) {
|
||||
struct bch_member m = members_v2_get(mi2, i);
|
||||
struct bch_member m = bch2_members_v2_get(mi2, i);
|
||||
bool removed = uuid_equal(&m.uuid, &BCH_SB_MEMBER_DELETED_UUID);
|
||||
mod_bit(i, c->devs_removed.d, removed);
|
||||
}
|
||||
|
||||
@ -14,11 +14,36 @@ __bch2_members_v2_get_mut(struct bch_sb_field_members_v2 *mi, unsigned i)
|
||||
return (void *) mi->_members + (i * le16_to_cpu(mi->member_bytes));
|
||||
}
|
||||
|
||||
static inline struct bch_member bch2_members_v2_get(struct bch_sb_field_members_v2 *mi, int i)
|
||||
{
|
||||
struct bch_member ret, *p = __bch2_members_v2_get_mut(mi, i);
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
memcpy(&ret, p, min_t(size_t, le16_to_cpu(mi->member_bytes), sizeof(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline struct bch_member *members_v1_get_mut(struct bch_sb_field_members_v1 *mi, int i)
|
||||
{
|
||||
return (void *) mi->_members + (i * BCH_MEMBER_V1_BYTES);
|
||||
}
|
||||
|
||||
static inline struct bch_member bch2_members_v1_get(struct bch_sb_field_members_v1 *mi, int i)
|
||||
{
|
||||
struct bch_member ret, *p = members_v1_get_mut(mi, i);
|
||||
memset(&ret, 0, sizeof(ret));
|
||||
memcpy(&ret, p, min_t(size_t, BCH_MEMBER_V1_BYTES, sizeof(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bch2_sb_members_v2_init(struct bch_fs *c);
|
||||
int bch2_sb_members_cpy_v2_v1(struct bch_sb_handle *disk_sb);
|
||||
struct bch_member *bch2_members_v2_get_mut(struct bch_sb *sb, int i);
|
||||
struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i);
|
||||
|
||||
void bch2_member_to_text(struct printbuf *, struct bch_member *,
|
||||
struct bch_sb_field_disk_groups *,
|
||||
struct bch_sb *, unsigned);
|
||||
|
||||
static inline bool bch2_dev_is_online(struct bch_dev *ca)
|
||||
{
|
||||
return !enumerated_ref_is_zero(&ca->io_ref[READ]);
|
||||
|
||||
@ -1146,7 +1146,7 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id)
|
||||
if (bch2_fs_inconsistent_on(i == 2, c,
|
||||
"snapshot %u missing child pointer to %u",
|
||||
parent_id, id))
|
||||
return ret;
|
||||
return bch_err_throw(c, ENOENT_snapshot);
|
||||
|
||||
parent->v.children[i] = cpu_to_le32(child_id);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user