diff options
author | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-06-19 04:15:52 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-21 01:15:22 +0200 |
commit | beeb94321a7a6d493b4a06ff0cd771f09f41c35e (patch) | |
tree | ae276de7228bf62512d5a9ce3b65c76017a6def0 | |
parent | pstore/ram: Fix error handling during przs allocation (diff) | |
download | linux-beeb94321a7a6d493b4a06ff0cd771f09f41c35e.tar.xz linux-beeb94321a7a6d493b4a06ff0cd771f09f41c35e.zip |
pstore/ram_core: Proper checking for post_init errors (e.g. improper ECC size)
We will implement variable-sized ECC buffers soon, so post_init routine
might fail much more likely, so we'd better check for its errors.
To make error handling simple, modify persistent_ram_free() to it be safe
at all times.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | fs/pstore/ram_core.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 26531856daf8..f62ebf2dfed7 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -427,11 +427,17 @@ static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, void persistent_ram_free(struct persistent_ram_zone *prz) { - if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { - vunmap(prz->vaddr); - } else { - iounmap(prz->vaddr); - release_mem_region(prz->paddr, prz->size); + if (!prz) + return; + + if (prz->vaddr) { + if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { + vunmap(prz->vaddr); + } else { + iounmap(prz->vaddr); + release_mem_region(prz->paddr, prz->size); + } + prz->vaddr = NULL; } persistent_ram_free_old(prz); kfree(prz); @@ -454,10 +460,12 @@ struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, if (ret) goto err; - persistent_ram_post_init(prz, ecc); + ret = persistent_ram_post_init(prz, ecc); + if (ret) + goto err; return prz; err: - kfree(prz); + persistent_ram_free(prz); return ERR_PTR(ret); } |