@@ -42,8 +42,7 @@
#define STREAM_END_SPACE 12
struct workspace {
- z_stream inf_strm;
- z_stream def_strm;
+ z_stream z_strm;
char *buf;
struct list_head list;
};
@@ -91,16 +90,13 @@ again:
goto fail;
}
- workspace->def_strm.workspace = vmalloc(zlib_deflate_workspacesize());
- if (!workspace->def_strm.workspace) {
+ workspace->z_strm.workspace = vmalloc(max(zlib_deflate_workspacesize(),
+ zlib_inflate_workspacesize()));
+ if (!workspace->z_strm.workspace) {
ret = -ENOMEM;
goto fail;
}
- workspace->inf_strm.workspace = vmalloc(zlib_inflate_workspacesize());
- if (!workspace->inf_strm.workspace) {
- ret = -ENOMEM;
- goto fail_inflate;
- }
+
workspace->buf = kmalloc(PAGE_CACHE_SIZE, GFP_NOFS);
if (!workspace->buf) {
ret = -ENOMEM;
@@ -109,9 +105,7 @@ again:
return workspace;
fail_kmalloc:
- vfree(workspace->inf_strm.workspace);
-fail_inflate:
- vfree(workspace->def_strm.workspace);
+ vfree(workspace->z_strm.workspace);
fail:
kfree(workspace);
atomic_dec(&alloc_workspace);
@@ -135,8 +129,7 @@ static int free_workspace(struct workspace *workspace)
return 0;
}
spin_unlock(&workspace_lock);
- vfree(workspace->def_strm.workspace);
- vfree(workspace->inf_strm.workspace);
+ vfree(workspace->z_strm.workspace);
kfree(workspace->buf);
kfree(workspace);
@@ -156,8 +149,7 @@ static void free_workspaces(void)
workspace = list_entry(idle_workspace.next, struct workspace,
list);
list_del(&workspace->list);
- vfree(workspace->def_strm.workspace);
- vfree(workspace->inf_strm.workspace);
+ vfree(workspace->z_strm.workspace);
kfree(workspace->buf);
kfree(workspace);
atomic_dec(&alloc_workspace);
@@ -211,14 +203,14 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
if (IS_ERR(workspace))
return -1;
- if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
+ if (Z_OK != zlib_deflateInit(&workspace->z_strm, 3)) {
printk(KERN_WARNING "deflateInit failed\n");
ret = -1;
goto out;
}
- workspace->def_strm.total_in = 0;
- workspace->def_strm.total_out = 0;
+ workspace->z_strm.total_in = 0;
+ workspace->z_strm.total_out = 0;
in_page = find_get_page(mapping, start >> PAGE_CACHE_SHIFT);
data_in = kmap(in_page);
@@ -228,28 +220,28 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
pages[0] = out_page;
nr_pages = 1;
- workspace->def_strm.next_in = data_in;
- workspace->def_strm.next_out = cpage_out;
- workspace->def_strm.avail_out = PAGE_CACHE_SIZE;
- workspace->def_strm.avail_in = min(len, PAGE_CACHE_SIZE);
+ workspace->z_strm.next_in = data_in;
+ workspace->z_strm.next_out = cpage_out;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.avail_in = min(len, PAGE_CACHE_SIZE);
out_written = 0;
in_read = 0;
- while (workspace->def_strm.total_in < len) {
- ret = zlib_deflate(&workspace->def_strm, Z_SYNC_FLUSH);
+ while (workspace->z_strm.total_in < len) {
+ ret = zlib_deflate(&workspace->z_strm, Z_SYNC_FLUSH);
if (ret != Z_OK) {
printk(KERN_DEBUG "btrfs deflate in loop returned %d\n",
ret);
- zlib_deflateEnd(&workspace->def_strm);
+ zlib_deflateEnd(&workspace->z_strm);
ret = -1;
goto out;
}
/* we're making it bigger, give up */
- if (workspace->def_strm.total_in > 8192 &&
- workspace->def_strm.total_in <
- workspace->def_strm.total_out) {
+ if (workspace->z_strm.total_in > 8192 &&
+ workspace->z_strm.total_in <
+ workspace->z_strm.total_out) {
ret = -1;
goto out;
}
@@ -257,7 +249,7 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
* before the total_in so we will pull in a new page for
* the stream end if required
*/
- if (workspace->def_strm.avail_out == 0) {
+ if (workspace->z_strm.avail_out == 0) {
kunmap(out_page);
if (nr_pages == nr_dest_pages) {
out_page = NULL;
@@ -268,19 +260,19 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
cpage_out = kmap(out_page);
pages[nr_pages] = out_page;
nr_pages++;
- workspace->def_strm.avail_out = PAGE_CACHE_SIZE;
- workspace->def_strm.next_out = cpage_out;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.next_out = cpage_out;
}
/* we're all done */
- if (workspace->def_strm.total_in >= len)
+ if (workspace->z_strm.total_in >= len)
break;
/* we've read in a full page, get a new one */
- if (workspace->def_strm.avail_in == 0) {
- if (workspace->def_strm.total_out > max_out)
+ if (workspace->z_strm.avail_in == 0) {
+ if (workspace->z_strm.total_out > max_out)
break;
- bytes_left = len - workspace->def_strm.total_in;
+ bytes_left = len - workspace->z_strm.total_in;
kunmap(in_page);
page_cache_release(in_page);
@@ -288,28 +280,28 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
in_page = find_get_page(mapping,
start >> PAGE_CACHE_SHIFT);
data_in = kmap(in_page);
- workspace->def_strm.avail_in = min(bytes_left,
+ workspace->z_strm.avail_in = min(bytes_left,
PAGE_CACHE_SIZE);
- workspace->def_strm.next_in = data_in;
+ workspace->z_strm.next_in = data_in;
}
}
- workspace->def_strm.avail_in = 0;
- ret = zlib_deflate(&workspace->def_strm, Z_FINISH);
- zlib_deflateEnd(&workspace->def_strm);
+ workspace->z_strm.avail_in = 0;
+ ret = zlib_deflate(&workspace->z_strm, Z_FINISH);
+ zlib_deflateEnd(&workspace->z_strm);
if (ret != Z_STREAM_END) {
ret = -1;
goto out;
}
- if (workspace->def_strm.total_out >= workspace->def_strm.total_in) {
+ if (workspace->z_strm.total_out >= workspace->z_strm.total_in) {
ret = -1;
goto out;
}
ret = 0;
- *total_out = workspace->def_strm.total_out;
- *total_in = workspace->def_strm.total_in;
+ *total_out = workspace->z_strm.total_out;
+ *total_in = workspace->z_strm.total_in;
out:
*out_pages = nr_pages;
if (out_page)
@@ -370,13 +362,13 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in,
return -ENOMEM;
data_in = kmap(pages_in[page_in_index]);
- workspace->inf_strm.next_in = data_in;
- workspace->inf_strm.avail_in = min_t(size_t, srclen, PAGE_CACHE_SIZE);
- workspace->inf_strm.total_in = 0;
+ workspace->z_strm.next_in = data_in;
+ workspace->z_strm.avail_in = min_t(size_t, srclen, PAGE_CACHE_SIZE);
+ workspace->z_strm.total_in = 0;
- workspace->inf_strm.total_out = 0;
- workspace->inf_strm.next_out = workspace->buf;
- workspace->inf_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.total_out = 0;
+ workspace->z_strm.next_out = workspace->buf;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
page_out = bvec[page_out_index].bv_page;
page_bytes_left = PAGE_CACHE_SIZE;
pg_offset = 0;
@@ -388,17 +380,17 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in,
!(((data_in[0]<<8) + data_in[1]) % 31)) {
wbits = -((data_in[0] >> 4) + 8);
- workspace->inf_strm.next_in += 2;
- workspace->inf_strm.avail_in -= 2;
+ workspace->z_strm.next_in += 2;
+ workspace->z_strm.avail_in -= 2;
}
- if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
+ if (Z_OK != zlib_inflateInit2(&workspace->z_strm, wbits)) {
printk(KERN_WARNING "inflateInit failed\n");
ret = -1;
goto out;
}
- while (workspace->inf_strm.total_in < srclen) {
- ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH);
+ while (workspace->z_strm.total_in < srclen) {
+ ret = zlib_inflate(&workspace->z_strm, Z_NO_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
break;
/*
@@ -408,7 +400,7 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in,
buf_start = total_out;
/* total_out is the last byte of the workspace buffer */
- total_out = workspace->inf_strm.total_out;
+ total_out = workspace->z_strm.total_out;
working_bytes = total_out - buf_start;
@@ -495,10 +487,10 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in,
}
}
next:
- workspace->inf_strm.next_out = workspace->buf;
- workspace->inf_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.next_out = workspace->buf;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
- if (workspace->inf_strm.avail_in == 0) {
+ if (workspace->z_strm.avail_in == 0) {
unsigned long tmp;
kunmap(pages_in[page_in_index]);
page_in_index++;
@@ -507,9 +499,9 @@ next:
break;
}
data_in = kmap(pages_in[page_in_index]);
- workspace->inf_strm.next_in = data_in;
- tmp = srclen - workspace->inf_strm.total_in;
- workspace->inf_strm.avail_in = min(tmp,
+ workspace->z_strm.next_in = data_in;
+ tmp = srclen - workspace->z_strm.total_in;
+ workspace->z_strm.avail_in = min(tmp,
PAGE_CACHE_SIZE);
}
}
@@ -518,7 +510,7 @@ next:
else
ret = 0;
done:
- zlib_inflateEnd(&workspace->inf_strm);
+ zlib_inflateEnd(&workspace->z_strm);
if (data_in)
kunmap(pages_in[page_in_index]);
out:
@@ -550,13 +542,13 @@ int btrfs_zlib_decompress(unsigned char *data_in,
if (IS_ERR(workspace))
return -ENOMEM;
- workspace->inf_strm.next_in = data_in;
- workspace->inf_strm.avail_in = srclen;
- workspace->inf_strm.total_in = 0;
+ workspace->z_strm.next_in = data_in;
+ workspace->z_strm.avail_in = srclen;
+ workspace->z_strm.total_in = 0;
- workspace->inf_strm.next_out = workspace->buf;
- workspace->inf_strm.avail_out = PAGE_CACHE_SIZE;
- workspace->inf_strm.total_out = 0;
+ workspace->z_strm.next_out = workspace->buf;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.total_out = 0;
/* If it's deflate, and it's got no preset dictionary, then
we can tell zlib to skip the adler32 check. */
if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
@@ -564,11 +556,11 @@ int btrfs_zlib_decompress(unsigned char *data_in,
!(((data_in[0]<<8) + data_in[1]) % 31)) {
wbits = -((data_in[0] >> 4) + 8);
- workspace->inf_strm.next_in += 2;
- workspace->inf_strm.avail_in -= 2;
+ workspace->z_strm.next_in += 2;
+ workspace->z_strm.avail_in -= 2;
}
- if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
+ if (Z_OK != zlib_inflateInit2(&workspace->z_strm, wbits)) {
printk(KERN_WARNING "inflateInit failed\n");
ret = -1;
goto out;
@@ -580,12 +572,12 @@ int btrfs_zlib_decompress(unsigned char *data_in,
unsigned long bytes;
unsigned long pg_offset = 0;
- ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH);
+ ret = zlib_inflate(&workspace->z_strm, Z_NO_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
break;
buf_start = total_out;
- total_out = workspace->inf_strm.total_out;
+ total_out = workspace->z_strm.total_out;
if (total_out == buf_start) {
ret = -1;
@@ -611,8 +603,8 @@ int btrfs_zlib_decompress(unsigned char *data_in,
pg_offset += bytes;
bytes_left -= bytes;
next:
- workspace->inf_strm.next_out = workspace->buf;
- workspace->inf_strm.avail_out = PAGE_CACHE_SIZE;
+ workspace->z_strm.next_out = workspace->buf;
+ workspace->z_strm.avail_out = PAGE_CACHE_SIZE;
}
if (ret != Z_STREAM_END && bytes_left != 0)
@@ -620,7 +612,7 @@ next:
else
ret = 0;
- zlib_inflateEnd(&workspace->inf_strm);
+ zlib_inflateEnd(&workspace->z_strm);
out:
free_workspace(workspace);
return ret;