aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-06-15 08:07:51 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-15 17:53:59 -0400
commite2ae715d66bf4becfb85eb84b7150e23cf27df30 (patch)
tree206f08bc1f5138d1416c040f78c5b527ca07536d /fs/pstore
parent1bd289d1e8e29c09be0e783a53f16a1dc80684be (diff)
kmsg - kmsg_dump() use iterator to receive log buffer content
Provide an iterator to receive the log buffer content, and convert all kmsg_dump() users to it. The structured data in the kmsg buffer now contains binary data, which should no longer be copied verbatim to the kmsg_dump() users. The iterator should provide reliable access to the buffer data, and also supports proper log line-aware chunking of data while iterating. Signed-off-by: Kay Sievers <kay@vrfy.org> Tested-by: Tony Luck <tony.luck@intel.com> Reported-by: Anton Vorontsov <anton.vorontsov@linaro.org> Tested-by: Anton Vorontsov <anton.vorontsov@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore')
-rw-r--r--fs/pstore/platform.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 82c585f715e..03ce7a9b81c 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -94,20 +94,15 @@ static const char *get_reason_str(enum kmsg_dump_reason reason)
94 * as we can from the end of the buffer. 94 * as we can from the end of the buffer.
95 */ 95 */
96static void pstore_dump(struct kmsg_dumper *dumper, 96static void pstore_dump(struct kmsg_dumper *dumper,
97 enum kmsg_dump_reason reason, 97 enum kmsg_dump_reason reason)
98 const char *s1, unsigned long l1,
99 const char *s2, unsigned long l2)
100{ 98{
101 unsigned long s1_start, s2_start; 99 unsigned long total = 0;
102 unsigned long l1_cpy, l2_cpy;
103 unsigned long size, total = 0;
104 char *dst;
105 const char *why; 100 const char *why;
106 u64 id; 101 u64 id;
107 int hsize, ret;
108 unsigned int part = 1; 102 unsigned int part = 1;
109 unsigned long flags = 0; 103 unsigned long flags = 0;
110 int is_locked = 0; 104 int is_locked = 0;
105 int ret;
111 106
112 why = get_reason_str(reason); 107 why = get_reason_str(reason);
113 108
@@ -119,30 +114,25 @@ static void pstore_dump(struct kmsg_dumper *dumper,
119 spin_lock_irqsave(&psinfo->buf_lock, flags); 114 spin_lock_irqsave(&psinfo->buf_lock, flags);
120 oopscount++; 115 oopscount++;
121 while (total < kmsg_bytes) { 116 while (total < kmsg_bytes) {
117 char *dst;
118 unsigned long size;
119 int hsize;
120 size_t len;
121
122 dst = psinfo->buf; 122 dst = psinfo->buf;
123 hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part); 123 hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part);
124 size = psinfo->bufsize - hsize; 124 size = psinfo->bufsize - hsize;
125 dst += hsize; 125 dst += hsize;
126 126
127 l2_cpy = min(l2, size); 127 if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len))
128 l1_cpy = min(l1, size - l2_cpy);
129
130 if (l1_cpy + l2_cpy == 0)
131 break; 128 break;
132 129
133 s2_start = l2 - l2_cpy;
134 s1_start = l1 - l1_cpy;
135
136 memcpy(dst, s1 + s1_start, l1_cpy);
137 memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy);
138
139 ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, 130 ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part,
140 hsize + l1_cpy + l2_cpy, psinfo); 131 hsize + len, psinfo);
141 if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) 132 if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted())
142 pstore_new_entry = 1; 133 pstore_new_entry = 1;
143 l1 -= l1_cpy; 134
144 l2 -= l2_cpy; 135 total += hsize + len;
145 total += l1_cpy + l2_cpy;
146 part++; 136 part++;
147 } 137 }
148 if (in_nmi()) { 138 if (in_nmi()) {