Compare commits

...

1 Commits

Author SHA1 Message Date
Tom Marshall 8b08b0c2c1 Make detect zeros a runtime flag 2019-11-17 10:09:58 -08:00
6 changed files with 56 additions and 17 deletions

View File

@ -70,6 +70,27 @@ parse_numeric_arg(const char* arg, uint64_t* val)
return true;
}
static bool
parse_boolean_arg(const char* arg, uint64_t* val)
{
if (!strcmp(arg, "1") ||
!strcasecmp(arg, "true") ||
!strcasecmp(arg, "on") ||
!strcasecmp(arg, "yes")) {
*val = 1;
return true;
}
else if (!strcmp(arg, "0") ||
!strcasecmp(arg, "false") ||
!strcasecmp(arg, "off") ||
!strcasecmp(arg, "no")) {
*val = 0;
return true;
}
return false;
}
struct profile {
const char* name;
uint pblksize;
@ -139,6 +160,7 @@ usage(void)
" -s --size Logical size\n"
" -z --compress-alg Compression algorithm [lz4]\n"
" -Z --compress-level Compression level [1]\n"
" --detect-zeros Detect and free zero blocks at runtime\n"
" --profile Set -p -l -z -Z automatically\n"
" --full-init Fully init device (no lazy init)\n"
" Note:\n"
@ -180,8 +202,9 @@ do_format(int argc, char** argv)
{ "size", required_argument, NULL, 's' },
{ "compress-alg", required_argument, NULL, 'z' },
{ "compress-level", required_argument, NULL, 'Z' },
{ "profile", required_argument, NULL, 0x1 },
{ "full-init", no_argument, NULL, 0x2 },
{ "detect-zeros", optional_argument, NULL, 0x1 },
{ "profile", required_argument, NULL, 0x2 },
{ "full-init", no_argument, NULL, 0x3 },
{ NULL, no_argument, NULL, 0 }
};
char opt;
@ -191,6 +214,7 @@ do_format(int argc, char** argv)
uint pblksize = PAGE_SIZE;
uint lblksize = 16 * PAGE_SIZE;
uint pbatsize = 1;
uint16_t flags = 0;
enum cbd_alg alg = CBD_ALG_LZ4;
uint level = 1;
bool full_init = false;
@ -267,11 +291,22 @@ do_format(int argc, char** argv)
level = optval;
break;
case 0x1:
optval = 1;
if (optarg) {
if (!parse_boolean_arg(optarg, &optval)) {
error("Failed to parse \"%s\"\n", optarg);
}
}
if (optval) {
flags |= CBD_FLAG_DETECT_ZEROS;
}
break;
case 0x2:
if (!parse_profile(optarg, &pblksize, &lblksize, &alg, &level)) {
error("Invalid profile \"%s\"\n", optarg);
}
break;
case 0x2:
case 0x3:
full_init = true;
break;
default:
@ -295,7 +330,7 @@ do_format(int argc, char** argv)
}
dev = argv[optind++];
cbd_format(dev, alg, level,
cbd_format(dev, flags, alg, level,
pshift, lshift, pbatshift, psize, lsize,
full_init);

View File

@ -30,10 +30,6 @@
#include <linux/dm-compress.h>
// XXX: find a better name for this, something about storage vs. speed.
// XXX: should this be in cbd_params?
// #define CBD_DETECT_ZERO_BLOCKS
/*
* XXX
* If we don't use a workqueue, pblk_read() stalls. Why?

View File

@ -52,20 +52,19 @@ struct lbd {
static inline bool
lblk_is_zeros(struct cbd_params* params, struct lbd* lbd)
{
#ifdef CBD_DETECT_ZERO_BLOCKS
u32 off;
u32 len = PBLK_SIZE * lblk_per_pblk(params);
u32 len = lblk_per_pblk(params) * pblk_size(params);
if (!(params->flags & CBD_FLAG_DETECT_ZEROS)) {
return false;
}
for (off = 0; off < len; ++off) {
if (lbd->lblk_buf[off]) {
if (lbd->buf[off]) {
return false;
}
}
return true;
#else
return false;
#endif
}
struct lblk_compress_state {

View File

@ -66,6 +66,7 @@ typedef enum {
} tristate_t;
int cbd_format(const char* dev,
uint16_t flags,
enum cbd_alg alg, uint level,
uint8_t pshift, uint8_t lshift,
uint8_t pbatshift,

View File

@ -20,8 +20,9 @@ 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
#define CBD_FLAG_ERROR 0x02
#define CBD_FLAG_DIRTY 0x0001
#define CBD_FLAG_ERROR 0x0002
#define CBD_FLAG_DETECT_ZEROS 0x0100
enum cbd_alg {
CBD_ALG_NONE,

View File

@ -25,8 +25,12 @@ pblk_write(int fd, u32 pblk_size, u64 pblk, u32 count, const u8* data)
}
}
#define FORMAT_FLAGS_MASK \
(CBD_FLAG_DETECT_ZEROS)
int
cbd_format(const char* dev,
uint16_t flags,
enum cbd_alg alg, uint level,
uint8_t pshift, uint8_t lshift,
uint8_t pbatshift,
@ -45,6 +49,9 @@ cbd_format(const char* dev,
error("Cannot open device\n");
}
if (flags != (flags & FORMAT_FLAGS_MASK)) {
error("Bad flags 0x%04x\n", (unsigned int)flags);
}
if (alg <= CBD_ALG_NONE || alg >= CBD_ALG_MAX) {
error("Compression algorithm %d unknown\n", (int)alg);
}
@ -102,7 +109,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.flags = flags;
header.params.compression = 0;
cbd_compression_alg_put(&header.params, alg);
cbd_compression_level_put(&header.params, level);