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:
parent
141888fa98
commit
f37155f527
35
cbd/cbd.c
35
cbd/cbd.c
|
@ -85,6 +85,7 @@ usage(void)
|
|||
" format [opts] <device> Create (format) a compressed device\n"
|
||||
" -S --pysical-size Physical size [device 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"
|
||||
" -l --logical-shift Logical block shift [4]\n"
|
||||
" -s --size Logical size\n"
|
||||
|
@ -100,6 +101,7 @@ usage(void)
|
|||
" create [opts] <device> <name> Alias for open\n"
|
||||
" close [opts] <name> Close an opened 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"
|
||||
" -y --assume-yes Assume \"yes\" to all questions\n"
|
||||
" resize [opts] <device> Resize an existing compressed device\n"
|
||||
|
@ -112,10 +114,11 @@ usage(void)
|
|||
static int
|
||||
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[] = {
|
||||
{ "physical-size", required_argument, NULL, 'S' },
|
||||
{ "logical-blksize", required_argument, NULL, 'L' },
|
||||
{ "pbat-len", required_argument, NULL, 'P' },
|
||||
{ "compress-factor", required_argument, NULL, 'c' },
|
||||
{ "logical-shift", required_argument, NULL, 'l' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
|
@ -126,6 +129,7 @@ do_format(int argc, char** argv)
|
|||
char opt;
|
||||
uint64_t optval;
|
||||
uint64_t psize = 0;
|
||||
uint16_t pbatlen = 1;
|
||||
uint16_t lshift = 0;
|
||||
uint64_t lsize = 0;
|
||||
enum cbd_alg alg = CBD_ALG_LZ4;
|
||||
|
@ -150,6 +154,12 @@ do_format(int argc, char** argv)
|
|||
}
|
||||
lshift = (optval >> PBLK_SHIFT);
|
||||
break;
|
||||
case 'P':
|
||||
if (!parse_numeric_arg(optarg, &optval)) {
|
||||
error("Failed to parse \"%s\"\n", optarg);
|
||||
}
|
||||
pbatlen = optval;
|
||||
break;
|
||||
case 'c':
|
||||
error("Implement me!\n");
|
||||
break;
|
||||
|
@ -195,7 +205,7 @@ do_format(int argc, char** argv)
|
|||
}
|
||||
dev = argv[optind++];
|
||||
|
||||
cbd_format(dev, psize, lshift, lsize, alg, level);
|
||||
cbd_format(dev, psize, pbatlen, lshift, lsize, alg, level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -253,25 +263,23 @@ do_stats(int argc, char** argv)
|
|||
static int
|
||||
do_check(int argc, char** argv)
|
||||
{
|
||||
static const char short_opts[] = "ny";
|
||||
static const char short_opts[] = "fny";
|
||||
static const struct option long_opts[] = {
|
||||
{ "force", no_argument, NULL, 'f' },
|
||||
{ "assume-no", no_argument, NULL, 'n' },
|
||||
{ "assume-yes", no_argument, NULL, 'y' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
char opt;
|
||||
bool force = false;
|
||||
tristate_t auto_response = t_none;
|
||||
|
||||
const char* dev;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'y':
|
||||
if (auto_response == t_false) {
|
||||
fprintf(stderr, "Cannot specify both -y and -n\n");
|
||||
usage();
|
||||
}
|
||||
auto_response = t_true;
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
case 'n':
|
||||
if (auto_response == t_true) {
|
||||
|
@ -280,6 +288,13 @@ do_check(int argc, char** argv)
|
|||
}
|
||||
auto_response = t_false;
|
||||
break;
|
||||
case 'y':
|
||||
if (auto_response == t_false) {
|
||||
fprintf(stderr, "Cannot specify both -y and -n\n");
|
||||
usage();
|
||||
}
|
||||
auto_response = t_true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
@ -289,7 +304,7 @@ do_check(int argc, char** argv)
|
|||
}
|
||||
dev = argv[optind++];
|
||||
|
||||
cbd_check(dev, auto_response);
|
||||
cbd_check(dev, force, auto_response);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -162,6 +162,36 @@ out:
|
|||
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*
|
||||
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) {
|
||||
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) */
|
||||
if (c->params.nr_pblk > dev_nr_pblks) {
|
||||
|
@ -413,11 +455,19 @@ err:
|
|||
static void
|
||||
compress_dtr(struct dm_target *ti)
|
||||
{
|
||||
int ret;
|
||||
struct compress *c;
|
||||
|
||||
printk(KERN_INFO "%s: enter\n", __func__);
|
||||
|
||||
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);
|
||||
kfree(c->lc);
|
||||
if (c->io_workq) {
|
||||
|
|
|
@ -144,23 +144,19 @@ pblk_read_wait(struct block_device* bdev,
|
|||
}
|
||||
|
||||
int
|
||||
pblk_read(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv)
|
||||
pblk_write_wait(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev)
|
||||
{
|
||||
int ret;
|
||||
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) {
|
||||
printk(KERN_ERR "%s: out of memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
bio->bi_end_io = endio;
|
||||
bio->bi_private = endio_priv;
|
||||
|
||||
ret = submit_bio(bio);
|
||||
if (ret != 0) {
|
||||
ret = submit_bio_wait(bio);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret);
|
||||
}
|
||||
bio_put(bio);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/* Kernel compatibility */
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#ifndef BITS_PER_BYTE
|
||||
|
@ -60,6 +61,7 @@ int cbd_close(const char* name);
|
|||
int cbd_stats(const char* name);
|
||||
|
||||
int cbd_check(const char* dev,
|
||||
bool force,
|
||||
tristate_t auto_response);
|
||||
int cbd_resize(const char* dev,
|
||||
uint64_t lsize);
|
||||
|
|
|
@ -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_MINOR = 1;
|
||||
|
||||
#define CBD_FLAG_DIRTY 0x01
|
||||
|
||||
enum cbd_alg {
|
||||
CBD_ALG_NONE,
|
||||
CBD_ALG_LZ4,
|
||||
|
@ -37,6 +39,7 @@ enum cbd_alg {
|
|||
};
|
||||
|
||||
struct cbd_params {
|
||||
u16 flags;
|
||||
u8 algorithm; /* enum cbd_alg */
|
||||
u8 compression; /* 0..9 */
|
||||
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));
|
||||
header->version_major = get16_le(&buf);
|
||||
header->version_minor = get16_le(&buf);
|
||||
header->params.flags = get16_le(&buf);
|
||||
header->params.algorithm = get_byte(&buf);
|
||||
header->params.compression = get_byte(&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));
|
||||
put16_le(&buf, header->version_major);
|
||||
put16_le(&buf, header->version_minor);
|
||||
put16_le(&buf, header->params.flags);
|
||||
put_byte(&buf, header->params.algorithm);
|
||||
put_byte(&buf, header->params.compression);
|
||||
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 */
|
||||
int pblk_read_wait(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev);
|
||||
int pblk_read(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv);
|
||||
int pblk_write_wait(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev);
|
||||
void pblk_write(struct block_device* bdev,
|
||||
u64 pblk, u32 count, struct page** pagev);
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ check_zone_metadata(const struct cbd_params* params,
|
|||
|
||||
int
|
||||
cbd_check(const char* dev,
|
||||
bool force,
|
||||
tristate_t auto_response)
|
||||
{
|
||||
int devfd;
|
||||
|
@ -200,6 +201,11 @@ cbd_check(const char* dev,
|
|||
pblk_read(devfd, 0, 1, pblkbuf);
|
||||
cbd_header_get(pblkbuf, &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));
|
||||
for (zone = 0; zone < header.params.nr_zones; ++zone) {
|
||||
|
@ -223,5 +229,7 @@ cbd_check(const char* dev,
|
|||
}
|
||||
free(zmvec);
|
||||
|
||||
close(devfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ cbd_format(const char* dev,
|
|||
memcpy(header.magic, CBD_MAGIC, sizeof(header.magic));
|
||||
header.version_major = CBD_VERSION_MAJOR;
|
||||
header.version_minor = CBD_VERSION_MINOR;
|
||||
header.params.flags = 0;
|
||||
header.params.algorithm = alg;
|
||||
header.params.compression = level;
|
||||
header.params.pbat_len = pbatlen;
|
||||
|
|
Loading…
Reference in New Issue