Lines Matching refs:btt
19 #include "btt.h"
255 static void btt_debugfs_init(struct btt *btt)
260 btt->debugfs_dir = debugfs_create_dir(dev_name(&btt->nd_btt->dev),
262 if (IS_ERR_OR_NULL(btt->debugfs_dir))
265 list_for_each_entry(arena, &btt->arena_list, list) {
266 arena_debugfs_init(arena, btt->debugfs_dir, i);
611 * Detecting valid log indices: We read a log group (see the comments in btt.h
745 static struct arena_info *alloc_arena(struct btt *btt, size_t size,
755 arena->nd_btt = btt->nd_btt;
756 arena->sector_size = btt->sector_size;
764 arena->external_lbasize = btt->lbasize;
768 arena->version_major = btt->nd_btt->version_major;
769 arena->version_minor = btt->nd_btt->version_minor;
802 static void free_arenas(struct btt *btt)
806 list_for_each_entry_safe(arena, next, &btt->arena_list, list) {
817 * This function reads an existing valid btt superblock and
846 static int discover_arenas(struct btt *btt)
851 size_t remaining = btt->rawsize;
862 arena = alloc_arena(btt, 0, 0, 0);
873 if (!nd_btt_arena_is_valid(btt->nd_btt, super)) {
874 if (remaining == btt->rawsize) {
875 btt->init_state = INIT_NOTFOUND;
908 list_add_tail(&arena->list, &btt->arena_list);
918 btt->num_arenas = num_arenas;
919 btt->nlba = cur_nlba;
920 btt->init_state = INIT_READY;
927 free_arenas(btt);
933 static int create_arenas(struct btt *btt)
935 size_t remaining = btt->rawsize;
946 arena = alloc_arena(btt, arena_size, btt->nlba, cur_off);
948 free_arenas(btt);
951 btt->nlba += arena->external_nlba;
957 list_add_tail(&arena->list, &btt->arena_list);
1025 static int btt_meta_init(struct btt *btt)
1030 mutex_lock(&btt->init_lock);
1031 list_for_each_entry(arena, &btt->arena_list, list) {
1049 btt->init_state = INIT_READY;
1052 mutex_unlock(&btt->init_lock);
1056 static u32 btt_meta_size(struct btt *btt)
1058 return btt->lbasize - btt->sector_size;
1068 static int lba_to_arena(struct btt *btt, sector_t sector, __u32 *premap,
1072 __u64 lba = div_u64(sector << SECTOR_SHIFT, btt->sector_size);
1074 list_for_each_entry(arena_list, &btt->arena_list, list) {
1141 static int btt_rw_integrity(struct btt *btt, struct bio_integrity_payload *bip,
1144 unsigned int len = btt_meta_size(btt);
1151 meta_nsoff = to_namespace_offset(arena, postmap) + btt->sector_size;
1190 static int btt_rw_integrity(struct btt *btt, struct bio_integrity_payload *bip,
1197 static int btt_read_pg(struct btt *btt, struct bio_integrity_payload *bip,
1209 lane = nd_region_acquire_lane(btt->nd_region);
1211 ret = lba_to_arena(btt, sector, &premap, &arena);
1215 cur_len = min(btt->sector_size, len);
1273 ret = btt_rw_integrity(btt, bip, arena, postmap, READ);
1279 nd_region_release_lane(btt->nd_region, lane);
1283 sector += btt->sector_size >> SECTOR_SHIFT;
1291 nd_region_release_lane(btt->nd_region, lane);
1300 static bool btt_is_badblock(struct btt *btt, struct arena_info *arena,
1307 return is_bad_pmem(btt->phys_bb, phys_sector, arena->internal_lbasize);
1310 static int btt_write_pg(struct btt *btt, struct bio_integrity_payload *bip,
1325 lane = nd_region_acquire_lane(btt->nd_region);
1327 ret = lba_to_arena(btt, sector, &premap, &arena);
1330 cur_len = min(btt->sector_size, len);
1337 if (btt_is_badblock(btt, arena, arena->freelist[lane].block))
1342 nd_region_release_lane(btt->nd_region, lane);
1370 ret = btt_rw_integrity(btt, bip, arena, new_postmap,
1403 nd_region_release_lane(btt->nd_region, lane);
1413 sector += btt->sector_size >> SECTOR_SHIFT;
1421 nd_region_release_lane(btt->nd_region, lane);
1425 static int btt_do_bvec(struct btt *btt, struct bio_integrity_payload *bip,
1432 ret = btt_read_pg(btt, bip, page, off, sector, len);
1436 ret = btt_write_pg(btt, bip, sector, page, off, len);
1445 struct btt *btt = bio->bi_disk->private_data;
1461 if (len > PAGE_SIZE || len < btt->sector_size ||
1462 len % btt->sector_size) {
1463 dev_err_ratelimited(&btt->nd_btt->dev,
1469 err = btt_do_bvec(btt, bip, bvec.bv_page, len, bvec.bv_offset,
1472 dev_err(&btt->nd_btt->dev,
1491 struct btt *btt = bdev->bd_disk->private_data;
1494 rc = btt_do_bvec(btt, NULL, page, thp_size(page), 0, op, sector);
1518 static int btt_blk_init(struct btt *btt)
1520 struct nd_btt *nd_btt = btt->nd_btt;
1523 /* create a new disk and request queue for btt */
1524 btt->btt_queue = blk_alloc_queue(NUMA_NO_NODE);
1525 if (!btt->btt_queue)
1528 btt->btt_disk = alloc_disk(0);
1529 if (!btt->btt_disk) {
1530 blk_cleanup_queue(btt->btt_queue);
1534 nvdimm_namespace_disk_name(ndns, btt->btt_disk->disk_name);
1535 btt->btt_disk->first_minor = 0;
1536 btt->btt_disk->fops = &btt_fops;
1537 btt->btt_disk->private_data = btt;
1538 btt->btt_disk->queue = btt->btt_queue;
1539 btt->btt_disk->flags = GENHD_FL_EXT_DEVT;
1541 blk_queue_logical_block_size(btt->btt_queue, btt->sector_size);
1542 blk_queue_max_hw_sectors(btt->btt_queue, UINT_MAX);
1543 blk_queue_flag_set(QUEUE_FLAG_NONROT, btt->btt_queue);
1545 if (btt_meta_size(btt)) {
1546 int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
1549 del_gendisk(btt->btt_disk);
1550 put_disk(btt->btt_disk);
1551 blk_cleanup_queue(btt->btt_queue);
1555 set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
1556 device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL);
1557 btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
1558 nvdimm_check_and_set_ro(btt->btt_disk);
1563 static void btt_blk_cleanup(struct btt *btt)
1565 del_gendisk(btt->btt_disk);
1566 put_disk(btt->btt_disk);
1567 blk_cleanup_queue(btt->btt_queue);
1585 * Pointer to a new struct btt on success, NULL on failure.
1587 static struct btt *btt_init(struct nd_btt *nd_btt, unsigned long long rawsize,
1591 struct btt *btt;
1595 btt = devm_kzalloc(dev, sizeof(struct btt), GFP_KERNEL);
1596 if (!btt)
1599 btt->nd_btt = nd_btt;
1600 btt->rawsize = rawsize;
1601 btt->lbasize = lbasize;
1602 btt->sector_size = ((lbasize >= 4096) ? 4096 : 512);
1603 INIT_LIST_HEAD(&btt->arena_list);
1604 mutex_init(&btt->init_lock);
1605 btt->nd_region = nd_region;
1607 btt->phys_bb = &nsio->bb;
1609 ret = discover_arenas(btt);
1615 if (btt->init_state != INIT_READY && nd_region->ro) {
1616 dev_warn(dev, "%s is read-only, unable to init btt metadata\n",
1619 } else if (btt->init_state != INIT_READY) {
1620 btt->num_arenas = (rawsize / ARENA_MAX_SIZE) +
1623 btt->num_arenas, rawsize);
1625 ret = create_arenas(btt);
1631 ret = btt_meta_init(btt);
1638 ret = btt_blk_init(btt);
1644 btt_debugfs_init(btt);
1646 return btt;
1651 * @btt: the BTT handle that was generated by btt_init
1658 static void btt_fini(struct btt *btt)
1660 if (btt) {
1661 btt_blk_cleanup(btt);
1662 free_arenas(btt);
1663 debugfs_remove_recursive(btt->debugfs_dir);
1672 struct btt *btt;
1677 dev_dbg(&nd_btt->dev, "incomplete btt configuration\n");
1706 btt = btt_init(nd_btt, rawsize, nd_btt->lbasize, nd_btt->uuid,
1708 if (!btt)
1710 nd_btt->btt = btt;
1718 struct btt *btt = nd_btt->btt;
1720 btt_fini(btt);
1721 nd_btt->btt = NULL;
1731 debugfs_root = debugfs_create_dir("btt", NULL);