summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/lzo.c
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2014-11-30 14:56:33 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2014-11-30 18:33:51 +0100
commit2f19cad94cee3c9bd52d0c9ca584ef506302fb7c (patch)
treeca1a69874842c86904ff6b66cb7430c818f2baa4 /fs/btrfs/lzo.c
parentMerge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/ker... (diff)
downloadlinux-2f19cad94cee3c9bd52d0c9ca584ef506302fb7c.tar.xz
linux-2f19cad94cee3c9bd52d0c9ca584ef506302fb7c.zip
btrfs: zero out left over bytes after processing compression streams
Don Bailey noticed that our page zeroing for compression at end-io time isn't complete. This reworks a patch from Linus to push the zeroing into the zlib and lzo specific functions instead of trying to handle the corners inside btrfs_decompress_buf2page Signed-off-by: Chris Mason <clm@fb.com> Reviewed-by: Josef Bacik <jbacik@fb.com> Reported-by: Don A. Bailey <donb@securitymouse.com> cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/btrfs/lzo.c')
-rw-r--r--fs/btrfs/lzo.c15
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:
}
done:
kunmap(pages_in[page_in_index]);
+ if (!ret)
+ btrfs_clear_biovec_end(bvec, vcnt, page_out_index, pg_offset);
return ret;
}
@@ -410,10 +412,23 @@ static int lzo_decompress(struct list_head *ws, unsigned char *data_in,
goto out;
}
+ /*
+ * the caller is already checking against PAGE_SIZE, but lets
+ * move this check closer to the memcpy/memset
+ */
+ destlen = min_t(unsigned long, destlen, PAGE_SIZE);
bytes = min_t(unsigned long, destlen, out_len - start_byte);
kaddr = kmap_atomic(dest_page);
memcpy(kaddr, workspace->buf + start_byte, bytes);
+
+ /*
+ * btrfs_getblock is doing a zero on the tail of the page too,
+ * but this will cover anything missing from the decompressed
+ * data.
+ */
+ if (bytes < destlen)
+ memset(kaddr+bytes, 0, destlen-bytes);
kunmap_atomic(kaddr);
out:
return ret;