bcachefs: for_each_online_member_rcu()

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet
2025-04-18 22:11:15 -04:00
parent 2483dd1243
commit 9fa4a8a3bd
6 changed files with 35 additions and 21 deletions

View File

@@ -1645,7 +1645,12 @@ static noinline void bch2_print_allocator_stuck(struct bch_fs *c)
printbuf_indent_sub(&buf, 2);
prt_newline(&buf);
for_each_online_member(c, ca) {
bch2_printbuf_make_room(&buf, 4096);
rcu_read_lock();
buf.atomic++;
for_each_online_member_rcu(c, ca) {
prt_printf(&buf, "Dev %u:\n", ca->dev_idx);
printbuf_indent_add(&buf, 2);
bch2_dev_alloc_debug_to_text(&buf, ca);
@@ -1653,6 +1658,9 @@ static noinline void bch2_print_allocator_stuck(struct bch_fs *c)
prt_newline(&buf);
}
--buf.atomic;
rcu_read_unlock();
prt_printf(&buf, "Copygc debug:\n");
printbuf_indent_add(&buf, 2);
bch2_copygc_wait_to_text(&buf, c);

View File

@@ -891,6 +891,7 @@ struct bch_fs {
struct workqueue_struct *write_ref_wq;
/* ALLOCATION */
struct bch_devs_mask online_devs;
struct bch_devs_mask rw_devs[BCH_DATA_NR];
unsigned long rw_devs_change_count;

View File

@@ -613,11 +613,13 @@ static long bch2_ioctl_disk_get_idx(struct bch_fs *c,
if (!dev)
return -EINVAL;
for_each_online_member(c, ca)
rcu_read_lock();
for_each_online_member_rcu(c, ca)
if (ca->dev == dev) {
percpu_ref_put(&ca->io_ref[READ]);
rcu_read_unlock();
return ca->dev_idx;
}
rcu_read_unlock();
return -BCH_ERR_ENOENT_dev_idx_not_found;
}

View File

@@ -2327,12 +2327,14 @@ static int bch2_show_devname(struct seq_file *seq, struct dentry *root)
struct bch_fs *c = root->d_sb->s_fs_info;
bool first = true;
for_each_online_member(c, ca) {
rcu_read_lock();
for_each_online_member_rcu(c, ca) {
if (!first)
seq_putc(seq, ':');
first = false;
seq_puts(seq, ca->disk_sb.sb_name);
}
rcu_read_unlock();
return 0;
}
@@ -2529,15 +2531,16 @@ static int bch2_fs_get_tree(struct fs_context *fc)
sb->s_bdi->ra_pages = VM_READAHEAD_PAGES;
for_each_online_member(c, ca) {
rcu_read_lock();
for_each_online_member_rcu(c, ca) {
struct block_device *bdev = ca->disk_sb.bdev;
/* XXX: create an anonymous device for multi device filesystems */
sb->s_bdev = bdev;
sb->s_dev = bdev->bd_dev;
percpu_ref_put(&ca->io_ref[READ]);
break;
}
rcu_read_unlock();
c->dev = sb->s_dev;

View File

@@ -104,6 +104,9 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, struct bch_dev *
for (struct bch_dev *_ca = NULL; \
(_ca = __bch2_next_dev((_c), _ca, (_mask)));)
#define for_each_online_member_rcu(_c, _ca) \
for_each_member_device_rcu(_c, _ca, &(_c)->online_devs)
static inline void bch2_dev_get(struct bch_dev *ca)
{
#ifdef CONFIG_BCACHEFS_DEBUG
@@ -307,17 +310,6 @@ static inline struct bch_dev *bch2_dev_get_ioref(struct bch_fs *c, unsigned dev,
return NULL;
}
/* XXX kill, move to struct bch_fs */
static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
{
struct bch_devs_mask devs;
memset(&devs, 0, sizeof(devs));
for_each_online_member(c, ca)
__set_bit(ca->dev_idx, devs.d);
return devs;
}
extern const struct bch_sb_field_ops bch_sb_field_ops_members_v1;
extern const struct bch_sb_field_ops bch_sb_field_ops_members_v2;

View File

@@ -1105,7 +1105,7 @@ static bool bch2_fs_may_start(struct bch_fs *c)
break;
}
return bch2_have_enough_devs(c, bch2_online_devs(c), flags, true);
return bch2_have_enough_devs(c, c->online_devs, flags, true);
}
int bch2_fs_start(struct bch_fs *c)
@@ -1138,8 +1138,11 @@ int bch2_fs_start(struct bch_fs *c)
goto err;
}
for_each_online_member(c, ca)
bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = cpu_to_le64(now);
rcu_read_lock();
for_each_online_member_rcu(c, ca)
bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount =
cpu_to_le64(now);
rcu_read_unlock();
/*
* Dno't write superblock yet: recovery might have to downgrade
@@ -1294,6 +1297,9 @@ static int bch2_dev_in_fs(struct bch_sb_handle *fs,
static void bch2_dev_io_ref_stop(struct bch_dev *ca, int rw)
{
if (rw == READ)
clear_bit(ca->dev_idx, ca->fs->online_devs.d);
if (!percpu_ref_is_zero(&ca->io_ref[rw])) {
reinit_completion(&ca->io_ref_completion[rw]);
percpu_ref_kill(&ca->io_ref[rw]);
@@ -1577,6 +1583,8 @@ static int bch2_dev_attach_bdev(struct bch_fs *c, struct bch_sb_handle *sb)
if (ret)
return ret;
set_bit(ca->dev_idx, c->online_devs.d);
bch2_dev_sysfs_online(c, ca);
struct printbuf name = PRINTBUF;
@@ -1634,7 +1642,7 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
return true;
/* do we have enough devices to read from? */
new_online_devs = bch2_online_devs(c);
new_online_devs = c->online_devs;
__clear_bit(ca->dev_idx, new_online_devs.d);
return bch2_have_enough_devs(c, new_online_devs, flags, false);