summaryrefslogtreecommitdiff
path: root/fs/bcachefs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/super.c')
-rw-r--r--fs/bcachefs/super.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 3f674bf061ff..84fc22b3d2c8 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -65,19 +65,10 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kent Overstreet <kent.overstreet@gmail.com>");
#define KTYPE(type) \
-static const struct attribute_group type ## _group = { \
- .attrs = type ## _files \
-}; \
- \
-static const struct attribute_group *type ## _groups[] = { \
- &type ## _group, \
- NULL \
-}; \
- \
-static const struct kobj_type type ## _ktype = { \
+struct kobj_type type ## _ktype = { \
.release = type ## _release, \
.sysfs_ops = &type ## _sysfs_ops, \
- .default_groups = type ## _groups \
+ .default_attrs = type ## _files \
}
static void bch2_fs_release(struct kobject *);
@@ -182,6 +173,44 @@ static void bch2_dev_usage_journal_reserve(struct bch_fs *c)
&c->dev_usage_journal_res, u64s * nr);
}
+int bch2_congested(void *data, int bdi_bits)
+{
+ struct bch_fs *c = data;
+ struct backing_dev_info *bdi;
+ struct bch_dev *ca;
+ unsigned i;
+ int ret = 0;
+
+ rcu_read_lock();
+ if (bdi_bits & (1 << WB_sync_congested)) {
+ /* Reads - check all devices: */
+ for_each_readable_member(ca, c, i) {
+ bdi = ca->disk_sb.bdev->bd_bdi;
+
+ if (bdi_congested(bdi, bdi_bits)) {
+ ret = 1;
+ break;
+ }
+ }
+ } else {
+ const struct bch_devs_mask *devs =
+ bch2_target_to_mask(c, c->opts.foreground_target) ?:
+ &c->rw_devs[BCH_DATA_user];
+
+ for_each_member_device_rcu(ca, c, i, devs) {
+ bdi = ca->disk_sb.bdev->bd_bdi;
+
+ if (bdi_congested(bdi, bdi_bits)) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ rcu_read_unlock();
+
+ return ret;
+}
+
/* Filesystem RO/RW: */
/*
@@ -502,7 +531,8 @@ void __bch2_fs_stop(struct bch_fs *c)
for_each_member_device(ca, c, i)
if (ca->kobj.state_in_sysfs &&
ca->disk_sb.bdev)
- sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
+ sysfs_remove_link(&part_to_dev(ca->disk_sb.bdev->bd_part)->kobj,
+ "bcachefs");
if (c->kobj.state_in_sysfs)
kobject_del(&c->kobj);
@@ -993,7 +1023,8 @@ static void bch2_dev_free(struct bch_dev *ca)
if (ca->kobj.state_in_sysfs &&
ca->disk_sb.bdev)
- sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
+ sysfs_remove_link(&part_to_dev(ca->disk_sb.bdev->bd_part)->kobj,
+ "bcachefs");
if (ca->kobj.state_in_sysfs)
kobject_del(&ca->kobj);
@@ -1029,7 +1060,10 @@ static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca)
wait_for_completion(&ca->io_ref_completion);
if (ca->kobj.state_in_sysfs) {
- sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
+ struct kobject *block =
+ &part_to_dev(ca->disk_sb.bdev->bd_part)->kobj;
+
+ sysfs_remove_link(block, "bcachefs");
sysfs_remove_link(&ca->kobj, "block");
}
@@ -1066,12 +1100,12 @@ static int bch2_dev_sysfs_online(struct bch_fs *c, struct bch_dev *ca)
}
if (ca->disk_sb.bdev) {
- struct kobject *block = bdev_kobj(ca->disk_sb.bdev);
+ struct kobject *block =
+ &part_to_dev(ca->disk_sb.bdev->bd_part)->kobj;
ret = sysfs_create_link(block, &ca->kobj, "bcachefs");
if (ret)
return ret;
-
ret = sysfs_create_link(&ca->kobj, block, "block");
if (ret)
return ret;