Lines Matching refs:ca

186 		for_each_member_device_rcu(c, ca, NULL)
187 if (ca->disk_sb.bdev && ca->disk_sb.bdev->bd_dev == dev) {
233 for_each_member_device_rcu(c, ca, NULL)
300 for_each_member_device(c, ca)
301 bch2_dev_allocator_remove(c, ca);
472 for_each_rw_member(c, ca)
473 bch2_dev_allocator_add(c, ca);
616 for_each_member_device(c, ca)
617 if (ca->kobj.state_in_sysfs &&
618 ca->disk_sb.bdev)
619 sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
638 for_each_member_device(c, ca)
639 cancel_work_sync(&ca->io_error_work);
656 struct bch_dev *ca = rcu_dereference_protected(c->devs[i], true);
658 if (ca) {
659 EBUG_ON(atomic_long_read(&ca->ref) != 1);
660 bch2_free_super(&ca->disk_sb);
661 bch2_dev_free(ca);
710 for_each_member_device(c, ca) {
711 ret = bch2_dev_sysfs_online(c, ca);
714 bch2_dev_put(ca);
1013 for_each_online_member(c, ca)
1014 bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = cpu_to_le64(now);
1026 for_each_rw_member(c, ca)
1027 bch2_dev_allocator_add(c, ca);
1175 struct bch_dev *ca = container_of(kobj, struct bch_dev, kobj);
1177 kfree(ca);
1180 static void bch2_dev_free(struct bch_dev *ca)
1182 cancel_work_sync(&ca->io_error_work);
1184 if (ca->kobj.state_in_sysfs &&
1185 ca->disk_sb.bdev)
1186 sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
1188 if (ca->kobj.state_in_sysfs)
1189 kobject_del(&ca->kobj);
1191 kfree(ca->buckets_nouse);
1192 bch2_free_super(&ca->disk_sb);
1193 bch2_dev_journal_exit(ca);
1195 free_percpu(ca->io_done);
1196 bch2_dev_buckets_free(ca);
1197 free_page((unsigned long) ca->sb_read_scratch);
1199 bch2_time_stats_quantiles_exit(&ca->io_latency[WRITE]);
1200 bch2_time_stats_quantiles_exit(&ca->io_latency[READ]);
1202 percpu_ref_exit(&ca->io_ref);
1204 percpu_ref_exit(&ca->ref);
1206 kobject_put(&ca->kobj);
1209 static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca)
1214 if (percpu_ref_is_zero(&ca->io_ref))
1217 __bch2_dev_read_only(c, ca);
1219 reinit_completion(&ca->io_ref_completion);
1220 percpu_ref_kill(&ca->io_ref);
1221 wait_for_completion(&ca->io_ref_completion);
1223 if (ca->kobj.state_in_sysfs) {
1224 sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
1225 sysfs_remove_link(&ca->kobj, "block");
1228 bch2_free_super(&ca->disk_sb);
1229 bch2_dev_journal_exit(ca);
1235 struct bch_dev *ca = container_of(ref, struct bch_dev, ref);
1237 complete(&ca->ref_completion);
1243 struct bch_dev *ca = container_of(ref, struct bch_dev, io_ref);
1245 complete(&ca->io_ref_completion);
1248 static int bch2_dev_sysfs_online(struct bch_fs *c, struct bch_dev *ca)
1255 if (!ca->kobj.state_in_sysfs) {
1256 ret = kobject_add(&ca->kobj, &c->kobj,
1257 "dev-%u", ca->dev_idx);
1262 if (ca->disk_sb.bdev) {
1263 struct kobject *block = bdev_kobj(ca->disk_sb.bdev);
1265 ret = sysfs_create_link(block, &ca->kobj, "bcachefs");
1269 ret = sysfs_create_link(&ca->kobj, block, "block");
1280 struct bch_dev *ca;
1283 ca = kzalloc(sizeof(*ca), GFP_KERNEL);
1284 if (!ca)
1287 kobject_init(&ca->kobj, &bch2_dev_ktype);
1288 init_completion(&ca->ref_completion);
1289 init_completion(&ca->io_ref_completion);
1291 init_rwsem(&ca->bucket_lock);
1293 INIT_WORK(&ca->io_error_work, bch2_io_error_work);
1295 bch2_time_stats_quantiles_init(&ca->io_latency[READ]);
1296 bch2_time_stats_quantiles_init(&ca->io_latency[WRITE]);
1298 ca->mi = bch2_mi_to_cpu(member);
1301 atomic64_set(&ca->errors[i], le64_to_cpu(member->errors[i]));
1303 ca->uuid = member->uuid;
1305 ca->nr_btree_reserve = DIV_ROUND_UP(BTREE_NODE_RESERVE,
1306 ca->mi.bucket_size / btree_sectors(c));
1309 if (percpu_ref_init(&ca->ref, bch2_dev_ref_complete, 0, GFP_KERNEL))
1312 atomic_long_set(&ca->ref, 1);
1315 if (percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete,
1317 !(ca->sb_read_scratch = (void *) __get_free_page(GFP_KERNEL)) ||
1318 bch2_dev_buckets_alloc(c, ca) ||
1319 !(ca->io_done = alloc_percpu(*ca->io_done)))
1322 return ca;
1324 bch2_dev_free(ca);
1328 static void bch2_dev_attach(struct bch_fs *c, struct bch_dev *ca,
1331 ca->dev_idx = dev_idx;
1332 __set_bit(ca->dev_idx, ca->self.d);
1333 scnprintf(ca->name, sizeof(ca->name), "dev-%u", dev_idx);
1335 ca->fs = c;
1336 rcu_assign_pointer(c->devs[ca->dev_idx], ca);
1338 if (bch2_dev_sysfs_online(c, ca))
1345 struct bch_dev *ca = NULL;
1351 ca = __bch2_dev_alloc(c, &member);
1352 if (!ca)
1355 ca->fs = c;
1357 bch2_dev_attach(c, ca, dev_idx);
1360 if (ca)
1361 bch2_dev_free(ca);
1365 static int __bch2_dev_attach_bdev(struct bch_dev *ca, struct bch_sb_handle *sb)
1369 if (bch2_dev_is_online(ca)) {
1370 bch_err(ca, "already have device online in slot %u",
1376 ca->mi.bucket_size * ca->mi.nbuckets) {
1377 bch_err(ca, "cannot online: device too small");
1381 BUG_ON(!percpu_ref_is_zero(&ca->io_ref));
1383 ret = bch2_dev_journal_init(ca, sb->sb);
1388 ca->disk_sb = *sb;
1391 ca->dev = ca->disk_sb.bdev->bd_dev;
1393 percpu_ref_reinit(&ca->io_ref);
1400 struct bch_dev *ca;
1411 ca = bch2_dev_locked(c, sb->sb->dev_idx);
1413 ret = __bch2_dev_attach_bdev(ca, sb);
1417 bch2_dev_sysfs_online(c, ca);
1420 prt_bdevname(&name, ca->disk_sb.bdev);
1424 strscpy(ca->name, name.buf, sizeof(ca->name));
1443 bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
1455 if (ca->mi.state != BCH_MEMBER_STATE_rw)
1460 if (ca2 != ca)
1473 if (ca->mi.state != BCH_MEMBER_STATE_rw &&
1474 ca->mi.state != BCH_MEMBER_STATE_ro)
1479 __clear_bit(ca->dev_idx, new_online_devs.d);
1489 struct bch_dev *ca;
1506 ca = bch2_dev_locked(c, i);
1508 if (!bch2_dev_is_online(ca) &&
1509 (ca->mi.state == BCH_MEMBER_STATE_rw ||
1510 ca->mi.state == BCH_MEMBER_STATE_ro)) {
1521 static void __bch2_dev_read_only(struct bch_fs *c, struct bch_dev *ca)
1526 bch2_dev_allocator_remove(c, ca);
1527 bch2_dev_journal_stop(&c->journal, ca);
1530 static void __bch2_dev_read_write(struct bch_fs *c, struct bch_dev *ca)
1534 BUG_ON(ca->mi.state != BCH_MEMBER_STATE_rw);
1536 bch2_dev_allocator_add(c, ca);
1540 int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
1546 if (ca->mi.state == new_state)
1549 if (!bch2_dev_state_allowed(c, ca, new_state, flags))
1553 __bch2_dev_read_only(c, ca);
1555 bch_notice(ca, "%s", bch2_member_states[new_state]);
1558 m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
1564 __bch2_dev_read_write(c, ca);
1571 int bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
1577 ret = __bch2_dev_set_state(c, ca, new_state, flags);
1585 static int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
1587 struct bpos start = POS(ca->dev_idx, 0);
1588 struct bpos end = POS(ca->dev_idx, U64_MAX);
1611 int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
1614 unsigned dev_idx = ca->dev_idx, data;
1620 * We consume a reference to ca->ref, regardless of whether we succeed
1623 bch2_dev_put(ca);
1625 if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) {
1626 bch_err(ca, "Cannot remove without losing data");
1631 __bch2_dev_read_only(c, ca);
1633 ret = bch2_dev_data_drop(c, ca->dev_idx, flags);
1634 bch_err_msg(ca, ret, "bch2_dev_data_drop()");
1638 ret = bch2_dev_remove_alloc(c, ca);
1639 bch_err_msg(ca, ret, "bch2_dev_remove_alloc()");
1643 ret = bch2_journal_flush_device_pins(&c->journal, ca->dev_idx);
1644 bch_err_msg(ca, ret, "bch2_journal_flush_device_pins()");
1649 bch_err_msg(ca, ret, "bch2_journal_flush()");
1654 bch_err_msg(ca, ret, "bch2_replicas_gc2()");
1658 data = bch2_dev_has_data(c, ca);
1663 bch_err(ca, "Remove failed, still has data (%s)", data_has.buf);
1669 __bch2_dev_offline(c, ca);
1672 rcu_assign_pointer(c->devs[ca->dev_idx], NULL);
1676 percpu_ref_kill(&ca->ref);
1678 ca->dying = true;
1679 bch2_dev_put(ca);
1681 wait_for_completion(&ca->ref_completion);
1683 bch2_dev_free(ca);
1712 if (ca->mi.state == BCH_MEMBER_STATE_rw &&
1713 !percpu_ref_is_zero(&ca->io_ref))
1714 __bch2_dev_read_write(c, ca);
1724 struct bch_dev *ca = NULL;
1751 ca = __bch2_dev_alloc(c, &dev_mi);
1752 if (!ca) {
1757 bch2_dev_usage_init(ca);
1759 ret = __bch2_dev_attach_bdev(ca, &sb);
1763 ret = bch2_dev_journal_alloc(ca);
1771 ret = bch2_sb_from_fs(c, ca);
1827 ca->disk_sb.sb->dev_idx = dev_idx;
1828 bch2_dev_attach(c, ca, dev_idx);
1831 ret = __bch2_dev_group_set(c, ca, label.buf);
1842 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional);
1843 bch_err_msg(ca, ret, "marking new superblock");
1848 bch_err_msg(ca, ret, "initializing free space");
1852 ca->new_fs_bucket_idx = 0;
1854 if (ca->mi.state == BCH_MEMBER_STATE_rw)
1855 __bch2_dev_read_write(c, ca);
1864 if (ca)
1865 bch2_dev_free(ca);
1873 ca = NULL;
1882 struct bch_dev *ca;
1905 ca = bch2_dev_locked(c, dev_idx);
1907 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional);
1912 if (ca->mi.state == BCH_MEMBER_STATE_rw)
1913 __bch2_dev_read_write(c, ca);
1915 if (!ca->mi.freespace_initialized) {
1916 ret = bch2_dev_freespace_init(c, ca, 0, ca->mi.nbuckets);
1917 bch_err_msg(ca, ret, "initializing free space");
1922 if (!ca->journal.nr) {
1923 ret = bch2_dev_journal_alloc(ca);
1924 bch_err_msg(ca, ret, "allocating journal");
1930 bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount =
1943 int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags)
1947 if (!bch2_dev_is_online(ca)) {
1948 bch_err(ca, "Already offline");
1953 if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) {
1954 bch_err(ca, "Cannot offline required disk");
1959 __bch2_dev_offline(c, ca);
1965 int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
1972 old_nbuckets = ca->mi.nbuckets;
1974 if (nbuckets < ca->mi.nbuckets) {
1975 bch_err(ca, "Cannot shrink yet");
1981 bch_err(ca, "New device size too big (%llu greater than max %u)",
1987 if (bch2_dev_is_online(ca) &&
1988 get_capacity(ca->disk_sb.bdev->bd_disk) <
1989 ca->mi.bucket_size * nbuckets) {
1990 bch_err(ca, "New size larger than device");
1995 ret = bch2_dev_buckets_resize(c, ca, nbuckets);
1996 bch_err_msg(ca, ret, "resizing buckets");
2000 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional);
2005 m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
2011 if (ca->mi.freespace_initialized) {
2012 ret = bch2_dev_freespace_init(c, ca, old_nbuckets, nbuckets);
2020 ca->usage_base->d[BCH_DATA_free].buckets += nbuckets - old_nbuckets;
2029 /* return with ref on ca->ref: */
2032 for_each_member_device(c, ca)
2033 if (!strcmp(name, ca->name))
2034 return ca;