aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorSunghan Suh <sunghan.suh@samsung.com>2013-07-03 20:10:05 +0900
committerSimon Shields <keepcalm444@gmail.com>2016-06-12 21:19:45 +1000
commita0b95fe74c5e5fc02f3749cf3a31ab787014a5d7 (patch)
tree4d8b649bb3230bb7e24cf77a4ae4d916672a478b /drivers/staging
parentcb42ec818eff1844d66b891fdeb784f3a9b7b25b (diff)
downloadkernel_samsung_smdk4412-a0b95fe74c5e5fc02f3749cf3a31ab787014a5d7.zip
kernel_samsung_smdk4412-a0b95fe74c5e5fc02f3749cf3a31ab787014a5d7.tar.gz
kernel_samsung_smdk4412-a0b95fe74c5e5fc02f3749cf3a31ab787014a5d7.tar.bz2
zram: prevent data loss in error cases of function zram_bvec_write()
In function zram_bvec_write(), previous data at the index is already freed by function zram_free_page(). When failed to compress or zs_malloc, there is no way to restore old data. Therefore, free previous data when it's about to update. Also, no need to check whether table is not empty outside of function zram_free_page(), because the function properly checks inside. Change-Id: I8cb3daf146a99d3b5999c7a42e5e2a260f4c3a48 Signed-off-by: Sunghan Suh <sunghan.suh@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Git-commit: f40ac2ae1b506484dd9261a24bbf3e86b2206ff8 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/zram/zram_drv.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 5b76365..e74425a 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -418,14 +418,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
goto out;
}
- /*
- * System overwrites unused sectors. Free memory associated
- * with this sector now.
- */
- if (meta->table[index].handle ||
- zram_test_flag(meta, index, ZRAM_ZERO))
- zram_free_page(zram, index);
-
user_mem = kmap_atomic(page);
if (is_partial_io(bvec)) {
@@ -439,6 +431,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
if (page_zero_filled(uncmem)) {
kunmap_atomic(user_mem);
+ /* Free memory associated with this sector now. */
+ zram_free_page(zram, index);
+
zram->stats.pages_zero++;
zram_set_flag(meta, index, ZRAM_ZERO);
ret = 0;
@@ -486,6 +481,12 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
zs_unmap_object(meta->mem_pool, handle);
+ /*
+ * Free memory associated with this sector
+ * before overwriting unused sectors.
+ */
+ zram_free_page(zram, index);
+
meta->table[index].handle = handle;
meta->table[index].size = clen;