diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/zram/zram_drv.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index fb4a7c94aed3..f2a73bd739fb 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
@@ -265,7 +265,7 @@ out_cleanup: | |||
265 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | 265 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, |
266 | int offset) | 266 | int offset) |
267 | { | 267 | { |
268 | int ret; | 268 | int ret = 0; |
269 | size_t clen; | 269 | size_t clen; |
270 | unsigned long handle; | 270 | unsigned long handle; |
271 | struct page *page; | 271 | struct page *page; |
@@ -286,10 +286,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
286 | goto out; | 286 | goto out; |
287 | } | 287 | } |
288 | ret = zram_decompress_page(zram, uncmem, index); | 288 | ret = zram_decompress_page(zram, uncmem, index); |
289 | if (ret) { | 289 | if (ret) |
290 | kfree(uncmem); | ||
291 | goto out; | 290 | goto out; |
292 | } | ||
293 | } | 291 | } |
294 | 292 | ||
295 | /* | 293 | /* |
@@ -302,16 +300,18 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
302 | 300 | ||
303 | user_mem = kmap_atomic(page); | 301 | user_mem = kmap_atomic(page); |
304 | 302 | ||
305 | if (is_partial_io(bvec)) | 303 | if (is_partial_io(bvec)) { |
306 | memcpy(uncmem + offset, user_mem + bvec->bv_offset, | 304 | memcpy(uncmem + offset, user_mem + bvec->bv_offset, |
307 | bvec->bv_len); | 305 | bvec->bv_len); |
308 | else | 306 | kunmap_atomic(user_mem); |
307 | user_mem = NULL; | ||
308 | } else { | ||
309 | uncmem = user_mem; | 309 | uncmem = user_mem; |
310 | } | ||
310 | 311 | ||
311 | if (page_zero_filled(uncmem)) { | 312 | if (page_zero_filled(uncmem)) { |
312 | kunmap_atomic(user_mem); | 313 | if (!is_partial_io(bvec)) |
313 | if (is_partial_io(bvec)) | 314 | kunmap_atomic(user_mem); |
314 | kfree(uncmem); | ||
315 | zram_stat_inc(&zram->stats.pages_zero); | 315 | zram_stat_inc(&zram->stats.pages_zero); |
316 | zram_set_flag(zram, index, ZRAM_ZERO); | 316 | zram_set_flag(zram, index, ZRAM_ZERO); |
317 | ret = 0; | 317 | ret = 0; |
@@ -321,9 +321,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
321 | ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, | 321 | ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, |
322 | zram->compress_workmem); | 322 | zram->compress_workmem); |
323 | 323 | ||
324 | kunmap_atomic(user_mem); | 324 | if (!is_partial_io(bvec)) { |
325 | if (is_partial_io(bvec)) | 325 | kunmap_atomic(user_mem); |
326 | kfree(uncmem); | 326 | user_mem = NULL; |
327 | uncmem = NULL; | ||
328 | } | ||
327 | 329 | ||
328 | if (unlikely(ret != LZO_E_OK)) { | 330 | if (unlikely(ret != LZO_E_OK)) { |
329 | pr_err("Compression failed! err=%d\n", ret); | 331 | pr_err("Compression failed! err=%d\n", ret); |
@@ -332,8 +334,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
332 | 334 | ||
333 | if (unlikely(clen > max_zpage_size)) { | 335 | if (unlikely(clen > max_zpage_size)) { |
334 | zram_stat_inc(&zram->stats.bad_compress); | 336 | zram_stat_inc(&zram->stats.bad_compress); |
335 | src = uncmem; | ||
336 | clen = PAGE_SIZE; | 337 | clen = PAGE_SIZE; |
338 | src = NULL; | ||
339 | if (is_partial_io(bvec)) | ||
340 | src = uncmem; | ||
337 | } | 341 | } |
338 | 342 | ||
339 | handle = zs_malloc(zram->mem_pool, clen); | 343 | handle = zs_malloc(zram->mem_pool, clen); |
@@ -345,7 +349,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
345 | } | 349 | } |
346 | cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); | 350 | cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); |
347 | 351 | ||
352 | if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) | ||
353 | src = kmap_atomic(page); | ||
348 | memcpy(cmem, src, clen); | 354 | memcpy(cmem, src, clen); |
355 | if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) | ||
356 | kunmap_atomic(src); | ||
349 | 357 | ||
350 | zs_unmap_object(zram->mem_pool, handle); | 358 | zs_unmap_object(zram->mem_pool, handle); |
351 | 359 | ||
@@ -358,9 +366,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
358 | if (clen <= PAGE_SIZE / 2) | 366 | if (clen <= PAGE_SIZE / 2) |
359 | zram_stat_inc(&zram->stats.good_compress); | 367 | zram_stat_inc(&zram->stats.good_compress); |
360 | 368 | ||
361 | return 0; | ||
362 | |||
363 | out: | 369 | out: |
370 | if (is_partial_io(bvec)) | ||
371 | kfree(uncmem); | ||
372 | |||
364 | if (ret) | 373 | if (ret) |
365 | zram_stat64_inc(zram, &zram->stats.failed_writes); | 374 | zram_stat64_inc(zram, &zram->stats.failed_writes); |
366 | return ret; | 375 | return ret; |