xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/src/compr.c (revision 104654410c56c573564690304ae786df310c91fc)
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