summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunghan Suh <sunghan.suh@samsung.com>2013-07-03 20:10:05 +0900
committerChanho Park <chanho61.park@samsung.com>2014-03-20 17:44:27 +0900
commit3f80fa78947be146caba45541e09e81c391aa70b (patch)
tree9c6d71772596df2e3897e92aa79b3535426efbfc
parent261268f71f53e813c74527dc9c8907d49f0831cb (diff)
downloadlinux-3.10-3f80fa78947be146caba45541e09e81c391aa70b.tar.gz
linux-3.10-3f80fa78947be146caba45541e09e81c391aa70b.tar.bz2
linux-3.10-3f80fa78947be146caba45541e09e81c391aa70b.zip
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: Ieeecfa00839cd4440781ece7f9bbed123e3651d5 Signed-off-by: Sunghan Suh <sunghan.suh@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 1b30a5e87c7..5ef6508a587 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;