Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1593861
| From | Kees Cook <keescook@chromium.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 12/18] pstore: Pass record contents instead of copying |
| Date | 2017-03-07 03:20 +0100 |
| Message-ID | <ticTf-u5-1@gated-at.bofh.it> (permalink) |
| References | <ti98Z-6eI-5@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
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>
---
fs/pstore/inode.c | 22 +++++++++++++++-------
fs/pstore/platform.c | 16 ++++++++++++----
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index a98787bab3e6..3d1f047e4f41 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -52,7 +52,7 @@ struct pstore_private {
u64 id;
int count;
ssize_t size;
- char data[];
+ char *buf;
};
struct pstore_ftrace_seq_data {
@@ -63,6 +63,14 @@ struct pstore_ftrace_seq_data {
#define REC_SIZE sizeof(struct pstore_ftrace_record)
+static void free_pstore_private(struct pstore_private *private)
+{
+ if (!private)
+ return;
+ kfree(private->buf);
+ kfree(private);
+}
+
static void *pstore_ftrace_seq_start(struct seq_file *s, loff_t *pos)
{
struct pstore_private *ps = s->private;
@@ -105,7 +113,7 @@ static int pstore_ftrace_seq_show(struct seq_file *s, void *v)
{
struct pstore_private *ps = s->private;
struct pstore_ftrace_seq_data *data = v;
- struct pstore_ftrace_record *rec = (void *)(ps->data + data->off);
+ struct pstore_ftrace_record *rec = (void *)(ps->buf + data->off);
seq_printf(s, "CPU:%d ts:%llu %08lx %08lx %pf <- %pF\n",
pstore_ftrace_decode_cpu(rec),
@@ -143,7 +151,7 @@ static ssize_t pstore_file_read(struct file *file, char __user *userbuf,
if (ps->type == PSTORE_TYPE_FTRACE)
return seq_read(file, userbuf, count, ppos);
- return simple_read_from_buffer(userbuf, count, ppos, ps->data, ps->size);
+ return simple_read_from_buffer(userbuf, count, ppos, ps->buf, ps->size);
}
static int pstore_file_open(struct inode *inode, struct file *file)
@@ -221,7 +229,7 @@ static void pstore_evict_inode(struct inode *inode)
spin_lock_irqsave(&allpstore_lock, flags);
list_del(&p->list);
spin_unlock_irqrestore(&allpstore_lock, flags);
- kfree(p);
+ free_pstore_private(p);
}
}
@@ -332,7 +340,7 @@ int pstore_mkfile(struct pstore_record *record)
goto fail;
inode->i_mode = S_IFREG | 0444;
inode->i_fop = &pstore_file_operations;
- private = kmalloc(sizeof *private + size, GFP_KERNEL);
+ private = kzalloc(sizeof(*private), GFP_KERNEL);
if (!private)
goto fail_alloc;
private->type = record->type;
@@ -394,7 +402,7 @@ int pstore_mkfile(struct pstore_record *record)
if (!dentry)
goto fail_lockedalloc;
- memcpy(private->data, record->buf, size);
+ private->buf = record->buf;
inode->i_size = private->size = size;
inode->i_private = private;
@@ -414,7 +422,7 @@ int pstore_mkfile(struct pstore_record *record)
fail_lockedalloc:
inode_unlock(d_inode(root));
- kfree(private);
+ free_pstore_private(private);
fail_alloc:
iput(inode);
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;
}
--
2.7.4
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 00/18] pstore: refactor internal APIs Kees Cook <keescook@chromium.org> - 2017-03-06 23:30 +0100
[PATCH 10/18] pstore: Replace arguments for write() API Kees Cook <keescook@chromium.org> - 2017-03-06 23:30 +0100
[PATCH 08/18] pstore: Switch pstore_mkfile to pass record Kees Cook <keescook@chromium.org> - 2017-03-06 23:30 +0100
[PATCH 04/18] pstore: Improve register_pstore() error reporting Kees Cook <keescook@chromium.org> - 2017-03-06 23:30 +0100
[PATCH 14/18] pstore: Do not duplicate record metadata Kees Cook <keescook@chromium.org> - 2017-03-07 00:00 +0100
[PATCH 16/18] pstore: Replace arguments for write_buf() API Kees Cook <keescook@chromium.org> - 2017-03-07 00:00 +0100
[PATCH 15/18] pstore: Replace arguments for erase() API Kees Cook <keescook@chromium.org> - 2017-03-07 00:00 +0100
[PATCH 01/18] pstore: Use dynamic spinlock initializer Kees Cook <keescook@chromium.org> - 2017-03-07 00:10 +0100
[PATCH 17/18] pstore: Replace arguments for write_buf_user() API Kees Cook <keescook@chromium.org> - 2017-03-07 02:00 +0100
[PATCH 06/18] pstore: Extract common arguments into structure Kees Cook <keescook@chromium.org> - 2017-03-07 03:00 +0100
Re: [PATCH 06/18] pstore: Extract common arguments into structure Namhyung Kim <namhyung@gmail.com> - 2017-03-07 17:30 +0100
Re: [PATCH 06/18] pstore: Extract common arguments into structure Kees Cook <keescook@chromium.org> - 2017-03-07 21:40 +0100
[PATCH 12/18] pstore: Pass record contents instead of copying Kees Cook <keescook@chromium.org> - 2017-03-07 03:20 +0100
[PATCH 09/18] pstore: Replace arguments for read() API Kees Cook <keescook@chromium.org> - 2017-03-07 05:40 +0100
csiph-web