diff options
-rw-r--r-- | fs/pstore/platform.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 879658b4c679..c0d401e732e6 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -768,6 +768,7 @@ EXPORT_SYMBOL_GPL(pstore_unregister); | |||
768 | static void decompress_record(struct pstore_record *record) | 768 | static void decompress_record(struct pstore_record *record) |
769 | { | 769 | { |
770 | int unzipped_len; | 770 | int unzipped_len; |
771 | char *decompressed; | ||
771 | 772 | ||
772 | /* Only PSTORE_TYPE_DMESG support compression. */ | 773 | /* Only PSTORE_TYPE_DMESG support compression. */ |
773 | if (!record->compressed || record->type != PSTORE_TYPE_DMESG) { | 774 | if (!record->compressed || record->type != PSTORE_TYPE_DMESG) { |
@@ -783,17 +784,29 @@ static void decompress_record(struct pstore_record *record) | |||
783 | 784 | ||
784 | unzipped_len = pstore_decompress(record->buf, big_oops_buf, | 785 | unzipped_len = pstore_decompress(record->buf, big_oops_buf, |
785 | record->size, big_oops_buf_sz); | 786 | record->size, big_oops_buf_sz); |
786 | if (unzipped_len > 0) { | 787 | if (unzipped_len <= 0) { |
787 | if (record->ecc_notice_size) | ||
788 | memcpy(big_oops_buf + unzipped_len, | ||
789 | record->buf + record->size, | ||
790 | record->ecc_notice_size); | ||
791 | kfree(record->buf); | ||
792 | record->buf = big_oops_buf; | ||
793 | record->size = unzipped_len; | ||
794 | record->compressed = false; | ||
795 | } else | ||
796 | pr_err("decompression failed: %d\n", unzipped_len); | 788 | pr_err("decompression failed: %d\n", unzipped_len); |
789 | return; | ||
790 | } | ||
791 | |||
792 | /* Build new buffer for decompressed contents. */ | ||
793 | decompressed = kmalloc(unzipped_len + record->ecc_notice_size, | ||
794 | GFP_KERNEL); | ||
795 | if (!decompressed) { | ||
796 | pr_err("decompression ran out of memory\n"); | ||
797 | return; | ||
798 | } | ||
799 | memcpy(decompressed, big_oops_buf, unzipped_len); | ||
800 | |||
801 | /* Append ECC notice to decompressed buffer. */ | ||
802 | memcpy(decompressed + unzipped_len, record->buf + record->size, | ||
803 | record->ecc_notice_size); | ||
804 | |||
805 | /* Swap out compresed contents with decompressed contents. */ | ||
806 | kfree(record->buf); | ||
807 | record->buf = decompressed; | ||
808 | record->size = unzipped_len; | ||
809 | record->compressed = false; | ||
797 | } | 810 | } |
798 | 811 | ||
799 | /* | 812 | /* |
@@ -819,13 +832,10 @@ void pstore_get_records(int quiet) | |||
819 | decompress_record(&record); | 832 | decompress_record(&record); |
820 | rc = pstore_mkfile(&record); | 833 | rc = pstore_mkfile(&record); |
821 | 834 | ||
822 | /* Free buffer other than big oops */ | ||
823 | if (record.buf != big_oops_buf) | ||
824 | kfree(record.buf); | ||
825 | |||
826 | if (rc && (rc != -EEXIST || !quiet)) | 835 | if (rc && (rc != -EEXIST || !quiet)) |
827 | failed++; | 836 | failed++; |
828 | 837 | ||
838 | kfree(record.buf); | ||
829 | memset(&record, 0, sizeof(record)); | 839 | memset(&record, 0, sizeof(record)); |
830 | record.psi = psi; | 840 | record.psi = psi; |
831 | } | 841 | } |