Make detect zeros a runtime flag
This commit is contained in:
parent
9f9722bb26
commit
8b08b0c2c1
43
cbd/cbd.c
43
cbd/cbd.c
|
@ -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);
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue