embox

Форк
0
/
compr_zlib.c 
195 строк · 4.8 Кб
1
/*
2
 * JFFS2 -- Journalling Flash File System, Version 2.
3
 *
4
 * Copyright (C) 2001-2003 Red Hat, Inc.
5
 *
6
 * Created by David Woodhouse <dwmw2@infradead.org>
7
 *
8
 * For licensing information, see the file 'LICENCE' in this directory.
9
 *
10
 * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
11
 *
12
 */
13

14
#include <linux/zutil.h>
15
#undef local
16

17
#include <linux/config.h>
18
#include <linux/kernel.h>
19
#include <linux/sched.h>
20
#include <linux/slab.h>
21
#include <linux/zlib.h>
22
#include "nodelist.h"
23
#include "compr.h"
24

25
	/* Plan: call deflate() with avail_in == *sourcelen,
26
	 * avail_out = *dstlen - 12 and flush == Z_FINISH.
27
	 * If it doesn't manage to finish,	call it again with
28
	 * avail_in == 0 and avail_out set to the remaining 12
29
	 * bytes for it to clean up.
30
	 * Q: Is 12 bytes sufficient?
31
	 */
32
#define STREAM_END_SPACE 12
33

34
static struct mutex deflate_sem = MUTEX_INIT(deflate_sem);
35
static struct mutex inflate_sem = MUTEX_INIT(inflate_sem);;
36

37
static z_stream inf_strm, def_strm;
38

39
#define alloc_workspaces() (0)
40
#define free_workspaces() do { } while(0)
41

42
static int jffs2_zlib_compress(unsigned char *data_in,
43
			       unsigned char *cpage_out,
44
			       uint32_t *sourcelen, uint32_t *dstlen,
45
			       void *model) {
46
	int ret;
47

48
	if (*dstlen <= STREAM_END_SPACE) {
49
		return -1;
50
	}
51

52
	mutex_lock(&deflate_sem);
53

54
	if (Z_OK != deflateInit(&def_strm, 3)) {
55
		printk(KERN_WARNING "deflateInit failed\n");
56
		mutex_unlock(&deflate_sem);
57
		return -1;
58
	}
59

60
	def_strm.next_in = data_in;
61
	def_strm.total_in = 0;
62

63
	def_strm.next_out = cpage_out;
64
	def_strm.total_out = 0;
65

66
	while (def_strm.total_out < *dstlen - STREAM_END_SPACE &&
67
			def_strm.total_in < *sourcelen) {
68
		def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE);
69
		def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in),
70
				def_strm.avail_out);
71
		D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
72
			  def_strm.avail_in, def_strm.avail_out));
73
		ret = deflate(&def_strm, Z_PARTIAL_FLUSH);
74
		D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
75
			  def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
76
		if (ret != Z_OK) {
77
			D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
78
			deflateEnd(&def_strm);
79
			mutex_unlock(&deflate_sem);
80
			return -1;
81
		}
82
	}
83
	def_strm.avail_out += STREAM_END_SPACE;
84
	def_strm.avail_in = 0;
85
	ret = deflate(&def_strm, Z_FINISH);
86
	deflateEnd(&def_strm);
87

88
	if (ret != Z_STREAM_END) {
89
		D1(printk(KERN_DEBUG "final deflate returned %d\n", ret));
90
		ret = -1;
91
		goto out;
92
	}
93

94
	if (def_strm.total_out >= def_strm.total_in) {
95
		D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n",
96
			  def_strm.total_in, def_strm.total_out));
97
		ret = -1;
98
		goto out;
99
	}
100

101
	D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
102
		  def_strm.total_in, def_strm.total_out));
103

104
	*dstlen = def_strm.total_out;
105
	*sourcelen = def_strm.total_in;
106
	ret = 0;
107
out:
108
	mutex_unlock(&deflate_sem);
109
	return ret;
110
}
111

112
static int jffs2_zlib_decompress(unsigned char *data_in,
113
				 unsigned char *cpage_out,
114
				 uint32_t srclen, uint32_t destlen,
115
				 void *model) {
116
	int ret;
117
	int wbits = MAX_WBITS;
118

119
	mutex_lock(&inflate_sem);
120

121
	inf_strm.next_in = data_in;
122
	inf_strm.avail_in = srclen;
123
	inf_strm.total_in = 0;
124

125
	inf_strm.next_out = cpage_out;
126
	inf_strm.avail_out = destlen;
127
	inf_strm.total_out = 0;
128

129
	/* If it's deflate, and it's got no preset dictionary, then
130
	 * we can tell zlib to skip the adler32 check.
131
	 */
132
	if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
133
	    ((data_in[0] & 0x0f) == Z_DEFLATED) &&
134
	    !(((data_in[0]<<8) + data_in[1]) % 31)) {
135

136
		D2(printk(KERN_DEBUG "inflate skipping adler32\n"));
137
		wbits = -((data_in[0] >> 4) + 8);
138
		inf_strm.next_in += 2;
139
		inf_strm.avail_in -= 2;
140
	} else {
141
		/* Let this remain D1 for now -- it should never happen */
142
		D1(printk(KERN_DEBUG "inflate not skipping adler32\n"));
143
	}
144

145

146
	if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) {
147
		printk(KERN_WARNING "inflateInit failed\n");
148
		mutex_unlock(&inflate_sem);
149
		return 1;
150
	}
151

152
	while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK) {
153
		;
154
	}
155
	if (ret != Z_STREAM_END) {
156
		printk(KERN_NOTICE "inflate returned %d\n", ret);
157
	}
158
	zlib_inflateEnd(&inf_strm);
159
	mutex_unlock(&inflate_sem);
160
    return 0;
161
}
162

163
static struct jffs2_compressor jffs2_zlib_comp = {
164
    .priority = JFFS2_ZLIB_PRIORITY,
165
    .name = "zlib",
166
    .compr = JFFS2_COMPR_ZLIB,
167
    .compress = &jffs2_zlib_compress,
168
    .decompress = &jffs2_zlib_decompress,
169
#ifdef JFFS2_ZLIB_DISABLED
170
    .disabled = 1,
171
#else
172
    .disabled = 0,
173
#endif
174
};
175

176
int __init jffs2_zlib_init(void) {
177
    int ret;
178

179
    ret = alloc_workspaces();
180
    if (ret) {
181
    	return ret;
182
    }
183

184
    ret = jffs2_register_compressor(&jffs2_zlib_comp);
185
    if (ret) {
186
    	free_workspaces();
187
    }
188

189
    return ret;
190
}
191

192
void jffs2_zlib_exit(void) {
193
    jffs2_unregister_compressor(&jffs2_zlib_comp);
194
    free_workspaces();
195
}
196

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.