1 /* 2 * This file is part of UBIFS. 3 * 4 * Copyright (C) 2006-2008 Nokia Corporation. 5 * Copyright (C) 2006, 2007 University of Szeged, Hungary 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program; if not, write to the Free Software Foundation, Inc., 51 18 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 * Authors: Adrian Hunter 21 * Artem Bityutskiy (Битюцкий Артём) 22 * Zoltan Sogor 23 */ 24 25 /* 26 * This file provides a single place to access to compression and 27 * decompression. 28 */ 29 30 #include <linux/crypto.h> 31 #include "ubifs.h" 32 33 /* Fake description object for the "none" compressor */ 34 static struct ubifs_compressor none_compr = { 35 .compr_type = UBIFS_COMPR_NONE, 36 .name = "no compression", 37 .capi_name = "", 38 }; 39 40 #ifdef CONFIG_UBIFS_FS_LZO 41 static DEFINE_MUTEX(lzo_mutex); 42 43 static struct ubifs_compressor lzo_compr = { 44 .compr_type = UBIFS_COMPR_LZO, 45 .comp_mutex = &lzo_mutex, 46 .name = "LZO", 47 .capi_name = "lzo", 48 }; 49 #else 50 static struct ubifs_compressor lzo_compr = { 51 .compr_type = UBIFS_COMPR_LZO, 52 .name = "LZO", 53 }; 54 #endif 55 56 #ifdef CONFIG_UBIFS_FS_ZLIB 57 static DEFINE_MUTEX(deflate_mutex); 58 static DEFINE_MUTEX(inflate_mutex); 59 60 static struct ubifs_compressor zlib_compr = { 61 .compr_type = UBIFS_COMPR_ZLIB, 62 .comp_mutex = &deflate_mutex, 63 .decomp_mutex = &inflate_mutex, 64 .name = "zlib", 65 .capi_name = "deflate", 66 }; 67 #else 68 static struct ubifs_compressor zlib_compr = { 69 .compr_type = UBIFS_COMPR_ZLIB, 70 .name = "zlib", 71 }; 72 #endif 73 74 /* All UBIFS compressors */ 75 struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; 76 77 /** 78 * ubifs_compress - compress data. 79 * @in_buf: data to compress 80 * @in_len: length of the data to compress 81 * @out_buf: output buffer where compressed data should be stored 82 * @out_len: output buffer length is returned here 83 * @compr_type: type of compression to use on enter, actually used compression 84 * type on exit 85 * 86 * This function compresses input buffer @in_buf of length @in_len and stores 87 * the result in the output buffer @out_buf and the resulting length in 88 * @out_len. If the input buffer does not compress, it is just copied to the 89 * @out_buf. The same happens if @compr_type is %UBIFS_COMPR_NONE or if 90 * compression error occurred. 91 * 92 * Note, if the input buffer was not compressed, it is copied to the output 93 * buffer and %UBIFS_COMPR_NONE is returned in @compr_type. 94 * 95 * This functions returns %0 on success or a negative error code on failure. 96 */ 97 void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, 98 int *compr_type) 99 { 100 int err; 101 struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; 102 103 if (*compr_type == UBIFS_COMPR_NONE) 104 goto no_compr; 105 106 /* If the input data is small, do not even try to compress it */ 107 if (in_len < UBIFS_MIN_COMPR_LEN) 108 goto no_compr; 109 110 if (compr->comp_mutex) 111 mutex_lock(compr->comp_mutex); 112 err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, 113 out_len); 114 if (compr->comp_mutex) 115 mutex_unlock(compr->comp_mutex); 116 if (unlikely(err)) { 117 ubifs_warn("cannot compress %d bytes, compressor %s, " 118 "error %d, leave data uncompressed", 119 in_len, compr->name, err); 120 goto no_compr; 121 } 122 123 /* 124 * Presently, we just require that compression results in less data, 125 * rather than any defined minimum compression ratio or amount. 126 */ 127 if (ALIGN(*out_len, 8) >= ALIGN(in_len, 8)) 128 goto no_compr; 129 130 return; 131 132 no_compr: 133 memcpy(out_buf, in_buf, in_len); 134 *out_len = in_len; 135 *compr_type = UBIFS_COMPR_NONE; 136 } 137 138 /** 139 * ubifs_decompress - decompress data. 140 * @in_buf: data to decompress 141 * @in_len: length of the data to decompress 142 * @out_buf: output buffer where decompressed data should 143 * @out_len: output length is returned here 144 * @compr_type: type of compression 145 * 146 * This function decompresses data from buffer @in_buf into buffer @out_buf. 147 * The length of the uncompressed data is returned in @out_len. This functions 148 * returns %0 on success or a negative error code on failure. 149 */ 150 int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, 151 int *out_len, int compr_type) 152 { 153 int err; 154 struct ubifs_compressor *compr; 155 156 if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { 157 ubifs_err("invalid compression type %d", compr_type); 158 return -EINVAL; 159 } 160 161 compr = ubifs_compressors[compr_type]; 162 163 if (unlikely(!compr->capi_name)) { 164 ubifs_err("%s compression is not compiled in", compr->name); 165 return -EINVAL; 166 } 167 168 if (compr_type == UBIFS_COMPR_NONE) { 169 memcpy(out_buf, in_buf, in_len); 170 *out_len = in_len; 171 return 0; 172 } 173 174 if (compr->decomp_mutex) 175 mutex_lock(compr->decomp_mutex); 176 err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf, 177 out_len); 178 if (compr->decomp_mutex) 179 mutex_unlock(compr->decomp_mutex); 180 if (err) 181 ubifs_err("cannot decompress %d bytes, compressor %s, " 182 "error %d", in_len, compr->name, err); 183 184 return err; 185 } 186 187 /** 188 * compr_init - initialize a compressor. 189 * @compr: compressor description object 190 * 191 * This function initializes the requested compressor and returns zero in case 192 * of success or a negative error code in case of failure. 193 */ 194 static int __init compr_init(struct ubifs_compressor *compr) 195 { 196 if (compr->capi_name) { 197 compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0); 198 if (IS_ERR(compr->cc)) { 199 ubifs_err("cannot initialize compressor %s, error %ld", 200 compr->name, PTR_ERR(compr->cc)); 201 return PTR_ERR(compr->cc); 202 } 203 } 204 205 ubifs_compressors[compr->compr_type] = compr; 206 return 0; 207 } 208 209 /** 210 * compr_exit - de-initialize a compressor. 211 * @compr: compressor description object 212 */ 213 static void compr_exit(struct ubifs_compressor *compr) 214 { 215 if (compr->capi_name) 216 crypto_free_comp(compr->cc); 217 return; 218 } 219 220 /** 221 * ubifs_compressors_init - initialize UBIFS compressors. 222 * 223 * This function initializes the compressor which were compiled in. Returns 224 * zero in case of success and a negative error code in case of failure. 225 */ 226 int __init ubifs_compressors_init(void) 227 { 228 int err; 229 230 err = compr_init(&lzo_compr); 231 if (err) 232 return err; 233 234 err = compr_init(&zlib_compr); 235 if (err) 236 goto out_lzo; 237 238 ubifs_compressors[UBIFS_COMPR_NONE] = &none_compr; 239 return 0; 240 241 out_lzo: 242 compr_exit(&lzo_compr); 243 return err; 244 } 245 246 /** 247 * ubifs_compressors_exit - de-initialize UBIFS compressors. 248 */ 249 void __exit ubifs_compressors_exit(void) 250 { 251 compr_exit(&lzo_compr); 252 compr_exit(&zlib_compr); 253 } 254