aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/platform.c
diff options
context:
space:
mode:
authorAruna Balakrishnaiah <aruna@linux.vnet.ibm.com>2013-08-16 16:53:28 -0400
committerTony Luck <tony.luck@intel.com>2013-08-19 14:53:20 -0400
commitadb42f5e105502aff2fc4518b16ba79c203fae4f (patch)
treeb600e1292775e66dcbcc9f2d5a02ab4bf0a9372a /fs/pstore/platform.c
parent9a4e1398208d147a9240731a1f8cfe7d8cc4c553 (diff)
pstore: Add decompression support to pstore
Based on the flag 'compressed' set or not, pstore will decompress the data returning a plain text file. If decompression fails for a particular record it will have the compressed data in the file which can be decompressed with 'openssl' command line tool. Signed-off-by: Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r--fs/pstore/platform.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 6418eb77d64b..76bc5c12c0cf 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -162,6 +162,36 @@ error:
162 return ret; 162 return ret;
163} 163}
164 164
165/* Derived from logfs_uncompress */
166static int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen)
167{
168 int err, ret;
169
170 ret = -EIO;
171 err = zlib_inflateInit(&stream);
172 if (err != Z_OK)
173 goto error;
174
175 stream.next_in = in;
176 stream.avail_in = inlen;
177 stream.total_in = 0;
178 stream.next_out = out;
179 stream.avail_out = outlen;
180 stream.total_out = 0;
181
182 err = zlib_inflate(&stream, Z_FINISH);
183 if (err != Z_STREAM_END)
184 goto error;
185
186 err = zlib_inflateEnd(&stream);
187 if (err != Z_OK)
188 goto error;
189
190 ret = stream.total_out;
191error:
192 return ret;
193}
194
165static void allocate_buf_for_compression(void) 195static void allocate_buf_for_compression(void)
166{ 196{
167 size_t size; 197 size_t size;
@@ -429,6 +459,7 @@ void pstore_get_records(int quiet)
429 struct timespec time; 459 struct timespec time;
430 int failed = 0, rc; 460 int failed = 0, rc;
431 bool compressed; 461 bool compressed;
462 int unzipped_len = -1;
432 463
433 if (!psi) 464 if (!psi)
434 return; 465 return;
@@ -439,10 +470,28 @@ void pstore_get_records(int quiet)
439 470
440 while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed, 471 while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed,
441 psi)) > 0) { 472 psi)) > 0) {
473 if (compressed && (type == PSTORE_TYPE_DMESG)) {
474 if (big_oops_buf)
475 unzipped_len = pstore_decompress(buf,
476 big_oops_buf, size,
477 big_oops_buf_sz);
478
479 if (unzipped_len > 0) {
480 buf = big_oops_buf;
481 size = unzipped_len;
482 } else {
483 pr_err("pstore: decompression failed;"
484 "returned %d\n", unzipped_len);
485 }
486 }
442 rc = pstore_mkfile(type, psi->name, id, count, buf, 487 rc = pstore_mkfile(type, psi->name, id, count, buf,
443 (size_t)size, time, psi); 488 (size_t)size, time, psi);
444 kfree(buf); 489 if (unzipped_len < 0) {
445 buf = NULL; 490 /* Free buffer other than big oops */
491 kfree(buf);
492 buf = NULL;
493 } else
494 unzipped_len = -1;
446 if (rc && (rc != -EEXIST || !quiet)) 495 if (rc && (rc != -EEXIST || !quiet))
447 failed++; 496 failed++;
448 } 497 }