diff options
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r-- | fs/pstore/ram.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 3b5744306ed8..ec881b312700 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, | |||
135 | return prz; | 135 | return prz; |
136 | } | 136 | } |
137 | 137 | ||
138 | static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time, | 138 | static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time, |
139 | bool *compressed) | 139 | bool *compressed) |
140 | { | 140 | { |
141 | char data_type; | 141 | char data_type; |
142 | int header_length = 0; | ||
142 | 143 | ||
143 | if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n", | 144 | if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", &time->tv_sec, |
144 | &time->tv_sec, &time->tv_nsec, &data_type) == 3) { | 145 | &time->tv_nsec, &data_type, &header_length) == 3) { |
145 | if (data_type == 'C') | 146 | if (data_type == 'C') |
146 | *compressed = true; | 147 | *compressed = true; |
147 | else | 148 | else |
148 | *compressed = false; | 149 | *compressed = false; |
149 | } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n", | 150 | } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n", |
150 | &time->tv_sec, &time->tv_nsec) == 2) { | 151 | &time->tv_sec, &time->tv_nsec, &header_length) == 2) { |
151 | *compressed = false; | 152 | *compressed = false; |
152 | } else { | 153 | } else { |
153 | time->tv_sec = 0; | 154 | time->tv_sec = 0; |
154 | time->tv_nsec = 0; | 155 | time->tv_nsec = 0; |
155 | *compressed = false; | 156 | *compressed = false; |
156 | } | 157 | } |
158 | return header_length; | ||
157 | } | 159 | } |
158 | 160 | ||
159 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | 161 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, |
@@ -165,6 +167,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
165 | ssize_t ecc_notice_size; | 167 | ssize_t ecc_notice_size; |
166 | struct ramoops_context *cxt = psi->data; | 168 | struct ramoops_context *cxt = psi->data; |
167 | struct persistent_ram_zone *prz; | 169 | struct persistent_ram_zone *prz; |
170 | int header_length; | ||
168 | 171 | ||
169 | prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, | 172 | prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, |
170 | cxt->max_dump_cnt, id, type, | 173 | cxt->max_dump_cnt, id, type, |
@@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
178 | if (!prz) | 181 | if (!prz) |
179 | return 0; | 182 | return 0; |
180 | 183 | ||
184 | if (!persistent_ram_old(prz)) | ||
185 | return 0; | ||
186 | |||
181 | size = persistent_ram_old_size(prz); | 187 | size = persistent_ram_old_size(prz); |
188 | header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time, | ||
189 | compressed); | ||
190 | size -= header_length; | ||
182 | 191 | ||
183 | /* ECC correction notice */ | 192 | /* ECC correction notice */ |
184 | ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0); | 193 | ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0); |
@@ -187,8 +196,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
187 | if (*buf == NULL) | 196 | if (*buf == NULL) |
188 | return -ENOMEM; | 197 | return -ENOMEM; |
189 | 198 | ||
190 | memcpy(*buf, persistent_ram_old(prz), size); | 199 | memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size); |
191 | ramoops_read_kmsg_hdr(*buf, time, compressed); | ||
192 | persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); | 200 | persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); |
193 | 201 | ||
194 | return size + ecc_notice_size; | 202 | return size + ecc_notice_size; |