Update bcachefs sources to a180af9dd349 bcachefs: Refactor memcpy into direct assignment

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2023-10-18 21:57:11 -04:00
parent 9f98746bfc
commit 6a34032417
30 changed files with 156 additions and 126 deletions

View File

@ -1 +1 @@
7bf1ac0d46ebede68561e0476f7af9c07ac21de8
a180af9dd349d9819b13af43f877bea4f94c1c79

View File

@ -348,7 +348,7 @@ int cmd_show_super(int argc, char *argv[])
die("Error opening %s: %s", dev, bch2_err_str(ret));
if (print_default_fields)
fields = bch2_sb_get_members_v2(sb.sb)
fields = bch2_sb_field_get(sb.sb, members_v2)
? 1 << BCH_SB_FIELD_members_v2
: 1 << BCH_SB_FIELD_members_v1;

View File

@ -92,7 +92,7 @@ int cmd_set_passphrase(int argc, char *argv[])
if (IS_ERR(c))
die("Error opening %s: %s", argv[1], bch2_err_str(PTR_ERR(c)));
struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb.sb);
struct bch_sb_field_crypt *crypt = bch2_sb_field_get(c->disk_sb.sb, crypt);
if (!crypt)
die("Filesystem does not have encryption enabled");
@ -130,7 +130,7 @@ int cmd_remove_passphrase(int argc, char *argv[])
if (IS_ERR(c))
die("Error opening %s: %s", argv[1], bch2_err_str(PTR_ERR(c)));
struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb.sb);
struct bch_sb_field_crypt *crypt = bch2_sb_field_get(c->disk_sb.sb, crypt);
if (!crypt)
die("Filesystem does not have encryption enabled");

View File

@ -105,7 +105,7 @@ bool bch2_sb_is_encrypted(struct bch_sb *sb)
{
struct bch_sb_field_crypt *crypt;
return (crypt = bch2_sb_get_crypt(sb)) &&
return (crypt = bch2_sb_field_get(sb, crypt)) &&
bch2_key_is_encrypted(&crypt->key);
}
@ -113,7 +113,7 @@ void bch2_passphrase_check(struct bch_sb *sb, const char *passphrase,
struct bch_key *passphrase_key,
struct bch_encrypted_key *sb_key)
{
struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(sb);
struct bch_sb_field_crypt *crypt = bch2_sb_field_get(sb, crypt);
if (!crypt)
die("filesystem is not encrypted");

View File

@ -66,6 +66,7 @@
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define fallthrough __attribute__((__fallthrough__))
#define __noreturn __attribute__((__noreturn__))
#define __counted_by(nr)
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)

View File

@ -221,7 +221,7 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
/* Member info: */
struct bch_sb_field_members_v2 *mi =
bch2_sb_resize_members_v2(&sb,
bch2_sb_field_resize(&sb, members_v2,
(sizeof(*mi) + sizeof(struct bch_member) *
nr_devs) / sizeof(u64));
mi->member_bytes = cpu_to_le16(sizeof(struct bch_member));
@ -270,7 +270,7 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
/* Crypt: */
if (opts.encrypted) {
struct bch_sb_field_crypt *crypt =
bch2_sb_resize_crypt(&sb, sizeof(*crypt) / sizeof(u64));
bch2_sb_field_resize(&sb, crypt, sizeof(*crypt) / sizeof(u64));
bch_sb_crypt_init(sb.sb, crypt, opts.passphrase);
SET_BCH_SB_ENCRYPTION_TYPE(sb.sb, 1);

View File

@ -1839,7 +1839,7 @@ int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
struct bkey_s_c k;
struct bkey hole;
struct bpos end = POS(ca->dev_idx, bucket_end);
struct bch_member m;
struct bch_member *m;
unsigned long last_updated = jiffies;
int ret;
@ -1926,8 +1926,8 @@ bkey_err:
}
mutex_lock(&c->sb_lock);
m = bch2_sb_member_get(c->disk_sb.sb, ca->dev_idx);
SET_BCH_MEMBER_FREESPACE_INITIALIZED(&m, true);
m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
SET_BCH_MEMBER_FREESPACE_INITIALIZED(m, true);
mutex_unlock(&c->sb_lock);
return 0;

View File

@ -746,6 +746,7 @@ struct bch_fs {
struct snapshot_table __rcu *snapshots;
size_t snapshot_table_size;
struct mutex snapshot_table_lock;
struct rw_semaphore snapshot_create_lock;
struct work_struct snapshot_delete_work;
struct work_struct snapshot_wait_for_pagecache_and_delete_work;

View File

@ -121,7 +121,6 @@ const struct bkey_ops bch2_bkey_ops[] = {
};
const struct bkey_ops bch2_bkey_null_ops = {
.min_val_size = U8_MAX,
};
int bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k,

View File

@ -473,8 +473,9 @@ static inline int update_replicas_list(struct btree_trans *trans,
d = trans->fs_usage_deltas;
n = (void *) d->d + d->used;
n->delta = sectors;
memcpy((void *) n + offsetof(struct replicas_delta, r),
r, replicas_entry_bytes(r));
unsafe_memcpy((void *) n + offsetof(struct replicas_delta, r),
r, replicas_entry_bytes(r),
"flexible array member embedded in strcuct with padding");
bch2_replicas_entry_sort(&n->r);
d->used += b;
return 0;

View File

@ -678,7 +678,7 @@ int bch2_disable_encryption(struct bch_fs *c)
mutex_lock(&c->sb_lock);
crypt = bch2_sb_get_crypt(c->disk_sb.sb);
crypt = bch2_sb_field_get(c->disk_sb.sb, crypt);
if (!crypt)
goto out;
@ -712,7 +712,7 @@ int bch2_enable_encryption(struct bch_fs *c, bool keyed)
mutex_lock(&c->sb_lock);
/* Do we already have an encryption key? */
if (bch2_sb_get_crypt(c->disk_sb.sb))
if (bch2_sb_field_get(c->disk_sb.sb, crypt))
goto err;
ret = bch2_alloc_ciphers(c);
@ -740,7 +740,8 @@ int bch2_enable_encryption(struct bch_fs *c, bool keyed)
if (ret)
goto err;
crypt = bch2_sb_resize_crypt(&c->disk_sb, sizeof(*crypt) / sizeof(u64));
crypt = bch2_sb_field_resize(&c->disk_sb, crypt,
sizeof(*crypt) / sizeof(u64));
if (!crypt) {
ret = -BCH_ERR_ENOSPC_sb_crypt;
goto err;
@ -781,7 +782,7 @@ int bch2_fs_encryption_init(struct bch_fs *c)
goto out;
}
crypt = bch2_sb_get_crypt(c->disk_sb.sb);
crypt = bch2_sb_field_get(c->disk_sb.sb, crypt);
if (!crypt)
goto out;

View File

@ -48,7 +48,7 @@ static void bch2_sb_counters_to_text(struct printbuf *out, struct bch_sb *sb,
int bch2_sb_counters_to_cpu(struct bch_fs *c)
{
struct bch_sb_field_counters *ctrs = bch2_sb_get_counters(c->disk_sb.sb);
struct bch_sb_field_counters *ctrs = bch2_sb_field_get(c->disk_sb.sb, counters);
unsigned int i;
unsigned int nr = bch2_sb_counter_nr_entries(ctrs);
u64 val = 0;
@ -66,13 +66,13 @@ int bch2_sb_counters_to_cpu(struct bch_fs *c)
int bch2_sb_counters_from_cpu(struct bch_fs *c)
{
struct bch_sb_field_counters *ctrs = bch2_sb_get_counters(c->disk_sb.sb);
struct bch_sb_field_counters *ctrs = bch2_sb_field_get(c->disk_sb.sb, counters);
struct bch_sb_field_counters *ret;
unsigned int i;
unsigned int nr = bch2_sb_counter_nr_entries(ctrs);
if (nr < BCH_COUNTER_NR) {
ret = bch2_sb_resize_counters(&c->disk_sb,
ret = bch2_sb_field_resize(&c->disk_sb, counters,
sizeof(*ctrs) / sizeof(u64) + BCH_COUNTER_NR);
if (ret) {

View File

@ -157,14 +157,13 @@ int bch2_sb_disk_groups_to_cpu(struct bch_fs *c)
lockdep_assert_held(&c->sb_lock);
groups = bch2_sb_get_disk_groups(c->disk_sb.sb);
groups = bch2_sb_field_get(c->disk_sb.sb, disk_groups);
nr_groups = disk_groups_nr(groups);
if (!groups)
return 0;
cpu_g = kzalloc(sizeof(*cpu_g) +
sizeof(cpu_g->entries[0]) * nr_groups, GFP_KERNEL);
cpu_g = kzalloc(struct_size(cpu_g, entries, nr_groups), GFP_KERNEL);
if (!cpu_g)
return -BCH_ERR_ENOMEM_disk_groups_to_cpu;
@ -296,7 +295,7 @@ static int __bch2_disk_group_add(struct bch_sb_handle *sb, unsigned parent,
const char *name, unsigned namelen)
{
struct bch_sb_field_disk_groups *groups =
bch2_sb_get_disk_groups(sb->sb);
bch2_sb_field_get(sb->sb, disk_groups);
unsigned i, nr_groups = disk_groups_nr(groups);
struct bch_disk_group *g;
@ -314,7 +313,7 @@ static int __bch2_disk_group_add(struct bch_sb_handle *sb, unsigned parent,
sizeof(struct bch_disk_group) * (nr_groups + 1)) /
sizeof(u64);
groups = bch2_sb_resize_disk_groups(sb, u64s);
groups = bch2_sb_field_resize(sb, disk_groups, u64s);
if (!groups)
return -BCH_ERR_ENOSPC_disk_label_add;
@ -338,7 +337,7 @@ static int __bch2_disk_group_add(struct bch_sb_handle *sb, unsigned parent,
int bch2_disk_path_find(struct bch_sb_handle *sb, const char *name)
{
struct bch_sb_field_disk_groups *groups =
bch2_sb_get_disk_groups(sb->sb);
bch2_sb_field_get(sb->sb, disk_groups);
int v = -1;
do {
@ -368,7 +367,7 @@ int bch2_disk_path_find_or_create(struct bch_sb_handle *sb, const char *name)
if (*next == '.')
next++;
groups = bch2_sb_get_disk_groups(sb->sb);
groups = bch2_sb_field_get(sb->sb, disk_groups);
v = __bch2_disk_group_find(groups, parent, name, len);
if (v < 0)
@ -386,7 +385,7 @@ int bch2_disk_path_find_or_create(struct bch_sb_handle *sb, const char *name)
void bch2_disk_path_to_text(struct printbuf *out, struct bch_sb *sb, unsigned v)
{
struct bch_sb_field_disk_groups *groups =
bch2_sb_get_disk_groups(sb);
bch2_sb_field_get(sb, disk_groups);
struct bch_disk_group *g;
unsigned nr = 0;
u16 path[32];

View File

@ -520,6 +520,7 @@ static inline bool bkey_extent_is_allocation(const struct bkey *k)
case KEY_TYPE_reflink_v:
case KEY_TYPE_inline_data:
case KEY_TYPE_indirect_inline_data:
case KEY_TYPE_error:
return true;
default:
return false;
@ -632,6 +633,8 @@ 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)
{
struct bch_extent_ptr *dest;
EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev));
switch (k->k.type) {
@ -641,10 +644,8 @@ static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr
EBUG_ON(bkey_val_u64s(&k->k) >= BKEY_EXTENT_VAL_U64s_MAX);
ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
memcpy((void *) &k->v + bkey_val_bytes(&k->k),
&ptr,
sizeof(ptr));
dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k));
*dest = ptr;
k->k.u64s++;
break;
default:

View File

@ -318,8 +318,8 @@ err:
return ret;
}
static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp,
struct bch_ioctl_subvolume arg)
static long __bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp,
struct bch_ioctl_subvolume arg)
{
struct inode *dir;
struct bch_inode_info *inode;
@ -440,6 +440,16 @@ err1:
return error;
}
static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp,
struct bch_ioctl_subvolume arg)
{
down_write(&c->snapshot_create_lock);
long ret = __bch2_ioctl_subvolume_create(c, filp, arg);
up_write(&c->snapshot_create_lock);
return ret;
}
static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp,
struct bch_ioctl_subvolume arg)
{

View File

@ -287,9 +287,18 @@ int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sec
op.v.inum = cpu_to_le64(inum.inum);
op.v.new_i_size = cpu_to_le64(new_i_size);
return bch2_trans_run(c,
/*
* Logged ops aren't atomic w.r.t. snapshot creation: creating a
* snapshot while they're in progress, then crashing, will result in the
* resume only proceeding in one of the snapshots
*/
down_read(&c->snapshot_create_lock);
int ret = bch2_trans_run(c,
bch2_logged_op_start(trans, &op.k_i) ?:
__bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta));
up_read(&c->snapshot_create_lock);
return ret;
}
/* finsert/fcollapse: */
@ -491,7 +500,16 @@ int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum,
op.v.src_offset = cpu_to_le64(offset);
op.v.pos = cpu_to_le64(insert ? U64_MAX : offset);
return bch2_trans_run(c,
/*
* Logged ops aren't atomic w.r.t. snapshot creation: creating a
* snapshot while they're in progress, then crashing, will result in the
* resume only proceeding in one of the snapshots
*/
down_read(&c->snapshot_create_lock);
int ret = bch2_trans_run(c,
bch2_logged_op_start(trans, &op.k_i) ?:
__bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta));
up_read(&c->snapshot_create_lock);
return ret;
}

View File

@ -1170,9 +1170,9 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
{
struct journal_device *ja = &ca->journal;
struct bch_sb_field_journal *journal_buckets =
bch2_sb_get_journal(sb);
bch2_sb_field_get(sb, journal);
struct bch_sb_field_journal_v2 *journal_buckets_v2 =
bch2_sb_get_journal_v2(sb);
bch2_sb_field_get(sb, journal_v2);
unsigned i, nr_bvecs;
ja->nr = 0;

View File

@ -194,7 +194,7 @@ int bch2_journal_buckets_to_sb(struct bch_fs *c, struct bch_dev *ca,
if (buckets[i] + 1 != buckets[i + 1])
nr_compacted++;
j = bch2_sb_resize_journal_v2(&ca->disk_sb,
j = bch2_sb_field_resize(&ca->disk_sb, journal_v2,
(sizeof(*j) + sizeof(j->d[0]) * nr_compacted) / sizeof(u64));
if (!j)
return -BCH_ERR_ENOSPC_sb_journal;

View File

@ -58,8 +58,8 @@ blacklist_entry_try_merge(struct bch_fs *c,
&bl->start[i + 1],
sizeof(bl->start[0]) * (nr - i));
bl = bch2_sb_resize_journal_seq_blacklist(&c->disk_sb,
sb_blacklist_u64s(nr));
bl = bch2_sb_field_resize(&c->disk_sb, journal_seq_blacklist,
sb_blacklist_u64s(nr));
BUG_ON(!bl);
}
@ -79,7 +79,7 @@ int bch2_journal_seq_blacklist_add(struct bch_fs *c, u64 start, u64 end)
int ret = 0;
mutex_lock(&c->sb_lock);
bl = bch2_sb_get_journal_seq_blacklist(c->disk_sb.sb);
bl = bch2_sb_field_get(c->disk_sb.sb, journal_seq_blacklist);
nr = blacklist_nr_entries(bl);
for (i = 0; i < nr; i++) {
@ -100,8 +100,8 @@ int bch2_journal_seq_blacklist_add(struct bch_fs *c, u64 start, u64 end)
}
}
bl = bch2_sb_resize_journal_seq_blacklist(&c->disk_sb,
sb_blacklist_u64s(nr + 1));
bl = bch2_sb_field_resize(&c->disk_sb, journal_seq_blacklist,
sb_blacklist_u64s(nr + 1));
if (!bl) {
ret = -BCH_ERR_ENOSPC_sb_journal_seq_blacklist;
goto out;
@ -158,7 +158,7 @@ bool bch2_journal_seq_is_blacklisted(struct bch_fs *c, u64 seq,
int bch2_blacklist_table_initialize(struct bch_fs *c)
{
struct bch_sb_field_journal_seq_blacklist *bl =
bch2_sb_get_journal_seq_blacklist(c->disk_sb.sb);
bch2_sb_field_get(c->disk_sb.sb, journal_seq_blacklist);
struct journal_seq_blacklist_table *t;
unsigned i, nr = blacklist_nr_entries(bl);
@ -281,7 +281,7 @@ retry:
return;
mutex_lock(&c->sb_lock);
bl = bch2_sb_get_journal_seq_blacklist(c->disk_sb.sb);
bl = bch2_sb_field_get(c->disk_sb.sb, journal_seq_blacklist);
if (!bl)
goto out;
@ -306,7 +306,7 @@ retry:
bch_info(c, "nr blacklist entries was %u, now %u", nr, new_nr);
if (new_nr != nr) {
bl = bch2_sb_resize_journal_seq_blacklist(&c->disk_sb,
bl = bch2_sb_field_resize(&c->disk_sb, journal_seq_blacklist,
new_nr ? sb_blacklist_u64s(new_nr) : 0);
BUG_ON(new_nr && !bl);

View File

@ -513,12 +513,12 @@ void bch2_fs_quota_init(struct bch_fs *c)
static struct bch_sb_field_quota *bch2_sb_get_or_create_quota(struct bch_sb_handle *sb)
{
struct bch_sb_field_quota *sb_quota = bch2_sb_get_quota(sb->sb);
struct bch_sb_field_quota *sb_quota = bch2_sb_field_get(sb->sb, quota);
if (sb_quota)
return sb_quota;
sb_quota = bch2_sb_resize_quota(sb, sizeof(*sb_quota) / sizeof(u64));
sb_quota = bch2_sb_field_resize(sb, quota, sizeof(*sb_quota) / sizeof(u64));
if (sb_quota) {
unsigned qtype, qc;
@ -536,7 +536,7 @@ static void bch2_sb_quota_read(struct bch_fs *c)
struct bch_sb_field_quota *sb_quota;
unsigned i, j;
sb_quota = bch2_sb_get_quota(c->disk_sb.sb);
sb_quota = bch2_sb_field_get(c->disk_sb.sb, quota);
if (!sb_quota)
return;

View File

@ -35,13 +35,27 @@
#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
static bool btree_id_is_alloc(enum btree_id id)
{
switch (id) {
case BTREE_ID_alloc:
case BTREE_ID_backpointers:
case BTREE_ID_need_discard:
case BTREE_ID_freespace:
case BTREE_ID_bucket_gens:
return true;
default:
return false;
}
}
/* for -o reconstruct_alloc: */
static void drop_alloc_keys(struct journal_keys *keys)
{
size_t src, dst;
for (src = 0, dst = 0; src < keys->nr; src++)
if (keys->d[src].btree_id != BTREE_ID_alloc)
if (!btree_id_is_alloc(keys->d[src].btree_id))
keys->d[dst++] = keys->d[src];
keys->nr = dst;
@ -332,20 +346,6 @@ static int journal_replay_early(struct bch_fs *c,
/* sb clean section: */
static bool btree_id_is_alloc(enum btree_id id)
{
switch (id) {
case BTREE_ID_alloc:
case BTREE_ID_backpointers:
case BTREE_ID_need_discard:
case BTREE_ID_freespace:
case BTREE_ID_bucket_gens:
return true;
default:
return false;
}
}
static int read_btree_roots(struct bch_fs *c)
{
unsigned i;

View File

@ -700,9 +700,9 @@ int bch2_sb_replicas_to_cpu_replicas(struct bch_fs *c)
struct bch_replicas_cpu new_r = { 0, 0, NULL };
int ret = 0;
if ((sb_v1 = bch2_sb_get_replicas(c->disk_sb.sb)))
if ((sb_v1 = bch2_sb_field_get(c->disk_sb.sb, replicas)))
ret = __bch2_sb_replicas_to_cpu_replicas(sb_v1, &new_r);
else if ((sb_v0 = bch2_sb_get_replicas_v0(c->disk_sb.sb)))
else if ((sb_v0 = bch2_sb_field_get(c->disk_sb.sb, replicas_v0)))
ret = __bch2_sb_replicas_v0_to_cpu_replicas(sb_v0, &new_r);
if (ret)
return ret;
@ -732,13 +732,13 @@ static int bch2_cpu_replicas_to_sb_replicas_v0(struct bch_fs *c,
for_each_cpu_replicas_entry(r, src)
bytes += replicas_entry_bytes(src) - 1;
sb_r = bch2_sb_resize_replicas_v0(&c->disk_sb,
sb_r = bch2_sb_field_resize(&c->disk_sb, replicas_v0,
DIV_ROUND_UP(bytes, sizeof(u64)));
if (!sb_r)
return -BCH_ERR_ENOSPC_sb_replicas;
bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas);
sb_r = bch2_sb_get_replicas_v0(c->disk_sb.sb);
sb_r = bch2_sb_field_get(c->disk_sb.sb, replicas_v0);
memset(&sb_r->entries, 0,
vstruct_end(&sb_r->field) -
@ -777,13 +777,13 @@ static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *c,
if (!need_v1)
return bch2_cpu_replicas_to_sb_replicas_v0(c, r);
sb_r = bch2_sb_resize_replicas(&c->disk_sb,
sb_r = bch2_sb_field_resize(&c->disk_sb, replicas,
DIV_ROUND_UP(bytes, sizeof(u64)));
if (!sb_r)
return -BCH_ERR_ENOSPC_sb_replicas;
bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas_v0);
sb_r = bch2_sb_get_replicas(c->disk_sb.sb);
sb_r = bch2_sb_field_get(c->disk_sb.sb, replicas);
memset(&sb_r->entries, 0,
vstruct_end(&sb_r->field) -
@ -998,8 +998,8 @@ unsigned bch2_sb_dev_has_data(struct bch_sb *sb, unsigned dev)
struct bch_sb_field_replicas_v0 *replicas_v0;
unsigned i, data_has = 0;
replicas = bch2_sb_get_replicas(sb);
replicas_v0 = bch2_sb_get_replicas_v0(sb);
replicas = bch2_sb_field_get(sb, replicas);
replicas_v0 = bch2_sb_field_get(sb, replicas_v0);
if (replicas) {
struct bch_replicas_entry *r;

View File

@ -137,7 +137,7 @@ struct bch_sb_field_clean *bch2_read_superblock_clean(struct bch_fs *c)
int ret;
mutex_lock(&c->sb_lock);
sb_clean = bch2_sb_get_clean(c->disk_sb.sb);
sb_clean = bch2_sb_field_get(c->disk_sb.sb, clean);
if (fsck_err_on(!sb_clean, c,
"superblock marked clean but clean section not present")) {
@ -359,7 +359,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
u64s = sizeof(*sb_clean) / sizeof(u64) + c->journal.entry_u64s_reserved;
sb_clean = bch2_sb_resize_clean(&c->disk_sb, u64s);
sb_clean = bch2_sb_field_resize(&c->disk_sb, clean, u64s);
if (!sb_clean) {
bch_err(c, "error resizing superblock while setting filesystem clean");
goto out;

View File

@ -16,7 +16,7 @@ static struct bch_member *members_v2_get_mut(struct bch_sb_field_members_v2 *mi,
struct bch_member *bch2_members_v2_get_mut(struct bch_sb *sb, int i)
{
return members_v2_get_mut(bch2_sb_get_members_v2(sb), i);
return 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)
@ -41,22 +41,22 @@ static struct bch_member members_v1_get(struct bch_sb_field_members_v1 *mi, int
struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i)
{
struct bch_sb_field_members_v2 *mi2 = bch2_sb_get_members_v2(sb);
struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(sb, members_v2);
if (mi2)
return members_v2_get(mi2, i);
struct bch_sb_field_members_v1 *mi1 = bch2_sb_get_members_v1(sb);
struct bch_sb_field_members_v1 *mi1 = bch2_sb_field_get(sb, members_v1);
return members_v1_get(mi1, i);
}
static int sb_members_v2_resize_entries(struct bch_fs *c)
{
struct bch_sb_field_members_v2 *mi = bch2_sb_get_members_v2(c->disk_sb.sb);
struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
if (le16_to_cpu(mi->member_bytes) < sizeof(struct bch_member)) {
unsigned u64s = DIV_ROUND_UP((sizeof(*mi) + sizeof(mi->_members[0]) *
c->disk_sb.sb->nr_devices), 8);
mi = bch2_sb_resize_members_v2(&c->disk_sb, u64s);
mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
if (!mi)
return -BCH_ERR_ENOSPC_sb_members_v2;
@ -76,12 +76,12 @@ int bch2_members_v2_init(struct bch_fs *c)
struct bch_sb_field_members_v1 *mi1;
struct bch_sb_field_members_v2 *mi2;
if (!bch2_sb_get_members_v2(c->disk_sb.sb)) {
mi2 = bch2_sb_resize_members_v2(&c->disk_sb,
if (!bch2_sb_field_get(c->disk_sb.sb, members_v2)) {
mi2 = bch2_sb_field_resize(&c->disk_sb, members_v2,
DIV_ROUND_UP(sizeof(*mi2) +
sizeof(struct bch_member) * c->sb.nr_devices,
sizeof(u64)));
mi1 = bch2_sb_get_members_v1(c->disk_sb.sb);
mi1 = bch2_sb_field_get(c->disk_sb.sb, members_v1);
memcpy(&mi2->_members[0], &mi1->_members[0],
BCH_MEMBER_V1_BYTES * c->sb.nr_devices);
memset(&mi2->pad[0], 0, sizeof(mi2->pad));
@ -96,13 +96,13 @@ int bch_members_cpy_v2_v1(struct bch_sb_handle *disk_sb)
struct bch_sb_field_members_v1 *mi1;
struct bch_sb_field_members_v2 *mi2;
mi1 = bch2_sb_resize_members_v1(disk_sb,
mi1 = bch2_sb_field_resize(disk_sb, members_v1,
DIV_ROUND_UP(sizeof(*mi1) + BCH_MEMBER_V1_BYTES *
disk_sb->sb->nr_devices, sizeof(u64)));
if (!mi1)
return -BCH_ERR_ENOSPC_sb_members;
mi2 = bch2_sb_get_members_v2(disk_sb->sb);
mi2 = bch2_sb_field_get(disk_sb->sb, members_v2);
for (unsigned i = 0; i < disk_sb->sb->nr_devices; i++)
memcpy(members_v1_get_mut(mi1, i), members_v2_get_mut(mi2, i), BCH_MEMBER_V1_BYTES);
@ -283,7 +283,7 @@ static void bch2_sb_members_v1_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_members_v1 *mi = field_to_type(f, members_v1);
struct bch_sb_field_disk_groups *gi = bch2_sb_get_disk_groups(sb);
struct bch_sb_field_disk_groups *gi = bch2_sb_field_get(sb, disk_groups);
unsigned i;
for (i = 0; i < sb->nr_devices; i++) {
@ -301,7 +301,7 @@ static void bch2_sb_members_v2_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_members_v2 *mi = field_to_type(f, members_v2);
struct bch_sb_field_disk_groups *gi = bch2_sb_get_disk_groups(sb);
struct bch_sb_field_disk_groups *gi = bch2_sb_field_get(sb, disk_groups);
unsigned i;
for (i = 0; i < sb->nr_devices; i++) {

View File

@ -1288,6 +1288,9 @@ static inline u32 bch2_snapshot_nth_parent_skip(struct bch_fs *c, u32 id, u32 n,
snapshot_id_list *skip)
{
rcu_read_lock();
while (snapshot_list_has_id(skip, id))
id = __bch2_snapshot_parent(c, id);
while (n--) {
do {
id = __bch2_snapshot_parent(c, id);
@ -1444,6 +1447,8 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
}
}
down_write(&c->snapshot_create_lock);
for_each_btree_key(trans, iter, BTREE_ID_snapshots,
POS_MIN, 0, k, ret) {
u32 snapshot = k.k->p.offset;
@ -1454,6 +1459,9 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
}
bch2_trans_iter_exit(trans, &iter);
if (ret)
goto err_create_lock;
/*
* Fixing children of deleted snapshots can't be done completely
* atomically, if we crash between here and when we delete the interior
@ -1464,14 +1472,14 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
NULL, NULL, BTREE_INSERT_NOFAIL,
bch2_fix_child_of_deleted_snapshot(trans, &iter, k, &deleted_interior));
if (ret)
goto err;
goto err_create_lock;
darray_for_each(deleted, i) {
ret = commit_do(trans, NULL, NULL, 0,
bch2_snapshot_node_delete(trans, *i));
if (ret) {
bch_err_msg(c, ret, "deleting snapshot %u", *i);
goto err;
goto err_create_lock;
}
}
@ -1480,11 +1488,13 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
bch2_snapshot_node_delete(trans, *i));
if (ret) {
bch_err_msg(c, ret, "deleting snapshot %u", *i);
goto err;
goto err_create_lock;
}
}
clear_bit(BCH_FS_HAVE_DELETED_SNAPSHOTS, &c->flags);
err_create_lock:
up_write(&c->snapshot_create_lock);
err:
darray_exit(&deleted_interior);
darray_exit(&deleted);

View File

@ -96,7 +96,7 @@ const char * const bch2_sb_fields[] = {
static int bch2_sb_field_validate(struct bch_sb *, struct bch_sb_field *,
struct printbuf *);
struct bch_sb_field *bch2_sb_field_get(struct bch_sb *sb,
struct bch_sb_field *bch2_sb_field_get_id(struct bch_sb *sb,
enum bch_sb_field_type type)
{
struct bch_sb_field *f;
@ -151,7 +151,7 @@ static struct bch_sb_field *__bch2_sb_field_resize(struct bch_sb_handle *sb,
void bch2_sb_field_delete(struct bch_sb_handle *sb,
enum bch_sb_field_type type)
{
struct bch_sb_field *f = bch2_sb_field_get(sb->sb, type);
struct bch_sb_field *f = bch2_sb_field_get_id(sb->sb, type);
if (f)
__bch2_sb_field_resize(sb, f, 0);
@ -225,11 +225,11 @@ int bch2_sb_realloc(struct bch_sb_handle *sb, unsigned u64s)
return 0;
}
struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *sb,
struct bch_sb_field *bch2_sb_field_resize_id(struct bch_sb_handle *sb,
enum bch_sb_field_type type,
unsigned u64s)
{
struct bch_sb_field *f = bch2_sb_field_get(sb->sb, type);
struct bch_sb_field *f = bch2_sb_field_get_id(sb->sb, type);
ssize_t old_u64s = f ? le32_to_cpu(f->u64s) : 0;
ssize_t d = -old_u64s + u64s;
@ -255,7 +255,7 @@ struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *sb,
}
}
f = bch2_sb_field_get(sb->sb, type);
f = bch2_sb_field_get_id(sb->sb, type);
f = __bch2_sb_field_resize(sb, f, u64s);
if (f)
f->type = cpu_to_le32(type);
@ -458,7 +458,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
}
/* members must be validated first: */
mi = bch2_sb_get_members_v1(sb);
mi = bch2_sb_field_get(sb, members_v1);
if (!mi) {
prt_printf(out, "Invalid superblock: member info area missing");
return -BCH_ERR_invalid_sb_members_missing;
@ -546,8 +546,8 @@ static int __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
if ((1U << i) & BCH_SINGLE_DEVICE_SB_FIELDS)
continue;
src_f = bch2_sb_field_get(src, i);
dst_f = bch2_sb_field_get(dst, i);
src_f = bch2_sb_field_get_id(src, i);
dst_f = bch2_sb_field_get_id(dst, i);
d = (src_f ? le32_to_cpu(src_f->u64s) : 0) -
(dst_f ? le32_to_cpu(dst_f->u64s) : 0);
@ -559,7 +559,7 @@ static int __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
return ret;
dst = dst_handle->sb;
dst_f = bch2_sb_field_get(dst, i);
dst_f = bch2_sb_field_get_id(dst, i);
}
dst_f = __bch2_sb_field_resize(dst_handle, dst_f,

View File

@ -23,31 +23,19 @@ u64 bch2_upgrade_recovery_passes(struct bch_fs *c,
unsigned,
unsigned);
struct bch_sb_field *bch2_sb_field_get(struct bch_sb *, enum bch_sb_field_type);
struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *,
enum bch_sb_field_type, unsigned);
void bch2_sb_field_delete(struct bch_sb_handle *, enum bch_sb_field_type);
#define field_to_type(_f, _name) \
container_of_or_null(_f, struct bch_sb_field_##_name, field)
#define x(_name, _nr) \
static inline struct bch_sb_field_##_name * \
bch2_sb_get_##_name(struct bch_sb *sb) \
{ \
return field_to_type(bch2_sb_field_get(sb, \
BCH_SB_FIELD_##_name), _name); \
} \
\
static inline struct bch_sb_field_##_name * \
bch2_sb_resize_##_name(struct bch_sb_handle *sb, unsigned u64s) \
{ \
return field_to_type(bch2_sb_field_resize(sb, \
BCH_SB_FIELD_##_name, u64s), _name); \
}
struct bch_sb_field *bch2_sb_field_get_id(struct bch_sb *, enum bch_sb_field_type);
#define bch2_sb_field_get(_sb, _name) \
field_to_type(bch2_sb_field_get_id(_sb, BCH_SB_FIELD_##_name), _name)
BCH_SB_FIELDS()
#undef x
struct bch_sb_field *bch2_sb_field_resize_id(struct bch_sb_handle *,
enum bch_sb_field_type, unsigned);
#define bch2_sb_field_resize(_sb, _name, _u64s) \
field_to_type(bch2_sb_field_resize_id(_sb, BCH_SB_FIELD_##_name, _u64s), _name)
void bch2_sb_field_delete(struct bch_sb_handle *, enum bch_sb_field_type);
extern const char * const bch2_sb_fields[];

View File

@ -720,6 +720,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
mutex_init(&c->bio_bounce_pages_lock);
mutex_init(&c->snapshot_table_lock);
init_rwsem(&c->snapshot_create_lock);
spin_lock_init(&c->btree_write_error_lock);
@ -1630,9 +1631,9 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
goto err_unlock;
}
mi = bch2_sb_get_members_v2(ca->disk_sb.sb);
mi = bch2_sb_field_get(ca->disk_sb.sb, members_v2);
if (!bch2_sb_resize_members_v2(&ca->disk_sb,
if (!bch2_sb_field_resize(&ca->disk_sb, members_v2,
le32_to_cpu(mi->field.u64s) +
sizeof(dev_mi) / sizeof(u64))) {
ret = -BCH_ERR_ENOSPC_sb_members;
@ -1656,7 +1657,7 @@ have_slot:
u64s = DIV_ROUND_UP(sizeof(struct bch_sb_field_members_v2) +
le16_to_cpu(mi->member_bytes) * nr_devices, sizeof(u64));
mi = bch2_sb_resize_members_v2(&c->disk_sb, u64s);
mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
if (!mi) {
ret = -BCH_ERR_ENOSPC_sb_members;
bch_err_msg(c, ret, "setting up new superblock");

View File

@ -46,7 +46,7 @@ struct bch_disk_group_cpu {
struct bch_disk_groups_cpu {
struct rcu_head rcu;
unsigned nr;
struct bch_disk_group_cpu entries[];
struct bch_disk_group_cpu entries[] __counted_by(nr);
};
#endif /* _BCACHEFS_SUPER_TYPES_H */

View File

@ -43,7 +43,7 @@ impl PartialEq for bch_sb {
impl bch_sb {
pub fn crypt(&self) -> Option<&bch_sb_field_crypt> {
unsafe {
let ptr = bch2_sb_field_get(
let ptr = bch2_sb_field_get_id(
self as *const _ as *mut _,
bch_sb_field_type::BCH_SB_FIELD_crypt,
) as *const u8;