The compression layer seems to have been built to return -1 and have
callers make up errors that make sense. This isn't great because there
are different errors that originate down in the compression layer.
Let's return real negative errnos from the compression layer so that
callers can pass on the error without having to guess what happened.
ENOMEM for allocation failure, E2BIG when compression exceeds the
uncompressed input, and EIO for everything else.
This helps a future path return errors from btrfs_decompress().
Signed-off-by: Zach Brown <zab@redhat.com>
Signed-off-by: Chris Mason <clm@fb.com>
if (ret != LZO_E_OK) {
printk(KERN_DEBUG "BTRFS: deflate in loop returned %d\n",
ret);
if (ret != LZO_E_OK) {
printk(KERN_DEBUG "BTRFS: deflate in loop returned %d\n",
ret);
kunmap(out_page);
if (nr_pages == nr_dest_pages) {
out_page = NULL;
kunmap(out_page);
if (nr_pages == nr_dest_pages) {
out_page = NULL;
/* we're making it bigger, give up */
if (tot_in > 8192 && tot_in < tot_out) {
/* we're making it bigger, give up */
if (tot_in > 8192 && tot_in < tot_out) {
break;
if (page_in_index + 1 >= total_pages_in) {
break;
if (page_in_index + 1 >= total_pages_in) {
kunmap(pages_in[page_in_index - 1]);
if (ret != LZO_E_OK) {
printk(KERN_WARNING "BTRFS: decompress failed\n");
kunmap(pages_in[page_in_index - 1]);
if (ret != LZO_E_OK) {
printk(KERN_WARNING "BTRFS: decompress failed\n");
ret = lzo1x_decompress_safe(data_in, in_len, workspace->buf, &out_len);
if (ret != LZO_E_OK) {
printk(KERN_WARNING "BTRFS: decompress failed!\n");
ret = lzo1x_decompress_safe(data_in, in_len, workspace->buf, &out_len);
if (ret != LZO_E_OK) {
printk(KERN_WARNING "BTRFS: decompress failed!\n");
goto out;
}
if (out_len < start_byte) {
goto out;
}
if (out_len < start_byte) {
if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
printk(KERN_WARNING "BTRFS: deflateInit failed\n");
if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
printk(KERN_WARNING "BTRFS: deflateInit failed\n");
out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
if (out_page == NULL) {
out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
if (out_page == NULL) {
goto out;
}
cpage_out = kmap(out_page);
goto out;
}
cpage_out = kmap(out_page);
printk(KERN_DEBUG "BTRFS: deflate in loop returned %d\n",
ret);
zlib_deflateEnd(&workspace->def_strm);
printk(KERN_DEBUG "BTRFS: deflate in loop returned %d\n",
ret);
zlib_deflateEnd(&workspace->def_strm);
if (workspace->def_strm.total_in > 8192 &&
workspace->def_strm.total_in <
workspace->def_strm.total_out) {
if (workspace->def_strm.total_in > 8192 &&
workspace->def_strm.total_in <
workspace->def_strm.total_out) {
goto out;
}
/* we need another page for writing out. Test this
goto out;
}
/* we need another page for writing out. Test this
kunmap(out_page);
if (nr_pages == nr_dest_pages) {
out_page = NULL;
kunmap(out_page);
if (nr_pages == nr_dest_pages) {
out_page = NULL;
goto out;
}
out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
if (out_page == NULL) {
goto out;
}
out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
if (out_page == NULL) {
goto out;
}
cpage_out = kmap(out_page);
goto out;
}
cpage_out = kmap(out_page);
zlib_deflateEnd(&workspace->def_strm);
if (ret != Z_STREAM_END) {
zlib_deflateEnd(&workspace->def_strm);
if (ret != Z_STREAM_END) {
goto out;
}
if (workspace->def_strm.total_out >= workspace->def_strm.total_in) {
goto out;
}
if (workspace->def_strm.total_out >= workspace->def_strm.total_in) {
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
printk(KERN_WARNING "BTRFS: inflateInit failed\n");
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
printk(KERN_WARNING "BTRFS: inflateInit failed\n");
}
while (workspace->inf_strm.total_in < srclen) {
ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH);
}
while (workspace->inf_strm.total_in < srclen) {
ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH);
}
}
if (ret != Z_STREAM_END)
}
}
if (ret != Z_STREAM_END)
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
printk(KERN_WARNING "BTRFS: inflateInit failed\n");
if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
printk(KERN_WARNING "BTRFS: inflateInit failed\n");
}
while (bytes_left > 0) {
}
while (bytes_left > 0) {
total_out = workspace->inf_strm.total_out;
if (total_out == buf_start) {
total_out = workspace->inf_strm.total_out;
if (total_out == buf_start) {
}
if (ret != Z_STREAM_END && bytes_left != 0)
}
if (ret != Z_STREAM_END && bytes_left != 0)