BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / linux / linux-2.6 / include / linux / squashfs_fs.h
blobce9a7797783e26852344be486cd2246c9bf4e965
1 #ifndef SQUASHFS_FS
2 #define SQUASHFS_FS
4 /*
5 * Squashfs
7 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
8 * Phillip Lougher <phillip@lougher.org.uk>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2,
13 * or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * squashfs_fs.h
27 #ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
28 #define CONFIG_SQUASHFS_2_0_COMPATIBILITY
29 #endif
31 #ifdef CONFIG_SQUASHFS_VMALLOC
32 #define SQUASHFS_ALLOC(a) vmalloc(a)
33 #define SQUASHFS_FREE(a) vfree(a)
34 #else
35 #define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL)
36 #define SQUASHFS_FREE(a) kfree(a)
37 #endif
38 #ifdef CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
39 #define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
40 #else
41 #define SQUASHFS_CACHED_FRAGMENTS 3
42 #endif
43 #define SQUASHFS_MAJOR 3
44 #define SQUASHFS_MINOR 0
45 #define SQUASHFS_MAGIC 0x73717368
46 #define SQUASHFS_MAGIC_SWAP 0x68737173
47 #define SQUASHFS_MAGIC_LZMA 0x71736873
48 #define SQUASHFS_MAGIC_LZMA_SWAP 0x73687371
49 #define SQUASHFS_START 0
51 /* size of metadata (inode and directory) blocks */
52 #define SQUASHFS_METADATA_SIZE 8192
53 #define SQUASHFS_METADATA_LOG 13
55 /* default size of data blocks */
56 #define SQUASHFS_FILE_SIZE 65536
57 #define SQUASHFS_FILE_LOG 16
59 #define SQUASHFS_FILE_MAX_SIZE 65536
61 /* Max number of uids and gids */
62 #define SQUASHFS_UIDS 256
63 #define SQUASHFS_GUIDS 255
65 /* Max length of filename (not 255) */
66 #define SQUASHFS_NAME_LEN 256
68 #define SQUASHFS_INVALID ((long long) 0xffffffffffff)
69 #define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
70 #define SQUASHFS_INVALID_BLK ((long long) -1)
71 #define SQUASHFS_USED_BLK ((long long) -2)
73 /* Filesystem flags */
74 #define SQUASHFS_NOI 0
75 #define SQUASHFS_NOD 1
76 #define SQUASHFS_CHECK 2
77 #define SQUASHFS_NOF 3
78 #define SQUASHFS_NO_FRAG 4
79 #define SQUASHFS_ALWAYS_FRAG 5
80 #define SQUASHFS_DUPLICATE 6
81 #define SQUASHFS_EXPORT 7
83 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
85 #define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
86 SQUASHFS_NOI)
88 #define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
89 SQUASHFS_NOD)
91 #define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
92 SQUASHFS_NOF)
94 #define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
95 SQUASHFS_NO_FRAG)
97 #define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
98 SQUASHFS_ALWAYS_FRAG)
100 #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
101 SQUASHFS_DUPLICATE)
103 #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
104 SQUASHFS_EXPORT)
106 #define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
107 SQUASHFS_CHECK)
109 #define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
110 duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \
111 | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
112 (duplicate_checking << 6) | (exportable << 7))
114 /* Max number of types and file types */
115 #define SQUASHFS_DIR_TYPE 1
116 #define SQUASHFS_FILE_TYPE 2
117 #define SQUASHFS_SYMLINK_TYPE 3
118 #define SQUASHFS_BLKDEV_TYPE 4
119 #define SQUASHFS_CHRDEV_TYPE 5
120 #define SQUASHFS_FIFO_TYPE 6
121 #define SQUASHFS_SOCKET_TYPE 7
122 #define SQUASHFS_LDIR_TYPE 8
123 #define SQUASHFS_LREG_TYPE 9
125 /* 1.0 filesystem type definitions */
126 #define SQUASHFS_TYPES 5
127 #define SQUASHFS_IPC_TYPE 0
129 /* Flag whether block is compressed or uncompressed, bit is set if block is
130 * uncompressed */
131 #define SQUASHFS_COMPRESSED_BIT (1 << 15)
133 #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
134 (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
136 #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
138 #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
140 #define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
141 ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
142 ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
144 #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
147 * Inode number ops. Inodes consist of a compressed block number, and an
148 * uncompressed offset within that block
150 #define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
152 #define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
154 #define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
155 << 16) + (B)))
157 /* Compute 32 bit VFS inode number from squashfs inode number */
158 #define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
159 ((b) >> 2) + 1))
161 /* Translate between VFS mode and squashfs mode */
162 #define SQUASHFS_MODE(a) ((a) & 0xfff)
164 /* fragment and fragment table defines */
165 #define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry))
167 #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
168 SQUASHFS_METADATA_SIZE)
170 #define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
171 SQUASHFS_METADATA_SIZE)
173 #define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
174 SQUASHFS_METADATA_SIZE - 1) / \
175 SQUASHFS_METADATA_SIZE)
177 #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
178 sizeof(long long))
180 /* inode lookup table defines */
181 #define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
183 #define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
184 SQUASHFS_METADATA_SIZE)
186 #define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
187 SQUASHFS_METADATA_SIZE)
189 #define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
190 SQUASHFS_METADATA_SIZE - 1) / \
191 SQUASHFS_METADATA_SIZE)
193 #define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
194 sizeof(long long))
196 /* cached data constants for filesystem */
197 #define SQUASHFS_CACHED_BLKS 8
199 #define SQUASHFS_MAX_FILE_SIZE_LOG 64
201 #define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
202 (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
204 #define SQUASHFS_MARKER_BYTE 0xff
206 /* meta index cache */
207 #define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
208 #define SQUASHFS_META_ENTRIES 31
209 #define SQUASHFS_META_NUMBER 8
210 #define SQUASHFS_SLOTS 4
212 struct meta_entry {
213 long long data_block;
214 unsigned int index_block;
215 unsigned short offset;
216 unsigned short pad;
219 struct meta_index {
220 unsigned int inode_number;
221 unsigned int offset;
222 unsigned short entries;
223 unsigned short skip;
224 unsigned short locked;
225 unsigned short pad;
226 struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
231 * definitions for structures on disk
234 typedef long long squashfs_block_t;
235 typedef long long squashfs_inode_t;
237 struct squashfs_super_block {
238 unsigned int s_magic;
239 unsigned int inodes;
240 unsigned int bytes_used_2;
241 unsigned int uid_start_2;
242 unsigned int guid_start_2;
243 unsigned int inode_table_start_2;
244 unsigned int directory_table_start_2;
245 unsigned int s_major:16;
246 unsigned int s_minor:16;
247 unsigned int block_size_1:16;
248 unsigned int block_log:16;
249 unsigned int flags:8;
250 unsigned int no_uids:8;
251 unsigned int no_guids:8;
252 unsigned int mkfs_time /* time of filesystem creation */;
253 squashfs_inode_t root_inode;
254 unsigned int block_size;
255 unsigned int fragments;
256 unsigned int fragment_table_start_2;
257 long long bytes_used;
258 long long uid_start;
259 long long guid_start;
260 long long inode_table_start;
261 long long directory_table_start;
262 long long fragment_table_start;
263 long long lookup_table_start;
264 } __attribute__ ((packed));
266 struct squashfs_dir_index {
267 unsigned int index;
268 unsigned int start_block;
269 unsigned char size;
270 unsigned char name[0];
271 } __attribute__ ((packed));
273 #define SQUASHFS_BASE_INODE_HEADER \
274 unsigned int inode_type:4; \
275 unsigned int mode:12; \
276 unsigned int uid:8; \
277 unsigned int guid:8; \
278 unsigned int mtime; \
279 unsigned int inode_number;
281 struct squashfs_base_inode_header {
282 SQUASHFS_BASE_INODE_HEADER;
283 } __attribute__ ((packed));
285 struct squashfs_ipc_inode_header {
286 SQUASHFS_BASE_INODE_HEADER;
287 unsigned int nlink;
288 } __attribute__ ((packed));
290 struct squashfs_dev_inode_header {
291 SQUASHFS_BASE_INODE_HEADER;
292 unsigned int nlink;
293 unsigned short rdev;
294 } __attribute__ ((packed));
296 struct squashfs_symlink_inode_header {
297 SQUASHFS_BASE_INODE_HEADER;
298 unsigned int nlink;
299 unsigned short symlink_size;
300 char symlink[0];
301 } __attribute__ ((packed));
303 struct squashfs_reg_inode_header {
304 SQUASHFS_BASE_INODE_HEADER;
305 squashfs_block_t start_block;
306 unsigned int fragment;
307 unsigned int offset;
308 unsigned int file_size;
309 unsigned short block_list[0];
310 } __attribute__ ((packed));
312 struct squashfs_lreg_inode_header {
313 SQUASHFS_BASE_INODE_HEADER;
314 unsigned int nlink;
315 squashfs_block_t start_block;
316 unsigned int fragment;
317 unsigned int offset;
318 long long file_size;
319 unsigned short block_list[0];
320 } __attribute__ ((packed));
322 struct squashfs_dir_inode_header {
323 SQUASHFS_BASE_INODE_HEADER;
324 unsigned int nlink;
325 unsigned int file_size:19;
326 unsigned int offset:13;
327 unsigned int start_block;
328 unsigned int parent_inode;
329 } __attribute__ ((packed));
331 struct squashfs_ldir_inode_header {
332 SQUASHFS_BASE_INODE_HEADER;
333 unsigned int nlink;
334 unsigned int file_size:27;
335 unsigned int offset:13;
336 unsigned int start_block;
337 unsigned int i_count:16;
338 unsigned int parent_inode;
339 struct squashfs_dir_index index[0];
340 } __attribute__ ((packed));
342 union squashfs_inode_header {
343 struct squashfs_base_inode_header base;
344 struct squashfs_dev_inode_header dev;
345 struct squashfs_symlink_inode_header symlink;
346 struct squashfs_reg_inode_header reg;
347 struct squashfs_lreg_inode_header lreg;
348 struct squashfs_dir_inode_header dir;
349 struct squashfs_ldir_inode_header ldir;
350 struct squashfs_ipc_inode_header ipc;
353 struct squashfs_dir_entry {
354 unsigned int offset:13;
355 unsigned int type:3;
356 unsigned int size:8;
357 int inode_number:16;
358 char name[0];
359 } __attribute__ ((packed));
361 struct squashfs_dir_header {
362 unsigned int count:8;
363 unsigned int start_block;
364 unsigned int inode_number;
365 } __attribute__ ((packed));
367 struct squashfs_fragment_entry {
368 long long start_block;
369 unsigned int size;
370 unsigned int pending;
371 } __attribute__ ((packed));
373 extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
374 extern int squashfs_uncompress_init(void);
375 extern int squashfs_uncompress_exit(void);
378 * macros to convert each packed bitfield structure from little endian to big
379 * endian and vice versa. These are needed when creating or using a filesystem
380 * on a machine with different byte ordering to the target architecture.
384 #define SQUASHFS_SWAP_START \
385 int bits;\
386 int b_pos;\
387 unsigned long long val;\
388 unsigned char *s;\
389 unsigned char *d;
391 #define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
392 SQUASHFS_SWAP_START\
393 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
394 SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
395 SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
396 SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
397 SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
398 SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
399 SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
400 SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
401 SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
402 SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
403 SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
404 SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
405 SQUASHFS_SWAP((s)->flags, d, 288, 8);\
406 SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
407 SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
408 SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
409 SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
410 SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
411 SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
412 SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
413 SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
414 SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
415 SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
416 SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
417 SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
418 SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
419 SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
422 #define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
423 SQUASHFS_MEMSET(s, d, n);\
424 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
425 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
426 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
427 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
428 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
429 SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
431 #define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
432 SQUASHFS_SWAP_START\
433 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
436 #define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
437 SQUASHFS_SWAP_START\
438 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
439 sizeof(struct squashfs_ipc_inode_header))\
440 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
443 #define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
444 SQUASHFS_SWAP_START\
445 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
446 sizeof(struct squashfs_dev_inode_header)); \
447 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
448 SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
451 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
452 SQUASHFS_SWAP_START\
453 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
454 sizeof(struct squashfs_symlink_inode_header));\
455 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
456 SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
459 #define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
460 SQUASHFS_SWAP_START\
461 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
462 sizeof(struct squashfs_reg_inode_header));\
463 SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
464 SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
465 SQUASHFS_SWAP((s)->offset, d, 192, 32);\
466 SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
469 #define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
470 SQUASHFS_SWAP_START\
471 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
472 sizeof(struct squashfs_lreg_inode_header));\
473 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
474 SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
475 SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
476 SQUASHFS_SWAP((s)->offset, d, 224, 32);\
477 SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
480 #define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
481 SQUASHFS_SWAP_START\
482 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
483 sizeof(struct squashfs_dir_inode_header));\
484 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
485 SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
486 SQUASHFS_SWAP((s)->offset, d, 147, 13);\
487 SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
488 SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
491 #define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
492 SQUASHFS_SWAP_START\
493 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
494 sizeof(struct squashfs_ldir_inode_header));\
495 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
496 SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
497 SQUASHFS_SWAP((s)->offset, d, 155, 13);\
498 SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
499 SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
500 SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
503 #define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
504 SQUASHFS_SWAP_START\
505 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
506 SQUASHFS_SWAP((s)->index, d, 0, 32);\
507 SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
508 SQUASHFS_SWAP((s)->size, d, 64, 8);\
511 #define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
512 SQUASHFS_SWAP_START\
513 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
514 SQUASHFS_SWAP((s)->count, d, 0, 8);\
515 SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
516 SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
519 #define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
520 SQUASHFS_SWAP_START\
521 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
522 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
523 SQUASHFS_SWAP((s)->type, d, 13, 3);\
524 SQUASHFS_SWAP((s)->size, d, 16, 8);\
525 SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
528 #define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
529 SQUASHFS_SWAP_START\
530 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
531 SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
532 SQUASHFS_SWAP((s)->size, d, 64, 32);\
535 #define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
537 #define SQUASHFS_SWAP_SHORTS(s, d, n) {\
538 int entry;\
539 int bit_position;\
540 SQUASHFS_SWAP_START\
541 SQUASHFS_MEMSET(s, d, n * 2);\
542 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
543 16)\
544 SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
547 #define SQUASHFS_SWAP_INTS(s, d, n) {\
548 int entry;\
549 int bit_position;\
550 SQUASHFS_SWAP_START\
551 SQUASHFS_MEMSET(s, d, n * 4);\
552 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
553 32)\
554 SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
557 #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
558 int entry;\
559 int bit_position;\
560 SQUASHFS_SWAP_START\
561 SQUASHFS_MEMSET(s, d, n * 8);\
562 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
563 64)\
564 SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
567 #define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
568 int entry;\
569 int bit_position;\
570 SQUASHFS_SWAP_START\
571 SQUASHFS_MEMSET(s, d, n * bits / 8);\
572 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
573 bits)\
574 SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
577 #define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
578 #define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
580 #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
582 struct squashfs_base_inode_header_1 {
583 unsigned int inode_type:4;
584 unsigned int mode:12; /* protection */
585 unsigned int uid:4; /* index into uid table */
586 unsigned int guid:4; /* index into guid table */
587 } __attribute__ ((packed));
589 struct squashfs_ipc_inode_header_1 {
590 unsigned int inode_type:4;
591 unsigned int mode:12; /* protection */
592 unsigned int uid:4; /* index into uid table */
593 unsigned int guid:4; /* index into guid table */
594 unsigned int type:4;
595 unsigned int offset:4;
596 } __attribute__ ((packed));
598 struct squashfs_dev_inode_header_1 {
599 unsigned int inode_type:4;
600 unsigned int mode:12; /* protection */
601 unsigned int uid:4; /* index into uid table */
602 unsigned int guid:4; /* index into guid table */
603 unsigned short rdev;
604 } __attribute__ ((packed));
606 struct squashfs_symlink_inode_header_1 {
607 unsigned int inode_type:4;
608 unsigned int mode:12; /* protection */
609 unsigned int uid:4; /* index into uid table */
610 unsigned int guid:4; /* index into guid table */
611 unsigned short symlink_size;
612 char symlink[0];
613 } __attribute__ ((packed));
615 struct squashfs_reg_inode_header_1 {
616 unsigned int inode_type:4;
617 unsigned int mode:12; /* protection */
618 unsigned int uid:4; /* index into uid table */
619 unsigned int guid:4; /* index into guid table */
620 unsigned int mtime;
621 unsigned int start_block;
622 unsigned int file_size:32;
623 unsigned short block_list[0];
624 } __attribute__ ((packed));
626 struct squashfs_dir_inode_header_1 {
627 unsigned int inode_type:4;
628 unsigned int mode:12; /* protection */
629 unsigned int uid:4; /* index into uid table */
630 unsigned int guid:4; /* index into guid table */
631 unsigned int file_size:19;
632 unsigned int offset:13;
633 unsigned int mtime;
634 unsigned int start_block:24;
635 } __attribute__ ((packed));
637 #define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
638 SQUASHFS_MEMSET(s, d, n);\
639 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
640 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
641 SQUASHFS_SWAP((s)->uid, d, 16, 4);\
642 SQUASHFS_SWAP((s)->guid, d, 20, 4);
644 #define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
645 SQUASHFS_SWAP_START\
646 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
649 #define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
650 SQUASHFS_SWAP_START\
651 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
652 sizeof(struct squashfs_ipc_inode_header_1));\
653 SQUASHFS_SWAP((s)->type, d, 24, 4);\
654 SQUASHFS_SWAP((s)->offset, d, 28, 4);\
657 #define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
658 SQUASHFS_SWAP_START\
659 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
660 sizeof(struct squashfs_dev_inode_header_1));\
661 SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
664 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
665 SQUASHFS_SWAP_START\
666 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
667 sizeof(struct squashfs_symlink_inode_header_1));\
668 SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
671 #define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
672 SQUASHFS_SWAP_START\
673 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
674 sizeof(struct squashfs_reg_inode_header_1));\
675 SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
676 SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
677 SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
680 #define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
681 SQUASHFS_SWAP_START\
682 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
683 sizeof(struct squashfs_dir_inode_header_1));\
684 SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
685 SQUASHFS_SWAP((s)->offset, d, 43, 13);\
686 SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
687 SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
690 #endif
692 #ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
694 struct squashfs_dir_index_2 {
695 unsigned int index:27;
696 unsigned int start_block:29;
697 unsigned char size;
698 unsigned char name[0];
699 } __attribute__ ((packed));
701 struct squashfs_base_inode_header_2 {
702 unsigned int inode_type:4;
703 unsigned int mode:12; /* protection */
704 unsigned int uid:8; /* index into uid table */
705 unsigned int guid:8; /* index into guid table */
706 } __attribute__ ((packed));
708 struct squashfs_ipc_inode_header_2 {
709 unsigned int inode_type:4;
710 unsigned int mode:12; /* protection */
711 unsigned int uid:8; /* index into uid table */
712 unsigned int guid:8; /* index into guid table */
713 } __attribute__ ((packed));
715 struct squashfs_dev_inode_header_2 {
716 unsigned int inode_type:4;
717 unsigned int mode:12; /* protection */
718 unsigned int uid:8; /* index into uid table */
719 unsigned int guid:8; /* index into guid table */
720 unsigned short rdev;
721 } __attribute__ ((packed));
723 struct squashfs_symlink_inode_header_2 {
724 unsigned int inode_type:4;
725 unsigned int mode:12; /* protection */
726 unsigned int uid:8; /* index into uid table */
727 unsigned int guid:8; /* index into guid table */
728 unsigned short symlink_size;
729 char symlink[0];
730 } __attribute__ ((packed));
732 struct squashfs_reg_inode_header_2 {
733 unsigned int inode_type:4;
734 unsigned int mode:12; /* protection */
735 unsigned int uid:8; /* index into uid table */
736 unsigned int guid:8; /* index into guid table */
737 unsigned int mtime;
738 unsigned int start_block;
739 unsigned int fragment;
740 unsigned int offset;
741 unsigned int file_size:32;
742 unsigned short block_list[0];
743 } __attribute__ ((packed));
745 struct squashfs_dir_inode_header_2 {
746 unsigned int inode_type:4;
747 unsigned int mode:12; /* protection */
748 unsigned int uid:8; /* index into uid table */
749 unsigned int guid:8; /* index into guid table */
750 unsigned int file_size:19;
751 unsigned int offset:13;
752 unsigned int mtime;
753 unsigned int start_block:24;
754 } __attribute__ ((packed));
756 struct squashfs_ldir_inode_header_2 {
757 unsigned int inode_type:4;
758 unsigned int mode:12; /* protection */
759 unsigned int uid:8; /* index into uid table */
760 unsigned int guid:8; /* index into guid table */
761 unsigned int file_size:27;
762 unsigned int offset:13;
763 unsigned int mtime;
764 unsigned int start_block:24;
765 unsigned int i_count:16;
766 struct squashfs_dir_index_2 index[0];
767 } __attribute__ ((packed));
769 union squashfs_inode_header_2 {
770 struct squashfs_base_inode_header_2 base;
771 struct squashfs_dev_inode_header_2 dev;
772 struct squashfs_symlink_inode_header_2 symlink;
773 struct squashfs_reg_inode_header_2 reg;
774 struct squashfs_dir_inode_header_2 dir;
775 struct squashfs_ldir_inode_header_2 ldir;
776 struct squashfs_ipc_inode_header_2 ipc;
779 struct squashfs_dir_header_2 {
780 unsigned int count:8;
781 unsigned int start_block:24;
782 } __attribute__ ((packed));
784 struct squashfs_dir_entry_2 {
785 unsigned int offset:13;
786 unsigned int type:3;
787 unsigned int size:8;
788 char name[0];
789 } __attribute__ ((packed));
791 struct squashfs_fragment_entry_2 {
792 unsigned int start_block;
793 unsigned int size;
794 } __attribute__ ((packed));
796 #define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
797 SQUASHFS_MEMSET(s, d, n);\
798 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
799 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
800 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
801 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
803 #define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
804 SQUASHFS_SWAP_START\
805 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
808 #define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
809 SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
811 #define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
812 SQUASHFS_SWAP_START\
813 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
814 sizeof(struct squashfs_dev_inode_header_2)); \
815 SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
818 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
819 SQUASHFS_SWAP_START\
820 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
821 sizeof(struct squashfs_symlink_inode_header_2));\
822 SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
825 #define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
826 SQUASHFS_SWAP_START\
827 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
828 sizeof(struct squashfs_reg_inode_header_2));\
829 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
830 SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
831 SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
832 SQUASHFS_SWAP((s)->offset, d, 128, 32);\
833 SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
836 #define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
837 SQUASHFS_SWAP_START\
838 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
839 sizeof(struct squashfs_dir_inode_header_2));\
840 SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
841 SQUASHFS_SWAP((s)->offset, d, 51, 13);\
842 SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
843 SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
846 #define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
847 SQUASHFS_SWAP_START\
848 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
849 sizeof(struct squashfs_ldir_inode_header_2));\
850 SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
851 SQUASHFS_SWAP((s)->offset, d, 59, 13);\
852 SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
853 SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
854 SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
857 #define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
858 SQUASHFS_SWAP_START\
859 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
860 SQUASHFS_SWAP((s)->index, d, 0, 27);\
861 SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
862 SQUASHFS_SWAP((s)->size, d, 56, 8);\
864 #define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
865 SQUASHFS_SWAP_START\
866 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
867 SQUASHFS_SWAP((s)->count, d, 0, 8);\
868 SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
871 #define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
872 SQUASHFS_SWAP_START\
873 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
874 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
875 SQUASHFS_SWAP((s)->type, d, 13, 3);\
876 SQUASHFS_SWAP((s)->size, d, 16, 8);\
879 #define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
880 SQUASHFS_SWAP_START\
881 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
882 SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
883 SQUASHFS_SWAP((s)->size, d, 32, 32);\
886 #define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
888 /* fragment and fragment table defines */
889 #define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
891 #define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
892 SQUASHFS_METADATA_SIZE)
894 #define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
895 SQUASHFS_METADATA_SIZE)
897 #define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
898 SQUASHFS_METADATA_SIZE - 1) / \
899 SQUASHFS_METADATA_SIZE)
901 #define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
902 sizeof(int))
904 #endif
906 #ifdef __KERNEL__
909 * macros used to swap each structure entry, taking into account
910 * bitfields and different bitfield placing conventions on differing
911 * architectures
914 #include <asm/byteorder.h>
916 #ifdef __BIG_ENDIAN
917 /* convert from little endian to big endian */
918 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
919 tbits, b_pos)
920 #else
921 /* convert from big endian to little endian */
922 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
923 tbits, 64 - tbits - b_pos)
924 #endif
926 #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
927 b_pos = pos % 8;\
928 val = 0;\
929 s = (unsigned char *)p + (pos / 8);\
930 d = ((unsigned char *) &val) + 7;\
931 for(bits = 0; bits < (tbits + b_pos); bits += 8) \
932 *d-- = *s++;\
933 value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
936 #define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
938 #endif
939 #endif