aboutsummaryrefslogtreecommitdiffstats
path: root/fs/squashfs/lzo_wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/squashfs/lzo_wrapper.c')
-rw-r--r--fs/squashfs/lzo_wrapper.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c
index 00f4dfc5f088..244b9fbfff7b 100644
--- a/fs/squashfs/lzo_wrapper.c
+++ b/fs/squashfs/lzo_wrapper.c
@@ -31,13 +31,14 @@
31#include "squashfs_fs_sb.h" 31#include "squashfs_fs_sb.h"
32#include "squashfs.h" 32#include "squashfs.h"
33#include "decompressor.h" 33#include "decompressor.h"
34#include "page_actor.h"
34 35
35struct squashfs_lzo { 36struct squashfs_lzo {
36 void *input; 37 void *input;
37 void *output; 38 void *output;
38}; 39};
39 40
40static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len) 41static void *lzo_init(struct squashfs_sb_info *msblk, void *buff)
41{ 42{
42 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); 43 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
43 44
@@ -74,22 +75,16 @@ static void lzo_free(void *strm)
74} 75}
75 76
76 77
77static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer, 78static int lzo_uncompress(struct squashfs_sb_info *msblk, void *strm,
78 struct buffer_head **bh, int b, int offset, int length, int srclength, 79 struct buffer_head **bh, int b, int offset, int length,
79 int pages) 80 struct squashfs_page_actor *output)
80{ 81{
81 struct squashfs_lzo *stream = msblk->stream; 82 struct squashfs_lzo *stream = strm;
82 void *buff = stream->input; 83 void *buff = stream->input, *data;
83 int avail, i, bytes = length, res; 84 int avail, i, bytes = length, res;
84 size_t out_len = srclength; 85 size_t out_len = output->length;
85
86 mutex_lock(&msblk->read_data_mutex);
87 86
88 for (i = 0; i < b; i++) { 87 for (i = 0; i < b; i++) {
89 wait_on_buffer(bh[i]);
90 if (!buffer_uptodate(bh[i]))
91 goto block_release;
92
93 avail = min(bytes, msblk->devblksize - offset); 88 avail = min(bytes, msblk->devblksize - offset);
94 memcpy(buff, bh[i]->b_data + offset, avail); 89 memcpy(buff, bh[i]->b_data + offset, avail);
95 buff += avail; 90 buff += avail;
@@ -104,24 +99,24 @@ static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer,
104 goto failed; 99 goto failed;
105 100
106 res = bytes = (int)out_len; 101 res = bytes = (int)out_len;
107 for (i = 0, buff = stream->output; bytes && i < pages; i++) { 102 data = squashfs_first_page(output);
108 avail = min_t(int, bytes, PAGE_CACHE_SIZE); 103 buff = stream->output;
109 memcpy(buffer[i], buff, avail); 104 while (data) {
110 buff += avail; 105 if (bytes <= PAGE_CACHE_SIZE) {
111 bytes -= avail; 106 memcpy(data, buff, bytes);
107 break;
108 } else {
109 memcpy(data, buff, PAGE_CACHE_SIZE);
110 buff += PAGE_CACHE_SIZE;
111 bytes -= PAGE_CACHE_SIZE;
112 data = squashfs_next_page(output);
113 }
112 } 114 }
115 squashfs_finish_page(output);
113 116
114 mutex_unlock(&msblk->read_data_mutex);
115 return res; 117 return res;
116 118
117block_release:
118 for (; i < b; i++)
119 put_bh(bh[i]);
120
121failed: 119failed:
122 mutex_unlock(&msblk->read_data_mutex);
123
124 ERROR("lzo decompression failed, data probably corrupt\n");
125 return -EIO; 120 return -EIO;
126} 121}
127 122