diff options
Diffstat (limited to 'fs/pstore/ram_core.c')
-rw-r--r-- | fs/pstore/ram_core.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 31f8d184f3a0..c5fbdbbf81ac 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c | |||
@@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, | |||
250 | persistent_ram_update_ecc(prz, start, count); | 250 | persistent_ram_update_ecc(prz, start, count); |
251 | } | 251 | } |
252 | 252 | ||
253 | static void __init | 253 | void persistent_ram_save_old(struct persistent_ram_zone *prz) |
254 | persistent_ram_save_old(struct persistent_ram_zone *prz) | ||
255 | { | 254 | { |
256 | struct persistent_ram_buffer *buffer = prz->buffer; | 255 | struct persistent_ram_buffer *buffer = prz->buffer; |
257 | size_t size = buffer_size(prz); | 256 | size_t size = buffer_size(prz); |
258 | size_t start = buffer_start(prz); | 257 | size_t start = buffer_start(prz); |
259 | char *dest; | ||
260 | 258 | ||
261 | persistent_ram_ecc_old(prz); | 259 | if (!size) |
260 | return; | ||
262 | 261 | ||
263 | dest = kmalloc(size, GFP_KERNEL); | 262 | if (!prz->old_log) { |
264 | if (dest == NULL) { | 263 | persistent_ram_ecc_old(prz); |
264 | prz->old_log = kmalloc(size, GFP_KERNEL); | ||
265 | } | ||
266 | if (!prz->old_log) { | ||
265 | pr_err("persistent_ram: failed to allocate buffer\n"); | 267 | pr_err("persistent_ram: failed to allocate buffer\n"); |
266 | return; | 268 | return; |
267 | } | 269 | } |
268 | 270 | ||
269 | prz->old_log = dest; | ||
270 | prz->old_log_size = size; | 271 | prz->old_log_size = size; |
271 | memcpy(prz->old_log, &buffer->data[start], size - start); | 272 | memcpy(prz->old_log, &buffer->data[start], size - start); |
272 | memcpy(prz->old_log + size - start, &buffer->data[0], start); | 273 | memcpy(prz->old_log + size - start, &buffer->data[0], start); |
@@ -319,6 +320,13 @@ void persistent_ram_free_old(struct persistent_ram_zone *prz) | |||
319 | prz->old_log_size = 0; | 320 | prz->old_log_size = 0; |
320 | } | 321 | } |
321 | 322 | ||
323 | void persistent_ram_zap(struct persistent_ram_zone *prz) | ||
324 | { | ||
325 | atomic_set(&prz->buffer->start, 0); | ||
326 | atomic_set(&prz->buffer->size, 0); | ||
327 | persistent_ram_update_header_ecc(prz); | ||
328 | } | ||
329 | |||
322 | static void *persistent_ram_vmap(phys_addr_t start, size_t size) | 330 | static void *persistent_ram_vmap(phys_addr_t start, size_t size) |
323 | { | 331 | { |
324 | struct page **pages; | 332 | struct page **pages; |
@@ -405,6 +413,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool | |||
405 | " size %zu, start %zu\n", | 413 | " size %zu, start %zu\n", |
406 | buffer_size(prz), buffer_start(prz)); | 414 | buffer_size(prz), buffer_start(prz)); |
407 | persistent_ram_save_old(prz); | 415 | persistent_ram_save_old(prz); |
416 | return 0; | ||
408 | } | 417 | } |
409 | } else { | 418 | } else { |
410 | pr_info("persistent_ram: no valid data in buffer" | 419 | pr_info("persistent_ram: no valid data in buffer" |
@@ -412,8 +421,7 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool | |||
412 | } | 421 | } |
413 | 422 | ||
414 | prz->buffer->sig = PERSISTENT_RAM_SIG; | 423 | prz->buffer->sig = PERSISTENT_RAM_SIG; |
415 | atomic_set(&prz->buffer->start, 0); | 424 | persistent_ram_zap(prz); |
416 | atomic_set(&prz->buffer->size, 0); | ||
417 | 425 | ||
418 | return 0; | 426 | return 0; |
419 | } | 427 | } |
@@ -448,7 +456,6 @@ struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start, | |||
448 | goto err; | 456 | goto err; |
449 | 457 | ||
450 | persistent_ram_post_init(prz, ecc); | 458 | persistent_ram_post_init(prz, ecc); |
451 | persistent_ram_update_header_ecc(prz); | ||
452 | 459 | ||
453 | return prz; | 460 | return prz; |
454 | err: | 461 | err: |