aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Jennings <sjenning@linux.vnet.ibm.com>2011-08-10 13:56:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-23 17:52:20 -0400
commitc5f5c4db393837ebb2ae47bf061d70e498f48f8c (patch)
treee3b8823d57cd884d19ce2c98647ea32bd9b01a9c
parent20cc7995fe66ce6417678bb0db6b3d4955fb1ff6 (diff)
staging: zcache: fix crash on high memory swap
zcache_put_page() was modified to pass page_address(page) instead of the actual page structure. In combination with the function signature changes to tmem_put() and zcache_pampd_create(), zcache_pampd_create() tries to (re)derive the page structure from the virtual address. However, if the original page is a high memory page (or any unmapped page), this virt_to_page() fails because the page_address() in zcache_put_page() returned NULL. This patch changes zcache_put_page() and zcache_get_page() to pass the page structure instead of the page's virtual address, which may or may not exist. Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com> Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/zcache/zcache-main.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index 855a5bb56a47..a3f5162bfedc 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -1158,7 +1158,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
1158 size_t clen; 1158 size_t clen;
1159 int ret; 1159 int ret;
1160 unsigned long count; 1160 unsigned long count;
1161 struct page *page = virt_to_page(data); 1161 struct page *page = (struct page *)(data);
1162 struct zcache_client *cli = pool->client; 1162 struct zcache_client *cli = pool->client;
1163 uint16_t client_id = get_client_id_from_client(cli); 1163 uint16_t client_id = get_client_id_from_client(cli);
1164 unsigned long zv_mean_zsize; 1164 unsigned long zv_mean_zsize;
@@ -1227,7 +1227,7 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw,
1227 int ret = 0; 1227 int ret = 0;
1228 1228
1229 BUG_ON(is_ephemeral(pool)); 1229 BUG_ON(is_ephemeral(pool));
1230 zv_decompress(virt_to_page(data), pampd); 1230 zv_decompress((struct page *)(data), pampd);
1231 return ret; 1231 return ret;
1232} 1232}
1233 1233
@@ -1539,7 +1539,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp,
1539 goto out; 1539 goto out;
1540 if (!zcache_freeze && zcache_do_preload(pool) == 0) { 1540 if (!zcache_freeze && zcache_do_preload(pool) == 0) {
1541 /* preload does preempt_disable on success */ 1541 /* preload does preempt_disable on success */
1542 ret = tmem_put(pool, oidp, index, page_address(page), 1542 ret = tmem_put(pool, oidp, index, (char *)(page),
1543 PAGE_SIZE, 0, is_ephemeral(pool)); 1543 PAGE_SIZE, 0, is_ephemeral(pool));
1544 if (ret < 0) { 1544 if (ret < 0) {
1545 if (is_ephemeral(pool)) 1545 if (is_ephemeral(pool))
@@ -1572,7 +1572,7 @@ static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp,
1572 pool = zcache_get_pool_by_id(cli_id, pool_id); 1572 pool = zcache_get_pool_by_id(cli_id, pool_id);
1573 if (likely(pool != NULL)) { 1573 if (likely(pool != NULL)) {
1574 if (atomic_read(&pool->obj_count) > 0) 1574 if (atomic_read(&pool->obj_count) > 0)
1575 ret = tmem_get(pool, oidp, index, page_address(page), 1575 ret = tmem_get(pool, oidp, index, (char *)(page),
1576 &size, 0, is_ephemeral(pool)); 1576 &size, 0, is_ephemeral(pool));
1577 zcache_put_pool(pool); 1577 zcache_put_pool(pool);
1578 } 1578 }