|
|
@@ -1001,11 +1001,11 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
|
|
|
struct zswap_entry *entry, *dupentry;
|
|
|
struct crypto_comp *tfm;
|
|
|
int ret;
|
|
|
- unsigned int dlen = PAGE_SIZE, len;
|
|
|
+ unsigned int hlen, dlen = PAGE_SIZE;
|
|
|
unsigned long handle, value;
|
|
|
char *buf;
|
|
|
u8 *src, *dst;
|
|
|
- struct zswap_header *zhdr;
|
|
|
+ struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) };
|
|
|
|
|
|
if (!zswap_enabled || !tree) {
|
|
|
ret = -ENODEV;
|
|
|
@@ -1063,8 +1063,8 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
|
|
|
}
|
|
|
|
|
|
/* store */
|
|
|
- len = dlen + sizeof(struct zswap_header);
|
|
|
- ret = zpool_malloc(entry->pool->zpool, len,
|
|
|
+ hlen = zpool_evictable(entry->pool->zpool) ? sizeof(zhdr) : 0;
|
|
|
+ ret = zpool_malloc(entry->pool->zpool, hlen + dlen,
|
|
|
__GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM,
|
|
|
&handle);
|
|
|
if (ret == -ENOSPC) {
|
|
|
@@ -1075,10 +1075,9 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
|
|
|
zswap_reject_alloc_fail++;
|
|
|
goto put_dstmem;
|
|
|
}
|
|
|
- zhdr = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW);
|
|
|
- zhdr->swpentry = swp_entry(type, offset);
|
|
|
- buf = (u8 *)(zhdr + 1);
|
|
|
- memcpy(buf, dst, dlen);
|
|
|
+ buf = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW);
|
|
|
+ memcpy(buf, &zhdr, hlen);
|
|
|
+ memcpy(buf + hlen, dst, dlen);
|
|
|
zpool_unmap_handle(entry->pool->zpool, handle);
|
|
|
put_cpu_var(zswap_dstmem);
|
|
|
|
|
|
@@ -1149,8 +1148,9 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset,
|
|
|
|
|
|
/* decompress */
|
|
|
dlen = PAGE_SIZE;
|
|
|
- src = (u8 *)zpool_map_handle(entry->pool->zpool, entry->handle,
|
|
|
- ZPOOL_MM_RO) + sizeof(struct zswap_header);
|
|
|
+ src = zpool_map_handle(entry->pool->zpool, entry->handle, ZPOOL_MM_RO);
|
|
|
+ if (zpool_evictable(entry->pool->zpool))
|
|
|
+ src += sizeof(struct zswap_header);
|
|
|
dst = kmap_atomic(page);
|
|
|
tfm = *get_cpu_ptr(entry->pool->tfm);
|
|
|
ret = crypto_comp_decompress(tfm, src, entry->length, dst, &dlen);
|