diff options
| author | Takashi Iwai <tiwai@suse.de> | 2014-12-03 09:38:03 +0100 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-12-03 09:38:58 +0100 |
| commit | 2e3d4de1bd80b2f205aab0ed0a25daef464ab91c (patch) | |
| tree | 7caa6a353f9ff9f5e196ed01bbbfce1c8c5ec8ae /fs/btrfs/zlib.c | |
| parent | 492a7ea0a6d3cc9c16ad5f8af832ed4278225b2e (diff) | |
| parent | 009d0431c3914de64666bec0d350e54fdd59df6a (diff) | |
Merge tag 'v3.18-rc7' into for-next
... for allowing more cleanups of hda_intel.c driver-caps where both
upstream and for-next contain the changes.
Diffstat (limited to 'fs/btrfs/zlib.c')
| -rw-r--r-- | fs/btrfs/zlib.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 759fa4e2de8f..fb22fd8d8fb8 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -299,6 +299,8 @@ done: zlib_inflateEnd(&workspace->strm); if (data_in) kunmap(pages_in[page_in_index]); + if (!ret) + btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset); return ret; } @@ -310,10 +312,14 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in, struct workspace *workspace = list_entry(ws, struct workspace, list); int ret = 0; int wbits = MAX_WBITS; - unsigned long bytes_left = destlen; + unsigned long bytes_left; unsigned long total_out = 0; + unsigned long pg_offset = 0; char *kaddr; + destlen = min_t(unsigned long, destlen, PAGE_SIZE); + bytes_left = destlen; + workspace->strm.next_in = data_in; workspace->strm.avail_in = srclen; workspace->strm.total_in = 0; @@ -341,7 +347,6 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in, unsigned long buf_start; unsigned long buf_offset; unsigned long bytes; - unsigned long pg_offset = 0; ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) @@ -384,6 +389,17 @@ next: ret = 0; zlib_inflateEnd(&workspace->strm); + + /* + * this should only happen if zlib returned fewer bytes than we + * expected. btrfs_get_block is responsible for zeroing from the + * end of the inline extent (destlen) to the end of the page + */ + if (pg_offset < destlen) { + kaddr = kmap_atomic(dest_page); + memset(kaddr + pg_offset, 0, destlen - pg_offset); + kunmap_atomic(kaddr); + } return ret; } |
