diff options
Diffstat (limited to 'fs/squashfs/lzo_wrapper.c')
| -rw-r--r-- | fs/squashfs/lzo_wrapper.c | 47 |
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 | ||
| 35 | struct squashfs_lzo { | 36 | struct squashfs_lzo { |
| 36 | void *input; | 37 | void *input; |
| 37 | void *output; | 38 | void *output; |
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len) | 41 | static 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 | ||
| 77 | static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer, | 78 | static 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 | ||
| 117 | block_release: | ||
| 118 | for (; i < b; i++) | ||
| 119 | put_bh(bh[i]); | ||
| 120 | |||
| 121 | failed: | 119 | failed: |
| 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 | ||
