Blame view
fs/btrfs/compression.c
2.48 KB
21a14facb fs: btrfs: Add si... |
1 2 3 4 5 6 7 8 9 10 11 |
/* * BTRFS filesystem implementation for U-Boot * * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz * * SPDX-License-Identifier: GPL-2.0+ */ #include "btrfs.h" #include <linux/lzo.h> #include <u-boot/zlib.h> |
2021f083e fs: btrfs: Fix un... |
12 |
#include <asm/unaligned.h> |
21a14facb fs: btrfs: Add si... |
13 14 15 16 17 18 19 20 21 |
static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen) { u32 tot_len, in_len, res; size_t out_len; int ret; if (clen < 4) return -1; |
2021f083e fs: btrfs: Fix un... |
22 |
tot_len = le32_to_cpu(get_unaligned((u32 *)cbuf)); |
21a14facb fs: btrfs: Add si... |
23 24 25 26 27 28 29 30 31 32 33 34 |
cbuf += 4; clen -= 4; tot_len -= 4; if (tot_len == 0 && dlen) return -1; if (tot_len < 4) return -1; res = 0; while (tot_len > 4) { |
2021f083e fs: btrfs: Fix un... |
35 |
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf)); |
21a14facb fs: btrfs: Add si... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
cbuf += 4; clen -= 4; if (in_len > clen || tot_len < 4 + in_len) return -1; tot_len -= 4 + in_len; out_len = dlen; ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len); if (ret != LZO_E_OK) return -1; cbuf += in_len; clen -= in_len; dbuf += out_len; dlen -= out_len; res += out_len; } return res; } /* from zutil.h */ #define PRESET_DICT 0x20 static u32 decompress_zlib(const u8 *_cbuf, u32 clen, u8 *dbuf, u32 dlen) { int wbits = MAX_WBITS, ret = -1; z_stream stream; u8 *cbuf; u32 res; memset(&stream, 0, sizeof(stream)); cbuf = (u8 *) _cbuf; stream.total_in = 0; stream.next_out = dbuf; stream.avail_out = dlen; stream.total_out = 0; /* skip adler32 check if deflate and no dictionary */ if (clen > 2 && !(cbuf[1] & PRESET_DICT) && ((cbuf[0] & 0x0f) == Z_DEFLATED) && !(((cbuf[0] << 8) + cbuf[1]) % 31)) { wbits = -((cbuf[0] >> 4) + 8); cbuf += 2; clen -= 2; } if (Z_OK != inflateInit2(&stream, wbits)) return -1; while (stream.total_in < clen) { stream.next_in = cbuf + stream.total_in; stream.avail_in = min((u32) (clen - stream.total_in), (u32) btrfs_info.sb.sectorsize); ret = inflate(&stream, Z_NO_FLUSH); if (ret != Z_OK) break; } res = stream.total_out; inflateEnd(&stream); if (ret != Z_STREAM_END) return -1; return res; } u32 btrfs_decompress(u8 type, const char *c, u32 clen, char *d, u32 dlen) { u32 res; const u8 *cbuf; u8 *dbuf; cbuf = (const u8 *) c; dbuf = (u8 *) d; switch (type) { case BTRFS_COMPRESS_NONE: res = dlen < clen ? dlen : clen; memcpy(dbuf, cbuf, res); return res; case BTRFS_COMPRESS_ZLIB: return decompress_zlib(cbuf, clen, dbuf, dlen); case BTRFS_COMPRESS_LZO: return decompress_lzo(cbuf, clen, dbuf, dlen); default: printf("%s: Unsupported compression in extent: %i ", __func__, type); return -1; } } |