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