diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/pstore/Kconfig | 2 | ||||
-rw-r--r-- | fs/pstore/inode.c | 10 | ||||
-rw-r--r-- | fs/pstore/internal.h | 5 | ||||
-rw-r--r-- | fs/pstore/platform.c | 212 | ||||
-rw-r--r-- | fs/pstore/ram.c | 47 |
5 files changed, 242 insertions, 34 deletions
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig index ca71db69da07..983d9510becc 100644 --- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig | |||
@@ -1,6 +1,8 @@ | |||
1 | config PSTORE | 1 | config PSTORE |
2 | bool "Persistent store support" | 2 | bool "Persistent store support" |
3 | default n | 3 | default n |
4 | select ZLIB_DEFLATE | ||
5 | select ZLIB_INFLATE | ||
4 | help | 6 | help |
5 | This option enables generic access to platform level | 7 | This option enables generic access to platform level |
6 | persistent storage via "pstore" filesystem that can | 8 | persistent storage via "pstore" filesystem that can |
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 71bf5f4ae84c..12823845d324 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
@@ -275,8 +275,8 @@ int pstore_is_mounted(void) | |||
275 | * Set the mtime & ctime to the date that this record was originally stored. | 275 | * Set the mtime & ctime to the date that this record was originally stored. |
276 | */ | 276 | */ |
277 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, | 277 | int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, |
278 | char *data, size_t size, struct timespec time, | 278 | char *data, bool compressed, size_t size, |
279 | struct pstore_info *psi) | 279 | struct timespec time, struct pstore_info *psi) |
280 | { | 280 | { |
281 | struct dentry *root = pstore_sb->s_root; | 281 | struct dentry *root = pstore_sb->s_root; |
282 | struct dentry *dentry; | 282 | struct dentry *dentry; |
@@ -315,7 +315,8 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, | |||
315 | 315 | ||
316 | switch (type) { | 316 | switch (type) { |
317 | case PSTORE_TYPE_DMESG: | 317 | case PSTORE_TYPE_DMESG: |
318 | sprintf(name, "dmesg-%s-%lld", psname, id); | 318 | sprintf(name, "dmesg-%s-%lld%s", psname, id, |
319 | compressed ? ".enc.z" : ""); | ||
319 | break; | 320 | break; |
320 | case PSTORE_TYPE_CONSOLE: | 321 | case PSTORE_TYPE_CONSOLE: |
321 | sprintf(name, "console-%s", psname); | 322 | sprintf(name, "console-%s", psname); |
@@ -345,9 +346,8 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, | |||
345 | 346 | ||
346 | mutex_lock(&root->d_inode->i_mutex); | 347 | mutex_lock(&root->d_inode->i_mutex); |
347 | 348 | ||
348 | rc = -ENOSPC; | ||
349 | dentry = d_alloc_name(root, name); | 349 | dentry = d_alloc_name(root, name); |
350 | if (IS_ERR(dentry)) | 350 | if (!dentry) |
351 | goto fail_lockedalloc; | 351 | goto fail_lockedalloc; |
352 | 352 | ||
353 | memcpy(private->data, data, size); | 353 | memcpy(private->data, data, size); |
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index 937d820f273c..3b3d305277c4 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h | |||
@@ -50,8 +50,9 @@ 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 | int count, char *data, size_t size, | 53 | int count, char *data, bool compressed, |
54 | struct timespec time, struct pstore_info *psi); | 54 | size_t size, struct timespec time, |
55 | struct pstore_info *psi); | ||
55 | extern int pstore_is_mounted(void); | 56 | extern int pstore_is_mounted(void); |
56 | 57 | ||
57 | #endif | 58 | #endif |
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 422962ae9fc2..4ffb7ab5e397 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pstore.h> | 28 | #include <linux/pstore.h> |
29 | #include <linux/zlib.h> | ||
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
30 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
@@ -65,6 +66,15 @@ struct pstore_info *psinfo; | |||
65 | 66 | ||
66 | static char *backend; | 67 | static char *backend; |
67 | 68 | ||
69 | /* Compression parameters */ | ||
70 | #define COMPR_LEVEL 6 | ||
71 | #define WINDOW_BITS 12 | ||
72 | #define MEM_LEVEL 4 | ||
73 | static struct z_stream_s stream; | ||
74 | |||
75 | static char *big_oops_buf; | ||
76 | static size_t big_oops_buf_sz; | ||
77 | |||
68 | /* How much of the console log to snapshot */ | 78 | /* How much of the console log to snapshot */ |
69 | static unsigned long kmsg_bytes = 10240; | 79 | static unsigned long kmsg_bytes = 10240; |
70 | 80 | ||
@@ -117,6 +127,121 @@ bool pstore_cannot_block_path(enum kmsg_dump_reason reason) | |||
117 | } | 127 | } |
118 | EXPORT_SYMBOL_GPL(pstore_cannot_block_path); | 128 | EXPORT_SYMBOL_GPL(pstore_cannot_block_path); |
119 | 129 | ||
130 | /* Derived from logfs_compress() */ | ||
131 | static int pstore_compress(const void *in, void *out, size_t inlen, | ||
132 | size_t outlen) | ||
133 | { | ||
134 | int err, ret; | ||
135 | |||
136 | ret = -EIO; | ||
137 | err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS, | ||
138 | MEM_LEVEL, Z_DEFAULT_STRATEGY); | ||
139 | if (err != Z_OK) | ||
140 | goto error; | ||
141 | |||
142 | stream.next_in = in; | ||
143 | stream.avail_in = inlen; | ||
144 | stream.total_in = 0; | ||
145 | stream.next_out = out; | ||
146 | stream.avail_out = outlen; | ||
147 | stream.total_out = 0; | ||
148 | |||
149 | err = zlib_deflate(&stream, Z_FINISH); | ||
150 | if (err != Z_STREAM_END) | ||
151 | goto error; | ||
152 | |||
153 | err = zlib_deflateEnd(&stream); | ||
154 | if (err != Z_OK) | ||
155 | goto error; | ||
156 | |||
157 | if (stream.total_out >= stream.total_in) | ||
158 | goto error; | ||
159 | |||
160 | ret = stream.total_out; | ||
161 | error: | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | /* Derived from logfs_uncompress */ | ||
166 | static int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen) | ||
167 | { | ||
168 | int err, ret; | ||
169 | |||
170 | ret = -EIO; | ||
171 | err = zlib_inflateInit(&stream); | ||
172 | if (err != Z_OK) | ||
173 | goto error; | ||
174 | |||
175 | stream.next_in = in; | ||
176 | stream.avail_in = inlen; | ||
177 | stream.total_in = 0; | ||
178 | stream.next_out = out; | ||
179 | stream.avail_out = outlen; | ||
180 | stream.total_out = 0; | ||
181 | |||
182 | err = zlib_inflate(&stream, Z_FINISH); | ||
183 | if (err != Z_STREAM_END) | ||
184 | goto error; | ||
185 | |||
186 | err = zlib_inflateEnd(&stream); | ||
187 | if (err != Z_OK) | ||
188 | goto error; | ||
189 | |||
190 | ret = stream.total_out; | ||
191 | error: | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static void allocate_buf_for_compression(void) | ||
196 | { | ||
197 | size_t size; | ||
198 | |||
199 | big_oops_buf_sz = (psinfo->bufsize * 100) / 45; | ||
200 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); | ||
201 | if (big_oops_buf) { | ||
202 | size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), | ||
203 | zlib_inflate_workspacesize()); | ||
204 | stream.workspace = kmalloc(size, GFP_KERNEL); | ||
205 | if (!stream.workspace) { | ||
206 | pr_err("pstore: No memory for compression workspace; " | ||
207 | "skipping compression\n"); | ||
208 | kfree(big_oops_buf); | ||
209 | big_oops_buf = NULL; | ||
210 | } | ||
211 | } else { | ||
212 | pr_err("No memory for uncompressed data; " | ||
213 | "skipping compression\n"); | ||
214 | stream.workspace = NULL; | ||
215 | } | ||
216 | |||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Called when compression fails, since the printk buffer | ||
221 | * would be fetched for compression calling it again when | ||
222 | * compression fails would have moved the iterator of | ||
223 | * printk buffer which results in fetching old contents. | ||
224 | * Copy the recent messages from big_oops_buf to psinfo->buf | ||
225 | */ | ||
226 | static size_t copy_kmsg_to_buffer(int hsize, size_t len) | ||
227 | { | ||
228 | size_t total_len; | ||
229 | size_t diff; | ||
230 | |||
231 | total_len = hsize + len; | ||
232 | |||
233 | if (total_len > psinfo->bufsize) { | ||
234 | diff = total_len - psinfo->bufsize + hsize; | ||
235 | memcpy(psinfo->buf, big_oops_buf, hsize); | ||
236 | memcpy(psinfo->buf + hsize, big_oops_buf + diff, | ||
237 | psinfo->bufsize - hsize); | ||
238 | total_len = psinfo->bufsize; | ||
239 | } else | ||
240 | memcpy(psinfo->buf, big_oops_buf, total_len); | ||
241 | |||
242 | return total_len; | ||
243 | } | ||
244 | |||
120 | /* | 245 | /* |
121 | * callback from kmsg_dump. (s2,l2) has the most recently | 246 | * callback from kmsg_dump. (s2,l2) has the most recently |
122 | * written bytes, older bytes are in (s1,l1). Save as much | 247 | * written bytes, older bytes are in (s1,l1). Save as much |
@@ -148,22 +273,56 @@ static void pstore_dump(struct kmsg_dumper *dumper, | |||
148 | char *dst; | 273 | char *dst; |
149 | unsigned long size; | 274 | unsigned long size; |
150 | int hsize; | 275 | int hsize; |
276 | int zipped_len = -1; | ||
151 | size_t len; | 277 | size_t len; |
278 | bool compressed; | ||
279 | size_t total_len; | ||
152 | 280 | ||
153 | dst = psinfo->buf; | 281 | if (big_oops_buf) { |
154 | hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, part); | 282 | dst = big_oops_buf; |
155 | size = psinfo->bufsize - hsize; | 283 | hsize = sprintf(dst, "%s#%d Part%d\n", why, |
156 | dst += hsize; | 284 | oopscount, part); |
285 | size = big_oops_buf_sz - hsize; | ||
157 | 286 | ||
158 | if (!kmsg_dump_get_buffer(dumper, true, dst, size, &len)) | 287 | if (!kmsg_dump_get_buffer(dumper, true, dst + hsize, |
159 | break; | 288 | size, &len)) |
289 | break; | ||
290 | |||
291 | zipped_len = pstore_compress(dst, psinfo->buf, | ||
292 | hsize + len, psinfo->bufsize); | ||
293 | |||
294 | if (zipped_len > 0) { | ||
295 | compressed = true; | ||
296 | total_len = zipped_len; | ||
297 | } else { | ||
298 | pr_err("pstore: compression failed for Part %d" | ||
299 | " returned %d\n", part, zipped_len); | ||
300 | pr_err("pstore: Capture uncompressed" | ||
301 | " oops/panic report of Part %d\n", part); | ||
302 | compressed = false; | ||
303 | total_len = copy_kmsg_to_buffer(hsize, len); | ||
304 | } | ||
305 | } else { | ||
306 | dst = psinfo->buf; | ||
307 | hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, | ||
308 | part); | ||
309 | size = psinfo->bufsize - hsize; | ||
310 | dst += hsize; | ||
311 | |||
312 | if (!kmsg_dump_get_buffer(dumper, true, dst, | ||
313 | size, &len)) | ||
314 | break; | ||
315 | |||
316 | compressed = false; | ||
317 | total_len = hsize + len; | ||
318 | } | ||
160 | 319 | ||
161 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, | 320 | ret = psinfo->write(PSTORE_TYPE_DMESG, reason, &id, part, |
162 | oopscount, hsize, hsize + len, psinfo); | 321 | oopscount, compressed, total_len, psinfo); |
163 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) | 322 | if (ret == 0 && reason == KMSG_DUMP_OOPS && pstore_is_mounted()) |
164 | pstore_new_entry = 1; | 323 | pstore_new_entry = 1; |
165 | 324 | ||
166 | total += hsize + len; | 325 | total += total_len; |
167 | part++; | 326 | part++; |
168 | } | 327 | } |
169 | if (pstore_cannot_block_path(reason)) { | 328 | if (pstore_cannot_block_path(reason)) { |
@@ -221,10 +380,10 @@ static void pstore_register_console(void) {} | |||
221 | static int pstore_write_compat(enum pstore_type_id type, | 380 | static int pstore_write_compat(enum pstore_type_id type, |
222 | enum kmsg_dump_reason reason, | 381 | enum kmsg_dump_reason reason, |
223 | u64 *id, unsigned int part, int count, | 382 | u64 *id, unsigned int part, int count, |
224 | size_t hsize, size_t size, | 383 | bool compressed, size_t size, |
225 | struct pstore_info *psi) | 384 | struct pstore_info *psi) |
226 | { | 385 | { |
227 | return psi->write_buf(type, reason, id, part, psinfo->buf, hsize, | 386 | return psi->write_buf(type, reason, id, part, psinfo->buf, compressed, |
228 | size, psi); | 387 | size, psi); |
229 | } | 388 | } |
230 | 389 | ||
@@ -261,6 +420,8 @@ int pstore_register(struct pstore_info *psi) | |||
261 | return -EINVAL; | 420 | return -EINVAL; |
262 | } | 421 | } |
263 | 422 | ||
423 | allocate_buf_for_compression(); | ||
424 | |||
264 | if (pstore_is_mounted()) | 425 | if (pstore_is_mounted()) |
265 | pstore_get_records(0); | 426 | pstore_get_records(0); |
266 | 427 | ||
@@ -297,6 +458,8 @@ void pstore_get_records(int quiet) | |||
297 | enum pstore_type_id type; | 458 | enum pstore_type_id type; |
298 | struct timespec time; | 459 | struct timespec time; |
299 | int failed = 0, rc; | 460 | int failed = 0, rc; |
461 | bool compressed; | ||
462 | int unzipped_len = -1; | ||
300 | 463 | ||
301 | if (!psi) | 464 | if (!psi) |
302 | return; | 465 | return; |
@@ -305,11 +468,32 @@ void pstore_get_records(int quiet) | |||
305 | if (psi->open && psi->open(psi)) | 468 | if (psi->open && psi->open(psi)) |
306 | goto out; | 469 | goto out; |
307 | 470 | ||
308 | while ((size = psi->read(&id, &type, &count, &time, &buf, psi)) > 0) { | 471 | while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed, |
472 | psi)) > 0) { | ||
473 | if (compressed && (type == PSTORE_TYPE_DMESG)) { | ||
474 | if (big_oops_buf) | ||
475 | unzipped_len = pstore_decompress(buf, | ||
476 | big_oops_buf, size, | ||
477 | big_oops_buf_sz); | ||
478 | |||
479 | if (unzipped_len > 0) { | ||
480 | buf = big_oops_buf; | ||
481 | size = unzipped_len; | ||
482 | compressed = false; | ||
483 | } else { | ||
484 | pr_err("pstore: decompression failed;" | ||
485 | "returned %d\n", unzipped_len); | ||
486 | compressed = true; | ||
487 | } | ||
488 | } | ||
309 | rc = pstore_mkfile(type, psi->name, id, count, buf, | 489 | rc = pstore_mkfile(type, psi->name, id, count, buf, |
310 | (size_t)size, time, psi); | 490 | compressed, (size_t)size, time, psi); |
311 | kfree(buf); | 491 | if (unzipped_len < 0) { |
312 | buf = NULL; | 492 | /* Free buffer other than big oops */ |
493 | kfree(buf); | ||
494 | buf = NULL; | ||
495 | } else | ||
496 | unzipped_len = -1; | ||
313 | if (rc && (rc != -EEXIST || !quiet)) | 497 | if (rc && (rc != -EEXIST || !quiet)) |
314 | failed++; | 498 | failed++; |
315 | } | 499 | } |
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index a6119f9469e2..fa8cef2cca3a 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -131,9 +131,31 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, | |||
131 | return prz; | 131 | return prz; |
132 | } | 132 | } |
133 | 133 | ||
134 | static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time, | ||
135 | bool *compressed) | ||
136 | { | ||
137 | char data_type; | ||
138 | |||
139 | if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n", | ||
140 | &time->tv_sec, &time->tv_nsec, &data_type) == 3) { | ||
141 | if (data_type == 'C') | ||
142 | *compressed = true; | ||
143 | else | ||
144 | *compressed = false; | ||
145 | } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n", | ||
146 | &time->tv_sec, &time->tv_nsec) == 2) { | ||
147 | *compressed = false; | ||
148 | } else { | ||
149 | time->tv_sec = 0; | ||
150 | time->tv_nsec = 0; | ||
151 | *compressed = false; | ||
152 | } | ||
153 | } | ||
154 | |||
134 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | 155 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, |
135 | int *count, struct timespec *time, | 156 | int *count, struct timespec *time, |
136 | char **buf, struct pstore_info *psi) | 157 | char **buf, bool *compressed, |
158 | struct pstore_info *psi) | ||
137 | { | 159 | { |
138 | ssize_t size; | 160 | ssize_t size; |
139 | ssize_t ecc_notice_size; | 161 | ssize_t ecc_notice_size; |
@@ -152,10 +174,6 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
152 | if (!prz) | 174 | if (!prz) |
153 | return 0; | 175 | return 0; |
154 | 176 | ||
155 | /* TODO(kees): Bogus time for the moment. */ | ||
156 | time->tv_sec = 0; | ||
157 | time->tv_nsec = 0; | ||
158 | |||
159 | size = persistent_ram_old_size(prz); | 177 | size = persistent_ram_old_size(prz); |
160 | 178 | ||
161 | /* ECC correction notice */ | 179 | /* ECC correction notice */ |
@@ -166,12 +184,14 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
166 | return -ENOMEM; | 184 | return -ENOMEM; |
167 | 185 | ||
168 | memcpy(*buf, persistent_ram_old(prz), size); | 186 | memcpy(*buf, persistent_ram_old(prz), size); |
187 | ramoops_read_kmsg_hdr(*buf, time, compressed); | ||
169 | persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); | 188 | persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); |
170 | 189 | ||
171 | return size + ecc_notice_size; | 190 | return size + ecc_notice_size; |
172 | } | 191 | } |
173 | 192 | ||
174 | static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz) | 193 | static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz, |
194 | bool compressed) | ||
175 | { | 195 | { |
176 | char *hdr; | 196 | char *hdr; |
177 | struct timespec timestamp; | 197 | struct timespec timestamp; |
@@ -182,8 +202,9 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz) | |||
182 | timestamp.tv_sec = 0; | 202 | timestamp.tv_sec = 0; |
183 | timestamp.tv_nsec = 0; | 203 | timestamp.tv_nsec = 0; |
184 | } | 204 | } |
185 | hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n", | 205 | hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n", |
186 | (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000)); | 206 | (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000), |
207 | compressed ? 'C' : 'D'); | ||
187 | WARN_ON_ONCE(!hdr); | 208 | WARN_ON_ONCE(!hdr); |
188 | len = hdr ? strlen(hdr) : 0; | 209 | len = hdr ? strlen(hdr) : 0; |
189 | persistent_ram_write(prz, hdr, len); | 210 | persistent_ram_write(prz, hdr, len); |
@@ -196,7 +217,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
196 | enum kmsg_dump_reason reason, | 217 | enum kmsg_dump_reason reason, |
197 | u64 *id, unsigned int part, | 218 | u64 *id, unsigned int part, |
198 | const char *buf, | 219 | const char *buf, |
199 | size_t hsize, size_t size, | 220 | bool compressed, size_t size, |
200 | struct pstore_info *psi) | 221 | struct pstore_info *psi) |
201 | { | 222 | { |
202 | struct ramoops_context *cxt = psi->data; | 223 | struct ramoops_context *cxt = psi->data; |
@@ -242,7 +263,7 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
242 | 263 | ||
243 | prz = cxt->przs[cxt->dump_write_cnt]; | 264 | prz = cxt->przs[cxt->dump_write_cnt]; |
244 | 265 | ||
245 | hlen = ramoops_write_kmsg_hdr(prz); | 266 | hlen = ramoops_write_kmsg_hdr(prz, compressed); |
246 | if (size + hlen > prz->buffer_size) | 267 | if (size + hlen > prz->buffer_size) |
247 | size = prz->buffer_size - hlen; | 268 | size = prz->buffer_size - hlen; |
248 | persistent_ram_write(prz, buf, size); | 269 | persistent_ram_write(prz, buf, size); |
@@ -400,11 +421,11 @@ static int ramoops_probe(struct platform_device *pdev) | |||
400 | goto fail_out; | 421 | goto fail_out; |
401 | } | 422 | } |
402 | 423 | ||
403 | if (!is_power_of_2(pdata->record_size)) | 424 | if (pdata->record_size && !is_power_of_2(pdata->record_size)) |
404 | pdata->record_size = rounddown_pow_of_two(pdata->record_size); | 425 | pdata->record_size = rounddown_pow_of_two(pdata->record_size); |
405 | if (!is_power_of_2(pdata->console_size)) | 426 | if (pdata->console_size && !is_power_of_2(pdata->console_size)) |
406 | pdata->console_size = rounddown_pow_of_two(pdata->console_size); | 427 | pdata->console_size = rounddown_pow_of_two(pdata->console_size); |
407 | if (!is_power_of_2(pdata->ftrace_size)) | 428 | if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size)) |
408 | pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); | 429 | pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); |
409 | 430 | ||
410 | cxt->dump_read_cnt = 0; | 431 | cxt->dump_read_cnt = 0; |