Fix a bunch of things

* Fix command line handling.
* Move option/parameter validation to libcbd.
* Make resize argument the logical size.
* Make blkdev_pblk_* take dm_compress instead of block_device.
* Reinstate dm_compress.io_failed.
* Other misc stuff.
This commit is contained in:
Tom Marshall 2019-10-10 13:21:36 -07:00
parent 36dec597ac
commit 07f4221a5f
8 changed files with 130 additions and 126 deletions

115
cbd/cbd.c
View File

@ -84,7 +84,6 @@ usage(void)
fprintf(stderr, "Commands:\n" fprintf(stderr, "Commands:\n"
" format [opts] <device> Create (format) a compressed device\n" " format [opts] <device> Create (format) a compressed device\n"
" -S --pysical-size Physical size [device size]\n" " -S --pysical-size Physical size [device size]\n"
" -O --offset Offset in device [0]\n"
" -L --logical-blksize Logical block size\n" " -L --logical-blksize Logical block size\n"
" -c --compress-factor Compression factor [2.0]\n" " -c --compress-factor Compression factor [2.0]\n"
" -l --logical-shift Logical block shift [4]\n" " -l --logical-shift Logical block shift [4]\n"
@ -102,7 +101,7 @@ usage(void)
" -n --assume-no Assume \"no\" no all questions\n" " -n --assume-no Assume \"no\" no all questions\n"
" -y --assume-yes Assume \"yes\" to all questions\n" " -y --assume-yes Assume \"yes\" to all questions\n"
" resize [opts] <device> Resize an existing compressed device\n" " resize [opts] <device> Resize an existing compressed device\n"
" -S --physical-size New (physical) size [use all]\n" " -s --size New logical size [use all]\n"
" stats [opts] <name> Show device statistics\n" " stats [opts] <name> Show device statistics\n"
"\n"); "\n");
exit(1); exit(1);
@ -111,22 +110,20 @@ usage(void)
static int static int
do_format(int argc, char** argv) do_format(int argc, char** argv)
{ {
static const char short_opts[] = "S:O:L:c:l:s:"; static const char short_opts[] = "S:L:c:l:s:";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "physical-size", 1, NULL, 'S' }, { "physical-size", required_argument, NULL, 'S' },
{ "offset", 1, NULL, 'O' }, { "logical-blksize", required_argument, NULL, 'L' },
{ "logical-blksize", 1, NULL, 'L' }, { "compress-factor", required_argument, NULL, 'c' },
{ "compress-factor", 1, NULL, 'c' }, { "logical-shift", required_argument, NULL, 'l' },
{ "logical-shift", 1, NULL, 'l' }, { "size", required_argument, NULL, 's' },
{ "size", 1, NULL, 's' }, { NULL, no_argument, NULL, 0 }
{ NULL, 0, NULL, 0 }
}; };
char opt; char opt;
uint64_t optval; uint64_t optval;
uint64_t poff = 0;
uint64_t psize = 0; uint64_t psize = 0;
uint64_t lsize = 0;
uint16_t lshift = 0; uint16_t lshift = 0;
uint64_t lsize = 0;
const char* dev; const char* dev;
@ -137,23 +134,12 @@ do_format(int argc, char** argv)
error("Failed to parse \"%s\"\n", optarg); error("Failed to parse \"%s\"\n", optarg);
} }
psize = optval; psize = optval;
if (psize % PBLK_SIZE) {
error("Size \"%s\" is not a multiple of %u bytes\n", optarg, (uint)PBLK_SIZE);
}
break;
case 'O':
if (!parse_arg(optarg, &optval)) {
error("Failed to parse \"%s\"\n", optarg);
}
poff = optval;
break; break;
case 'L': case 'L':
if (!parse_arg(optarg, &optval)) { if (!parse_arg(optarg, &optval)) {
error("Failed to parse \"%s\"\n", optarg); error("Failed to parse \"%s\"\n", optarg);
} }
if ((optval & (optval-1)) || if ((optval & (optval-1)) || optval < PBLK_SIZE) {
optval < (1 << (PBLK_SHIFT + LBLK_SHIFT_MIN)) ||
optval > (1 << (PBLK_SHIFT + LBLK_SHIFT_MAX))) {
error("Size \"%s\" is not a valid logical block size\n", optarg); error("Size \"%s\" is not a valid logical block size\n", optarg);
} }
lshift = (optval >> PBLK_SHIFT); lshift = (optval >> PBLK_SHIFT);
@ -165,9 +151,6 @@ do_format(int argc, char** argv)
if (!parse_arg(optarg, &optval)) { if (!parse_arg(optarg, &optval)) {
error("Failed to parse \"%s\"\n", optarg); error("Failed to parse \"%s\"\n", optarg);
} }
if (optval < LBLK_SHIFT_MIN || optval > LBLK_SHIFT_MAX) {
error("Size \"%s\" is not a valid logical block shift\n", optarg);
}
lshift = optval; lshift = optval;
break; break;
case 's': case 's':
@ -175,9 +158,6 @@ do_format(int argc, char** argv)
error("Failed to parse \"%s\"\n", optarg); error("Failed to parse \"%s\"\n", optarg);
} }
lsize = optval; lsize = optval;
if (lsize % PBLK_SIZE) {
error("Size \"%s\" is not a multiple of %u bytes\n", optarg, (uint)PBLK_SIZE);
}
break; break;
default: default:
usage(); usage();
@ -188,7 +168,7 @@ do_format(int argc, char** argv)
} }
dev = argv[optind++]; dev = argv[optind++];
cbd_format(dev, poff, psize, lsize, lshift); cbd_format(dev, psize, lshift, lsize);
return 0; return 0;
} }
@ -197,19 +177,18 @@ static int
do_open(int argc, char** argv) do_open(int argc, char** argv)
{ {
char dev[PATH_MAX]; char dev[PATH_MAX];
char name[PATH_MAX]; const char* name;
if (argc != 3) { if (argc != 3) {
usage(); usage();
} }
strcpy(dev, argv[1]); strcpy(dev, argv[1]);
strcpy(name, argv[2]);
if (dev[0] != '/') { if (dev[0] != '/') {
sprintf(dev, "/dev/mapper/%s", argv[1]); sprintf(dev, "/dev/mapper/%s", argv[1]);
} }
name = argv[2];
cbd_open(dev, 0, 0, name); cbd_open(dev, name);
return 0; return 0;
} }
@ -229,14 +208,29 @@ do_close(int argc, char** argv)
return 0; return 0;
} }
static int
do_stats(int argc, char** argv)
{
const char* name;
if (argc != 2) {
usage();
}
name = argv[1];
cbd_stats(name);
return 0;
}
static int static int
do_check(int argc, char** argv) do_check(int argc, char** argv)
{ {
static const char short_opts[] = "ny"; static const char short_opts[] = "ny";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "assume-no", 0, NULL, 'n' }, { "assume-no", no_argument, NULL, 'n' },
{ "assume-yes", 0, NULL, 'y' }, { "assume-yes", no_argument, NULL, 'y' },
{ NULL, 0, NULL, 0 } { NULL, no_argument, NULL, 0 }
}; };
char opt; char opt;
tristate_t auto_response = t_none; tristate_t auto_response = t_none;
@ -276,27 +270,25 @@ do_check(int argc, char** argv)
static int static int
do_resize(int argc, char** argv) do_resize(int argc, char** argv)
{ {
static const char short_opts[] = "S:"; static const char short_opts[] = "s:";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "physical-size", 1, NULL, 'S' }, { "size", required_argument, NULL, 's' },
{ NULL, 0, NULL, 0 } { NULL, no_argument, NULL, 0 }
}; };
char opt; char opt;
uint64_t poff = 0; uint64_t optval;
uint64_t psize = 0; uint64_t lsize = 0;
const char* dev; char dev[PATH_MAX];
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (opt) { switch (opt) {
case 'S': case 's':
if (!parse_arg(optarg, &psize)) { if (!parse_arg(optarg, &optval)) {
fprintf(stderr, "Failed to parse \"%s\"\n", optarg); fprintf(stderr, "Failed to parse \"%s\"\n", optarg);
usage(); usage();
} }
if (psize % PBLK_SIZE) { lsize = optval;
fprintf(stderr, "Size \"%s\" is not a multiple of %u bytes\n", optarg, (uint)PBLK_SIZE);
}
break; break;
default: default:
usage(); usage();
@ -305,24 +297,13 @@ do_resize(int argc, char** argv)
if (argc - optind != 1) { if (argc - optind != 1) {
usage(); usage();
} }
dev = argv[optind++]; strcpy(dev, argv[optind]);
if (dev[0] != '/') {
cbd_resize(dev, poff, psize / PBLK_SHIFT); sprintf(dev, "/dev/mapper/%s", argv[optind]);
return 0;
}
static int
do_stats(int argc, char** argv)
{
const char* dev;
if (argc != 1) {
usage();
} }
dev = argv[0]; ++optind;
cbd_stats(dev); cbd_resize(dev, lsize);
return 0; return 0;
} }
@ -339,15 +320,15 @@ static struct cmd_dispatch dispatch[] =
{ "open", do_open }, { "open", do_open },
{ "create", do_open }, { "create", do_open },
{ "close", do_close }, { "close", do_close },
{ "stats", do_stats },
{ "check", do_check }, { "check", do_check },
{ "resize", do_resize }, { "resize", do_resize },
{ "stats", do_stats },
}; };
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
static const char short_opts[] = "v"; static const char short_opts[] = "+v";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "verbose", 0, NULL, 'v' }, { "verbose", 0, NULL, 'v' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }

View File

@ -53,12 +53,10 @@ struct dm_compress_io {
struct dm_compress struct dm_compress
{ {
struct dm_dev* dev; struct dm_dev* dev;
bool io_failed;
struct cbd_params params; struct cbd_params params;
/* XXX: dm_target.off */
sector_t dm_off;
u8* lz4_wrkmem; u8* lz4_wrkmem;
u8* lz4_cbuf; u8* lz4_cbuf;
@ -170,7 +168,7 @@ compress_free_pages(void* ptr, size_t size)
**************************************/ **************************************/
static struct bio* static struct bio*
blkdev_pblk_io_prepare(struct block_device* dev, unsigned int op, u64 pblk, u32 count, void *data) blkdev_pblk_io_prepare(struct dm_compress* dc, unsigned int op, u64 pblk, u32 count, void *data)
{ {
unsigned long data_addr; unsigned long data_addr;
struct bio* bio; struct bio* bio;
@ -184,7 +182,7 @@ blkdev_pblk_io_prepare(struct block_device* dev, unsigned int op, u64 pblk, u32
printk(KERN_ERR "%s: out of memory\n", __func__); printk(KERN_ERR "%s: out of memory\n", __func__);
return NULL; return NULL;
} }
bio_set_dev(bio, dev); bio_set_dev(bio, dc->dev->bdev);
bio->bi_opf = op; bio->bi_opf = op;
bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT)); bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT));
@ -200,12 +198,12 @@ blkdev_pblk_io_prepare(struct block_device* dev, unsigned int op, u64 pblk, u32
} }
static int static int
blkdev_pblk_read(struct block_device* dev, u64 pblk, u32 count, void *data) blkdev_pblk_read(struct dm_compress* dc, u64 pblk, u32 count, void *data)
{ {
int ret; int ret;
struct bio* bio; struct bio* bio;
bio = blkdev_pblk_io_prepare(dev, REQ_OP_READ, pblk, count, data); bio = blkdev_pblk_io_prepare(dc, REQ_OP_READ, pblk, count, data);
if (!bio) { if (!bio) {
printk(KERN_ERR "%s: out of memory\n", __func__); printk(KERN_ERR "%s: out of memory\n", __func__);
return -ENOMEM; return -ENOMEM;
@ -226,20 +224,25 @@ blkdev_pblk_write_endio(struct bio* bio)
void* data = page_address(bio->bi_io_vec[0].bv_page); void* data = page_address(bio->bi_io_vec[0].bv_page);
unsigned int count = bio->bi_max_vecs; unsigned int count = bio->bi_max_vecs;
compress_free_pages(data, count); compress_free_pages(data, count);
if (bio->bi_status != BLK_STS_OK) {
struct dm_compress* dc = bio->bi_private;
dc->io_failed = true;
}
bio_put(bio); bio_put(bio);
} }
static void static void
blkdev_pblk_write(struct block_device* dev, u64 pblk, u32 count, void *data) blkdev_pblk_write(struct dm_compress* dc, u64 pblk, u32 count, void *data)
{ {
struct bio* bio; struct bio* bio;
bio = blkdev_pblk_io_prepare(dev, REQ_OP_WRITE, pblk, count, data); bio = blkdev_pblk_io_prepare(dc, REQ_OP_WRITE, pblk, count, data);
if (!bio) { if (!bio) {
printk(KERN_ERR "%s: out of memory\n", __func__); printk(KERN_ERR "%s: out of memory\n", __func__);
return; return;
} }
bio->bi_end_io = blkdev_pblk_write_endio; bio->bi_end_io = blkdev_pblk_write_endio;
bio->bi_private = dc;
submit_bio(bio); submit_bio(bio);
} }
@ -264,7 +267,7 @@ pblk_alloc_write(struct dm_compress* dc)
return -ENOMEM; return -ENOMEM;
} }
memcpy(pg, dc->pblk_alloc, count * PBLK_SIZE); memcpy(pg, dc->pblk_alloc, count * PBLK_SIZE);
blkdev_pblk_write(dc->dev->bdev, pblk, count, pg); blkdev_pblk_write(dc, pblk, count, pg);
dc->pblk_alloc_dirty = false; dc->pblk_alloc_dirty = false;
@ -305,7 +308,7 @@ pblk_alloc_read(struct dm_compress* dc, u32 idx)
pblk = pblk_alloc_off(&dc->params, idx); pblk = pblk_alloc_off(&dc->params, idx);
count = pblk_alloc_len(&dc->params); count = pblk_alloc_len(&dc->params);
ret = blkdev_pblk_read(dc->dev->bdev, pblk, count, dc->pblk_alloc); ret = blkdev_pblk_read(dc, pblk, count, dc->pblk_alloc);
if (ret) { if (ret) {
return ret; return ret;
} }
@ -425,7 +428,7 @@ lblk_alloc_elem_write(struct dm_compress* dc)
return -ENOMEM; return -ENOMEM;
} }
memcpy(pg, dc->lblk_alloc, count * PBLK_SIZE); memcpy(pg, dc->lblk_alloc, count * PBLK_SIZE);
blkdev_pblk_write(dc->dev->bdev, pblk, count, pg); blkdev_pblk_write(dc, pblk, count, pg);
return 0; return 0;
} }
@ -455,7 +458,7 @@ lblk_alloc_elem_read(struct dm_compress* dc, u64 lblk)
count = 1 + (elem_end - 1) / PBLK_SIZE - (elem_off / PBLK_SIZE); count = 1 + (elem_end - 1) / PBLK_SIZE - (elem_off / PBLK_SIZE);
pblk = lblk_alloc_off(&dc->params, zone) + rel_pblk; pblk = lblk_alloc_off(&dc->params, zone) + rel_pblk;
if (dc->lblk_alloc_pblk != pblk || dc->lblk_alloc_len < count) { if (dc->lblk_alloc_pblk != pblk || dc->lblk_alloc_len < count) {
ret = blkdev_pblk_read(dc->dev->bdev, pblk, count, dc->lblk_alloc); ret = blkdev_pblk_read(dc, pblk, count, dc->lblk_alloc);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
@ -581,7 +584,7 @@ lblk_write(struct dm_compress* dc)
return -ENOMEM; return -ENOMEM;
} }
memcpy(pg, c_buf, PBLK_SIZE); memcpy(pg, c_buf, PBLK_SIZE);
blkdev_pblk_write(dc->dev->bdev, pblk, 1, pg); blkdev_pblk_write(dc, pblk, 1, pg);
c_buf += PBLK_SIZE; c_buf += PBLK_SIZE;
} }
else { else {
@ -674,7 +677,7 @@ lblk_read(struct dm_compress* dc, u64 idx)
for (n = 0; n * PBLK_SIZE < c_len; ++n, p += PBLK_SIZE) { for (n = 0; n * PBLK_SIZE < c_len; ++n, p += PBLK_SIZE) {
pblk = dc->lblk_alloc_elem->pblk[n]; pblk = dc->lblk_alloc_elem->pblk[n];
BUG_ON(pblk == 0); BUG_ON(pblk == 0);
ret = blkdev_pblk_read(dc->dev->bdev, pblk, 1, p); ret = blkdev_pblk_read(dc, pblk, 1, p);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
@ -787,7 +790,7 @@ compress_open(struct dm_compress* dc, u64 dev_nr_pblks)
return -ENOMEM; return -ENOMEM;
} }
err = blkdev_pblk_read(dc->dev->bdev, 0, 1, pblkbuf); err = blkdev_pblk_read(dc, 0, 1, pblkbuf);
if (err) { if (err) {
printk(KERN_ERR "%s: failed to read header\n", __func__); printk(KERN_ERR "%s: failed to read header\n", __func__);
goto out; goto out;
@ -1040,7 +1043,6 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
kfree(dc); kfree(dc);
return -EINVAL; return -EINVAL;
} }
dc->dm_off = ti->begin;
ti->private = dc; ti->private = dc;
@ -1088,6 +1090,10 @@ compress_map(struct dm_target *ti, struct bio *bio)
struct dm_compress *dc = (struct dm_compress *)ti->private; struct dm_compress *dc = (struct dm_compress *)ti->private;
struct dm_compress_io *io; struct dm_compress_io *io;
if (dc->io_failed) {
return DM_MAPIO_KILL;
}
/* from dm-crypt.c */ /* from dm-crypt.c */
if (unlikely(bio->bi_opf & REQ_PREFLUSH || bio_op(bio) == REQ_OP_DISCARD)) { if (unlikely(bio->bi_opf & REQ_PREFLUSH || bio_op(bio) == REQ_OP_DISCARD)) {
bio_set_dev(bio, dc->dev->bdev); bio_set_dev(bio, dc->dev->bdev);

View File

@ -50,17 +50,16 @@ typedef enum {
} tristate_t; } tristate_t;
int cbd_format(const char* dev, int cbd_format(const char* dev,
uint64_t poff, uint64_t psize, uint64_t psize, uint16_t lshift, uint64_t lsize);
uint64_t lsize, uint16_t lshift);
int cbd_open(const char* dev, int cbd_open(const char* dev,
uint64_t loff, uint64_t lsize,
const char* name); const char* name);
int cbd_close(const char* name); int cbd_close(const char* name);
int cbd_stats(const char* name); int cbd_stats(const char* name);
int cbd_check(const char* dev, tristate_t auto_response); int cbd_check(const char* dev,
tristate_t auto_response);
int cbd_resize(const char* dev, int cbd_resize(const char* dev,
uint64_t poff, uint64_t psize); uint64_t lsize);
#endif #endif

View File

@ -4,6 +4,9 @@
#ifndef SECTOR_SHIFT #ifndef SECTOR_SHIFT
#define SECTOR_SHIFT 9 #define SECTOR_SHIFT 9
#endif #endif
#ifndef SECTOR_SIZE
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#endif
#define PBLK_SHIFT 12 #define PBLK_SHIFT 12
#define PBLK_SIZE (1 << PBLK_SHIFT) #define PBLK_SIZE (1 << PBLK_SHIFT)

View File

@ -9,14 +9,14 @@ struct zone_metadata
}; };
static void static void
pblk_read(int fd, size_t pblk, size_t count, u8* data) pblk_read(int fd, u64 pblk, u32 count, u8* data)
{ {
off_t off; off_t pos;
size_t remain; size_t remain;
ssize_t ret; ssize_t ret;
off = lseek(fd, pblk * PBLK_SIZE, SEEK_SET); pos = lseek(fd, pblk * PBLK_SIZE, SEEK_SET);
if (off == (off_t)-1) { if (pos == (off_t)-1) {
error("Failed to seek\n"); error("Failed to seek\n");
} }

View File

@ -3,14 +3,14 @@
#include <cbdutil.h> #include <cbdutil.h>
static void static void
pblk_write(int fd, size_t pblk, size_t count, const u8* data) pblk_write(int fd, u64 pblk, u32 count, const u8* data)
{ {
off_t off; off_t pos;
size_t remain; size_t remain;
ssize_t ret; ssize_t ret;
off = lseek(fd, pblk * PBLK_SIZE, SEEK_SET); pos = lseek(fd, pblk * PBLK_SIZE, SEEK_SET);
if (off == (off_t)-1) { if (pos == (off_t)-1) {
error("Failed to seek\n"); error("Failed to seek\n");
} }
@ -27,10 +27,10 @@ pblk_write(int fd, size_t pblk, size_t count, const u8* data)
int int
cbd_format(const char* dev, cbd_format(const char* dev,
uint64_t poff, uint64_t psize, uint64_t psize, uint16_t lshift, uint64_t lsize)
uint64_t lsize, uint16_t lshift)
{ {
int devfd; int devfd;
uint32_t lblk_size;
struct cbd_header header; struct cbd_header header;
uint8_t pblkbuf[PBLK_SIZE]; uint8_t pblkbuf[PBLK_SIZE];
uint64_t pblk; uint64_t pblk;
@ -42,23 +42,36 @@ cbd_format(const char* dev,
} }
if (!psize) { if (!psize) {
off_t len; off_t pos;
len = lseek(devfd, 0, SEEK_END); pos = lseek(devfd, 0, SEEK_END);
if (len == (off_t)-1) { if (pos == (off_t)-1) {
error("Cannot seek device\n"); error("Cannot seek device\n");
} }
psize = len >> PBLK_SHIFT; psize = pos / PBLK_SIZE * PBLK_SIZE;
}
if (!lsize) {
lsize = psize * CBD_DEFAULT_COMPRESSION_FACTOR;
} }
if (!lshift) { if (!lshift) {
lshift = CBD_DEFAULT_LOGICAL_BLOCK_SHIFT; lshift = CBD_DEFAULT_LOGICAL_BLOCK_SHIFT;
} }
lblk_size = 1 << (lshift + PBLK_SHIFT);
if (!lsize) {
/* XXX: Why is the cast needed here? */
lsize = (uint64_t)(psize * CBD_DEFAULT_COMPRESSION_FACTOR) / lblk_size * lblk_size;
}
if (psize % PBLK_SIZE) {
error("Physical size %lu is not a multiple of %u bytes\n", (ulong)psize, (uint)PBLK_SIZE);
}
if (lshift < LBLK_SHIFT_MIN || lshift > LBLK_SHIFT_MAX) {
error("Logical shift %hu is not in [%u,%u]\n", (ushort)lshift, (uint)LBLK_SHIFT_MIN, (uint)LBLK_SHIFT_MAX);
}
if (lsize % (1 << (lshift + PBLK_SHIFT))) {
error("Logical size %lu is not a multiple of %u bytes\n", (ulong)psize, (uint)lblk_size);
}
printf("%s: paramaters...\n", __func__); printf("%s: paramaters...\n", __func__);
printf(" poff=%lu psize=%lu\n", (unsigned long)poff, (unsigned long)psize); printf(" psize=%lu\n", (unsigned long)psize);
printf(" lsize=%lu lshift=%hu\n", (unsigned long)lsize, (unsigned short)lshift); printf(" lshift=%hu\n", (unsigned short)lshift);
printf(" lsize=%lu\n", (unsigned long)lsize);
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
memcpy(header.magic, CBD_MAGIC, sizeof(header.magic)); memcpy(header.magic, CBD_MAGIC, sizeof(header.magic));
header.version_major = CBD_VERSION_MAJOR; header.version_major = CBD_VERSION_MAJOR;
@ -66,12 +79,12 @@ cbd_format(const char* dev,
header.params.algorithm = CBD_ALG_LZ4; header.params.algorithm = CBD_ALG_LZ4;
header.params.compression = 1; header.params.compression = 1;
header.params.lblk_shift = lshift; header.params.lblk_shift = lshift;
header.params.nr_pblk = psize; header.params.nr_pblk = psize / PBLK_SIZE;
/* XXX: Initial estimate */ /* XXX: Initial estimate */
header.params.lblk_per_zone = zone_data_len(&header.params) * (lsize >> lshift) / psize; header.params.lblk_per_zone = zone_data_len(&header.params) * (lsize / lblk_size) / (psize / PBLK_SIZE);
printf(" initial estimate for lblk_per_zone: %lu\n", (unsigned long)header.params.lblk_per_zone); printf(" initial estimate for lblk_per_zone: %lu\n", (unsigned long)header.params.lblk_per_zone);
header.params.nr_zones = (psize - CBD_HEADER_BLOCKS) / zone_len(&header.params); header.params.nr_zones = ((psize >> PBLK_SHIFT) - CBD_HEADER_BLOCKS) / zone_len(&header.params);
header.params.lblk_per_zone = DIV_ROUND_UP((lsize >> lshift), header.params.nr_zones); header.params.lblk_per_zone = DIV_ROUND_UP(lsize / lblk_size, header.params.nr_zones);
printf("%s: parameters...\n", __func__); printf("%s: parameters...\n", __func__);
printf(" lblk_shift=%hu\n", (unsigned short)header.params.lblk_shift); printf(" lblk_shift=%hu\n", (unsigned short)header.params.lblk_shift);
printf(" nr_pblk=%lu\n", (unsigned long)header.params.nr_pblk); printf(" nr_pblk=%lu\n", (unsigned long)header.params.nr_pblk);
@ -81,7 +94,7 @@ cbd_format(const char* dev,
memset(pblkbuf, 0, sizeof(pblkbuf)); memset(pblkbuf, 0, sizeof(pblkbuf));
cbd_header_put(pblkbuf, &header); cbd_header_put(pblkbuf, &header);
pblk = poff; pblk = 0;
pblk_write(devfd, pblk, 1, pblkbuf); pblk_write(devfd, pblk, 1, pblkbuf);
pblk += CBD_HEADER_BLOCKS; pblk += CBD_HEADER_BLOCKS;

View File

@ -10,6 +10,7 @@ device_logical_size(const char* dev)
int fd; int fd;
uint8_t pblkbuf[PBLK_SIZE]; uint8_t pblkbuf[PBLK_SIZE];
struct cbd_header header; struct cbd_header header;
uint64_t lblk_size;
fd = open(dev, O_RDONLY); fd = open(dev, O_RDONLY);
if (fd < 0) { if (fd < 0) {
@ -18,18 +19,23 @@ device_logical_size(const char* dev)
if (read(fd, pblkbuf, sizeof(pblkbuf)) != sizeof(pblkbuf)) { if (read(fd, pblkbuf, sizeof(pblkbuf)) != sizeof(pblkbuf)) {
error("Cannot read device\n"); error("Cannot read device\n");
} }
cbd_header_get(pblkbuf, &header);
close(fd); close(fd);
cbd_header_get(pblkbuf, &header);
if (memcmp(header.magic, CBD_MAGIC, sizeof(header.magic)) != 0) {
error("Bad magic\n");
}
return (header.params.lblk_per_zone << header.params.lblk_shift) * header.params.nr_zones; lblk_size = header.params.lblk_per_zone * header.params.nr_zones;
return (lblk_size << (header.params.lblk_shift + PBLK_SHIFT));
} }
int int
cbd_open(const char* dev, cbd_open(const char* dev,
uint64_t loff, uint64_t lsize,
const char* name) const char* name)
{ {
int ret; int ret;
uint64_t lsize;
struct stat st; struct stat st;
struct dm_task* dmt; struct dm_task* dmt;
uint32_t cookie = 0; uint32_t cookie = 0;
@ -41,10 +47,7 @@ cbd_open(const char* dev,
if (!S_ISBLK(st.st_mode)) { if (!S_ISBLK(st.st_mode)) {
error("Not a block device\n"); error("Not a block device\n");
} }
lsize = device_logical_size(dev);
if (!lsize) {
lsize = device_logical_size(dev);
}
dmt = dm_task_create(DM_DEVICE_CREATE); dmt = dm_task_create(DM_DEVICE_CREATE);
if (!dmt) { if (!dmt) {
@ -54,12 +57,11 @@ cbd_open(const char* dev,
if (ret == 0) { if (ret == 0) {
error("dm_task_set_name failed\n"); error("dm_task_set_name failed\n");
} }
printf("%s: start_sector=%lu num_sectors=%lu\n", __func__, printf("%s: start_sector=0 num_sectors=%lu\n", __func__,
(unsigned long)(loff * PBLK_PER_SECTOR), (unsigned long)(lsize / SECTOR_SIZE));
(unsigned long)(lsize * PBLK_PER_SECTOR));
ret = dm_task_add_target(dmt, ret = dm_task_add_target(dmt,
loff * PBLK_PER_SECTOR, 0,
lsize * PBLK_PER_SECTOR, lsize / SECTOR_SIZE,
"compress", "compress",
dev); dev);
if (ret == 0) { if (ret == 0) {

View File

@ -4,7 +4,7 @@
int int
cbd_resize(const char* dev, cbd_resize(const char* dev,
uint64_t poff, uint64_t psize) uint64_t lsize)
{ {
error("Not implemented\n"); error("Not implemented\n");