diff options
author | Seiji Aguchi <seiji.aguchi@hds.com> | 2012-11-26 19:07:44 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2012-11-26 19:07:44 -0500 |
commit | 755d4fe46529018ae45bc7c86df682de45ace764 (patch) | |
tree | 470788ad3e9fa704ef41fa62ac9e770193010853 /fs/pstore | |
parent | a9efd39cd547223597cfe7c53acec44c099b9264 (diff) |
efi_pstore: Add a sequence counter to a variable name
[Issue]
Currently, a variable name, which identifies each entry, consists of type, id and ctime.
But if multiple events happens in a short time, a second/third event may fail to log because
efi_pstore can't distinguish each event with current variable name.
[Solution]
A reasonable way to identify all events precisely is introducing a sequence counter to
the variable name.
The sequence counter has already supported in a pstore layer with "oopscount".
So, this patch adds it to a variable name.
Also, it is passed to read/erase callbacks of platform drivers in accordance with
the modification of the variable name.
<before applying this patch>
a variable name of first event: dump-type0-1-12345678
a variable name of second event: dump-type0-1-12345678
type:0
id:1
ctime:12345678
If multiple events happen in a short time, efi_pstore can't distinguish them because
variable names are same among them.
<after applying this patch>
it can be distinguishable by adding a sequence counter as follows.
a variable name of first event: dump-type0-1-1-12345678
a variable name of Second event: dump-type0-1-2-12345678
type:0
id:1
sequence counter: 1(first event), 2(second event)
ctime:12345678
In case of a write callback executed in pstore_console_write(), "0" is added to
an argument of the write callback because it just logs all kernel messages and
doesn't need to care about multiple events.
Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Mike Waychison <mikew@google.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'fs/pstore')
-rw-r--r-- | fs/pstore/inode.c | 8 | ||||
-rw-r--r-- | fs/pstore/internal.h | 2 | ||||
-rw-r--r-- | fs/pstore/platform.c | 13 | ||||
-rw-r--r-- | fs/pstore/ram.c | 7 |
4 files changed, 16 insertions, 14 deletions
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 4300af654710..ed1d8c7212da 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
@@ -49,6 +49,7 @@ struct pstore_private { | |||
49 | struct pstore_info *psi; | 49 | struct pstore_info *psi; |
50 | enum pstore_type_id type; | 50 | enum pstore_type_id type; |
51 | u64 id; | 51 | u64 id; |
52 | int count; | ||
52 | ssize_t size; | 53 | ssize_t size; |
53 | char data[]; | 54 | char data[]; |
54 | }; | 55 | }; |
@@ -175,8 +176,8 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) | |||
175 | struct pstore_private *p = dentry->d_inode->i_private; | 176 | struct pstore_private *p = dentry->d_inode->i_private; |
176 | 177 | ||
177 | if (p->psi->erase) | 178 | if (p->psi->erase) |
178 | p->psi->erase(p->type, p->id, dentry->d_inode->i_ctime, | 179 | p->psi->erase(p->type, p->id, p->count, |
179 | p->psi); | 180 | dentry->d_inode->i_ctime, p->psi); |
180 | 181 | ||
181 | return simple_unlink(dir, dentry); | 182 | return simple_unlink(dir, dentry); |
182 | } | 183 | } |
@@ -271,7 +272,7 @@ int pstore_is_mounted(void) | |||
271 | * Load it up with "size" bytes of data from "buf". | 272 | * Load it up with "size" bytes of data from "buf". |
272 | * Set the mtime & ctime to the date that this record was originally stored. | 273 | * Set the mtime & ctime to the date that this record was originally stored. |
273 | */ | 274 | */ |
274 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, | 275 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, |
275 | char *data, size_t size, struct timespec time, | 276 | char *data, size_t size, struct timespec time, |
276 | struct pstore_info *psi) | 277 | struct pstore_info *psi) |
277 | { | 278 | { |
@@ -307,6 +308,7 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, | |||
307 | goto fail_alloc; | 308 | goto fail_alloc; |
308 | private->type = type; | 309 | private->type = type; |
309 | private->id = id; | 310 | private->id = id; |
311 | private->count = count; | ||
310 | private->psi = psi; | 312 | private->psi = psi; |
311 | 313 | ||
312 | switch (type) { | 314 | switch (type) { |
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index 4847f588b7d5..937d820f273c 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h | |||
@@ -50,7 +50,7 @@ extern struct pstore_info *psinfo; | |||
50 | extern void pstore_set_kmsg_bytes(int); | 50 | extern void pstore_set_kmsg_bytes(int); |
51 | extern void pstore_get_records(int); | 51 | extern void pstore_get_records(int); |
52 | extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, | 52 | extern int pstore_mkfile(enum pstore_type_id, char *psname, u64 id, |
53 | char *data, size_t size, | 53 | int count, char *data, size_t size, |
54 | struct timespec time, struct pstore_info *psi); | 54 | struct timespec time, struct pstore_info *psi); |
55 | extern int pstore_is_mounted(void); | 55 | extern int pstore_is_mounted(void); |
56 | 56 | ||
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 947fbe06c3b1..5ea2e77ff023 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -136,7 +136,7 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
136 | break; | 136 | break; |
137 | 137 | ||
138 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, | 138 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, |
139 | hsize + len, psinfo); | 139 | oopscount, hsize + len, psinfo); |
140 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) | 140 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) |
141 | pstore_new_entry = 1; | 141 | pstore_new_entry = 1; |
142 | 142 | ||
@@ -173,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) | |||
173 | spin_lock_irqsave(&psinfo->buf_lock, flags); | 173 | spin_lock_irqsave(&psinfo->buf_lock, flags); |
174 | } | 174 | } |
175 | memcpy(psinfo->buf, s, c); | 175 | memcpy(psinfo->buf, s, c); |
176 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); | 176 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, c, psinfo); |
177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); | 177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
178 | s += c; | 178 | s += c; |
179 | c = e - s; | 179 | c = e - s; |
@@ -197,7 +197,7 @@ static void pstore_register_console(void) {} | |||
197 | 197 | ||
198 | static int pstore_write_compat(enum pstore_type_id type, | 198 | static int pstore_write_compat(enum pstore_type_id type, |
199 | enum kmsg_dump_reason reason, | 199 | enum kmsg_dump_reason reason, |
200 | u64 *id, unsigned int part, | 200 | u64 *id, unsigned int part, int count, |
201 | size_t size, struct pstore_info *psi) | 201 | size_t size, struct pstore_info *psi) |
202 | { | 202 | { |
203 | return psi->write_buf(type, reason, id, part, psinfo->buf, size, psi); | 203 | return psi->write_buf(type, reason, id, part, psinfo->buf, size, psi); |
@@ -267,6 +267,7 @@ void pstore_get_records(int quiet) | |||
267 | char *buf = NULL; | 267 | char *buf = NULL; |
268 | ssize_t size; | 268 | ssize_t size; |
269 | u64 id; | 269 | u64 id; |
270 | int count; | ||
270 | enum pstore_type_id type; | 271 | enum pstore_type_id type; |
271 | struct timespec time; | 272 | struct timespec time; |
272 | int failed = 0, rc; | 273 | int failed = 0, rc; |
@@ -278,9 +279,9 @@ void pstore_get_records(int quiet) | |||
278 | if (psi->open && psi->open(psi)) | 279 | if (psi->open && psi->open(psi)) |
279 | goto out; | 280 | goto out; |
280 | 281 | ||
281 | while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) { | 282 | while ((size = psi->read(&id, &type, &count, &time, &buf, psi)) > 0) { |
282 | rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size, | 283 | rc = pstore_mkfile(type, psi->name, id, count, buf, |
283 | time, psi); | 284 | (size_t)size, time, psi); |
284 | kfree(buf); | 285 | kfree(buf); |
285 | buf = NULL; | 286 | buf = NULL; |
286 | if (rc && (rc != -EEXIST || !quiet)) | 287 | if (rc && (rc != -EEXIST || !quiet)) |
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 749693fcb75a..2bfa36e0ffe8 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -132,9 +132,8 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, | |||
132 | } | 132 | } |
133 | 133 | ||
134 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | 134 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, |
135 | struct timespec *time, | 135 | int *count, struct timespec *time, |
136 | char **buf, | 136 | char **buf, struct pstore_info *psi) |
137 | struct pstore_info *psi) | ||
138 | { | 137 | { |
139 | ssize_t size; | 138 | ssize_t size; |
140 | struct ramoops_context *cxt = psi->data; | 139 | struct ramoops_context *cxt = psi->data; |
@@ -236,7 +235,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
236 | return 0; | 235 | return 0; |
237 | } | 236 | } |
238 | 237 | ||
239 | static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, | 238 | static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count, |
240 | struct timespec time, struct pstore_info *psi) | 239 | struct timespec time, struct pstore_info *psi) |
241 | { | 240 | { |
242 | struct ramoops_context *cxt = psi->data; | 241 | struct ramoops_context *cxt = psi->data; |