summaryrefslogtreecommitdiff
path: root/fs/pstore/platform.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-03-04 22:46:41 -0800
committerKees Cook <keescook@chromium.org>2017-03-07 14:00:58 -0800
commit1dfff7dd67d1a3be4d0ab4a5313f0363966bc70d (patch)
tree0de32506ec212d7a6a5b5d78f4e2b85d11bc5371 /fs/pstore/platform.c
parent7e8cc8dce17574e432945fa75882cd401c3ef673 (diff)
pstore: Pass record contents instead of copying
pstore_mkfile() shouldn't have to memcpy the record contents. It can use the existing copy instead. This adjusts the allocation lifetime management and renames the contents variable from "data" to "buf" to assist moving to struct pstore_record in the future. Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'fs/pstore/platform.c')
-rw-r--r--fs/pstore/platform.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index c0d401e732e6..d897e2f11b6a 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -828,14 +828,22 @@ void pstore_get_records(int quiet)
if (psi->open && psi->open(psi))
goto out;
+ /*
+ * Backend callback read() allocates record.buf. decompress_record()
+ * may reallocate record.buf. On success, pstore_mkfile() will keep
+ * the record.buf, so free it only on failure.
+ */
while ((record.size = psi->read(&record)) > 0) {
decompress_record(&record);
rc = pstore_mkfile(&record);
+ if (rc) {
+ /* pstore_mkfile() did not take buf, so free it. */
+ kfree(record.buf);
+ if (rc != -EEXIST || !quiet)
+ failed++;
+ }
- if (rc && (rc != -EEXIST || !quiet))
- failed++;
-
- kfree(record.buf);
+ /* Reset for next record. */
memset(&record, 0, sizeof(record));
record.psi = psi;
}