diff options
| -rw-r--r-- | fs/pstore/platform.c | 53 |
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 */ | ||
| 166 | static 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; | ||
| 191 | error: | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 165 | static void allocate_buf_for_compression(void) | 195 | static 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 | } |
