1*10465441SEvalZero /*
2*10465441SEvalZero * JFFS2 -- Journalling Flash File System, Version 2.
3*10465441SEvalZero *
4*10465441SEvalZero * Copyright (C) 2001-2003 Red Hat, Inc.
5*10465441SEvalZero * Created by Arjan van de Ven <[email protected]>
6*10465441SEvalZero *
7*10465441SEvalZero * Copyright (C) 2004 Ferenc Havasi <[email protected]>,
8*10465441SEvalZero * University of Szeged, Hungary
9*10465441SEvalZero *
10*10465441SEvalZero * For licensing information, see the file 'LICENCE' in this directory.
11*10465441SEvalZero *
12*10465441SEvalZero * $Id: compr.c,v 1.45 2005/07/26 13:24:40 havasi Exp $
13*10465441SEvalZero *
14*10465441SEvalZero */
15*10465441SEvalZero
16*10465441SEvalZero #include "compr.h"
17*10465441SEvalZero
18*10465441SEvalZero static DEFINE_SPINLOCK(jffs2_compressor_list_lock);
19*10465441SEvalZero
20*10465441SEvalZero /* Available compressors are on this list */
21*10465441SEvalZero static LIST_HEAD(jffs2_compressor_list);
22*10465441SEvalZero
23*10465441SEvalZero /* Actual compression mode */
24*10465441SEvalZero static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
25*10465441SEvalZero
26*10465441SEvalZero /* Statistics for blocks stored without compression */
27*10465441SEvalZero static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0;
28*10465441SEvalZero
29*10465441SEvalZero /* jffs2_compress:
30*10465441SEvalZero * @data: Pointer to uncompressed data
31*10465441SEvalZero * @cdata: Pointer to returned pointer to buffer for compressed data
32*10465441SEvalZero * @datalen: On entry, holds the amount of data available for compression.
33*10465441SEvalZero * On exit, expected to hold the amount of data actually compressed.
34*10465441SEvalZero * @cdatalen: On entry, holds the amount of space available for compressed
35*10465441SEvalZero * data. On exit, expected to hold the actual size of the compressed
36*10465441SEvalZero * data.
37*10465441SEvalZero *
38*10465441SEvalZero * Returns: Lower byte to be stored with data indicating compression type used.
39*10465441SEvalZero * Zero is used to show that the data could not be compressed - the
40*10465441SEvalZero * compressed version was actually larger than the original.
41*10465441SEvalZero * Upper byte will be used later. (soon)
42*10465441SEvalZero *
43*10465441SEvalZero * If the cdata buffer isn't large enough to hold all the uncompressed data,
44*10465441SEvalZero * jffs2_compress should compress as much as will fit, and should set
45*10465441SEvalZero * *datalen accordingly to show the amount of data which were compressed.
46*10465441SEvalZero */
jffs2_compress(struct jffs2_sb_info * c,struct jffs2_inode_info * f,unsigned char * data_in,unsigned char ** cpage_out,uint32_t * datalen,uint32_t * cdatalen)47*10465441SEvalZero uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
48*10465441SEvalZero unsigned char *data_in, unsigned char **cpage_out,
49*10465441SEvalZero uint32_t *datalen, uint32_t *cdatalen)
50*10465441SEvalZero {
51*10465441SEvalZero int ret = JFFS2_COMPR_NONE;
52*10465441SEvalZero int compr_ret;
53*10465441SEvalZero struct jffs2_compressor *this, *best=NULL;
54*10465441SEvalZero unsigned char *output_buf = NULL, *tmp_buf;
55*10465441SEvalZero uint32_t orig_slen, orig_dlen;
56*10465441SEvalZero uint32_t best_slen=0, best_dlen=0;
57*10465441SEvalZero
58*10465441SEvalZero switch (jffs2_compression_mode) {
59*10465441SEvalZero case JFFS2_COMPR_MODE_NONE:
60*10465441SEvalZero break;
61*10465441SEvalZero case JFFS2_COMPR_MODE_PRIORITY:
62*10465441SEvalZero output_buf = kmalloc(*cdatalen,GFP_KERNEL);
63*10465441SEvalZero if (!output_buf) {
64*10465441SEvalZero printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
65*10465441SEvalZero goto out;
66*10465441SEvalZero }
67*10465441SEvalZero orig_slen = *datalen;
68*10465441SEvalZero orig_dlen = *cdatalen;
69*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
70*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
71*10465441SEvalZero /* Skip decompress-only backwards-compatibility and disabled modules */
72*10465441SEvalZero if ((!this->compress)||(this->disabled))
73*10465441SEvalZero continue;
74*10465441SEvalZero
75*10465441SEvalZero this->usecount++;
76*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
77*10465441SEvalZero *datalen = orig_slen;
78*10465441SEvalZero *cdatalen = orig_dlen;
79*10465441SEvalZero compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL);
80*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
81*10465441SEvalZero this->usecount--;
82*10465441SEvalZero if (!compr_ret) {
83*10465441SEvalZero ret = this->compr;
84*10465441SEvalZero this->stat_compr_blocks++;
85*10465441SEvalZero this->stat_compr_orig_size += *datalen;
86*10465441SEvalZero this->stat_compr_new_size += *cdatalen;
87*10465441SEvalZero break;
88*10465441SEvalZero }
89*10465441SEvalZero }
90*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
91*10465441SEvalZero if (ret == JFFS2_COMPR_NONE) kfree(output_buf);
92*10465441SEvalZero break;
93*10465441SEvalZero case JFFS2_COMPR_MODE_SIZE:
94*10465441SEvalZero orig_slen = *datalen;
95*10465441SEvalZero orig_dlen = *cdatalen;
96*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
97*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
98*10465441SEvalZero /* Skip decompress-only backwards-compatibility and disabled modules */
99*10465441SEvalZero if ((!this->compress)||(this->disabled))
100*10465441SEvalZero continue;
101*10465441SEvalZero /* Allocating memory for output buffer if necessary */
102*10465441SEvalZero if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) {
103*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
104*10465441SEvalZero kfree(this->compr_buf);
105*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
106*10465441SEvalZero this->compr_buf_size=0;
107*10465441SEvalZero this->compr_buf=NULL;
108*10465441SEvalZero }
109*10465441SEvalZero if (!this->compr_buf) {
110*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
111*10465441SEvalZero tmp_buf = kmalloc(orig_dlen,GFP_KERNEL);
112*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
113*10465441SEvalZero if (!tmp_buf) {
114*10465441SEvalZero printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen);
115*10465441SEvalZero continue;
116*10465441SEvalZero }
117*10465441SEvalZero else {
118*10465441SEvalZero this->compr_buf = tmp_buf;
119*10465441SEvalZero this->compr_buf_size = orig_dlen;
120*10465441SEvalZero }
121*10465441SEvalZero }
122*10465441SEvalZero this->usecount++;
123*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
124*10465441SEvalZero *datalen = orig_slen;
125*10465441SEvalZero *cdatalen = orig_dlen;
126*10465441SEvalZero compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL);
127*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
128*10465441SEvalZero this->usecount--;
129*10465441SEvalZero if (!compr_ret) {
130*10465441SEvalZero if ((!best_dlen)||(best_dlen>*cdatalen)) {
131*10465441SEvalZero best_dlen = *cdatalen;
132*10465441SEvalZero best_slen = *datalen;
133*10465441SEvalZero best = this;
134*10465441SEvalZero }
135*10465441SEvalZero }
136*10465441SEvalZero }
137*10465441SEvalZero if (best_dlen) {
138*10465441SEvalZero *cdatalen = best_dlen;
139*10465441SEvalZero *datalen = best_slen;
140*10465441SEvalZero output_buf = best->compr_buf;
141*10465441SEvalZero best->compr_buf = NULL;
142*10465441SEvalZero best->compr_buf_size = 0;
143*10465441SEvalZero best->stat_compr_blocks++;
144*10465441SEvalZero best->stat_compr_orig_size += best_slen;
145*10465441SEvalZero best->stat_compr_new_size += best_dlen;
146*10465441SEvalZero ret = best->compr;
147*10465441SEvalZero }
148*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
149*10465441SEvalZero break;
150*10465441SEvalZero default:
151*10465441SEvalZero printk(KERN_ERR "JFFS2: unknow compression mode.\n");
152*10465441SEvalZero }
153*10465441SEvalZero out:
154*10465441SEvalZero if (ret == JFFS2_COMPR_NONE) {
155*10465441SEvalZero *cpage_out = data_in;
156*10465441SEvalZero *datalen = *cdatalen;
157*10465441SEvalZero none_stat_compr_blocks++;
158*10465441SEvalZero none_stat_compr_size += *datalen;
159*10465441SEvalZero }
160*10465441SEvalZero else {
161*10465441SEvalZero *cpage_out = output_buf;
162*10465441SEvalZero }
163*10465441SEvalZero return ret;
164*10465441SEvalZero }
165*10465441SEvalZero
jffs2_decompress(struct jffs2_sb_info * c,struct jffs2_inode_info * f,uint16_t comprtype,unsigned char * cdata_in,unsigned char * data_out,uint32_t cdatalen,uint32_t datalen)166*10465441SEvalZero int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
167*10465441SEvalZero uint16_t comprtype, unsigned char *cdata_in,
168*10465441SEvalZero unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
169*10465441SEvalZero {
170*10465441SEvalZero struct jffs2_compressor *this;
171*10465441SEvalZero int ret;
172*10465441SEvalZero
173*10465441SEvalZero /* Older code had a bug where it would write non-zero 'usercompr'
174*10465441SEvalZero fields. Deal with it. */
175*10465441SEvalZero if ((comprtype & 0xff) <= JFFS2_COMPR_ZLIB)
176*10465441SEvalZero comprtype &= 0xff;
177*10465441SEvalZero
178*10465441SEvalZero switch (comprtype & 0xff) {
179*10465441SEvalZero case JFFS2_COMPR_NONE:
180*10465441SEvalZero /* This should be special-cased elsewhere, but we might as well deal with it */
181*10465441SEvalZero memcpy(data_out, cdata_in, datalen);
182*10465441SEvalZero none_stat_decompr_blocks++;
183*10465441SEvalZero break;
184*10465441SEvalZero case JFFS2_COMPR_ZERO:
185*10465441SEvalZero memset(data_out, 0, datalen);
186*10465441SEvalZero break;
187*10465441SEvalZero default:
188*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
189*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
190*10465441SEvalZero if (comprtype == this->compr) {
191*10465441SEvalZero this->usecount++;
192*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
193*10465441SEvalZero ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL);
194*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
195*10465441SEvalZero if (ret) {
196*10465441SEvalZero printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret);
197*10465441SEvalZero }
198*10465441SEvalZero else {
199*10465441SEvalZero this->stat_decompr_blocks++;
200*10465441SEvalZero }
201*10465441SEvalZero this->usecount--;
202*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
203*10465441SEvalZero return ret;
204*10465441SEvalZero }
205*10465441SEvalZero }
206*10465441SEvalZero printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype);
207*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
208*10465441SEvalZero return -EIO;
209*10465441SEvalZero }
210*10465441SEvalZero return 0;
211*10465441SEvalZero }
212*10465441SEvalZero
jffs2_register_compressor(struct jffs2_compressor * comp)213*10465441SEvalZero int jffs2_register_compressor(struct jffs2_compressor *comp)
214*10465441SEvalZero {
215*10465441SEvalZero struct jffs2_compressor *this;
216*10465441SEvalZero
217*10465441SEvalZero if (!comp->name) {
218*10465441SEvalZero printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n");
219*10465441SEvalZero return -1;
220*10465441SEvalZero }
221*10465441SEvalZero comp->compr_buf_size=0;
222*10465441SEvalZero comp->compr_buf=NULL;
223*10465441SEvalZero comp->usecount=0;
224*10465441SEvalZero comp->stat_compr_orig_size=0;
225*10465441SEvalZero comp->stat_compr_new_size=0;
226*10465441SEvalZero comp->stat_compr_blocks=0;
227*10465441SEvalZero comp->stat_decompr_blocks=0;
228*10465441SEvalZero D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name));
229*10465441SEvalZero
230*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
231*10465441SEvalZero
232*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
233*10465441SEvalZero if (this->priority < comp->priority) {
234*10465441SEvalZero list_add(&comp->list, this->list.prev);
235*10465441SEvalZero goto out;
236*10465441SEvalZero }
237*10465441SEvalZero }
238*10465441SEvalZero list_add_tail(&comp->list, &jffs2_compressor_list);
239*10465441SEvalZero out:
240*10465441SEvalZero D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
241*10465441SEvalZero printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
242*10465441SEvalZero })
243*10465441SEvalZero
244*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
245*10465441SEvalZero
246*10465441SEvalZero return 0;
247*10465441SEvalZero }
248*10465441SEvalZero
jffs2_unregister_compressor(struct jffs2_compressor * comp)249*10465441SEvalZero int jffs2_unregister_compressor(struct jffs2_compressor *comp)
250*10465441SEvalZero {
251*10465441SEvalZero D2(struct jffs2_compressor *this;)
252*10465441SEvalZero
253*10465441SEvalZero D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name));
254*10465441SEvalZero
255*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
256*10465441SEvalZero
257*10465441SEvalZero if (comp->usecount) {
258*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
259*10465441SEvalZero printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n");
260*10465441SEvalZero return -1;
261*10465441SEvalZero }
262*10465441SEvalZero list_del(&comp->list);
263*10465441SEvalZero
264*10465441SEvalZero D2(list_for_each_entry(this, &jffs2_compressor_list, list) {
265*10465441SEvalZero printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority);
266*10465441SEvalZero })
267*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
268*10465441SEvalZero return 0;
269*10465441SEvalZero }
270*10465441SEvalZero
271*10465441SEvalZero #ifdef CONFIG_JFFS2_PROC
272*10465441SEvalZero
273*10465441SEvalZero #define JFFS2_STAT_BUF_SIZE 16000
274*10465441SEvalZero
jffs2_list_compressors(void)275*10465441SEvalZero char *jffs2_list_compressors(void)
276*10465441SEvalZero {
277*10465441SEvalZero struct jffs2_compressor *this;
278*10465441SEvalZero char *buf, *act_buf;
279*10465441SEvalZero
280*10465441SEvalZero act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL);
281*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
282*10465441SEvalZero act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority);
283*10465441SEvalZero if ((this->disabled)||(!this->compress))
284*10465441SEvalZero act_buf += sprintf(act_buf,"disabled");
285*10465441SEvalZero else
286*10465441SEvalZero act_buf += sprintf(act_buf,"enabled");
287*10465441SEvalZero act_buf += sprintf(act_buf,"\n");
288*10465441SEvalZero }
289*10465441SEvalZero return buf;
290*10465441SEvalZero }
291*10465441SEvalZero
jffs2_stats(void)292*10465441SEvalZero char *jffs2_stats(void)
293*10465441SEvalZero {
294*10465441SEvalZero struct jffs2_compressor *this;
295*10465441SEvalZero char *buf, *act_buf;
296*10465441SEvalZero
297*10465441SEvalZero act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL);
298*10465441SEvalZero
299*10465441SEvalZero act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n");
300*10465441SEvalZero act_buf += sprintf(act_buf,"%10s ","none");
301*10465441SEvalZero act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks,
302*10465441SEvalZero none_stat_compr_size, none_stat_decompr_blocks);
303*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
304*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
305*10465441SEvalZero act_buf += sprintf(act_buf,"%10s ",this->name);
306*10465441SEvalZero if ((this->disabled)||(!this->compress))
307*10465441SEvalZero act_buf += sprintf(act_buf,"- ");
308*10465441SEvalZero else
309*10465441SEvalZero act_buf += sprintf(act_buf,"+ ");
310*10465441SEvalZero act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks,
311*10465441SEvalZero this->stat_compr_new_size, this->stat_compr_orig_size,
312*10465441SEvalZero this->stat_decompr_blocks);
313*10465441SEvalZero act_buf += sprintf(act_buf,"\n");
314*10465441SEvalZero }
315*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
316*10465441SEvalZero
317*10465441SEvalZero return buf;
318*10465441SEvalZero }
319*10465441SEvalZero
jffs2_get_compression_mode_name(void)320*10465441SEvalZero char *jffs2_get_compression_mode_name(void)
321*10465441SEvalZero {
322*10465441SEvalZero switch (jffs2_compression_mode) {
323*10465441SEvalZero case JFFS2_COMPR_MODE_NONE:
324*10465441SEvalZero return "none";
325*10465441SEvalZero case JFFS2_COMPR_MODE_PRIORITY:
326*10465441SEvalZero return "priority";
327*10465441SEvalZero case JFFS2_COMPR_MODE_SIZE:
328*10465441SEvalZero return "size";
329*10465441SEvalZero }
330*10465441SEvalZero return "unkown";
331*10465441SEvalZero }
332*10465441SEvalZero
jffs2_set_compression_mode_name(const char * name)333*10465441SEvalZero int jffs2_set_compression_mode_name(const char *name)
334*10465441SEvalZero {
335*10465441SEvalZero if (!strcmp("none",name)) {
336*10465441SEvalZero jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
337*10465441SEvalZero return 0;
338*10465441SEvalZero }
339*10465441SEvalZero if (!strcmp("priority",name)) {
340*10465441SEvalZero jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY;
341*10465441SEvalZero return 0;
342*10465441SEvalZero }
343*10465441SEvalZero if (!strcmp("size",name)) {
344*10465441SEvalZero jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
345*10465441SEvalZero return 0;
346*10465441SEvalZero }
347*10465441SEvalZero return 1;
348*10465441SEvalZero }
349*10465441SEvalZero
jffs2_compressor_Xable(const char * name,int disabled)350*10465441SEvalZero static int jffs2_compressor_Xable(const char *name, int disabled)
351*10465441SEvalZero {
352*10465441SEvalZero struct jffs2_compressor *this;
353*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
354*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
355*10465441SEvalZero if (!strcmp(this->name, name)) {
356*10465441SEvalZero this->disabled = disabled;
357*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
358*10465441SEvalZero return 0;
359*10465441SEvalZero }
360*10465441SEvalZero }
361*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
362*10465441SEvalZero printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
363*10465441SEvalZero return 1;
364*10465441SEvalZero }
365*10465441SEvalZero
jffs2_enable_compressor_name(const char * name)366*10465441SEvalZero int jffs2_enable_compressor_name(const char *name)
367*10465441SEvalZero {
368*10465441SEvalZero return jffs2_compressor_Xable(name, 0);
369*10465441SEvalZero }
370*10465441SEvalZero
jffs2_disable_compressor_name(const char * name)371*10465441SEvalZero int jffs2_disable_compressor_name(const char *name)
372*10465441SEvalZero {
373*10465441SEvalZero return jffs2_compressor_Xable(name, 1);
374*10465441SEvalZero }
375*10465441SEvalZero
jffs2_set_compressor_priority(const char * name,int priority)376*10465441SEvalZero int jffs2_set_compressor_priority(const char *name, int priority)
377*10465441SEvalZero {
378*10465441SEvalZero struct jffs2_compressor *this,*comp;
379*10465441SEvalZero spin_lock(&jffs2_compressor_list_lock);
380*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
381*10465441SEvalZero if (!strcmp(this->name, name)) {
382*10465441SEvalZero this->priority = priority;
383*10465441SEvalZero comp = this;
384*10465441SEvalZero goto reinsert;
385*10465441SEvalZero }
386*10465441SEvalZero }
387*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
388*10465441SEvalZero printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name);
389*10465441SEvalZero return 1;
390*10465441SEvalZero reinsert:
391*10465441SEvalZero /* list is sorted in the order of priority, so if
392*10465441SEvalZero we change it we have to reinsert it into the
393*10465441SEvalZero good place */
394*10465441SEvalZero list_del(&comp->list);
395*10465441SEvalZero list_for_each_entry(this, &jffs2_compressor_list, list) {
396*10465441SEvalZero if (this->priority < comp->priority) {
397*10465441SEvalZero list_add(&comp->list, this->list.prev);
398*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
399*10465441SEvalZero return 0;
400*10465441SEvalZero }
401*10465441SEvalZero }
402*10465441SEvalZero list_add_tail(&comp->list, &jffs2_compressor_list);
403*10465441SEvalZero spin_unlock(&jffs2_compressor_list_lock);
404*10465441SEvalZero return 0;
405*10465441SEvalZero }
406*10465441SEvalZero
407*10465441SEvalZero #endif
408*10465441SEvalZero
jffs2_free_comprbuf(unsigned char * comprbuf,unsigned char * orig)409*10465441SEvalZero void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
410*10465441SEvalZero {
411*10465441SEvalZero if (orig != comprbuf)
412*10465441SEvalZero kfree(comprbuf);
413*10465441SEvalZero }
414*10465441SEvalZero
jffs2_compressors_init(void)415*10465441SEvalZero int jffs2_compressors_init(void)
416*10465441SEvalZero {
417*10465441SEvalZero /* Registering compressors */
418*10465441SEvalZero #ifdef CONFIG_JFFS2_ZLIB
419*10465441SEvalZero jffs2_zlib_init();
420*10465441SEvalZero #endif
421*10465441SEvalZero #ifdef CONFIG_JFFS2_RTIME
422*10465441SEvalZero jffs2_rtime_init();
423*10465441SEvalZero #endif
424*10465441SEvalZero #ifdef CONFIG_JFFS2_RUBIN
425*10465441SEvalZero jffs2_rubinmips_init();
426*10465441SEvalZero jffs2_dynrubin_init();
427*10465441SEvalZero #endif
428*10465441SEvalZero /* Setting default compression mode */
429*10465441SEvalZero #ifdef CONFIG_JFFS2_CMODE_NONE
430*10465441SEvalZero jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
431*10465441SEvalZero D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");)
432*10465441SEvalZero #else
433*10465441SEvalZero #ifdef CONFIG_JFFS2_CMODE_SIZE
434*10465441SEvalZero jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE;
435*10465441SEvalZero D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");)
436*10465441SEvalZero #else
437*10465441SEvalZero D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");)
438*10465441SEvalZero #endif
439*10465441SEvalZero #endif
440*10465441SEvalZero return 0;
441*10465441SEvalZero }
442*10465441SEvalZero
jffs2_compressors_exit(void)443*10465441SEvalZero int jffs2_compressors_exit(void)
444*10465441SEvalZero {
445*10465441SEvalZero /* Unregistering compressors */
446*10465441SEvalZero #ifdef CONFIG_JFFS2_RUBIN
447*10465441SEvalZero jffs2_dynrubin_exit();
448*10465441SEvalZero jffs2_rubinmips_exit();
449*10465441SEvalZero #endif
450*10465441SEvalZero #ifdef CONFIG_JFFS2_RTIME
451*10465441SEvalZero jffs2_rtime_exit();
452*10465441SEvalZero #endif
453*10465441SEvalZero #ifdef CONFIG_JFFS2_ZLIB
454*10465441SEvalZero jffs2_zlib_exit();
455*10465441SEvalZero #endif
456*10465441SEvalZero return 0;
457*10465441SEvalZero }
458