Add flags to header

Initial flag definition includes dirty flag.

Also remove unused pblk_read().

Also add pbat-len arg to format.
This commit is contained in:
Tom Marshall 2019-11-04 06:14:37 -08:00
parent 141888fa98
commit f37155f527
7 changed files with 98 additions and 22 deletions

View File

@ -85,6 +85,7 @@ usage(void)
" 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"
" -L --logical-blksize Logical block size\n" " -L --logical-blksize Logical block size\n"
" -P --pbat-len Physical block allocation table length [1]\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"
" -s --size Logical size\n" " -s --size Logical size\n"
@ -100,6 +101,7 @@ usage(void)
" create [opts] <device> <name> Alias for open\n" " create [opts] <device> <name> Alias for open\n"
" close [opts] <name> Close an opened compressed device\n" " close [opts] <name> Close an opened compressed device\n"
" check [opts] <device> Check and repair a compressed device\n" " check [opts] <device> Check and repair a compressed device\n"
" -f --force Force check even if device seems clean\n"
" -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"
@ -112,10 +114,11 @@ usage(void)
static int static int
do_format(int argc, char** argv) do_format(int argc, char** argv)
{ {
static const char short_opts[] = "S:L:c:l:s:z:Z:"; static const char short_opts[] = "S:L:P:c:l:s:z:Z:";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "physical-size", required_argument, NULL, 'S' }, { "physical-size", required_argument, NULL, 'S' },
{ "logical-blksize", required_argument, NULL, 'L' }, { "logical-blksize", required_argument, NULL, 'L' },
{ "pbat-len", required_argument, NULL, 'P' },
{ "compress-factor", required_argument, NULL, 'c' }, { "compress-factor", required_argument, NULL, 'c' },
{ "logical-shift", required_argument, NULL, 'l' }, { "logical-shift", required_argument, NULL, 'l' },
{ "size", required_argument, NULL, 's' }, { "size", required_argument, NULL, 's' },
@ -126,6 +129,7 @@ do_format(int argc, char** argv)
char opt; char opt;
uint64_t optval; uint64_t optval;
uint64_t psize = 0; uint64_t psize = 0;
uint16_t pbatlen = 1;
uint16_t lshift = 0; uint16_t lshift = 0;
uint64_t lsize = 0; uint64_t lsize = 0;
enum cbd_alg alg = CBD_ALG_LZ4; enum cbd_alg alg = CBD_ALG_LZ4;
@ -150,6 +154,12 @@ do_format(int argc, char** argv)
} }
lshift = (optval >> PBLK_SHIFT); lshift = (optval >> PBLK_SHIFT);
break; break;
case 'P':
if (!parse_numeric_arg(optarg, &optval)) {
error("Failed to parse \"%s\"\n", optarg);
}
pbatlen = optval;
break;
case 'c': case 'c':
error("Implement me!\n"); error("Implement me!\n");
break; break;
@ -195,7 +205,7 @@ do_format(int argc, char** argv)
} }
dev = argv[optind++]; dev = argv[optind++];
cbd_format(dev, psize, lshift, lsize, alg, level); cbd_format(dev, psize, pbatlen, lshift, lsize, alg, level);
return 0; return 0;
} }
@ -253,25 +263,23 @@ do_stats(int argc, char** argv)
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[] = "fny";
static const struct option long_opts[] = { static const struct option long_opts[] = {
{ "force", no_argument, NULL, 'f' },
{ "assume-no", no_argument, NULL, 'n' }, { "assume-no", no_argument, NULL, 'n' },
{ "assume-yes", no_argument, NULL, 'y' }, { "assume-yes", no_argument, NULL, 'y' },
{ NULL, no_argument, NULL, 0 } { NULL, no_argument, NULL, 0 }
}; };
char opt; char opt;
bool force = false;
tristate_t auto_response = t_none; tristate_t auto_response = t_none;
const char* dev; const char* dev;
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 'y': case 'f':
if (auto_response == t_false) { force = true;
fprintf(stderr, "Cannot specify both -y and -n\n");
usage();
}
auto_response = t_true;
break; break;
case 'n': case 'n':
if (auto_response == t_true) { if (auto_response == t_true) {
@ -280,6 +288,13 @@ do_check(int argc, char** argv)
} }
auto_response = t_false; auto_response = t_false;
break; break;
case 'y':
if (auto_response == t_false) {
fprintf(stderr, "Cannot specify both -y and -n\n");
usage();
}
auto_response = t_true;
break;
default: default:
usage(); usage();
} }
@ -289,7 +304,7 @@ do_check(int argc, char** argv)
} }
dev = argv[optind++]; dev = argv[optind++];
cbd_check(dev, auto_response); cbd_check(dev, force, auto_response);
return 0; return 0;
} }

View File

@ -162,6 +162,36 @@ out:
return ret; return ret;
} }
static int
compress_write_header(struct compress* c)
{
int ret = 0;
struct page* pblkpage;
u8* pblkbuf;
struct cbd_header header;
struct page* iopagev[1];
pblkpage = cbd_alloc_page();
if (!pblkpage) {
return -ENOMEM;
}
pblkbuf = page_address(pblkpage);
memset(&header, 0, sizeof(header));
memcpy(header.magic, CBD_MAGIC, sizeof(header.magic));
header.version_major = CBD_VERSION_MAJOR;
header.version_minor = CBD_VERSION_MINOR;
memcpy(&header.params, &c->params, sizeof(header.params));
cbd_header_put(pblkbuf, &header);
iopagev[0] = pblkpage;
ret = pblk_write_wait(c->params.priv, 0, 1, iopagev);
if (ret) {
printk(KERN_ERR "%s: failed to write header\n", __func__);
}
cbd_free_page(pblkpage);
return ret;
}
static struct lbd* static struct lbd*
compress_lbdcache_swap(struct compress* c, u64 lblk, struct lbd* oldlbd) compress_lbdcache_swap(struct compress* c, u64 lblk, struct lbd* oldlbd)
{ {
@ -365,6 +395,18 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (ret) { if (ret) {
goto err; goto err;
} }
if (c->params.flags & CBD_FLAG_DIRTY) {
printk(KERN_INFO "Warning: device was not properly closed\n");
}
if (dm_table_get_mode(ti->table) & FMODE_WRITE) {
u16 save_flags = c->params.flags;
c->params.flags |= CBD_FLAG_DIRTY;
ret = compress_write_header(c);
c->params.flags = save_flags;
if (ret) {
goto err;
}
}
/* XXX: validate minumum pblk using zone_off(max_zone+1) */ /* XXX: validate minumum pblk using zone_off(max_zone+1) */
if (c->params.nr_pblk > dev_nr_pblks) { if (c->params.nr_pblk > dev_nr_pblks) {
@ -413,11 +455,19 @@ err:
static void static void
compress_dtr(struct dm_target *ti) compress_dtr(struct dm_target *ti)
{ {
int ret;
struct compress *c; struct compress *c;
printk(KERN_INFO "%s: enter\n", __func__); printk(KERN_INFO "%s: enter\n", __func__);
c = ti->private; c = ti->private;
if (dm_table_get_mode(ti->table) & FMODE_WRITE) {
ret = compress_write_header(c);
if (ret) {
printk(KERN_INFO "Warning: failed to write header\n");
}
}
lbdcache_dtr(c->lc); lbdcache_dtr(c->lc);
kfree(c->lc); kfree(c->lc);
if (c->io_workq) { if (c->io_workq) {

View File

@ -144,23 +144,19 @@ pblk_read_wait(struct block_device* bdev,
} }
int int
pblk_read(struct block_device* bdev, pblk_write_wait(struct block_device* bdev,
u64 pblk, u32 count, struct page** pagev, u64 pblk, u32 count, struct page** pagev)
pblk_endio_t endio, void* endio_priv)
{ {
int ret; int ret;
struct bio* bio; struct bio* bio;
bio = pblk_io_prepare(bdev, REQ_OP_READ, pblk, count, pagev); bio = pblk_io_prepare(bdev, REQ_OP_WRITE, pblk, count, pagev);
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;
} }
bio->bi_end_io = endio; ret = submit_bio_wait(bio);
bio->bi_private = endio_priv; if (ret) {
ret = submit_bio(bio);
if (ret != 0) {
printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret); printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret);
} }
bio_put(bio); bio_put(bio);

View File

@ -4,6 +4,7 @@
/* Kernel compatibility */ /* Kernel compatibility */
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifndef BITS_PER_BYTE #ifndef BITS_PER_BYTE
@ -60,6 +61,7 @@ int cbd_close(const char* name);
int cbd_stats(const char* name); int cbd_stats(const char* name);
int cbd_check(const char* dev, int cbd_check(const char* dev,
bool force,
tristate_t auto_response); tristate_t auto_response);
int cbd_resize(const char* dev, int cbd_resize(const char* dev,
uint64_t lsize); uint64_t lsize);

View File

@ -28,6 +28,8 @@ static const u8 CBD_MAGIC[] = { 'C', 'B', 'D', '\0' };
static const u16 CBD_VERSION_MAJOR = 1; static const u16 CBD_VERSION_MAJOR = 1;
static const u16 CBD_VERSION_MINOR = 1; static const u16 CBD_VERSION_MINOR = 1;
#define CBD_FLAG_DIRTY 0x01
enum cbd_alg { enum cbd_alg {
CBD_ALG_NONE, CBD_ALG_NONE,
CBD_ALG_LZ4, CBD_ALG_LZ4,
@ -37,6 +39,7 @@ enum cbd_alg {
}; };
struct cbd_params { struct cbd_params {
u16 flags;
u8 algorithm; /* enum cbd_alg */ u8 algorithm; /* enum cbd_alg */
u8 compression; /* 0..9 */ u8 compression; /* 0..9 */
u16 pbat_len; u16 pbat_len;
@ -295,6 +298,7 @@ cbd_header_get(const u8* buf, struct cbd_header* header)
get_mem(&buf, header->magic, sizeof(header->magic)); get_mem(&buf, header->magic, sizeof(header->magic));
header->version_major = get16_le(&buf); header->version_major = get16_le(&buf);
header->version_minor = get16_le(&buf); header->version_minor = get16_le(&buf);
header->params.flags = get16_le(&buf);
header->params.algorithm = get_byte(&buf); header->params.algorithm = get_byte(&buf);
header->params.compression = get_byte(&buf); header->params.compression = get_byte(&buf);
header->params.pbat_len = get16_le(&buf); header->params.pbat_len = get16_le(&buf);
@ -310,6 +314,7 @@ cbd_header_put(u8* buf, const struct cbd_header* header)
put_mem(&buf, header->magic, sizeof(header->magic)); put_mem(&buf, header->magic, sizeof(header->magic));
put16_le(&buf, header->version_major); put16_le(&buf, header->version_major);
put16_le(&buf, header->version_minor); put16_le(&buf, header->version_minor);
put16_le(&buf, header->params.flags);
put_byte(&buf, header->params.algorithm); put_byte(&buf, header->params.algorithm);
put_byte(&buf, header->params.compression); put_byte(&buf, header->params.compression);
put16_le(&buf, header->params.pbat_len); put16_le(&buf, header->params.pbat_len);
@ -471,9 +476,8 @@ void cbd_free_pagev(struct page** pagev, size_t len);
/* Core low-level I/O */ /* Core low-level I/O */
int pblk_read_wait(struct block_device* bdev, int pblk_read_wait(struct block_device* bdev,
u64 pblk, u32 count, struct page** pagev); u64 pblk, u32 count, struct page** pagev);
int pblk_read(struct block_device* bdev, int pblk_write_wait(struct block_device* bdev,
u64 pblk, u32 count, struct page** pagev, u64 pblk, u32 count, struct page** pagev);
pblk_endio_t endio, void* endio_priv);
void pblk_write(struct block_device* bdev, void pblk_write(struct block_device* bdev,
u64 pblk, u32 count, struct page** pagev); u64 pblk, u32 count, struct page** pagev);

View File

@ -184,6 +184,7 @@ check_zone_metadata(const struct cbd_params* params,
int int
cbd_check(const char* dev, cbd_check(const char* dev,
bool force,
tristate_t auto_response) tristate_t auto_response)
{ {
int devfd; int devfd;
@ -200,6 +201,11 @@ cbd_check(const char* dev,
pblk_read(devfd, 0, 1, pblkbuf); pblk_read(devfd, 0, 1, pblkbuf);
cbd_header_get(pblkbuf, &header); cbd_header_get(pblkbuf, &header);
check_header(&header); check_header(&header);
if (!force && !(header.params.flags & CBD_FLAG_DIRTY)) {
printf("%s: clean\n", dev);
close(devfd);
return 0;
}
zmvec = calloc(header.params.nr_zones, sizeof(struct zone_metadata)); zmvec = calloc(header.params.nr_zones, sizeof(struct zone_metadata));
for (zone = 0; zone < header.params.nr_zones; ++zone) { for (zone = 0; zone < header.params.nr_zones; ++zone) {
@ -223,5 +229,7 @@ cbd_check(const char* dev,
} }
free(zmvec); free(zmvec);
close(devfd);
return 0; return 0;
} }

View File

@ -88,6 +88,7 @@ cbd_format(const char* dev,
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;
header.version_minor = CBD_VERSION_MINOR; header.version_minor = CBD_VERSION_MINOR;
header.params.flags = 0;
header.params.algorithm = alg; header.params.algorithm = alg;
header.params.compression = level; header.params.compression = level;
header.params.pbat_len = pbatlen; header.params.pbat_len = pbatlen;