Skip to content

Commit

Permalink
pstore: add lzo/lz4 compression support
Browse files Browse the repository at this point in the history
Like zlib compression in pstore, this patch added lzo and lz4
compression support so that users can have more options and better
compression ratio.

The original code treats the compressed data together with the
uncompressed ECC correction notice by using zlib decompress. The
ECC correction notice is missing in the decompression process. The
treatment also makes lzo and lz4 not working. So I treat them
separately by using pstore_decompress() to treat the compressed
data, and memcpy() to treat the uncompressed ECC correction notice.

Signed-off-by: Geliang Tang <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
  • Loading branch information
geliangtang authored and kees committed Jun 2, 2016
1 parent 235f6d1 commit 8cfc8dd
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 18 deletions.
4 changes: 3 additions & 1 deletion arch/powerpc/kernel/nvram_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ static int nvram_pstore_write(enum pstore_type_id type,
*/
static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time, char **buf,
bool *compressed, struct pstore_info *psi)
bool *compressed, ssize_t *ecc_notice_size,
struct pstore_info *psi)
{
struct oops_log_info *oops_hdr;
unsigned int err_type, id_no, size = 0;
Expand Down Expand Up @@ -545,6 +546,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
return -ENOMEM;
kfree(buff);

*ecc_notice_size = 0;
if (err_type == ERR_TYPE_KERNEL_PANIC_GZ)
*compressed = true;
else
Expand Down
7 changes: 5 additions & 2 deletions drivers/acpi/apei/erst.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,8 @@ static int erst_open_pstore(struct pstore_info *psi);
static int erst_close_pstore(struct pstore_info *psi);
static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
struct timespec *time, char **buf,
bool *compressed, struct pstore_info *psi);
bool *compressed, ssize_t *ecc_notice_size,
struct pstore_info *psi);
static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
u64 *id, unsigned int part, int count, bool compressed,
size_t size, struct pstore_info *psi);
Expand Down Expand Up @@ -987,7 +988,8 @@ static int erst_close_pstore(struct pstore_info *psi)

static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
struct timespec *time, char **buf,
bool *compressed, struct pstore_info *psi)
bool *compressed, ssize_t *ecc_notice_size,
struct pstore_info *psi)
{
int rc;
ssize_t len = 0;
Expand Down Expand Up @@ -1033,6 +1035,7 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
memcpy(*buf, rcd->data, len - sizeof(*rcd));
*id = record_id;
*compressed = false;
*ecc_notice_size = 0;
if (uuid_le_cmp(rcd->sec_hdr.section_type,
CPER_SECTION_TYPE_DMESG_Z) == 0) {
*type = PSTORE_TYPE_DMESG;
Expand Down
6 changes: 6 additions & 0 deletions drivers/firmware/efi/efi-pstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct pstore_read_data {
int *count;
struct timespec *timespec;
bool *compressed;
ssize_t *ecc_notice_size;
char **buf;
};

Expand Down Expand Up @@ -69,13 +70,15 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
*cb_data->compressed = true;
else
*cb_data->compressed = false;
*cb_data->ecc_notice_size = 0;
} else if (sscanf(name, "dump-type%u-%u-%d-%lu",
cb_data->type, &part, &cnt, &time) == 4) {
*cb_data->id = generic_id(time, part, cnt);
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
*cb_data->compressed = false;
*cb_data->ecc_notice_size = 0;
} else if (sscanf(name, "dump-type%u-%u-%lu",
cb_data->type, &part, &time) == 3) {
/*
Expand All @@ -88,6 +91,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
*cb_data->compressed = false;
*cb_data->ecc_notice_size = 0;
} else
return 0;

Expand Down Expand Up @@ -210,6 +214,7 @@ static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
char **buf, bool *compressed,
ssize_t *ecc_notice_size,
struct pstore_info *psi)
{
struct pstore_read_data data;
Expand All @@ -220,6 +225,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
data.count = count;
data.timespec = timespec;
data.compressed = compressed;
data.ecc_notice_size = ecc_notice_size;
data.buf = buf;

*data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
Expand Down
31 changes: 29 additions & 2 deletions fs/pstore/Kconfig
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
config PSTORE
tristate "Persistent store support"
default n
select ZLIB_DEFLATE
select ZLIB_INFLATE
help
This option enables generic access to platform level
persistent storage via "pstore" filesystem that can
Expand All @@ -14,6 +12,35 @@ config PSTORE
If you don't have a platform persistent store driver,
say N.

choice
prompt "Choose compression algorithm"
depends on PSTORE
default PSTORE_ZLIB_COMPRESS
help
This option chooses compression algorithm.

config PSTORE_ZLIB_COMPRESS
bool "ZLIB"
select ZLIB_DEFLATE
select ZLIB_INFLATE
help
This option enables ZLIB compression algorithm support.

config PSTORE_LZO_COMPRESS
bool "LZO"
select LZO_COMPRESS
select LZO_DECOMPRESS
help
This option enables LZO compression algorithm support.

config PSTORE_LZ4_COMPRESS
bool "LZ4"
select LZ4_COMPRESS
select LZ4_DECOMPRESS
help
This option enables LZ4 compression algorithm support.
endchoice

config PSTORE_CONSOLE
bool "Log kernel console messages"
depends on PSTORE
Expand Down
Loading

0 comments on commit 8cfc8dd

Please sign in to comment.