7 * Copyright (c) 2002, 2003, 2004, 2005, 2006
8 * Phillip Lougher <phillip@lougher.demon.co.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.
27 #ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
28 #define CONFIG_SQUASHFS_2_0_COMPATIBILITY
31 #ifdef CONFIG_SQUASHFS_VMALLOC
32 #define SQUASHFS_ALLOC(a) vmalloc(a)
33 #define SQUASHFS_FREE(a) vfree(a)
35 #define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL)
36 #define SQUASHFS_FREE(a) kfree(a)
38 #ifdef CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
39 #define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
41 #define SQUASHFS_CACHED_FRAGMENTS 3
43 #define SQUASHFS_MAJOR 3
44 #define SQUASHFS_MINOR 0
45 #define SQUASHFS_MAGIC 0x73717368
46 #define SQUASHFS_MAGIC_SWAP 0x68737173
47 #define SQUASHFS_START 0
49 /* size of metadata (inode and directory) blocks */
50 #define SQUASHFS_METADATA_SIZE 8192
51 #define SQUASHFS_METADATA_LOG 13
53 /* default size of data blocks */
54 #define SQUASHFS_FILE_SIZE 65536
55 #define SQUASHFS_FILE_LOG 16
57 #define SQUASHFS_FILE_MAX_SIZE 65536
59 /* Max number of uids and gids */
60 #define SQUASHFS_UIDS 256
61 #define SQUASHFS_GUIDS 255
63 /* Max length of filename (not 255) */
64 #define SQUASHFS_NAME_LEN 256
66 #define SQUASHFS_INVALID ((long long) 0xffffffffffff)
67 #define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
68 #define SQUASHFS_INVALID_BLK ((long long) -1)
69 #define SQUASHFS_USED_BLK ((long long) -2)
71 /* Filesystem flags */
72 #define SQUASHFS_NOI 0
73 #define SQUASHFS_NOD 1
74 #define SQUASHFS_CHECK 2
75 #define SQUASHFS_NOF 3
76 #define SQUASHFS_NO_FRAG 4
77 #define SQUASHFS_ALWAYS_FRAG 5
78 #define SQUASHFS_DUPLICATE 6
80 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
82 #define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
85 #define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
88 #define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
91 #define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
94 #define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
97 #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
100 #define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
103 #define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
104 duplicate_checking) (noi | (nod << 1) | (check_data << 2) \
105 | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
106 (duplicate_checking << 6))
108 /* Max number of types and file types */
109 #define SQUASHFS_DIR_TYPE 1
110 #define SQUASHFS_FILE_TYPE 2
111 #define SQUASHFS_SYMLINK_TYPE 3
112 #define SQUASHFS_BLKDEV_TYPE 4
113 #define SQUASHFS_CHRDEV_TYPE 5
114 #define SQUASHFS_FIFO_TYPE 6
115 #define SQUASHFS_SOCKET_TYPE 7
116 #define SQUASHFS_LDIR_TYPE 8
117 #define SQUASHFS_LREG_TYPE 9
119 /* 1.0 filesystem type definitions */
120 #define SQUASHFS_TYPES 5
121 #define SQUASHFS_IPC_TYPE 0
123 /* Flag whether block is compressed or uncompressed, bit is set if block is
125 #define SQUASHFS_COMPRESSED_BIT (1 << 15)
127 #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
128 (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
130 #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
132 #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
134 #define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
135 ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
136 ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
138 #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
141 * Inode number ops. Inodes consist of a compressed block number, and an
142 * uncompressed offset within that block
144 #define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
146 #define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
148 #define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
151 /* Compute 32 bit VFS inode number from squashfs inode number */
152 #define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
156 /* Translate between VFS mode and squashfs mode */
157 #define SQUASHFS_MODE(a) ((a) & 0xfff)
159 /* fragment and fragment table defines */
160 #define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry))
162 #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
163 SQUASHFS_METADATA_SIZE)
165 #define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
166 SQUASHFS_METADATA_SIZE)
168 #define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
169 SQUASHFS_METADATA_SIZE - 1) / \
170 SQUASHFS_METADATA_SIZE)
172 #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
175 /* cached data constants for filesystem */
176 #define SQUASHFS_CACHED_BLKS 8
178 #define SQUASHFS_MAX_FILE_SIZE_LOG 64
180 #define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
181 (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
183 #define SQUASHFS_MARKER_BYTE 0xff
185 /* meta index cache */
186 #define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
187 #define SQUASHFS_META_ENTRIES 31
188 #define SQUASHFS_META_NUMBER 8
189 #define SQUASHFS_SLOTS 4
192 long long data_block
;
193 unsigned int index_block
;
194 unsigned short offset
;
199 unsigned int inode_number
;
201 unsigned short entries
;
203 unsigned short locked
;
205 struct meta_entry meta_entry
[SQUASHFS_META_ENTRIES
];
210 * definitions for structures on disk
213 typedef long long squashfs_block_t
;
214 typedef long long squashfs_inode_t
;
216 struct squashfs_super_block
{
217 unsigned int s_magic
;
219 unsigned int bytes_used_2
;
220 unsigned int uid_start_2
;
221 unsigned int guid_start_2
;
222 unsigned int inode_table_start_2
;
223 unsigned int directory_table_start_2
;
224 unsigned int s_major
:16;
225 unsigned int s_minor
:16;
226 unsigned int block_size_1
:16;
227 unsigned int block_log
:16;
228 unsigned int flags
:8;
229 unsigned int no_uids
:8;
230 unsigned int no_guids
:8;
231 unsigned int mkfs_time
/* time of filesystem creation */;
232 squashfs_inode_t root_inode
;
233 unsigned int block_size
;
234 unsigned int fragments
;
235 unsigned int fragment_table_start_2
;
236 long long bytes_used
;
238 long long guid_start
;
239 long long inode_table_start
;
240 long long directory_table_start
;
241 long long fragment_table_start
;
243 } __attribute__ ((packed
));
245 struct squashfs_dir_index
{
247 unsigned int start_block
;
249 unsigned char name
[0];
250 } __attribute__ ((packed
));
252 #define SQUASHFS_BASE_INODE_HEADER \
253 unsigned int inode_type:4; \
254 unsigned int mode:12; \
255 unsigned int uid:8; \
256 unsigned int guid:8; \
257 unsigned int mtime; \
258 unsigned int inode_number;
260 struct squashfs_base_inode_header
{
261 SQUASHFS_BASE_INODE_HEADER
;
262 } __attribute__ ((packed
));
264 struct squashfs_ipc_inode_header
{
265 SQUASHFS_BASE_INODE_HEADER
;
267 } __attribute__ ((packed
));
269 struct squashfs_dev_inode_header
{
270 SQUASHFS_BASE_INODE_HEADER
;
273 } __attribute__ ((packed
));
275 struct squashfs_symlink_inode_header
{
276 SQUASHFS_BASE_INODE_HEADER
;
278 unsigned short symlink_size
;
280 } __attribute__ ((packed
));
282 struct squashfs_reg_inode_header
{
283 SQUASHFS_BASE_INODE_HEADER
;
284 squashfs_block_t start_block
;
285 unsigned int fragment
;
287 unsigned int file_size
;
288 unsigned short block_list
[0];
289 } __attribute__ ((packed
));
291 struct squashfs_lreg_inode_header
{
292 SQUASHFS_BASE_INODE_HEADER
;
294 squashfs_block_t start_block
;
295 unsigned int fragment
;
298 unsigned short block_list
[0];
299 } __attribute__ ((packed
));
301 struct squashfs_dir_inode_header
{
302 SQUASHFS_BASE_INODE_HEADER
;
304 unsigned int file_size
:19;
305 unsigned int offset
:13;
306 unsigned int start_block
;
307 unsigned int parent_inode
;
308 } __attribute__ ((packed
));
310 struct squashfs_ldir_inode_header
{
311 SQUASHFS_BASE_INODE_HEADER
;
313 unsigned int file_size
:27;
314 unsigned int offset
:13;
315 unsigned int start_block
;
316 unsigned int i_count
:16;
317 unsigned int parent_inode
;
318 struct squashfs_dir_index index
[0];
319 } __attribute__ ((packed
));
321 union squashfs_inode_header
{
322 struct squashfs_base_inode_header base
;
323 struct squashfs_dev_inode_header dev
;
324 struct squashfs_symlink_inode_header symlink
;
325 struct squashfs_reg_inode_header reg
;
326 struct squashfs_lreg_inode_header lreg
;
327 struct squashfs_dir_inode_header dir
;
328 struct squashfs_ldir_inode_header ldir
;
329 struct squashfs_ipc_inode_header ipc
;
332 struct squashfs_dir_entry
{
333 unsigned int offset
:13;
338 } __attribute__ ((packed
));
340 struct squashfs_dir_header
{
341 unsigned int count
:8;
342 unsigned int start_block
;
343 unsigned int inode_number
;
344 } __attribute__ ((packed
));
346 struct squashfs_fragment_entry
{
347 long long start_block
;
350 } __attribute__ ((packed
));
352 extern int squashfs_uncompress_block(void *d
, int dstlen
, void *s
, int srclen
);
353 extern int squashfs_uncompress_init(void);
354 extern int squashfs_uncompress_exit(void);
357 * macros to convert each packed bitfield structure from little endian to big
358 * endian and vice versa. These are needed when creating or using a filesystem
359 * on a machine with different byte ordering to the target architecture.
363 #define SQUASHFS_SWAP_START \
366 unsigned long long val;\
370 #define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
372 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
373 SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
374 SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
375 SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
376 SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
377 SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
378 SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
379 SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
380 SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
381 SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
382 SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
383 SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
384 SQUASHFS_SWAP((s)->flags, d, 288, 8);\
385 SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
386 SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
387 SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
388 SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
389 SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
390 SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
391 SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
392 SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
393 SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
394 SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
395 SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
396 SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
397 SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
398 SQUASHFS_SWAP((s)->unused, d, 888, 64);\
401 #define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
402 SQUASHFS_MEMSET(s, d, n);\
403 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
404 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
405 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
406 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
407 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
408 SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
410 #define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
412 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
415 #define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
417 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
418 sizeof(struct squashfs_ipc_inode_header))\
419 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
422 #define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
424 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
425 sizeof(struct squashfs_dev_inode_header)); \
426 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
427 SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
430 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
432 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
433 sizeof(struct squashfs_symlink_inode_header));\
434 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
435 SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
438 #define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
440 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
441 sizeof(struct squashfs_reg_inode_header));\
442 SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
443 SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
444 SQUASHFS_SWAP((s)->offset, d, 192, 32);\
445 SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
448 #define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
450 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
451 sizeof(struct squashfs_lreg_inode_header));\
452 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
453 SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
454 SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
455 SQUASHFS_SWAP((s)->offset, d, 224, 32);\
456 SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
459 #define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
461 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
462 sizeof(struct squashfs_dir_inode_header));\
463 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
464 SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
465 SQUASHFS_SWAP((s)->offset, d, 147, 13);\
466 SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
467 SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
470 #define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
472 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
473 sizeof(struct squashfs_ldir_inode_header));\
474 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
475 SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
476 SQUASHFS_SWAP((s)->offset, d, 155, 13);\
477 SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
478 SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
479 SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
482 #define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
484 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
485 SQUASHFS_SWAP((s)->index, d, 0, 32);\
486 SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
487 SQUASHFS_SWAP((s)->size, d, 64, 8);\
490 #define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
492 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
493 SQUASHFS_SWAP((s)->count, d, 0, 8);\
494 SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
495 SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
498 #define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
500 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
501 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
502 SQUASHFS_SWAP((s)->type, d, 13, 3);\
503 SQUASHFS_SWAP((s)->size, d, 16, 8);\
504 SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
507 #define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
509 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
510 SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
511 SQUASHFS_SWAP((s)->size, d, 64, 32);\
514 #define SQUASHFS_SWAP_SHORTS(s, d, n) {\
518 SQUASHFS_MEMSET(s, d, n * 2);\
519 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
521 SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
524 #define SQUASHFS_SWAP_INTS(s, d, n) {\
528 SQUASHFS_MEMSET(s, d, n * 4);\
529 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
531 SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
534 #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
538 SQUASHFS_MEMSET(s, d, n * 8);\
539 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
541 SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
544 #define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
548 SQUASHFS_MEMSET(s, d, n * bits / 8);\
549 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
551 SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
554 #define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
556 #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
558 struct squashfs_base_inode_header_1
{
559 unsigned int inode_type
:4;
560 unsigned int mode
:12; /* protection */
561 unsigned int uid
:4; /* index into uid table */
562 unsigned int guid
:4; /* index into guid table */
563 } __attribute__ ((packed
));
565 struct squashfs_ipc_inode_header_1
{
566 unsigned int inode_type
:4;
567 unsigned int mode
:12; /* protection */
568 unsigned int uid
:4; /* index into uid table */
569 unsigned int guid
:4; /* index into guid table */
571 unsigned int offset
:4;
572 } __attribute__ ((packed
));
574 struct squashfs_dev_inode_header_1
{
575 unsigned int inode_type
:4;
576 unsigned int mode
:12; /* protection */
577 unsigned int uid
:4; /* index into uid table */
578 unsigned int guid
:4; /* index into guid table */
580 } __attribute__ ((packed
));
582 struct squashfs_symlink_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 unsigned short symlink_size
;
589 } __attribute__ ((packed
));
591 struct squashfs_reg_inode_header_1
{
592 unsigned int inode_type
:4;
593 unsigned int mode
:12; /* protection */
594 unsigned int uid
:4; /* index into uid table */
595 unsigned int guid
:4; /* index into guid table */
597 unsigned int start_block
;
598 unsigned int file_size
:32;
599 unsigned short block_list
[0];
600 } __attribute__ ((packed
));
602 struct squashfs_dir_inode_header_1
{
603 unsigned int inode_type
:4;
604 unsigned int mode
:12; /* protection */
605 unsigned int uid
:4; /* index into uid table */
606 unsigned int guid
:4; /* index into guid table */
607 unsigned int file_size
:19;
608 unsigned int offset
:13;
610 unsigned int start_block
:24;
611 } __attribute__ ((packed
));
613 #define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
614 SQUASHFS_MEMSET(s, d, n);\
615 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
616 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
617 SQUASHFS_SWAP((s)->uid, d, 16, 4);\
618 SQUASHFS_SWAP((s)->guid, d, 20, 4);
620 #define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
622 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
625 #define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
627 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
628 sizeof(struct squashfs_ipc_inode_header_1));\
629 SQUASHFS_SWAP((s)->type, d, 24, 4);\
630 SQUASHFS_SWAP((s)->offset, d, 28, 4);\
633 #define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
635 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
636 sizeof(struct squashfs_dev_inode_header_1));\
637 SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
640 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
642 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
643 sizeof(struct squashfs_symlink_inode_header_1));\
644 SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
647 #define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
649 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
650 sizeof(struct squashfs_reg_inode_header_1));\
651 SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
652 SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
653 SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
656 #define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
658 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
659 sizeof(struct squashfs_dir_inode_header_1));\
660 SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
661 SQUASHFS_SWAP((s)->offset, d, 43, 13);\
662 SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
663 SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
668 #ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
670 struct squashfs_dir_index_2
{
671 unsigned int index
:27;
672 unsigned int start_block
:29;
674 unsigned char name
[0];
675 } __attribute__ ((packed
));
677 struct squashfs_base_inode_header_2
{
678 unsigned int inode_type
:4;
679 unsigned int mode
:12; /* protection */
680 unsigned int uid
:8; /* index into uid table */
681 unsigned int guid
:8; /* index into guid table */
682 } __attribute__ ((packed
));
684 struct squashfs_ipc_inode_header_2
{
685 unsigned int inode_type
:4;
686 unsigned int mode
:12; /* protection */
687 unsigned int uid
:8; /* index into uid table */
688 unsigned int guid
:8; /* index into guid table */
689 } __attribute__ ((packed
));
691 struct squashfs_dev_inode_header_2
{
692 unsigned int inode_type
:4;
693 unsigned int mode
:12; /* protection */
694 unsigned int uid
:8; /* index into uid table */
695 unsigned int guid
:8; /* index into guid table */
697 } __attribute__ ((packed
));
699 struct squashfs_symlink_inode_header_2
{
700 unsigned int inode_type
:4;
701 unsigned int mode
:12; /* protection */
702 unsigned int uid
:8; /* index into uid table */
703 unsigned int guid
:8; /* index into guid table */
704 unsigned short symlink_size
;
706 } __attribute__ ((packed
));
708 struct squashfs_reg_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 */
714 unsigned int start_block
;
715 unsigned int fragment
;
717 unsigned int file_size
:32;
718 unsigned short block_list
[0];
719 } __attribute__ ((packed
));
721 struct squashfs_dir_inode_header_2
{
722 unsigned int inode_type
:4;
723 unsigned int mode
:12; /* protection */
724 unsigned int uid
:8; /* index into uid table */
725 unsigned int guid
:8; /* index into guid table */
726 unsigned int file_size
:19;
727 unsigned int offset
:13;
729 unsigned int start_block
:24;
730 } __attribute__ ((packed
));
732 struct squashfs_ldir_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 file_size
:27;
738 unsigned int offset
:13;
740 unsigned int start_block
:24;
741 unsigned int i_count
:16;
742 struct squashfs_dir_index_2 index
[0];
743 } __attribute__ ((packed
));
745 union squashfs_inode_header_2
{
746 struct squashfs_base_inode_header_2 base
;
747 struct squashfs_dev_inode_header_2 dev
;
748 struct squashfs_symlink_inode_header_2 symlink
;
749 struct squashfs_reg_inode_header_2 reg
;
750 struct squashfs_dir_inode_header_2 dir
;
751 struct squashfs_ldir_inode_header_2 ldir
;
752 struct squashfs_ipc_inode_header_2 ipc
;
755 struct squashfs_dir_header_2
{
756 unsigned int count
:8;
757 unsigned int start_block
:24;
758 } __attribute__ ((packed
));
760 struct squashfs_dir_entry_2
{
761 unsigned int offset
:13;
765 } __attribute__ ((packed
));
767 struct squashfs_fragment_entry_2
{
768 unsigned int start_block
;
770 } __attribute__ ((packed
));
772 #define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
773 SQUASHFS_MEMSET(s, d, n);\
774 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
775 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
776 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
777 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
779 #define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
781 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
784 #define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
785 SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
787 #define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
789 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
790 sizeof(struct squashfs_dev_inode_header_2)); \
791 SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
794 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
796 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
797 sizeof(struct squashfs_symlink_inode_header_2));\
798 SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
801 #define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
803 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
804 sizeof(struct squashfs_reg_inode_header_2));\
805 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
806 SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
807 SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
808 SQUASHFS_SWAP((s)->offset, d, 128, 32);\
809 SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
812 #define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
814 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
815 sizeof(struct squashfs_dir_inode_header_2));\
816 SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
817 SQUASHFS_SWAP((s)->offset, d, 51, 13);\
818 SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
819 SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
822 #define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
824 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
825 sizeof(struct squashfs_ldir_inode_header_2));\
826 SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
827 SQUASHFS_SWAP((s)->offset, d, 59, 13);\
828 SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
829 SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
830 SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
833 #define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
835 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
836 SQUASHFS_SWAP((s)->index, d, 0, 27);\
837 SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
838 SQUASHFS_SWAP((s)->size, d, 56, 8);\
840 #define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
842 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
843 SQUASHFS_SWAP((s)->count, d, 0, 8);\
844 SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
847 #define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
849 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
850 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
851 SQUASHFS_SWAP((s)->type, d, 13, 3);\
852 SQUASHFS_SWAP((s)->size, d, 16, 8);\
855 #define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
857 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
858 SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
859 SQUASHFS_SWAP((s)->size, d, 32, 32);\
862 #define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
864 /* fragment and fragment table defines */
865 #define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
867 #define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
868 SQUASHFS_METADATA_SIZE)
870 #define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
871 SQUASHFS_METADATA_SIZE)
873 #define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
874 SQUASHFS_METADATA_SIZE - 1) / \
875 SQUASHFS_METADATA_SIZE)
877 #define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
885 * macros used to swap each structure entry, taking into account
886 * bitfields and different bitfield placing conventions on differing
890 #include <asm/byteorder.h>
893 /* convert from little endian to big endian */
894 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
897 /* convert from big endian to little endian */
898 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
899 tbits, 64 - tbits - b_pos)
902 #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
905 s = (unsigned char *)p + (pos / 8);\
906 d = ((unsigned char *) &val) + 7;\
907 for(bits = 0; bits < (tbits + b_pos); bits += 8) \
909 value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
912 #define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);