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