Lines 35-42
Link Here
|
35 |
#include <linux/sched.h> |
35 |
#include <linux/sched.h> |
36 |
|
36 |
|
37 |
#include "squashfs.h" |
37 |
#include "squashfs.h" |
|
|
38 |
#include "../../lib/lzma/sqlzma.h" |
39 |
#include "sqmagic.h" |
38 |
|
40 |
|
39 |
int squashfs_cached_blks; |
41 |
#undef KeepPreemptive |
|
|
42 |
#if defined(CONFIG_PREEMPT) && !defined(UnsquashNoPreempt) |
43 |
#define KeepPreemptive |
44 |
#endif |
45 |
|
46 |
struct sqlzma { |
47 |
#ifdef KeepPreemptive |
48 |
struct mutex mtx; |
49 |
#endif |
50 |
unsigned char read_data[SQUASHFS_FILE_MAX_SIZE]; |
51 |
struct sqlzma_un un; |
52 |
}; |
53 |
static DEFINE_PER_CPU(struct sqlzma *, sqlzma); |
54 |
|
55 |
#define dpri(fmt, args...) /* printk("%s:%d: " fmt, __func__, __LINE__, ##args) */ |
56 |
#define dpri_un(un) dpri("un{%d, {%d %p}, {%d %p}, {%d %p}}\n", \ |
57 |
(un)->un_lzma, (un)->un_a[0].sz, (un)->un_a[0].buf, \ |
58 |
(un)->un_a[1].sz, (un)->un_a[1].buf, \ |
59 |
(un)->un_a[2].sz, (un)->un_a[2].buf) |
60 |
|
61 |
static int squashfs_cached_blks; |
40 |
|
62 |
|
41 |
static struct dentry *squashfs_get_parent(struct dentry *child); |
63 |
static struct dentry *squashfs_get_parent(struct dentry *child); |
42 |
static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); |
64 |
static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); |
Lines 242-276
Link Here
|
242 |
} |
264 |
} |
243 |
|
265 |
|
244 |
if (compressed) { |
266 |
if (compressed) { |
245 |
int zlib_err = 0; |
267 |
int zlib_err = Z_STREAM_END; |
|
|
268 |
int start; |
269 |
enum {Src, Dst}; |
270 |
struct sized_buf sbuf[2]; |
271 |
struct sqlzma *percpu; |
272 |
unsigned char *p; |
246 |
|
273 |
|
247 |
/* |
274 |
/* |
248 |
* uncompress block |
275 |
* uncompress block |
249 |
*/ |
276 |
*/ |
250 |
|
277 |
|
251 |
mutex_lock(&msblk->read_data_mutex); |
278 |
/* mutex_lock(&msblk->read_data_mutex); */ |
252 |
|
|
|
253 |
msblk->stream.next_out = buffer; |
254 |
msblk->stream.avail_out = srclength; |
255 |
|
256 |
for (bytes = 0; k < b; k++) { |
257 |
avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); |
258 |
|
279 |
|
|
|
280 |
start = k; |
281 |
for (; k < b; k++) { |
259 |
wait_on_buffer(bh[k]); |
282 |
wait_on_buffer(bh[k]); |
260 |
if (!buffer_uptodate(bh[k])) |
283 |
if (!buffer_uptodate(bh[k])) |
261 |
goto release_mutex; |
284 |
goto release_mutex; |
|
|
285 |
} |
262 |
|
286 |
|
263 |
msblk->stream.next_in = bh[k]->b_data + offset; |
287 |
/* it disables preemption */ |
264 |
msblk->stream.avail_in = avail_bytes; |
288 |
percpu = get_cpu_var(sqlzma); |
|
|
289 |
#ifdef KeepPreemptive |
290 |
put_cpu_var(sqlzma); |
291 |
mutex_lock(&percpu->mtx); |
292 |
#endif |
293 |
p = percpu->read_data; |
294 |
k = start; |
295 |
for (bytes = 0; k < b; k++) { |
296 |
avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); |
265 |
|
297 |
|
266 |
if (k == 0) { |
298 |
if (k == 0) { |
267 |
zlib_err = zlib_inflateInit(&msblk->stream); |
299 |
/* |
268 |
if (zlib_err != Z_OK) { |
300 |
* keep this block structture to simplify the |
269 |
ERROR("zlib_inflateInit returned unexpected result 0x%x," |
301 |
* diff. |
270 |
" srclength %d\n", zlib_err, srclength); |
302 |
*/ |
271 |
goto release_mutex; |
|
|
272 |
} |
273 |
|
274 |
if (avail_bytes == 0) { |
303 |
if (avail_bytes == 0) { |
275 |
offset = 0; |
304 |
offset = 0; |
276 |
brelse(bh[k]); |
305 |
brelse(bh[k]); |
Lines 278-307
Link Here
|
278 |
} |
307 |
} |
279 |
} |
308 |
} |
280 |
|
309 |
|
281 |
zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); |
310 |
memcpy(p, bh[k]->b_data + offset, avail_bytes); |
282 |
if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { |
311 |
p += avail_bytes; |
283 |
ERROR("zlib_inflate returned unexpected result 0x%x," |
312 |
#if 0 |
284 |
" srclength %d, avail_in %d, avail_out %d\n", zlib_err, |
313 |
BUG_ON(percpu->read_data + sizeof(percpu->read_data) |
285 |
srclength, msblk->stream.avail_in, msblk->stream.avail_out); |
314 |
< p); |
286 |
goto release_mutex; |
315 |
#endif |
287 |
} |
|
|
288 |
|
316 |
|
289 |
bytes += avail_bytes; |
317 |
bytes += avail_bytes; |
290 |
offset = 0; |
318 |
offset = 0; |
291 |
brelse(bh[k]); |
319 |
brelse(bh[k]); |
292 |
} |
320 |
} |
293 |
|
321 |
|
294 |
if (zlib_err != Z_STREAM_END) |
322 |
sbuf[Src].buf = percpu->read_data; |
295 |
goto release_mutex; |
323 |
sbuf[Src].sz = bytes; |
296 |
|
324 |
sbuf[Dst].buf = buffer; |
297 |
zlib_err = zlib_inflateEnd(&msblk->stream); |
325 |
sbuf[Dst].sz = srclength; |
298 |
if (zlib_err != Z_OK) { |
326 |
dpri_un(&percpu->un); |
299 |
ERROR("zlib_inflateEnd returned unexpected result 0x%x," |
327 |
dpri("src %d %p, dst %d %p\n", sbuf[Src].sz, sbuf[Src].buf, |
300 |
" srclength %d\n", zlib_err, srclength); |
328 |
sbuf[Dst].sz, sbuf[Dst].buf); |
|
|
329 |
zlib_err = sqlzma_un(&percpu->un, sbuf + Src, sbuf + Dst); |
330 |
bytes = percpu->un.un_reslen; |
331 |
|
332 |
#ifdef KeepPreemptive |
333 |
mutex_unlock(&percpu->mtx); |
334 |
#else |
335 |
put_cpu_var(sqlzma); |
336 |
#endif |
337 |
if (unlikely(zlib_err)) { |
338 |
dpri("zlib_err %d\n", zlib_err); |
301 |
goto release_mutex; |
339 |
goto release_mutex; |
302 |
} |
340 |
} |
303 |
bytes = msblk->stream.total_out; |
341 |
/* mutex_unlock(&msblk->read_data_mutex); */ |
304 |
mutex_unlock(&msblk->read_data_mutex); |
|
|
305 |
} else { |
342 |
} else { |
306 |
int i; |
343 |
int i; |
307 |
|
344 |
|
Lines 329-335
Link Here
|
329 |
return bytes; |
366 |
return bytes; |
330 |
|
367 |
|
331 |
release_mutex: |
368 |
release_mutex: |
332 |
mutex_unlock(&msblk->read_data_mutex); |
369 |
/* mutex_unlock(&msblk->read_data_mutex); */ |
333 |
|
370 |
|
334 |
block_release: |
371 |
block_release: |
335 |
for (; k < b; k++) |
372 |
for (; k < b; k++) |
Lines 1083-1094
Link Here
|
1083 |
{ |
1120 |
{ |
1084 |
struct squashfs_sb_info *msblk; |
1121 |
struct squashfs_sb_info *msblk; |
1085 |
struct squashfs_super_block *sblk; |
1122 |
struct squashfs_super_block *sblk; |
1086 |
int i; |
1123 |
int i, err; |
1087 |
char b[BDEVNAME_SIZE]; |
1124 |
char b[BDEVNAME_SIZE]; |
1088 |
struct inode *root; |
1125 |
struct inode *root; |
1089 |
|
1126 |
|
1090 |
TRACE("Entered squashfs_fill_superblock\n"); |
1127 |
TRACE("Entered squashfs_fill_superblock\n"); |
1091 |
|
1128 |
|
|
|
1129 |
err = -ENOMEM; |
1092 |
s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL); |
1130 |
s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL); |
1093 |
if (s->s_fs_info == NULL) { |
1131 |
if (s->s_fs_info == NULL) { |
1094 |
ERROR("Failed to allocate superblock\n"); |
1132 |
ERROR("Failed to allocate superblock\n"); |
Lines 1096-1112
Link Here
|
1096 |
} |
1134 |
} |
1097 |
msblk = s->s_fs_info; |
1135 |
msblk = s->s_fs_info; |
1098 |
|
1136 |
|
1099 |
msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()); |
|
|
1100 |
if (msblk->stream.workspace == NULL) { |
1101 |
ERROR("Failed to allocate zlib workspace\n"); |
1102 |
goto failure; |
1103 |
} |
1104 |
sblk = &msblk->sblk; |
1137 |
sblk = &msblk->sblk; |
1105 |
|
1138 |
|
1106 |
msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); |
1139 |
msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); |
1107 |
msblk->devblksize_log2 = ffz(~msblk->devblksize); |
1140 |
msblk->devblksize_log2 = ffz(~msblk->devblksize); |
1108 |
|
1141 |
|
1109 |
mutex_init(&msblk->read_data_mutex); |
1142 |
/* mutex_init(&msblk->read_data_mutex); */ |
1110 |
mutex_init(&msblk->read_page_mutex); |
1143 |
mutex_init(&msblk->read_page_mutex); |
1111 |
mutex_init(&msblk->block_cache_mutex); |
1144 |
mutex_init(&msblk->block_cache_mutex); |
1112 |
mutex_init(&msblk->fragment_mutex); |
1145 |
mutex_init(&msblk->fragment_mutex); |
Lines 1118-1123
Link Here
|
1118 |
/* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not |
1151 |
/* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not |
1119 |
* beyond filesystem end. As we're using squashfs_read_data to read sblk here, |
1152 |
* beyond filesystem end. As we're using squashfs_read_data to read sblk here, |
1120 |
* first set sblk->bytes_used to a useful value */ |
1153 |
* first set sblk->bytes_used to a useful value */ |
|
|
1154 |
err = -EINVAL; |
1121 |
sblk->bytes_used = sizeof(struct squashfs_super_block); |
1155 |
sblk->bytes_used = sizeof(struct squashfs_super_block); |
1122 |
if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, |
1156 |
if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, |
1123 |
sizeof(struct squashfs_super_block) | |
1157 |
sizeof(struct squashfs_super_block) | |
Lines 1127-1147
Link Here
|
1127 |
} |
1161 |
} |
1128 |
|
1162 |
|
1129 |
/* Check it is a SQUASHFS superblock */ |
1163 |
/* Check it is a SQUASHFS superblock */ |
1130 |
if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { |
1164 |
s->s_magic = sblk->s_magic; |
1131 |
if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { |
1165 |
msblk->swap = 0; |
1132 |
struct squashfs_super_block ssblk; |
1166 |
dpri("magic 0x%x\n", sblk->s_magic); |
1133 |
|
1167 |
switch (sblk->s_magic) { |
1134 |
WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", |
1168 |
struct squashfs_super_block ssblk; |
1135 |
bdevname(s->s_bdev, b)); |
1169 |
|
1136 |
|
1170 |
case SQUASHFS_MAGIC_SWAP: |
1137 |
SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); |
1171 |
/*FALLTHROUGH*/ |
1138 |
memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); |
1172 |
case SQUASHFS_MAGIC_LZMA_SWAP: |
1139 |
msblk->swap = 1; |
1173 |
WARNING("Mounting a different endian SQUASHFS " |
1140 |
} else { |
1174 |
"filesystem on %s\n", bdevname(s->s_bdev, b)); |
1141 |
SERROR("Can't find a SQUASHFS superblock on %s\n", |
1175 |
|
1142 |
bdevname(s->s_bdev, b)); |
1176 |
SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); |
1143 |
goto failed_mount; |
1177 |
memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); |
1144 |
} |
1178 |
msblk->swap = 1; |
|
|
1179 |
/*FALLTHROUGH*/ |
1180 |
case SQUASHFS_MAGIC: |
1181 |
case SQUASHFS_MAGIC_LZMA: |
1182 |
break; |
1183 |
default: |
1184 |
SERROR("Can't find a SQUASHFS superblock on %s\n", |
1185 |
bdevname(s->s_bdev, b)); |
1186 |
goto failed_mount; |
1187 |
} |
1188 |
|
1189 |
{ |
1190 |
struct sqlzma *p; |
1191 |
dpri("block_size %d, devblksize %d\n", |
1192 |
sblk->block_size, msblk->devblksize); |
1193 |
BUG_ON(sblk->block_size > sizeof(p->read_data)); |
1145 |
} |
1194 |
} |
1146 |
|
1195 |
|
1147 |
/* Check the MAJOR & MINOR versions */ |
1196 |
/* Check the MAJOR & MINOR versions */ |
Lines 1185-1190
Link Here
|
1185 |
goto failed_mount; |
1234 |
goto failed_mount; |
1186 |
|
1235 |
|
1187 |
/* Allocate read_page block */ |
1236 |
/* Allocate read_page block */ |
|
|
1237 |
err = -ENOMEM; |
1188 |
msblk->read_page = vmalloc(sblk->block_size); |
1238 |
msblk->read_page = vmalloc(sblk->block_size); |
1189 |
if (msblk->read_page == NULL) { |
1239 |
if (msblk->read_page == NULL) { |
1190 |
ERROR("Failed to allocate read_page block\n"); |
1240 |
ERROR("Failed to allocate read_page block\n"); |
Lines 1200-1218
Link Here
|
1200 |
} |
1250 |
} |
1201 |
msblk->guid = msblk->uid + sblk->no_uids; |
1251 |
msblk->guid = msblk->uid + sblk->no_uids; |
1202 |
|
1252 |
|
|
|
1253 |
dpri("swap %d\n", msblk->swap); |
1254 |
err = -EINVAL; |
1203 |
if (msblk->swap) { |
1255 |
if (msblk->swap) { |
1204 |
unsigned int suid[sblk->no_uids + sblk->no_guids]; |
1256 |
unsigned int *suid; |
|
|
1257 |
|
1258 |
err = -ENOMEM; |
1259 |
suid = kmalloc(sizeof(*suid) * (sblk->no_uids + sblk->no_guids), |
1260 |
GFP_KERNEL); |
1261 |
if (unlikely(!suid)) |
1262 |
goto failed_mount; |
1205 |
|
1263 |
|
|
|
1264 |
err = -EINVAL; |
1206 |
if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, |
1265 |
if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, |
1207 |
((sblk->no_uids + sblk->no_guids) * |
1266 |
((sblk->no_uids + sblk->no_guids) * |
1208 |
sizeof(unsigned int)) | |
1267 |
sizeof(unsigned int)) | |
1209 |
SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { |
1268 |
SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { |
1210 |
ERROR("unable to read uid/gid table\n"); |
1269 |
ERROR("unable to read uid/gid table\n"); |
|
|
1270 |
kfree(suid); |
1211 |
goto failed_mount; |
1271 |
goto failed_mount; |
1212 |
} |
1272 |
} |
1213 |
|
1273 |
|
1214 |
SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + |
1274 |
SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + |
1215 |
sblk->no_guids), (sizeof(unsigned int) * 8)); |
1275 |
sblk->no_guids), (sizeof(unsigned int) * 8)); |
|
|
1276 |
kfree(suid); |
1216 |
} else |
1277 |
} else |
1217 |
if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, |
1278 |
if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, |
1218 |
((sblk->no_uids + sblk->no_guids) * |
1279 |
((sblk->no_uids + sblk->no_guids) * |
Lines 1226-1231
Link Here
|
1226 |
if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) |
1287 |
if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) |
1227 |
goto allocate_root; |
1288 |
goto allocate_root; |
1228 |
|
1289 |
|
|
|
1290 |
err = -ENOMEM; |
1229 |
msblk->fragment = kzalloc(sizeof(struct squashfs_fragment_cache) * |
1291 |
msblk->fragment = kzalloc(sizeof(struct squashfs_fragment_cache) * |
1230 |
SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL); |
1292 |
SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL); |
1231 |
if (msblk->fragment == NULL) { |
1293 |
if (msblk->fragment == NULL) { |
Lines 1255-1263
Link Here
|
1255 |
s->s_export_op = &squashfs_export_ops; |
1317 |
s->s_export_op = &squashfs_export_ops; |
1256 |
|
1318 |
|
1257 |
allocate_root: |
1319 |
allocate_root: |
|
|
1320 |
dpri("alloate_root\n"); |
1258 |
root = new_inode(s); |
1321 |
root = new_inode(s); |
1259 |
if ((msblk->read_inode)(root, sblk->root_inode) == 0) |
1322 |
if ((msblk->read_inode)(root, sblk->root_inode) == 0) { |
|
|
1323 |
iput(root); |
1260 |
goto failed_mount; |
1324 |
goto failed_mount; |
|
|
1325 |
} |
1261 |
insert_inode_hash(root); |
1326 |
insert_inode_hash(root); |
1262 |
|
1327 |
|
1263 |
s->s_root = d_alloc_root(root); |
1328 |
s->s_root = d_alloc_root(root); |
Lines 1278-1290
Link Here
|
1278 |
vfree(msblk->read_page); |
1343 |
vfree(msblk->read_page); |
1279 |
kfree(msblk->block_cache); |
1344 |
kfree(msblk->block_cache); |
1280 |
kfree(msblk->fragment_index_2); |
1345 |
kfree(msblk->fragment_index_2); |
1281 |
vfree(msblk->stream.workspace); |
|
|
1282 |
kfree(s->s_fs_info); |
1346 |
kfree(s->s_fs_info); |
1283 |
s->s_fs_info = NULL; |
1347 |
s->s_fs_info = NULL; |
1284 |
return -EINVAL; |
1348 |
failure: |
1285 |
|
1349 |
return err; |
1286 |
failure: |
|
|
1287 |
return -ENOMEM; |
1288 |
} |
1350 |
} |
1289 |
|
1351 |
|
1290 |
|
1352 |
|
Lines 1295-1301
Link Here
|
1295 |
|
1357 |
|
1296 |
TRACE("Entered squashfs_statfs\n"); |
1358 |
TRACE("Entered squashfs_statfs\n"); |
1297 |
|
1359 |
|
1298 |
buf->f_type = SQUASHFS_MAGIC; |
1360 |
buf->f_type = sblk->s_magic; |
1299 |
buf->f_bsize = sblk->block_size; |
1361 |
buf->f_bsize = sblk->block_size; |
1300 |
buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; |
1362 |
buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; |
1301 |
buf->f_bfree = buf->f_bavail = 0; |
1363 |
buf->f_bfree = buf->f_bavail = 0; |
Lines 1457-1471
Link Here
|
1457 |
int block = 0; |
1519 |
int block = 0; |
1458 |
|
1520 |
|
1459 |
if (msblk->swap) { |
1521 |
if (msblk->swap) { |
1460 |
char sblock_list[blocks << 2]; |
1522 |
char *sblock_list; |
|
|
1523 |
|
1524 |
sblock_list = kmalloc(blocks << 2, GFP_KERNEL); |
1525 |
if (unlikely(!sblock_list)) |
1526 |
goto failure; |
1461 |
|
1527 |
|
1462 |
if (!squashfs_get_cached_block(s, sblock_list, *start_block, |
1528 |
if (!squashfs_get_cached_block(s, sblock_list, *start_block, |
1463 |
*offset, blocks << 2, start_block, offset)) { |
1529 |
*offset, blocks << 2, start_block, offset)) { |
1464 |
ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); |
1530 |
ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); |
|
|
1531 |
kfree(sblock_list); |
1465 |
goto failure; |
1532 |
goto failure; |
1466 |
} |
1533 |
} |
1467 |
SQUASHFS_SWAP_INTS(((unsigned int *)block_list), |
1534 |
SQUASHFS_SWAP_INTS(((unsigned int *)block_list), |
1468 |
((unsigned int *)sblock_list), blocks); |
1535 |
((unsigned int *)sblock_list), blocks); |
|
|
1536 |
kfree(sblock_list); |
1469 |
} else { |
1537 |
} else { |
1470 |
if (!squashfs_get_cached_block(s, block_list, *start_block, |
1538 |
if (!squashfs_get_cached_block(s, block_list, *start_block, |
1471 |
*offset, blocks << 2, start_block, offset)) { |
1539 |
*offset, blocks << 2, start_block, offset)) { |
Lines 2097-2103
Link Here
|
2097 |
kfree(sbi->fragment_index); |
2165 |
kfree(sbi->fragment_index); |
2098 |
kfree(sbi->fragment_index_2); |
2166 |
kfree(sbi->fragment_index_2); |
2099 |
kfree(sbi->meta_index); |
2167 |
kfree(sbi->meta_index); |
2100 |
vfree(sbi->stream.workspace); |
|
|
2101 |
kfree(s->s_fs_info); |
2168 |
kfree(s->s_fs_info); |
2102 |
s->s_fs_info = NULL; |
2169 |
s->s_fs_info = NULL; |
2103 |
} |
2170 |
} |
Lines 2111-2129
Link Here
|
2111 |
mnt); |
2178 |
mnt); |
2112 |
} |
2179 |
} |
2113 |
|
2180 |
|
|
|
2181 |
static void free_sqlzma(void) |
2182 |
{ |
2183 |
int cpu; |
2184 |
struct sqlzma *p; |
2185 |
|
2186 |
for_each_online_cpu(cpu) { |
2187 |
p = per_cpu(sqlzma, cpu); |
2188 |
if (p) { |
2189 |
#ifdef KeepPreemptive |
2190 |
mutex_destroy(&p->mtx); |
2191 |
#endif |
2192 |
sqlzma_fin(&p->un); |
2193 |
kfree(p); |
2194 |
} |
2195 |
} |
2196 |
} |
2114 |
|
2197 |
|
2115 |
static int __init init_squashfs_fs(void) |
2198 |
static int __init init_squashfs_fs(void) |
2116 |
{ |
2199 |
{ |
|
|
2200 |
struct sqlzma *p; |
2201 |
int cpu; |
2117 |
int err = init_inodecache(); |
2202 |
int err = init_inodecache(); |
2118 |
if (err) |
2203 |
if (err) |
2119 |
goto out; |
2204 |
goto out; |
2120 |
|
2205 |
|
|
|
2206 |
for_each_online_cpu(cpu) { |
2207 |
dpri("%d: %p\n", cpu, per_cpu(sqlzma, cpu)); |
2208 |
err = -ENOMEM; |
2209 |
p = kmalloc(sizeof(struct sqlzma), GFP_KERNEL); |
2210 |
if (p) { |
2211 |
#ifdef KeepPreemptive |
2212 |
mutex_init(&p->mtx); |
2213 |
#endif |
2214 |
err = sqlzma_init(&p->un, 1, 0); |
2215 |
if (unlikely(err)) { |
2216 |
ERROR("Failed to intialize uncompress workspace\n"); |
2217 |
break; |
2218 |
} |
2219 |
per_cpu(sqlzma, cpu) = p; |
2220 |
err = 0; |
2221 |
} else |
2222 |
break; |
2223 |
} |
2224 |
if (unlikely(err)) { |
2225 |
free_sqlzma(); |
2226 |
goto out; |
2227 |
} |
2228 |
|
2121 |
printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) " |
2229 |
printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) " |
2122 |
"Phillip Lougher\n"); |
2230 |
"Phillip Lougher\n" |
|
|
2231 |
"squashfs: LZMA suppport for slax.org by jro\n"); |
2123 |
|
2232 |
|
2124 |
err = register_filesystem(&squashfs_fs_type); |
2233 |
err = register_filesystem(&squashfs_fs_type); |
2125 |
if (err) |
2234 |
if (err) { |
|
|
2235 |
free_sqlzma(); |
2126 |
destroy_inodecache(); |
2236 |
destroy_inodecache(); |
|
|
2237 |
} |
2127 |
|
2238 |
|
2128 |
out: |
2239 |
out: |
2129 |
return err; |
2240 |
return err; |
Lines 2133-2138
Link Here
|
2133 |
static void __exit exit_squashfs_fs(void) |
2244 |
static void __exit exit_squashfs_fs(void) |
2134 |
{ |
2245 |
{ |
2135 |
unregister_filesystem(&squashfs_fs_type); |
2246 |
unregister_filesystem(&squashfs_fs_type); |
|
|
2247 |
free_sqlzma(); |
2136 |
destroy_inodecache(); |
2248 |
destroy_inodecache(); |
2137 |
} |
2249 |
} |
2138 |
|
2250 |
|
Lines 2181-2186
Link Here
|
2181 |
|
2293 |
|
2182 |
module_init(init_squashfs_fs); |
2294 |
module_init(init_squashfs_fs); |
2183 |
module_exit(exit_squashfs_fs); |
2295 |
module_exit(exit_squashfs_fs); |
2184 |
MODULE_DESCRIPTION("squashfs 3.2-r2-CVS, a compressed read-only filesystem"); |
2296 |
MODULE_DESCRIPTION("squashfs 3.2-r2-CVS, a compressed read-only filesystem, and LZMA suppport for slax.org"); |
2185 |
MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>"); |
2297 |
MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>, and LZMA suppport for slax.org by jro"); |
2186 |
MODULE_LICENSE("GPL"); |
2298 |
MODULE_LICENSE("GPL"); |