From f53fb186b8909d9873726fa82f7ccaa6b204e686 Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Sun, 17 Nov 2019 08:24:11 -0800 Subject: [PATCH] Make detect zeros a runtime flag --- cbd/cbd.c | 14 ++++++++++---- dm-compress/compress.c | 4 ---- dm-compress/lbd.c | 11 +++++------ include/libcbd.h | 1 + include/linux/dm-compress.h | 5 +++-- libcbd/format.c | 9 ++++++++- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/cbd/cbd.c b/cbd/cbd.c index 6d18c68..9e1cd9c 100644 --- a/cbd/cbd.c +++ b/cbd/cbd.c @@ -139,6 +139,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 +181,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", no_argument, NULL, 0x1 }, + { "profile", required_argument, NULL, 0x2 }, + { "full-init", no_argument, NULL, 0x3 }, { NULL, no_argument, NULL, 0 } }; char opt; @@ -191,6 +193,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 +270,14 @@ do_format(int argc, char** argv) level = optval; break; case 0x1: + 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 +301,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); diff --git a/dm-compress/compress.c b/dm-compress/compress.c index d28c9f1..52b1812 100644 --- a/dm-compress/compress.c +++ b/dm-compress/compress.c @@ -30,10 +30,6 @@ #include -// 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? diff --git a/dm-compress/lbd.c b/dm-compress/lbd.c index cce4ef7..333a250 100644 --- a/dm-compress/lbd.c +++ b/dm-compress/lbd.c @@ -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 { diff --git a/include/libcbd.h b/include/libcbd.h index 4cf1657..2716042 100644 --- a/include/libcbd.h +++ b/include/libcbd.h @@ -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, diff --git a/include/linux/dm-compress.h b/include/linux/dm-compress.h index 0d52f72..e103f21 100644 --- a/include/linux/dm-compress.h +++ b/include/linux/dm-compress.h @@ -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, diff --git a/libcbd/format.c b/libcbd/format.c index 1446ad6..af47232 100644 --- a/libcbd/format.c +++ b/libcbd/format.c @@ -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);