Lines Matching full:ca

201 		for_each_member_device_rcu(c, ca, NULL)  in bch2_dev_to_fs()
202 if (ca->disk_sb.bdev && ca->disk_sb.bdev->bd_dev == dev) { in bch2_dev_to_fs()
300 for_each_member_device(c, ca) in __bch2_fs_read_only()
301 bch2_dev_allocator_remove(c, ca); in __bch2_fs_read_only()
473 for_each_rw_member(c, ca) in __bch2_fs_read_write()
474 bch2_dev_allocator_add(c, ca); in __bch2_fs_read_write()
624 for_each_member_device(c, ca) in __bch2_fs_stop()
625 bch2_dev_unlink(ca); in __bch2_fs_stop()
644 for_each_member_device(c, ca) in __bch2_fs_stop()
645 cancel_work_sync(&ca->io_error_work); in __bch2_fs_stop()
662 struct bch_dev *ca = rcu_dereference_protected(c->devs[i], true); in bch2_fs_free() local
664 if (ca) { in bch2_fs_free()
665 EBUG_ON(atomic_long_read(&ca->ref) != 1); in bch2_fs_free()
666 bch2_free_super(&ca->disk_sb); in bch2_fs_free()
667 bch2_dev_free(ca); in bch2_fs_free()
716 for_each_member_device(c, ca) { in bch2_fs_online()
717 ret = bch2_dev_sysfs_online(c, ca); in bch2_fs_online()
720 bch2_dev_put(ca); in bch2_fs_online()
1019 for_each_online_member(c, ca) in bch2_fs_start()
1020 bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = cpu_to_le64(now); in bch2_fs_start()
1032 for_each_rw_member(c, ca) in bch2_fs_start()
1033 bch2_dev_allocator_add(c, ca); in bch2_fs_start()
1181 struct bch_dev *ca = container_of(kobj, struct bch_dev, kobj); in bch2_dev_release() local
1183 kfree(ca); in bch2_dev_release()
1186 static void bch2_dev_free(struct bch_dev *ca) in bch2_dev_free() argument
1188 cancel_work_sync(&ca->io_error_work); in bch2_dev_free()
1190 bch2_dev_unlink(ca); in bch2_dev_free()
1192 if (ca->kobj.state_in_sysfs) in bch2_dev_free()
1193 kobject_del(&ca->kobj); in bch2_dev_free()
1195 bch2_free_super(&ca->disk_sb); in bch2_dev_free()
1196 bch2_dev_allocator_background_exit(ca); in bch2_dev_free()
1197 bch2_dev_journal_exit(ca); in bch2_dev_free()
1199 free_percpu(ca->io_done); in bch2_dev_free()
1200 bch2_dev_buckets_free(ca); in bch2_dev_free()
1201 free_page((unsigned long) ca->sb_read_scratch); in bch2_dev_free()
1203 bch2_time_stats_quantiles_exit(&ca->io_latency[WRITE]); in bch2_dev_free()
1204 bch2_time_stats_quantiles_exit(&ca->io_latency[READ]); in bch2_dev_free()
1206 percpu_ref_exit(&ca->io_ref); in bch2_dev_free()
1208 percpu_ref_exit(&ca->ref); in bch2_dev_free()
1210 kobject_put(&ca->kobj); in bch2_dev_free()
1213 static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca) in __bch2_dev_offline() argument
1218 if (percpu_ref_is_zero(&ca->io_ref)) in __bch2_dev_offline()
1221 __bch2_dev_read_only(c, ca); in __bch2_dev_offline()
1223 reinit_completion(&ca->io_ref_completion); in __bch2_dev_offline()
1224 percpu_ref_kill(&ca->io_ref); in __bch2_dev_offline()
1225 wait_for_completion(&ca->io_ref_completion); in __bch2_dev_offline()
1227 bch2_dev_unlink(ca); in __bch2_dev_offline()
1229 bch2_free_super(&ca->disk_sb); in __bch2_dev_offline()
1230 bch2_dev_journal_exit(ca); in __bch2_dev_offline()
1236 struct bch_dev *ca = container_of(ref, struct bch_dev, ref); in bch2_dev_ref_complete() local
1238 complete(&ca->ref_completion); in bch2_dev_ref_complete()
1244 struct bch_dev *ca = container_of(ref, struct bch_dev, io_ref); in bch2_dev_io_ref_complete() local
1246 complete(&ca->io_ref_completion); in bch2_dev_io_ref_complete()
1249 static void bch2_dev_unlink(struct bch_dev *ca) in bch2_dev_unlink() argument
1261 if (ca->kobj.state_in_sysfs && in bch2_dev_unlink()
1262 ca->disk_sb.bdev && in bch2_dev_unlink()
1263 (b = bdev_kobj(ca->disk_sb.bdev))->state_in_sysfs) { in bch2_dev_unlink()
1265 sysfs_remove_link(&ca->kobj, "block"); in bch2_dev_unlink()
1269 static int bch2_dev_sysfs_online(struct bch_fs *c, struct bch_dev *ca) in bch2_dev_sysfs_online() argument
1276 if (!ca->kobj.state_in_sysfs) { in bch2_dev_sysfs_online()
1277 ret = kobject_add(&ca->kobj, &c->kobj, in bch2_dev_sysfs_online()
1278 "dev-%u", ca->dev_idx); in bch2_dev_sysfs_online()
1283 if (ca->disk_sb.bdev) { in bch2_dev_sysfs_online()
1284 struct kobject *block = bdev_kobj(ca->disk_sb.bdev); in bch2_dev_sysfs_online()
1286 ret = sysfs_create_link(block, &ca->kobj, "bcachefs"); in bch2_dev_sysfs_online()
1290 ret = sysfs_create_link(&ca->kobj, block, "block"); in bch2_dev_sysfs_online()
1301 struct bch_dev *ca; in __bch2_dev_alloc() local
1304 ca = kzalloc(sizeof(*ca), GFP_KERNEL); in __bch2_dev_alloc()
1305 if (!ca) in __bch2_dev_alloc()
1308 kobject_init(&ca->kobj, &bch2_dev_ktype); in __bch2_dev_alloc()
1309 init_completion(&ca->ref_completion); in __bch2_dev_alloc()
1310 init_completion(&ca->io_ref_completion); in __bch2_dev_alloc()
1312 init_rwsem(&ca->bucket_lock); in __bch2_dev_alloc()
1314 INIT_WORK(&ca->io_error_work, bch2_io_error_work); in __bch2_dev_alloc()
1316 bch2_time_stats_quantiles_init(&ca->io_latency[READ]); in __bch2_dev_alloc()
1317 bch2_time_stats_quantiles_init(&ca->io_latency[WRITE]); in __bch2_dev_alloc()
1319 ca->mi = bch2_mi_to_cpu(member); in __bch2_dev_alloc()
1322 atomic64_set(&ca->errors[i], le64_to_cpu(member->errors[i])); in __bch2_dev_alloc()
1324 ca->uuid = member->uuid; in __bch2_dev_alloc()
1326 ca->nr_btree_reserve = DIV_ROUND_UP(BTREE_NODE_RESERVE, in __bch2_dev_alloc()
1327 ca->mi.bucket_size / btree_sectors(c)); in __bch2_dev_alloc()
1330 if (percpu_ref_init(&ca->ref, bch2_dev_ref_complete, 0, GFP_KERNEL)) in __bch2_dev_alloc()
1333 atomic_long_set(&ca->ref, 1); in __bch2_dev_alloc()
1336 bch2_dev_allocator_background_init(ca); in __bch2_dev_alloc()
1338 if (percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete, in __bch2_dev_alloc()
1340 !(ca->sb_read_scratch = (void *) __get_free_page(GFP_KERNEL)) || in __bch2_dev_alloc()
1341 bch2_dev_buckets_alloc(c, ca) || in __bch2_dev_alloc()
1342 !(ca->io_done = alloc_percpu(*ca->io_done))) in __bch2_dev_alloc()
1345 return ca; in __bch2_dev_alloc()
1347 bch2_dev_free(ca); in __bch2_dev_alloc()
1351 static void bch2_dev_attach(struct bch_fs *c, struct bch_dev *ca, in bch2_dev_attach() argument
1354 ca->dev_idx = dev_idx; in bch2_dev_attach()
1355 __set_bit(ca->dev_idx, ca->self.d); in bch2_dev_attach()
1356 scnprintf(ca->name, sizeof(ca->name), "dev-%u", dev_idx); in bch2_dev_attach()
1358 ca->fs = c; in bch2_dev_attach()
1359 rcu_assign_pointer(c->devs[ca->dev_idx], ca); in bch2_dev_attach()
1361 if (bch2_dev_sysfs_online(c, ca)) in bch2_dev_attach()
1368 struct bch_dev *ca = NULL; in bch2_dev_alloc() local
1374 ca = __bch2_dev_alloc(c, &member); in bch2_dev_alloc()
1375 if (!ca) in bch2_dev_alloc()
1378 ca->fs = c; in bch2_dev_alloc()
1380 bch2_dev_attach(c, ca, dev_idx); in bch2_dev_alloc()
1383 if (ca) in bch2_dev_alloc()
1384 bch2_dev_free(ca); in bch2_dev_alloc()
1388 static int __bch2_dev_attach_bdev(struct bch_dev *ca, struct bch_sb_handle *sb) in __bch2_dev_attach_bdev() argument
1392 if (bch2_dev_is_online(ca)) { in __bch2_dev_attach_bdev()
1393 bch_err(ca, "already have device online in slot %u", in __bch2_dev_attach_bdev()
1399 ca->mi.bucket_size * ca->mi.nbuckets) { in __bch2_dev_attach_bdev()
1400 bch_err(ca, "cannot online: device too small"); in __bch2_dev_attach_bdev()
1404 BUG_ON(!percpu_ref_is_zero(&ca->io_ref)); in __bch2_dev_attach_bdev()
1406 ret = bch2_dev_journal_init(ca, sb->sb); in __bch2_dev_attach_bdev()
1411 ca->disk_sb = *sb; in __bch2_dev_attach_bdev()
1414 ca->dev = ca->disk_sb.bdev->bd_dev; in __bch2_dev_attach_bdev()
1416 percpu_ref_reinit(&ca->io_ref); in __bch2_dev_attach_bdev()
1423 struct bch_dev *ca; in bch2_dev_attach_bdev() local
1434 ca = bch2_dev_locked(c, sb->sb->dev_idx); in bch2_dev_attach_bdev()
1436 ret = __bch2_dev_attach_bdev(ca, sb); in bch2_dev_attach_bdev()
1440 bch2_dev_sysfs_online(c, ca); in bch2_dev_attach_bdev()
1443 prt_bdevname(&name, ca->disk_sb.bdev); in bch2_dev_attach_bdev()
1447 strscpy(ca->name, name.buf, sizeof(ca->name)); in bch2_dev_attach_bdev()
1466 bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca, in bch2_dev_state_allowed() argument
1478 if (ca->mi.state != BCH_MEMBER_STATE_rw) in bch2_dev_state_allowed()
1483 if (ca2 != ca) in bch2_dev_state_allowed()
1496 if (ca->mi.state != BCH_MEMBER_STATE_rw && in bch2_dev_state_allowed()
1497 ca->mi.state != BCH_MEMBER_STATE_ro) in bch2_dev_state_allowed()
1502 __clear_bit(ca->dev_idx, new_online_devs.d); in bch2_dev_state_allowed()
1512 struct bch_dev *ca; in bch2_fs_may_start() local
1529 ca = bch2_dev_locked(c, i); in bch2_fs_may_start()
1531 if (!bch2_dev_is_online(ca) && in bch2_fs_may_start()
1532 (ca->mi.state == BCH_MEMBER_STATE_rw || in bch2_fs_may_start()
1533 ca->mi.state == BCH_MEMBER_STATE_ro)) { in bch2_fs_may_start()
1544 static void __bch2_dev_read_only(struct bch_fs *c, struct bch_dev *ca) in __bch2_dev_read_only() argument
1549 bch2_dev_allocator_remove(c, ca); in __bch2_dev_read_only()
1551 bch2_dev_journal_stop(&c->journal, ca); in __bch2_dev_read_only()
1554 static void __bch2_dev_read_write(struct bch_fs *c, struct bch_dev *ca) in __bch2_dev_read_write() argument
1558 BUG_ON(ca->mi.state != BCH_MEMBER_STATE_rw); in __bch2_dev_read_write()
1560 bch2_dev_allocator_add(c, ca); in __bch2_dev_read_write()
1562 bch2_dev_do_discards(ca); in __bch2_dev_read_write()
1565 int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, in __bch2_dev_set_state() argument
1571 if (ca->mi.state == new_state) in __bch2_dev_set_state()
1574 if (!bch2_dev_state_allowed(c, ca, new_state, flags)) in __bch2_dev_set_state()
1578 __bch2_dev_read_only(c, ca); in __bch2_dev_set_state()
1580 bch_notice(ca, "%s", bch2_member_states[new_state]); in __bch2_dev_set_state()
1583 m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx); in __bch2_dev_set_state()
1589 __bch2_dev_read_write(c, ca); in __bch2_dev_set_state()
1596 int bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, in bch2_dev_set_state() argument
1602 ret = __bch2_dev_set_state(c, ca, new_state, flags); in bch2_dev_set_state()
1610 int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags) in bch2_dev_remove() argument
1613 unsigned dev_idx = ca->dev_idx, data; in bch2_dev_remove()
1619 * We consume a reference to ca->ref, regardless of whether we succeed in bch2_dev_remove()
1622 bch2_dev_put(ca); in bch2_dev_remove()
1624 if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) { in bch2_dev_remove()
1625 bch_err(ca, "Cannot remove without losing data"); in bch2_dev_remove()
1630 __bch2_dev_read_only(c, ca); in bch2_dev_remove()
1632 ret = bch2_dev_data_drop(c, ca->dev_idx, flags); in bch2_dev_remove()
1633 bch_err_msg(ca, ret, "bch2_dev_data_drop()"); in bch2_dev_remove()
1637 ret = bch2_dev_remove_alloc(c, ca); in bch2_dev_remove()
1638 bch_err_msg(ca, ret, "bch2_dev_remove_alloc()"); in bch2_dev_remove()
1652 ret = bch2_journal_flush_device_pins(&c->journal, ca->dev_idx); in bch2_dev_remove()
1653 bch_err_msg(ca, ret, "bch2_journal_flush_device_pins()"); in bch2_dev_remove()
1658 bch_err_msg(ca, ret, "bch2_journal_flush()"); in bch2_dev_remove()
1663 bch_err_msg(ca, ret, "bch2_replicas_gc2()"); in bch2_dev_remove()
1667 data = bch2_dev_has_data(c, ca); in bch2_dev_remove()
1672 bch_err(ca, "Remove failed, still has data (%s)", data_has.buf); in bch2_dev_remove()
1678 __bch2_dev_offline(c, ca); in bch2_dev_remove()
1681 rcu_assign_pointer(c->devs[ca->dev_idx], NULL); in bch2_dev_remove()
1685 percpu_ref_kill(&ca->ref); in bch2_dev_remove()
1687 ca->dying = true; in bch2_dev_remove()
1688 bch2_dev_put(ca); in bch2_dev_remove()
1690 wait_for_completion(&ca->ref_completion); in bch2_dev_remove()
1692 bch2_dev_free(ca); in bch2_dev_remove()
1708 if (ca->mi.state == BCH_MEMBER_STATE_rw && in bch2_dev_remove()
1709 !percpu_ref_is_zero(&ca->io_ref)) in bch2_dev_remove()
1710 __bch2_dev_read_write(c, ca); in bch2_dev_remove()
1720 struct bch_dev *ca = NULL; in bch2_dev_add() local
1744 ca = __bch2_dev_alloc(c, &dev_mi); in bch2_dev_add()
1745 if (!ca) { in bch2_dev_add()
1750 ret = __bch2_dev_attach_bdev(ca, &sb); in bch2_dev_add()
1754 ret = bch2_dev_journal_alloc(ca, true); in bch2_dev_add()
1762 ret = bch2_sb_from_fs(c, ca); in bch2_dev_add()
1782 ca->disk_sb.sb->dev_idx = dev_idx; in bch2_dev_add()
1783 bch2_dev_attach(c, ca, dev_idx); in bch2_dev_add()
1786 ret = __bch2_dev_group_set(c, ca, label.buf); in bch2_dev_add()
1795 ret = bch2_dev_usage_init(ca, false); in bch2_dev_add()
1799 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional); in bch2_dev_add()
1800 bch_err_msg(ca, ret, "marking new superblock"); in bch2_dev_add()
1805 bch_err_msg(ca, ret, "initializing free space"); in bch2_dev_add()
1809 ca->new_fs_bucket_idx = 0; in bch2_dev_add()
1811 if (ca->mi.state == BCH_MEMBER_STATE_rw) in bch2_dev_add()
1812 __bch2_dev_read_write(c, ca); in bch2_dev_add()
1821 if (ca) in bch2_dev_add()
1822 bch2_dev_free(ca); in bch2_dev_add()
1830 ca = NULL; in bch2_dev_add()
1839 struct bch_dev *ca; in bch2_dev_online() local
1862 ca = bch2_dev_locked(c, dev_idx); in bch2_dev_online()
1864 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional); in bch2_dev_online()
1869 if (ca->mi.state == BCH_MEMBER_STATE_rw) in bch2_dev_online()
1870 __bch2_dev_read_write(c, ca); in bch2_dev_online()
1872 if (!ca->mi.freespace_initialized) { in bch2_dev_online()
1873 ret = bch2_dev_freespace_init(c, ca, 0, ca->mi.nbuckets); in bch2_dev_online()
1874 bch_err_msg(ca, ret, "initializing free space"); in bch2_dev_online()
1879 if (!ca->journal.nr) { in bch2_dev_online()
1880 ret = bch2_dev_journal_alloc(ca, false); in bch2_dev_online()
1881 bch_err_msg(ca, ret, "allocating journal"); in bch2_dev_online()
1887 bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = in bch2_dev_online()
1900 int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags) in bch2_dev_offline() argument
1904 if (!bch2_dev_is_online(ca)) { in bch2_dev_offline()
1905 bch_err(ca, "Already offline"); in bch2_dev_offline()
1910 if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) { in bch2_dev_offline()
1911 bch_err(ca, "Cannot offline required disk"); in bch2_dev_offline()
1916 __bch2_dev_offline(c, ca); in bch2_dev_offline()
1922 int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) in bch2_dev_resize() argument
1929 old_nbuckets = ca->mi.nbuckets; in bch2_dev_resize()
1931 if (nbuckets < ca->mi.nbuckets) { in bch2_dev_resize()
1932 bch_err(ca, "Cannot shrink yet"); in bch2_dev_resize()
1938 bch_err(ca, "New device size too big (%llu greater than max %u)", in bch2_dev_resize()
1944 if (bch2_dev_is_online(ca) && in bch2_dev_resize()
1945 get_capacity(ca->disk_sb.bdev->bd_disk) < in bch2_dev_resize()
1946 ca->mi.bucket_size * nbuckets) { in bch2_dev_resize()
1947 bch_err(ca, "New size larger than device"); in bch2_dev_resize()
1952 ret = bch2_dev_buckets_resize(c, ca, nbuckets); in bch2_dev_resize()
1953 bch_err_msg(ca, ret, "resizing buckets"); in bch2_dev_resize()
1957 ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional); in bch2_dev_resize()
1962 m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx); in bch2_dev_resize()
1968 if (ca->mi.freespace_initialized) { in bch2_dev_resize()
1971 .dev_data_type.dev = ca->dev_idx, in bch2_dev_resize()
1976 ret = bch2_trans_commit_do(ca->fs, NULL, NULL, 0, in bch2_dev_resize()
1978 bch2_dev_freespace_init(c, ca, old_nbuckets, nbuckets); in bch2_dev_resize()
1989 /* return with ref on ca->ref: */
1995 for_each_member_device(c, ca) in bch2_dev_lookup()
1996 if (!strcmp(name, ca->name)) in bch2_dev_lookup()
1997 return ca; in bch2_dev_lookup()