#include #include #include static uint64_t device_logical_size(const char* dev) { int fd; uint8_t pblkbuf[PBLK_SIZE]; struct cbd_header header; fd = open(dev, O_RDONLY); if (fd < 0) { error("Cannot open device\n"); } if (read(fd, pblkbuf, sizeof(pblkbuf)) != sizeof(pblkbuf)) { error("Cannot read device\n"); } cbd_header_get(pblkbuf, &header); close(fd); return (header.params.lblk_per_zone << header.params.lblk_shift) * header.params.nr_zones; } int cbd_open(const char* dev, uint64_t loff, uint64_t lsize, const char* name) { int ret; struct stat st; struct dm_task* dmt; uint32_t cookie = 0; ret = stat(dev, &st); if (ret) { error("Failed to stat device\n"); } if (!S_ISBLK(st.st_mode)) { error("Not a block device\n"); } if (!lsize) { lsize = device_logical_size(dev); } dmt = dm_task_create(DM_DEVICE_CREATE); if (!dmt) { error("dm_task_create failed\n"); } ret = dm_task_set_name(dmt, name); if (ret == 0) { error("dm_task_set_name failed\n"); } printf("%s: start_sector=%lu num_sectors=%lu\n", __func__, (unsigned long)(loff * PBLK_PER_SECTOR), (unsigned long)(lsize * PBLK_PER_SECTOR)); ret = dm_task_add_target(dmt, loff * PBLK_PER_SECTOR, lsize * PBLK_PER_SECTOR, "compress", dev); if (ret == 0) { error("dm_task_add_target failed\n"); } ret = dm_task_set_cookie(dmt, &cookie, 0); if (ret == 0) { error("dm_task_set_cookie failed\n"); } ret = dm_task_run(dmt); if (ret == 0) { error("dm_task_run failed\n"); } dm_udev_wait(cookie); dm_task_destroy(dmt); return 0; }