Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/boot/zfs/gzip.c
105687 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License (the "License").
6
* You may not use this file except in compliance with the License.
7
*
8
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9
* or http://www.opensolaris.org/os/licensing.
10
* See the License for the specific language governing permissions
11
* and limitations under the License.
12
*
13
* When distributing Covered Code, include this CDDL HEADER in each
14
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15
* If applicable, add the following below this CDDL HEADER, with the
16
* fields enclosed by brackets "[]" replaced with your own identifying
17
* information: Portions Copyright [yyyy] [name of copyright owner]
18
*
19
* CDDL HEADER END
20
*/
21
22
/*
23
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
/*
28
* Portions Copyright 2022 Mikhail Zakharov <[email protected]>
29
*/
30
31
#include <contrib/zlib/zlib.h>
32
#include <contrib/zlib/zutil.h>
33
34
static void *
35
zfs_zcalloc(void *opaque __unused, uint_t items, uint_t size)
36
{
37
38
return (calloc(items, size));
39
}
40
41
static void
42
zfs_zcfree(void *opaque __unused, void *ptr)
43
{
44
free(ptr);
45
}
46
47
/*
48
* Uncompress the buffer 'src' into the buffer 'dst'. The caller must store
49
* the expected decompressed data size externally so it can be passed in.
50
* The resulting decompressed size is then returned through dstlen. This
51
* function return Z_OK on success, or another error code on failure.
52
*/
53
static inline int
54
z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
55
{
56
z_stream zs;
57
int err;
58
59
bzero(&zs, sizeof (zs));
60
zs.next_in = (unsigned char *)src;
61
zs.avail_in = srclen;
62
zs.next_out = dst;
63
zs.avail_out = *dstlen;
64
zs.zalloc = zfs_zcalloc;
65
zs.zfree = zfs_zcfree;
66
67
/*
68
* Call inflateInit2() specifying a window size of DEF_WBITS
69
* with the 6th bit set to indicate that the compression format
70
* type (zlib or gzip) should be automatically detected.
71
*/
72
if ((err = inflateInit2(&zs, DEF_WBITS | 0x20)) != Z_OK)
73
return (err);
74
75
if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
76
(void) inflateEnd(&zs);
77
return (err == Z_OK ? Z_BUF_ERROR : err);
78
}
79
80
*dstlen = zs.total_out;
81
return (inflateEnd(&zs));
82
}
83
84
static int
85
gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len,
86
int n __unused)
87
{
88
size_t dstlen = d_len;
89
90
ASSERT(d_len >= s_len);
91
92
if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK)
93
return (-1);
94
95
return (0);
96
}
97
98