RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / scripts / squashfs / squashfs_fs.h
blobfbbb53c1508ba731608d614cd3ca889786211dd9
1 #ifndef SQUASHFS_FS
2 #define SQUASHFS_FS
4 /*
5 * Squashfs
7 * Copyright (c) 2002, 2003, 2004, 2005, 2006
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 #define SQUASHFS_MAJOR 3
28 #define SQUASHFS_MINOR 0
29 #define SQUASHFS_MAGIC 0x73717368
30 #define SQUASHFS_MAGIC_SWAP 0x68737173
31 #define SQUASHFS_START 0
33 /* size of metadata (inode and directory) blocks */
34 #define SQUASHFS_METADATA_SIZE 8192
35 #define SQUASHFS_METADATA_LOG 13
37 /* default size of data blocks */
38 #define SQUASHFS_FILE_SIZE 65536
39 #define SQUASHFS_FILE_LOG 16
41 #define SQUASHFS_FILE_MAX_SIZE 65536
43 /* Max number of uids and gids */
44 #define SQUASHFS_UIDS 256
45 #define SQUASHFS_GUIDS 255
47 /* Max length of filename (not 255) */
48 #define SQUASHFS_NAME_LEN 256
50 #define SQUASHFS_INVALID ((long long) 0xffffffffffff)
51 #define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
52 #define SQUASHFS_INVALID_BLK ((long long) -1)
53 #define SQUASHFS_USED_BLK ((long long) -2)
55 /* Filesystem flags */
56 #define SQUASHFS_NOI 0
57 #define SQUASHFS_NOD 1
58 #define SQUASHFS_CHECK 2
59 #define SQUASHFS_NOF 3
60 #define SQUASHFS_NO_FRAG 4
61 #define SQUASHFS_ALWAYS_FRAG 5
62 #define SQUASHFS_DUPLICATE 6
64 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
66 #define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
67 SQUASHFS_NOI)
69 #define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
70 SQUASHFS_NOD)
72 #define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
73 SQUASHFS_NOF)
75 #define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
76 SQUASHFS_NO_FRAG)
78 #define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
79 SQUASHFS_ALWAYS_FRAG)
81 #define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
82 SQUASHFS_DUPLICATE)
84 #define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
85 SQUASHFS_CHECK)
87 #define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
88 duplicate_checking) (noi | (nod << 1) | (check_data << 2) \
89 | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
90 (duplicate_checking << 6))
92 /* Max number of types and file types */
93 #define SQUASHFS_DIR_TYPE 1
94 #define SQUASHFS_FILE_TYPE 2
95 #define SQUASHFS_SYMLINK_TYPE 3
96 #define SQUASHFS_BLKDEV_TYPE 4
97 #define SQUASHFS_CHRDEV_TYPE 5
98 #define SQUASHFS_FIFO_TYPE 6
99 #define SQUASHFS_SOCKET_TYPE 7
100 #define SQUASHFS_LDIR_TYPE 8
101 #define SQUASHFS_LREG_TYPE 9
103 /* 1.0 filesystem type definitions */
104 #define SQUASHFS_TYPES 5
105 #define SQUASHFS_IPC_TYPE 0
107 /* Flag whether block is compressed or uncompressed, bit is set if block is
108 * uncompressed */
109 #define SQUASHFS_COMPRESSED_BIT (1 << 15)
111 #define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
112 (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
114 #define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
116 #define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
118 #define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
119 ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
120 ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
122 #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
125 * Inode number ops. Inodes consist of a compressed block number, and an
126 * uncompressed offset within that block
128 #define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
130 #define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
132 #define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
133 << 16) + (B)))
135 /* Compute 32 bit VFS inode number from squashfs inode number */
136 #define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
137 ((b) >> 2) + 1))
138 /* XXX */
140 /* Translate between VFS mode and squashfs mode */
141 #define SQUASHFS_MODE(a) ((a) & 0xfff)
143 /* fragment and fragment table defines */
144 #define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry))
146 #define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
147 SQUASHFS_METADATA_SIZE)
149 #define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
150 SQUASHFS_METADATA_SIZE)
152 #define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
153 SQUASHFS_METADATA_SIZE - 1) / \
154 SQUASHFS_METADATA_SIZE)
156 #define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
157 sizeof(long long))
159 #define SQUASHFS_CACHED_FRAGMENTS 3
161 /* cached data constants for filesystem */
162 #define SQUASHFS_CACHED_BLKS 8
164 #define SQUASHFS_MAX_FILE_SIZE_LOG 64
166 #define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
167 (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
169 #define SQUASHFS_MARKER_BYTE 0xff
172 * definitions for structures on disk
175 typedef long long squashfs_block_t;
176 typedef long long squashfs_inode_t;
178 struct squashfs_super_block {
179 unsigned int s_magic;
180 unsigned int inodes;
181 unsigned int bytes_used_2;
182 unsigned int uid_start_2;
183 unsigned int guid_start_2;
184 unsigned int inode_table_start_2;
185 unsigned int directory_table_start_2;
186 unsigned int s_major:16;
187 unsigned int s_minor:16;
188 unsigned int block_size_1:16;
189 unsigned int block_log:16;
190 unsigned int flags:8;
191 unsigned int no_uids:8;
192 unsigned int no_guids:8;
193 unsigned int mkfs_time /* time of filesystem creation */;
194 squashfs_inode_t root_inode;
195 unsigned int block_size;
196 unsigned int fragments;
197 unsigned int fragment_table_start_2;
198 long long bytes_used;
199 long long uid_start;
200 long long guid_start;
201 long long inode_table_start;
202 long long directory_table_start;
203 long long fragment_table_start;
204 long long unused;
205 } __attribute__ ((packed));
207 struct squashfs_dir_index {
208 unsigned int index;
209 unsigned int start_block;
210 unsigned char size;
211 unsigned char name[0];
212 } __attribute__ ((packed));
214 #define SQUASHFS_BASE_INODE_HEADER \
215 unsigned int inode_type:4; \
216 unsigned int mode:12; \
217 unsigned int uid:8; \
218 unsigned int guid:8; \
219 unsigned int mtime; \
220 unsigned int inode_number;
222 struct squashfs_base_inode_header {
223 SQUASHFS_BASE_INODE_HEADER;
224 } __attribute__ ((packed));
226 struct squashfs_ipc_inode_header {
227 SQUASHFS_BASE_INODE_HEADER;
228 unsigned int nlink;
229 } __attribute__ ((packed));
231 struct squashfs_dev_inode_header {
232 SQUASHFS_BASE_INODE_HEADER;
233 unsigned int nlink;
234 unsigned short rdev;
235 } __attribute__ ((packed));
237 struct squashfs_symlink_inode_header {
238 SQUASHFS_BASE_INODE_HEADER;
239 unsigned int nlink;
240 unsigned short symlink_size;
241 char symlink[0];
242 } __attribute__ ((packed));
244 struct squashfs_reg_inode_header {
245 SQUASHFS_BASE_INODE_HEADER;
246 squashfs_block_t start_block;
247 unsigned int fragment;
248 unsigned int offset;
249 unsigned int file_size;
250 unsigned short block_list[0];
251 } __attribute__ ((packed));
253 struct squashfs_lreg_inode_header {
254 SQUASHFS_BASE_INODE_HEADER;
255 unsigned int nlink;
256 squashfs_block_t start_block;
257 unsigned int fragment;
258 unsigned int offset;
259 long long file_size;
260 unsigned short block_list[0];
261 } __attribute__ ((packed));
263 struct squashfs_dir_inode_header {
264 SQUASHFS_BASE_INODE_HEADER;
265 unsigned int nlink;
266 unsigned int file_size:19;
267 unsigned int offset:13;
268 unsigned int start_block;
269 unsigned int parent_inode;
270 } __attribute__ ((packed));
272 struct squashfs_ldir_inode_header {
273 SQUASHFS_BASE_INODE_HEADER;
274 unsigned int nlink;
275 unsigned int file_size:27;
276 unsigned int offset:13;
277 unsigned int start_block;
278 unsigned int i_count:16;
279 unsigned int parent_inode;
280 struct squashfs_dir_index index[0];
281 } __attribute__ ((packed));
283 union squashfs_inode_header {
284 struct squashfs_base_inode_header base;
285 struct squashfs_dev_inode_header dev;
286 struct squashfs_symlink_inode_header symlink;
287 struct squashfs_reg_inode_header reg;
288 struct squashfs_lreg_inode_header lreg;
289 struct squashfs_dir_inode_header dir;
290 struct squashfs_ldir_inode_header ldir;
291 struct squashfs_ipc_inode_header ipc;
294 struct squashfs_dir_entry {
295 unsigned int offset:13;
296 unsigned int type:3;
297 unsigned int size:8;
298 int inode_number:16;
299 char name[0];
300 } __attribute__ ((packed));
302 struct squashfs_dir_header {
303 unsigned int count:8;
304 unsigned int start_block;
305 unsigned int inode_number;
306 } __attribute__ ((packed));
308 struct squashfs_fragment_entry {
309 long long start_block;
310 unsigned int size;
311 unsigned int unused;
312 } __attribute__ ((packed));
314 extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
315 extern int squashfs_uncompress_init(void);
316 extern int squashfs_uncompress_exit(void);
319 * macros to convert each packed bitfield structure from little endian to big
320 * endian and vice versa. These are needed when creating or using a filesystem
321 * on a machine with different byte ordering to the target architecture.
325 #define SQUASHFS_SWAP_START \
326 int bits;\
327 int b_pos;\
328 unsigned long long val;\
329 unsigned char *s;\
330 unsigned char *d;
332 #define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
333 SQUASHFS_SWAP_START\
334 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
335 SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
336 SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
337 SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
338 SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
339 SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
340 SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
341 SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
342 SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
343 SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
344 SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
345 SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
346 SQUASHFS_SWAP((s)->flags, d, 288, 8);\
347 SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
348 SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
349 SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
350 SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
351 SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
352 SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
353 SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
354 SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
355 SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
356 SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
357 SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
358 SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
359 SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
360 SQUASHFS_SWAP((s)->unused, d, 888, 64);\
363 #define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
364 SQUASHFS_MEMSET(s, d, n);\
365 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
366 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
367 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
368 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
369 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
370 SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
372 #define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
373 SQUASHFS_SWAP_START\
374 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
377 #define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
378 SQUASHFS_SWAP_START\
379 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
380 sizeof(struct squashfs_ipc_inode_header))\
381 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
384 #define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
385 SQUASHFS_SWAP_START\
386 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
387 sizeof(struct squashfs_dev_inode_header)); \
388 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
389 SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
392 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
393 SQUASHFS_SWAP_START\
394 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
395 sizeof(struct squashfs_symlink_inode_header));\
396 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
397 SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
400 #define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
401 SQUASHFS_SWAP_START\
402 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
403 sizeof(struct squashfs_reg_inode_header));\
404 SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
405 SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
406 SQUASHFS_SWAP((s)->offset, d, 192, 32);\
407 SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
410 #define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
411 SQUASHFS_SWAP_START\
412 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
413 sizeof(struct squashfs_lreg_inode_header));\
414 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
415 SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
416 SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
417 SQUASHFS_SWAP((s)->offset, d, 224, 32);\
418 SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
421 #define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
422 SQUASHFS_SWAP_START\
423 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
424 sizeof(struct squashfs_dir_inode_header));\
425 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
426 SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
427 SQUASHFS_SWAP((s)->offset, d, 147, 13);\
428 SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
429 SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
432 #define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
433 SQUASHFS_SWAP_START\
434 SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
435 sizeof(struct squashfs_ldir_inode_header));\
436 SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
437 SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
438 SQUASHFS_SWAP((s)->offset, d, 155, 13);\
439 SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
440 SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
441 SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
444 #define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
445 SQUASHFS_SWAP_START\
446 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
447 SQUASHFS_SWAP((s)->index, d, 0, 32);\
448 SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
449 SQUASHFS_SWAP((s)->size, d, 64, 8);\
452 #define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
453 SQUASHFS_SWAP_START\
454 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
455 SQUASHFS_SWAP((s)->count, d, 0, 8);\
456 SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
457 SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
460 #define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
461 SQUASHFS_SWAP_START\
462 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
463 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
464 SQUASHFS_SWAP((s)->type, d, 13, 3);\
465 SQUASHFS_SWAP((s)->size, d, 16, 8);\
466 SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
469 #define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
470 SQUASHFS_SWAP_START\
471 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
472 SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
473 SQUASHFS_SWAP((s)->size, d, 64, 32);\
476 #define SQUASHFS_SWAP_SHORTS(s, d, n) {\
477 int entry;\
478 int bit_position;\
479 SQUASHFS_SWAP_START\
480 SQUASHFS_MEMSET(s, d, n * 2);\
481 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
482 16)\
483 SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
486 #define SQUASHFS_SWAP_INTS(s, d, n) {\
487 int entry;\
488 int bit_position;\
489 SQUASHFS_SWAP_START\
490 SQUASHFS_MEMSET(s, d, n * 4);\
491 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
492 32)\
493 SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
496 #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
497 int entry;\
498 int bit_position;\
499 SQUASHFS_SWAP_START\
500 SQUASHFS_MEMSET(s, d, n * 8);\
501 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
502 64)\
503 SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
506 #define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
507 int entry;\
508 int bit_position;\
509 SQUASHFS_SWAP_START\
510 SQUASHFS_MEMSET(s, d, n * bits / 8);\
511 for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
512 bits)\
513 SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
516 #define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
518 #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
520 struct squashfs_base_inode_header_1 {
521 unsigned int inode_type:4;
522 unsigned int mode:12; /* protection */
523 unsigned int uid:4; /* index into uid table */
524 unsigned int guid:4; /* index into guid table */
525 } __attribute__ ((packed));
527 struct squashfs_ipc_inode_header_1 {
528 unsigned int inode_type:4;
529 unsigned int mode:12; /* protection */
530 unsigned int uid:4; /* index into uid table */
531 unsigned int guid:4; /* index into guid table */
532 unsigned int type:4;
533 unsigned int offset:4;
534 } __attribute__ ((packed));
536 struct squashfs_dev_inode_header_1 {
537 unsigned int inode_type:4;
538 unsigned int mode:12; /* protection */
539 unsigned int uid:4; /* index into uid table */
540 unsigned int guid:4; /* index into guid table */
541 unsigned short rdev;
542 } __attribute__ ((packed));
544 struct squashfs_symlink_inode_header_1 {
545 unsigned int inode_type:4;
546 unsigned int mode:12; /* protection */
547 unsigned int uid:4; /* index into uid table */
548 unsigned int guid:4; /* index into guid table */
549 unsigned short symlink_size;
550 char symlink[0];
551 } __attribute__ ((packed));
553 struct squashfs_reg_inode_header_1 {
554 unsigned int inode_type:4;
555 unsigned int mode:12; /* protection */
556 unsigned int uid:4; /* index into uid table */
557 unsigned int guid:4; /* index into guid table */
558 unsigned int mtime;
559 unsigned int start_block;
560 unsigned int file_size:32;
561 unsigned short block_list[0];
562 } __attribute__ ((packed));
564 struct squashfs_dir_inode_header_1 {
565 unsigned int inode_type:4;
566 unsigned int mode:12; /* protection */
567 unsigned int uid:4; /* index into uid table */
568 unsigned int guid:4; /* index into guid table */
569 unsigned int file_size:19;
570 unsigned int offset:13;
571 unsigned int mtime;
572 unsigned int start_block:24;
573 } __attribute__ ((packed));
575 #define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
576 SQUASHFS_MEMSET(s, d, n);\
577 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
578 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
579 SQUASHFS_SWAP((s)->uid, d, 16, 4);\
580 SQUASHFS_SWAP((s)->guid, d, 20, 4);
582 #define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
583 SQUASHFS_SWAP_START\
584 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
587 #define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
588 SQUASHFS_SWAP_START\
589 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
590 sizeof(struct squashfs_ipc_inode_header_1));\
591 SQUASHFS_SWAP((s)->type, d, 24, 4);\
592 SQUASHFS_SWAP((s)->offset, d, 28, 4);\
595 #define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
596 SQUASHFS_SWAP_START\
597 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
598 sizeof(struct squashfs_dev_inode_header_1));\
599 SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
602 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
603 SQUASHFS_SWAP_START\
604 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
605 sizeof(struct squashfs_symlink_inode_header_1));\
606 SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
609 #define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
610 SQUASHFS_SWAP_START\
611 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
612 sizeof(struct squashfs_reg_inode_header_1));\
613 SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
614 SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
615 SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\
618 #define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
619 SQUASHFS_SWAP_START\
620 SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
621 sizeof(struct squashfs_dir_inode_header_1));\
622 SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
623 SQUASHFS_SWAP((s)->offset, d, 43, 13);\
624 SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
625 SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
628 #endif
630 #ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
632 struct squashfs_dir_index_2 {
633 unsigned int index:27;
634 unsigned int start_block:29;
635 unsigned char size;
636 unsigned char name[0];
637 } __attribute__ ((packed));
639 struct squashfs_base_inode_header_2 {
640 unsigned int inode_type:4;
641 unsigned int mode:12; /* protection */
642 unsigned int uid:8; /* index into uid table */
643 unsigned int guid:8; /* index into guid table */
644 } __attribute__ ((packed));
646 struct squashfs_ipc_inode_header_2 {
647 unsigned int inode_type:4;
648 unsigned int mode:12; /* protection */
649 unsigned int uid:8; /* index into uid table */
650 unsigned int guid:8; /* index into guid table */
651 } __attribute__ ((packed));
653 struct squashfs_dev_inode_header_2 {
654 unsigned int inode_type:4;
655 unsigned int mode:12; /* protection */
656 unsigned int uid:8; /* index into uid table */
657 unsigned int guid:8; /* index into guid table */
658 unsigned short rdev;
659 } __attribute__ ((packed));
661 struct squashfs_symlink_inode_header_2 {
662 unsigned int inode_type:4;
663 unsigned int mode:12; /* protection */
664 unsigned int uid:8; /* index into uid table */
665 unsigned int guid:8; /* index into guid table */
666 unsigned short symlink_size;
667 char symlink[0];
668 } __attribute__ ((packed));
670 struct squashfs_reg_inode_header_2 {
671 unsigned int inode_type:4;
672 unsigned int mode:12; /* protection */
673 unsigned int uid:8; /* index into uid table */
674 unsigned int guid:8; /* index into guid table */
675 unsigned int mtime;
676 unsigned int start_block;
677 unsigned int fragment;
678 unsigned int offset;
679 unsigned int file_size:32;
680 unsigned short block_list[0];
681 } __attribute__ ((packed));
683 struct squashfs_dir_inode_header_2 {
684 unsigned int inode_type:4;
685 unsigned int mode:12; /* protection */
686 unsigned int uid:8; /* index into uid table */
687 unsigned int guid:8; /* index into guid table */
688 unsigned int file_size:19;
689 unsigned int offset:13;
690 unsigned int mtime;
691 unsigned int start_block:24;
692 } __attribute__ ((packed));
694 struct squashfs_ldir_inode_header_2 {
695 unsigned int inode_type:4;
696 unsigned int mode:12; /* protection */
697 unsigned int uid:8; /* index into uid table */
698 unsigned int guid:8; /* index into guid table */
699 unsigned int file_size:27;
700 unsigned int offset:13;
701 unsigned int mtime;
702 unsigned int start_block:24;
703 unsigned int i_count:16;
704 struct squashfs_dir_index_2 index[0];
705 } __attribute__ ((packed));
707 union squashfs_inode_header_2 {
708 struct squashfs_base_inode_header_2 base;
709 struct squashfs_dev_inode_header_2 dev;
710 struct squashfs_symlink_inode_header_2 symlink;
711 struct squashfs_reg_inode_header_2 reg;
712 struct squashfs_dir_inode_header_2 dir;
713 struct squashfs_ldir_inode_header_2 ldir;
714 struct squashfs_ipc_inode_header_2 ipc;
717 struct squashfs_dir_header_2 {
718 unsigned int count:8;
719 unsigned int start_block:24;
720 } __attribute__ ((packed));
722 struct squashfs_dir_entry_2 {
723 unsigned int offset:13;
724 unsigned int type:3;
725 unsigned int size:8;
726 char name[0];
727 } __attribute__ ((packed));
729 struct squashfs_fragment_entry_2 {
730 unsigned int start_block;
731 unsigned int size;
732 } __attribute__ ((packed));
734 #define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
735 SQUASHFS_MEMSET(s, d, n);\
736 SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
737 SQUASHFS_SWAP((s)->mode, d, 4, 12);\
738 SQUASHFS_SWAP((s)->uid, d, 16, 8);\
739 SQUASHFS_SWAP((s)->guid, d, 24, 8);\
741 #define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
742 SQUASHFS_SWAP_START\
743 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
746 #define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
747 SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
749 #define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
750 SQUASHFS_SWAP_START\
751 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
752 sizeof(struct squashfs_dev_inode_header_2)); \
753 SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
756 #define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
757 SQUASHFS_SWAP_START\
758 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
759 sizeof(struct squashfs_symlink_inode_header_2));\
760 SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
763 #define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
764 SQUASHFS_SWAP_START\
765 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
766 sizeof(struct squashfs_reg_inode_header_2));\
767 SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
768 SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
769 SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
770 SQUASHFS_SWAP((s)->offset, d, 128, 32);\
771 SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\
774 #define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
775 SQUASHFS_SWAP_START\
776 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
777 sizeof(struct squashfs_dir_inode_header_2));\
778 SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
779 SQUASHFS_SWAP((s)->offset, d, 51, 13);\
780 SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
781 SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
784 #define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
785 SQUASHFS_SWAP_START\
786 SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
787 sizeof(struct squashfs_ldir_inode_header_2));\
788 SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
789 SQUASHFS_SWAP((s)->offset, d, 59, 13);\
790 SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
791 SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
792 SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
795 #define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
796 SQUASHFS_SWAP_START\
797 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
798 SQUASHFS_SWAP((s)->index, d, 0, 27);\
799 SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
800 SQUASHFS_SWAP((s)->size, d, 56, 8);\
802 #define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
803 SQUASHFS_SWAP_START\
804 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
805 SQUASHFS_SWAP((s)->count, d, 0, 8);\
806 SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
809 #define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
810 SQUASHFS_SWAP_START\
811 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
812 SQUASHFS_SWAP((s)->offset, d, 0, 13);\
813 SQUASHFS_SWAP((s)->type, d, 13, 3);\
814 SQUASHFS_SWAP((s)->size, d, 16, 8);\
817 #define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
818 SQUASHFS_SWAP_START\
819 SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
820 SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
821 SQUASHFS_SWAP((s)->size, d, 32, 32);\
824 #define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
826 /* fragment and fragment table defines */
827 #define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
829 #define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
830 SQUASHFS_METADATA_SIZE)
832 #define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
833 SQUASHFS_METADATA_SIZE)
835 #define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
836 SQUASHFS_METADATA_SIZE - 1) / \
837 SQUASHFS_METADATA_SIZE)
839 #define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
840 sizeof(int))
842 #endif
844 #ifdef __KERNEL__
847 * macros used to swap each structure entry, taking into account
848 * bitfields and different bitfield placing conventions on differing
849 * architectures
852 #include <asm/byteorder.h>
854 #ifdef __BIG_ENDIAN
855 /* convert from little endian to big endian */
856 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
857 tbits, b_pos)
858 #else
859 /* convert from big endian to little endian */
860 #define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
861 tbits, 64 - tbits - b_pos)
862 #endif
864 #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
865 b_pos = pos % 8;\
866 val = 0;\
867 s = (unsigned char *)p + (pos / 8);\
868 d = ((unsigned char *) &val) + 7;\
869 for(bits = 0; bits < (tbits + b_pos); bits += 8) \
870 *d-- = *s++;\
871 value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
874 #define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
876 #endif
877 #endif