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