diff options
Diffstat (limited to 'fs/bcachefs/super.c')
-rw-r--r-- | fs/bcachefs/super.c | 66 |
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; |