diff options
Diffstat (limited to 'fs/btrfs/lzo.c')
-rw-r--r-- | fs/btrfs/lzo.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 78285f30909e..617553cdb7d3 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c | |||
@@ -373,6 +373,8 @@ cont: | |||
373 | } | 373 | } |
374 | done: | 374 | done: |
375 | kunmap(pages_in[page_in_index]); | 375 | kunmap(pages_in[page_in_index]); |
376 | if (!ret) | ||
377 | btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset); | ||
376 | return ret; | 378 | return ret; |
377 | } | 379 | } |
378 | 380 | ||
@@ -410,10 +412,23 @@ static int lzo_decompress(struct list_head *ws, unsigned char *data_in, | |||
410 | goto out; | 412 | goto out; |
411 | } | 413 | } |
412 | 414 | ||
415 | /* | ||
416 | * the caller is already checking against PAGE_SIZE, but lets | ||
417 | * move this check closer to the memcpy/memset | ||
418 | */ | ||
419 | destlen = min_t(unsigned long, destlen, PAGE_SIZE); | ||
413 | bytes = min_t(unsigned long, destlen, out_len - start_byte); | 420 | bytes = min_t(unsigned long, destlen, out_len - start_byte); |
414 | 421 | ||
415 | kaddr = kmap_atomic(dest_page); | 422 | kaddr = kmap_atomic(dest_page); |
416 | memcpy(kaddr, workspace->buf + start_byte, bytes); | 423 | memcpy(kaddr, workspace->buf + start_byte, bytes); |
424 | |||
425 | /* | ||
426 | * btrfs_getblock is doing a zero on the tail of the page too, | ||
427 | * but this will cover anything missing from the decompressed | ||
428 | * data. | ||
429 | */ | ||
430 | if (bytes < destlen) | ||
431 | memset(kaddr+bytes, 0, destlen-bytes); | ||
417 | kunmap_atomic(kaddr); | 432 | kunmap_atomic(kaddr); |
418 | out: | 433 | out: |
419 | return ret; | 434 | return ret; |