Home | History | Annotate | Download | only in squashfs
      1 /*
      2  * Squashfs - a compressed read only filesystem for Linux
      3  *
      4  * Copyright (c) 2002, 2003, 2004, 2005, 2006
      5  * Phillip Lougher <phillip (at) lougher.demon.co.uk>
      6  *
      7  * This program is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU General Public License
      9  * as published by the Free Software Foundation; either version 2,
     10  * or (at your option) any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  * GNU General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU General Public License
     18  * along with this program; if not, write to the Free Software
     19  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     20  *
     21  * inode.c
     22  */
     23 
     24 #include <linux/types.h>
     25 #include <linux/squashfs_fs.h>
     26 #include <linux/module.h>
     27 #include <linux/errno.h>
     28 #include <linux/slab.h>
     29 #include <linux/zlib.h>
     30 #include <linux/fs.h>
     31 #include <linux/smp_lock.h>
     32 #include <linux/locks.h>
     33 #include <linux/init.h>
     34 #include <linux/dcache.h>
     35 #include <linux/wait.h>
     36 #include <linux/blkdev.h>
     37 #include <linux/vmalloc.h>
     38 #include <asm/uaccess.h>
     39 #include <asm/semaphore.h>
     40 
     41 #include "squashfs.h"
     42 
     43 static struct super_block *squashfs_read_super(struct super_block *, void *, int);
     44 static void squashfs_put_super(struct super_block *);
     45 static int squashfs_statfs(struct super_block *, struct statfs *);
     46 static int squashfs_symlink_readpage(struct file *file, struct page *page);
     47 static int squashfs_readpage(struct file *file, struct page *page);
     48 static int squashfs_readpage4K(struct file *file, struct page *page);
     49 static int squashfs_readdir(struct file *, void *, filldir_t);
     50 static struct dentry *squashfs_lookup(struct inode *, struct dentry *);
     51 static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode);
     52 static long long read_blocklist(struct inode *inode, int index,
     53 				int readahead_blks, char *block_list,
     54 				unsigned short **block_p, unsigned int *bsize);
     55 
     56 static DECLARE_FSTYPE_DEV(squashfs_fs_type, "squashfs", squashfs_read_super);
     57 
     58 static unsigned char squashfs_filetype_table[] = {
     59 	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
     60 };
     61 
     62 static struct super_operations squashfs_ops = {
     63 	.statfs = squashfs_statfs,
     64 	.put_super = squashfs_put_super,
     65 };
     66 
     67 SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {
     68 	.readpage = squashfs_symlink_readpage
     69 };
     70 
     71 SQSH_EXTERN struct address_space_operations squashfs_aops = {
     72 	.readpage = squashfs_readpage
     73 };
     74 
     75 SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {
     76 	.readpage = squashfs_readpage4K
     77 };
     78 
     79 static struct file_operations squashfs_dir_ops = {
     80 	.read = generic_read_dir,
     81 	.readdir = squashfs_readdir
     82 };
     83 
     84 static struct inode_operations squashfs_dir_inode_ops = {
     85 	.lookup = squashfs_lookup
     86 };
     87 
     88 static struct buffer_head *get_block_length(struct super_block *s,
     89 				int *cur_index, int *offset, int *c_byte)
     90 {
     91 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
     92 	unsigned short temp;
     93 	struct buffer_head *bh;
     94 
     95 	if (!(bh = sb_bread(s, *cur_index)))
     96 		goto out;
     97 
     98 	if (msblk->devblksize - *offset == 1) {
     99 		if (msblk->swap)
    100 			((unsigned char *) &temp)[1] = *((unsigned char *)
    101 				(bh->b_data + *offset));
    102 		else
    103 			((unsigned char *) &temp)[0] = *((unsigned char *)
    104 				(bh->b_data + *offset));
    105 		brelse(bh);
    106 		if (!(bh = sb_bread(s, ++(*cur_index))))
    107 			goto out;
    108 		if (msblk->swap)
    109 			((unsigned char *) &temp)[0] = *((unsigned char *)
    110 				bh->b_data);
    111 		else
    112 			((unsigned char *) &temp)[1] = *((unsigned char *)
    113 				bh->b_data);
    114 		*c_byte = temp;
    115 		*offset = 1;
    116 	} else {
    117 		if (msblk->swap) {
    118 			((unsigned char *) &temp)[1] = *((unsigned char *)
    119 				(bh->b_data + *offset));
    120 			((unsigned char *) &temp)[0] = *((unsigned char *)
    121 				(bh->b_data + *offset + 1));
    122 		} else {
    123 			((unsigned char *) &temp)[0] = *((unsigned char *)
    124 				(bh->b_data + *offset));
    125 			((unsigned char *) &temp)[1] = *((unsigned char *)
    126 				(bh->b_data + *offset + 1));
    127 		}
    128 		*c_byte = temp;
    129 		*offset += 2;
    130 	}
    131 
    132 	if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
    133 		if (*offset == msblk->devblksize) {
    134 			brelse(bh);
    135 			if (!(bh = sb_bread(s, ++(*cur_index))))
    136 				goto out;
    137 			*offset = 0;
    138 		}
    139 		if (*((unsigned char *) (bh->b_data + *offset)) !=
    140 						SQUASHFS_MARKER_BYTE) {
    141 			ERROR("Metadata block marker corrupt @ %x\n",
    142 						*cur_index);
    143 			brelse(bh);
    144 			goto out;
    145 		}
    146 		(*offset)++;
    147 	}
    148 	return bh;
    149 
    150 out:
    151 	return NULL;
    152 }
    153 
    154 
    155 SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
    156 			long long index, unsigned int length,
    157 			long long *next_index)
    158 {
    159 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    160 	struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
    161 			msblk->devblksize_log2) + 2];
    162 	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
    163 	unsigned int cur_index = index >> msblk->devblksize_log2;
    164 	int bytes, avail_bytes, b = 0, k;
    165 	char *c_buffer;
    166 	unsigned int compressed;
    167 	unsigned int c_byte = length;
    168 
    169 	if (c_byte) {
    170 		bytes = msblk->devblksize - offset;
    171 		compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
    172 		c_buffer = compressed ? msblk->read_data : buffer;
    173 		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
    174 
    175 		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
    176 					? "" : "un", (unsigned int) c_byte);
    177 
    178 		if (!(bh[0] = sb_getblk(s, cur_index)))
    179 			goto block_release;
    180 
    181 		for (b = 1; bytes < c_byte; b++) {
    182 			if (!(bh[b] = sb_getblk(s, ++cur_index)))
    183 				goto block_release;
    184 			bytes += msblk->devblksize;
    185 		}
    186 		ll_rw_block(READ, b, bh);
    187 	} else {
    188 		if (!(bh[0] = get_block_length(s, &cur_index, &offset,
    189 								&c_byte)))
    190 			goto read_failure;
    191 
    192 		bytes = msblk->devblksize - offset;
    193 		compressed = SQUASHFS_COMPRESSED(c_byte);
    194 		c_buffer = compressed ? msblk->read_data : buffer;
    195 		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
    196 
    197 		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
    198 					? "" : "un", (unsigned int) c_byte);
    199 
    200 		for (b = 1; bytes < c_byte; b++) {
    201 			if (!(bh[b] = sb_getblk(s, ++cur_index)))
    202 				goto block_release;
    203 			bytes += msblk->devblksize;
    204 		}
    205 		ll_rw_block(READ, b - 1, bh + 1);
    206 	}
    207 
    208 	if (compressed)
    209 		down(&msblk->read_data_mutex);
    210 
    211 	for (bytes = 0, k = 0; k < b; k++) {
    212 		avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
    213 					msblk->devblksize - offset :
    214 					c_byte - bytes;
    215 		wait_on_buffer(bh[k]);
    216 		if (!buffer_uptodate(bh[k]))
    217 			goto block_release;
    218 		memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);
    219 		bytes += avail_bytes;
    220 		offset = 0;
    221 		brelse(bh[k]);
    222 	}
    223 
    224 	/*
    225 	 * uncompress block
    226 	 */
    227 	if (compressed) {
    228 		int zlib_err;
    229 
    230 		msblk->stream.next_in = c_buffer;
    231 		msblk->stream.avail_in = c_byte;
    232 		msblk->stream.next_out = buffer;
    233 		msblk->stream.avail_out = msblk->read_size;
    234 
    235 		if (((zlib_err = zlib_inflateInit(&msblk->stream)) != Z_OK) ||
    236 				((zlib_err = zlib_inflate(&msblk->stream, Z_FINISH))
    237 				 != Z_STREAM_END) || ((zlib_err =
    238 				zlib_inflateEnd(&msblk->stream)) != Z_OK)) {
    239 			ERROR("zlib_fs returned unexpected result 0x%x\n",
    240 				zlib_err);
    241 			bytes = 0;
    242 		} else
    243 			bytes = msblk->stream.total_out;
    244 
    245 		up(&msblk->read_data_mutex);
    246 	}
    247 
    248 	if (next_index)
    249 		*next_index = index + c_byte + (length ? 0 :
    250 				(SQUASHFS_CHECK_DATA(msblk->sblk.flags)
    251 				 ? 3 : 2));
    252 	return bytes;
    253 
    254 block_release:
    255 	while (--b >= 0)
    256 		brelse(bh[b]);
    257 
    258 read_failure:
    259 	ERROR("sb_bread failed reading block 0x%x\n", cur_index);
    260 	return 0;
    261 }
    262 
    263 
    264 SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
    265 				long long block, unsigned int offset,
    266 				int length, long long *next_block,
    267 				unsigned int *next_offset)
    268 {
    269 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    270 	int n, i, bytes, return_length = length;
    271 	long long next_index;
    272 
    273 	TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
    274 
    275 	while ( 1 ) {
    276 		for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
    277 			if (msblk->block_cache[i].block == block)
    278 				break;
    279 
    280 		down(&msblk->block_cache_mutex);
    281 
    282 		if (i == SQUASHFS_CACHED_BLKS) {
    283 			/* read inode header block */
    284 			for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
    285 					n ; n --, i = (i + 1) %
    286 					SQUASHFS_CACHED_BLKS)
    287 				if (msblk->block_cache[i].block !=
    288 							SQUASHFS_USED_BLK)
    289 					break;
    290 
    291 			if (n == 0) {
    292 				wait_queue_t wait;
    293 
    294 				init_waitqueue_entry(&wait, current);
    295 				add_wait_queue(&msblk->waitq, &wait);
    296 				set_current_state(TASK_UNINTERRUPTIBLE);
    297  				up(&msblk->block_cache_mutex);
    298 				schedule();
    299 				set_current_state(TASK_RUNNING);
    300 				remove_wait_queue(&msblk->waitq, &wait);
    301 				continue;
    302 			}
    303 			msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
    304 
    305 			if (msblk->block_cache[i].block ==
    306 							SQUASHFS_INVALID_BLK) {
    307 				if (!(msblk->block_cache[i].data =
    308 						kmalloc(SQUASHFS_METADATA_SIZE,
    309 						GFP_KERNEL))) {
    310 					ERROR("Failed to allocate cache"
    311 							"block\n");
    312 					up(&msblk->block_cache_mutex);
    313 					goto out;
    314 				}
    315 			}
    316 
    317 			msblk->block_cache[i].block = SQUASHFS_USED_BLK;
    318 			up(&msblk->block_cache_mutex);
    319 
    320 			if (!(msblk->block_cache[i].length =
    321 						squashfs_read_data(s,
    322 						msblk->block_cache[i].data,
    323 						block, 0, &next_index))) {
    324 				ERROR("Unable to read cache block [%llx:%x]\n",
    325 						block, offset);
    326 				goto out;
    327 			}
    328 
    329 			down(&msblk->block_cache_mutex);
    330 			wake_up(&msblk->waitq);
    331 			msblk->block_cache[i].block = block;
    332 			msblk->block_cache[i].next_index = next_index;
    333 			TRACE("Read cache block [%llx:%x]\n", block, offset);
    334 		}
    335 
    336 		if (msblk->block_cache[i].block != block) {
    337 			up(&msblk->block_cache_mutex);
    338 			continue;
    339 		}
    340 
    341 		if ((bytes = msblk->block_cache[i].length - offset) >= length) {
    342 			if (buffer)
    343 				memcpy(buffer, msblk->block_cache[i].data +
    344 						offset, length);
    345 			if (msblk->block_cache[i].length - offset == length) {
    346 				*next_block = msblk->block_cache[i].next_index;
    347 				*next_offset = 0;
    348 			} else {
    349 				*next_block = block;
    350 				*next_offset = offset + length;
    351 			}
    352 			up(&msblk->block_cache_mutex);
    353 			goto finish;
    354 		} else {
    355 			if (buffer) {
    356 				memcpy(buffer, msblk->block_cache[i].data +
    357 						offset, bytes);
    358 				buffer += bytes;
    359 			}
    360 			block = msblk->block_cache[i].next_index;
    361 			up(&msblk->block_cache_mutex);
    362 			length -= bytes;
    363 			offset = 0;
    364 		}
    365 	}
    366 
    367 finish:
    368 	return return_length;
    369 out:
    370 	return 0;
    371 }
    372 
    373 
    374 static int get_fragment_location(struct super_block *s, unsigned int fragment,
    375 				long long *fragment_start_block,
    376 				unsigned int *fragment_size)
    377 {
    378 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    379 	long long start_block =
    380 		msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
    381 	int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
    382 	struct squashfs_fragment_entry fragment_entry;
    383 
    384 	if (msblk->swap) {
    385 		struct squashfs_fragment_entry sfragment_entry;
    386 
    387 		if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
    388 					start_block, offset,
    389 					sizeof(sfragment_entry), &start_block,
    390 					&offset))
    391 			goto out;
    392 		SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
    393 	} else
    394 		if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
    395 					start_block, offset,
    396 					sizeof(fragment_entry), &start_block,
    397 					&offset))
    398 			goto out;
    399 
    400 	*fragment_start_block = fragment_entry.start_block;
    401 	*fragment_size = fragment_entry.size;
    402 
    403 	return 1;
    404 
    405 out:
    406 	return 0;
    407 }
    408 
    409 
    410 SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
    411 					squashfs_fragment_cache *fragment)
    412 {
    413 	down(&msblk->fragment_mutex);
    414 	fragment->locked --;
    415 	wake_up(&msblk->fragment_wait_queue);
    416 	up(&msblk->fragment_mutex);
    417 }
    418 
    419 
    420 SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
    421 					*s, long long start_block,
    422 					int length)
    423 {
    424 	int i, n;
    425 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    426 
    427 	while ( 1 ) {
    428 		down(&msblk->fragment_mutex);
    429 
    430 		for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
    431 				msblk->fragment[i].block != start_block; i++);
    432 
    433 		if (i == SQUASHFS_CACHED_FRAGMENTS) {
    434 			for (i = msblk->next_fragment, n =
    435 				SQUASHFS_CACHED_FRAGMENTS; n &&
    436 				msblk->fragment[i].locked; n--, i = (i + 1) %
    437 				SQUASHFS_CACHED_FRAGMENTS);
    438 
    439 			if (n == 0) {
    440 				wait_queue_t wait;
    441 
    442 				init_waitqueue_entry(&wait, current);
    443 				add_wait_queue(&msblk->fragment_wait_queue,
    444 									&wait);
    445 				set_current_state(TASK_UNINTERRUPTIBLE);
    446 				up(&msblk->fragment_mutex);
    447 				schedule();
    448 				set_current_state(TASK_RUNNING);
    449 				remove_wait_queue(&msblk->fragment_wait_queue,
    450 									&wait);
    451 				continue;
    452 			}
    453 			msblk->next_fragment = (msblk->next_fragment + 1) %
    454 				SQUASHFS_CACHED_FRAGMENTS;
    455 
    456 			if (msblk->fragment[i].data == NULL)
    457 				if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
    458 						(SQUASHFS_FILE_MAX_SIZE))) {
    459 					ERROR("Failed to allocate fragment "
    460 							"cache block\n");
    461 					up(&msblk->fragment_mutex);
    462 					goto out;
    463 				}
    464 
    465 			msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
    466 			msblk->fragment[i].locked = 1;
    467 			up(&msblk->fragment_mutex);
    468 
    469 			if (!(msblk->fragment[i].length = squashfs_read_data(s,
    470 						msblk->fragment[i].data,
    471 						start_block, length, NULL))) {
    472 				ERROR("Unable to read fragment cache block "
    473 							"[%llx]\n", start_block);
    474 				msblk->fragment[i].locked = 0;
    475 				goto out;
    476 			}
    477 
    478 			msblk->fragment[i].block = start_block;
    479 			TRACE("New fragment %d, start block %lld, locked %d\n",
    480 						i, msblk->fragment[i].block,
    481 						msblk->fragment[i].locked);
    482 			break;
    483 		}
    484 
    485 		msblk->fragment[i].locked++;
    486 		up(&msblk->fragment_mutex);
    487 		TRACE("Got fragment %d, start block %lld, locked %d\n", i,
    488 						msblk->fragment[i].block,
    489 						msblk->fragment[i].locked);
    490 		break;
    491 	}
    492 
    493 	return &msblk->fragment[i];
    494 
    495 out:
    496 	return NULL;
    497 }
    498 
    499 
    500 static struct inode *squashfs_new_inode(struct super_block *s,
    501 		struct squashfs_base_inode_header *inodeb)
    502 {
    503 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    504 	struct inode *i = new_inode(s);
    505 
    506 	if (i) {
    507 		i->i_ino = inodeb->inode_number;
    508 		i->i_mtime = inodeb->mtime;
    509 		i->i_atime = inodeb->mtime;
    510 		i->i_ctime = inodeb->mtime;
    511 		i->i_uid = msblk->uid[inodeb->uid];
    512 		i->i_mode = inodeb->mode;
    513 		i->i_size = 0;
    514 		if (inodeb->guid == SQUASHFS_GUIDS)
    515 			i->i_gid = i->i_uid;
    516 		else
    517 			i->i_gid = msblk->guid[inodeb->guid];
    518 	}
    519 
    520 	return i;
    521 }
    522 
    523 
    524 static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode)
    525 {
    526 	struct inode *i;
    527 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    528 	struct squashfs_super_block *sblk = &msblk->sblk;
    529 	long long block = SQUASHFS_INODE_BLK(inode) +
    530 		sblk->inode_table_start;
    531 	unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
    532 	long long next_block;
    533 	unsigned int next_offset;
    534 	union squashfs_inode_header id, sid;
    535 	struct squashfs_base_inode_header *inodeb = &id.base,
    536 					  *sinodeb = &sid.base;
    537 
    538 	TRACE("Entered squashfs_iget\n");
    539 
    540 	if (msblk->swap) {
    541 		if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
    542 					offset, sizeof(*sinodeb), &next_block,
    543 					&next_offset))
    544 			goto failed_read;
    545 		SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb,
    546 					sizeof(*sinodeb));
    547 	} else
    548 		if (!squashfs_get_cached_block(s, (char *) inodeb, block,
    549 					offset, sizeof(*inodeb), &next_block,
    550 					&next_offset))
    551 			goto failed_read;
    552 
    553 	switch(inodeb->inode_type) {
    554 		case SQUASHFS_FILE_TYPE: {
    555 			unsigned int frag_size;
    556 			long long frag_blk;
    557 			struct squashfs_reg_inode_header *inodep = &id.reg;
    558 			struct squashfs_reg_inode_header *sinodep = &sid.reg;
    559 
    560 			if (msblk->swap) {
    561 				if (!squashfs_get_cached_block(s, (char *)
    562 						sinodep, block, offset,
    563 						sizeof(*sinodep), &next_block,
    564 						&next_offset))
    565 					goto failed_read;
    566 				SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
    567 			} else
    568 				if (!squashfs_get_cached_block(s, (char *)
    569 						inodep, block, offset,
    570 						sizeof(*inodep), &next_block,
    571 						&next_offset))
    572 					goto failed_read;
    573 
    574 			frag_blk = SQUASHFS_INVALID_BLK;
    575 			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
    576 					!get_fragment_location(s,
    577 					inodep->fragment, &frag_blk, &frag_size))
    578 				goto failed_read;
    579 
    580 			if((i = squashfs_new_inode(s, inodeb)) == NULL)
    581 				goto failed_read1;
    582 
    583 			i->i_nlink = 1;
    584 			i->i_size = inodep->file_size;
    585 			i->i_fop = &generic_ro_fops;
    586 			i->i_mode |= S_IFREG;
    587 			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
    588 			i->i_blksize = PAGE_CACHE_SIZE;
    589 			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
    590 			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
    591 			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
    592 			SQUASHFS_I(i)->start_block = inodep->start_block;
    593 			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
    594 			SQUASHFS_I(i)->offset = next_offset;
    595 			if (sblk->block_size > 4096)
    596 				i->i_data.a_ops = &squashfs_aops;
    597 			else
    598 				i->i_data.a_ops = &squashfs_aops_4K;
    599 
    600 			TRACE("File inode %x:%x, start_block %llx, "
    601 					"block_list_start %llx, offset %x\n",
    602 					SQUASHFS_INODE_BLK(inode), offset,
    603 					inodep->start_block, next_block,
    604 					next_offset);
    605 			break;
    606 		}
    607 		case SQUASHFS_LREG_TYPE: {
    608 			unsigned int frag_size;
    609 			long long frag_blk;
    610 			struct squashfs_lreg_inode_header *inodep = &id.lreg;
    611 			struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
    612 
    613 			if (msblk->swap) {
    614 				if (!squashfs_get_cached_block(s, (char *)
    615 						sinodep, block, offset,
    616 						sizeof(*sinodep), &next_block,
    617 						&next_offset))
    618 					goto failed_read;
    619 				SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
    620 			} else
    621 				if (!squashfs_get_cached_block(s, (char *)
    622 						inodep, block, offset,
    623 						sizeof(*inodep), &next_block,
    624 						&next_offset))
    625 					goto failed_read;
    626 
    627 			frag_blk = SQUASHFS_INVALID_BLK;
    628 			if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
    629 					!get_fragment_location(s,
    630 					inodep->fragment, &frag_blk, &frag_size))
    631 				goto failed_read;
    632 
    633 			if((i = squashfs_new_inode(s, inodeb)) == NULL)
    634 				goto failed_read1;
    635 
    636 			i->i_nlink = inodep->nlink;
    637 			i->i_size = inodep->file_size;
    638 			i->i_fop = &generic_ro_fops;
    639 			i->i_mode |= S_IFREG;
    640 			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
    641 			i->i_blksize = PAGE_CACHE_SIZE;
    642 			SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
    643 			SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
    644 			SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
    645 			SQUASHFS_I(i)->start_block = inodep->start_block;
    646 			SQUASHFS_I(i)->u.s1.block_list_start = next_block;
    647 			SQUASHFS_I(i)->offset = next_offset;
    648 			if (sblk->block_size > 4096)
    649 				i->i_data.a_ops = &squashfs_aops;
    650 			else
    651 				i->i_data.a_ops = &squashfs_aops_4K;
    652 
    653 			TRACE("File inode %x:%x, start_block %llx, "
    654 					"block_list_start %llx, offset %x\n",
    655 					SQUASHFS_INODE_BLK(inode), offset,
    656 					inodep->start_block, next_block,
    657 					next_offset);
    658 			break;
    659 		}
    660 		case SQUASHFS_DIR_TYPE: {
    661 			struct squashfs_dir_inode_header *inodep = &id.dir;
    662 			struct squashfs_dir_inode_header *sinodep = &sid.dir;
    663 
    664 			if (msblk->swap) {
    665 				if (!squashfs_get_cached_block(s, (char *)
    666 						sinodep, block, offset,
    667 						sizeof(*sinodep), &next_block,
    668 						&next_offset))
    669 					goto failed_read;
    670 				SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
    671 			} else
    672 				if (!squashfs_get_cached_block(s, (char *)
    673 						inodep, block, offset,
    674 						sizeof(*inodep), &next_block,
    675 						&next_offset))
    676 					goto failed_read;
    677 
    678 			if((i = squashfs_new_inode(s, inodeb)) == NULL)
    679 				goto failed_read1;
    680 
    681 			i->i_nlink = inodep->nlink;
    682 			i->i_size = inodep->file_size;
    683 			i->i_op = &squashfs_dir_inode_ops;
    684 			i->i_fop = &squashfs_dir_ops;
    685 			i->i_mode |= S_IFDIR;
    686 			SQUASHFS_I(i)->start_block = inodep->start_block;
    687 			SQUASHFS_I(i)->offset = inodep->offset;
    688 			SQUASHFS_I(i)->u.s2.directory_index_count = 0;
    689 			SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
    690 
    691 			TRACE("Directory inode %x:%x, start_block %x, offset "
    692 					"%x\n", SQUASHFS_INODE_BLK(inode),
    693 					offset, inodep->start_block,
    694 					inodep->offset);
    695 			break;
    696 		}
    697 		case SQUASHFS_LDIR_TYPE: {
    698 			struct squashfs_ldir_inode_header *inodep = &id.ldir;
    699 			struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
    700 
    701 			if (msblk->swap) {
    702 				if (!squashfs_get_cached_block(s, (char *)
    703 						sinodep, block, offset,
    704 						sizeof(*sinodep), &next_block,
    705 						&next_offset))
    706 					goto failed_read;
    707 				SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep,
    708 						sinodep);
    709 			} else
    710 				if (!squashfs_get_cached_block(s, (char *)
    711 						inodep, block, offset,
    712 						sizeof(*inodep), &next_block,
    713 						&next_offset))
    714 					goto failed_read;
    715 
    716 			if((i = squashfs_new_inode(s, inodeb)) == NULL)
    717 				goto failed_read1;
    718 
    719 			i->i_nlink = inodep->nlink;
    720 			i->i_size = inodep->file_size;
    721 			i->i_op = &squashfs_dir_inode_ops;
    722 			i->i_fop = &squashfs_dir_ops;
    723 			i->i_mode |= S_IFDIR;
    724 			SQUASHFS_I(i)->start_block = inodep->start_block;
    725 			SQUASHFS_I(i)->offset = inodep->offset;
    726 			SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
    727 			SQUASHFS_I(i)->u.s2.directory_index_offset =
    728 								next_offset;
    729 			SQUASHFS_I(i)->u.s2.directory_index_count =
    730 								inodep->i_count;
    731 			SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
    732 
    733 			TRACE("Long directory inode %x:%x, start_block %x, "
    734 					"offset %x\n",
    735 					SQUASHFS_INODE_BLK(inode), offset,
    736 					inodep->start_block, inodep->offset);
    737 			break;
    738 		}
    739 		case SQUASHFS_SYMLINK_TYPE: {
    740 			struct squashfs_symlink_inode_header *inodep =
    741 								&id.symlink;
    742 			struct squashfs_symlink_inode_header *sinodep =
    743 								&sid.symlink;
    744 
    745 			if (msblk->swap) {
    746 				if (!squashfs_get_cached_block(s, (char *)
    747 						sinodep, block, offset,
    748 						sizeof(*sinodep), &next_block,
    749 						&next_offset))
    750 					goto failed_read;
    751 				SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep,
    752 								sinodep);
    753 			} else
    754 				if (!squashfs_get_cached_block(s, (char *)
    755 						inodep, block, offset,
    756 						sizeof(*inodep), &next_block,
    757 						&next_offset))
    758 					goto failed_read;
    759 
    760 			if((i = squashfs_new_inode(s, inodeb)) == NULL)
    761 				goto failed_read1;
    762 
    763 			i->i_nlink = inodep->nlink;
    764 			i->i_size = inodep->symlink_size;
    765 			i->i_op = &page_symlink_inode_operations;
    766 			i->i_data.a_ops = &squashfs_symlink_aops;
    767 			i->i_mode |= S_IFLNK;
    768 			SQUASHFS_I(i)->start_block = next_block;
    769 			SQUASHFS_I(i)->offset = next_offset;
    770 
    771 			TRACE("Symbolic link inode %x:%x, start_block %llx, "
    772 					"offset %x\n",
    773 					SQUASHFS_INODE_BLK(inode), offset,
    774 					next_block, next_offset);
    775 			break;
    776 		 }
    777 		 case SQUASHFS_BLKDEV_TYPE:
    778 		 case SQUASHFS_CHRDEV_TYPE: {
    779 			struct squashfs_dev_inode_header *inodep = &id.dev;
    780 			struct squashfs_dev_inode_header *sinodep = &sid.dev;
    781 
    782 			if (msblk->swap) {
    783 				if (!squashfs_get_cached_block(s, (char *)
    784 						sinodep, block, offset,
    785 						sizeof(*sinodep), &next_block,
    786 						&next_offset))
    787 					goto failed_read;
    788 				SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
    789 			} else
    790 				if (!squashfs_get_cached_block(s, (char *)
    791 						inodep, block, offset,
    792 						sizeof(*inodep), &next_block,
    793 						&next_offset))
    794 					goto failed_read;
    795 
    796 			if ((i = squashfs_new_inode(s, inodeb)) == NULL)
    797 				goto failed_read1;
    798 
    799 			i->i_nlink = inodep->nlink;
    800 			i->i_mode |= (inodeb->inode_type ==
    801 					SQUASHFS_CHRDEV_TYPE) ?  S_IFCHR :
    802 					S_IFBLK;
    803 			init_special_inode(i, i->i_mode, inodep->rdev);
    804 
    805 			TRACE("Device inode %x:%x, rdev %x\n",
    806 					SQUASHFS_INODE_BLK(inode), offset,
    807 					inodep->rdev);
    808 			break;
    809 		 }
    810 		 case SQUASHFS_FIFO_TYPE:
    811 		 case SQUASHFS_SOCKET_TYPE: {
    812 			struct squashfs_ipc_inode_header *inodep = &id.ipc;
    813 			struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
    814 
    815 			if (msblk->swap) {
    816 				if (!squashfs_get_cached_block(s, (char *)
    817 						sinodep, block, offset,
    818 						sizeof(*sinodep), &next_block,
    819 						&next_offset))
    820 					goto failed_read;
    821 				SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
    822 			} else
    823 				if (!squashfs_get_cached_block(s, (char *)
    824 						inodep, block, offset,
    825 						sizeof(*inodep), &next_block,
    826 						&next_offset))
    827 					goto failed_read;
    828 
    829 			if ((i = squashfs_new_inode(s, inodeb)) == NULL)
    830 				goto failed_read1;
    831 
    832 			i->i_nlink = inodep->nlink;
    833 			i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
    834 							? S_IFIFO : S_IFSOCK;
    835 			init_special_inode(i, i->i_mode, 0);
    836 			break;
    837 		 }
    838 		 default:
    839 			ERROR("Unknown inode type %d in squashfs_iget!\n",
    840 					inodeb->inode_type);
    841 			goto failed_read1;
    842 	}
    843 
    844 	insert_inode_hash(i);
    845 	return i;
    846 
    847 failed_read:
    848 	ERROR("Unable to read inode [%llx:%x]\n", block, offset);
    849 
    850 failed_read1:
    851 	return NULL;
    852 }
    853 
    854 
    855 int read_fragment_index_table(struct super_block *s)
    856 {
    857 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    858 	struct squashfs_super_block *sblk = &msblk->sblk;
    859 
    860 	if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
    861 					(sblk->fragments), GFP_KERNEL))) {
    862 		ERROR("Failed to allocate uid/gid table\n");
    863 		return 0;
    864 	}
    865 
    866 	if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&
    867 					!squashfs_read_data(s, (char *)
    868 					msblk->fragment_index,
    869 					sblk->fragment_table_start,
    870 					SQUASHFS_FRAGMENT_INDEX_BYTES
    871 					(sblk->fragments) |
    872 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
    873 		ERROR("unable to read fragment index table\n");
    874 		return 0;
    875 	}
    876 
    877 	if (msblk->swap) {
    878 		int i;
    879 		long long fragment;
    880 
    881 		for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);
    882 									i++) {
    883 			SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
    884 						&msblk->fragment_index[i], 1);
    885 			msblk->fragment_index[i] = fragment;
    886 		}
    887 	}
    888 
    889 	return 1;
    890 }
    891 
    892 
    893 static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
    894 {
    895 	struct squashfs_super_block *sblk = &msblk->sblk;
    896 
    897 	msblk->iget = squashfs_iget;
    898 	msblk->read_blocklist = read_blocklist;
    899 	msblk->read_fragment_index_table = read_fragment_index_table;
    900 
    901 	if (sblk->s_major == 1) {
    902 		if (!squashfs_1_0_supported(msblk)) {
    903 			SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
    904 				"are unsupported\n");
    905 			SERROR("Please recompile with "
    906 				"Squashfs 1.0 support enabled\n");
    907 			return 0;
    908 		}
    909 	} else if (sblk->s_major == 2) {
    910 		if (!squashfs_2_0_supported(msblk)) {
    911 			SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
    912 				"are unsupported\n");
    913 			SERROR("Please recompile with "
    914 				"Squashfs 2.0 support enabled\n");
    915 			return 0;
    916 		}
    917 	} else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
    918 			SQUASHFS_MINOR) {
    919 		SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
    920 				"filesystem\n", sblk->s_major, sblk->s_minor);
    921 		SERROR("Please update your kernel\n");
    922 		return 0;
    923 	}
    924 
    925 	return 1;
    926 }
    927 
    928 
    929 static struct super_block *squashfs_read_super(struct super_block *s,
    930 		void *data, int silent)
    931 {
    932 	kdev_t dev = s->s_dev;
    933 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
    934 	struct squashfs_super_block *sblk = &msblk->sblk;
    935 	int i;
    936 	struct inode *root;
    937 
    938 	if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
    939 		ERROR("Failed to allocate zlib workspace\n");
    940 		goto failed_mount;
    941 	}
    942 
    943 	msblk->devblksize = get_hardsect_size(dev);
    944 	if(msblk->devblksize < BLOCK_SIZE)
    945 		msblk->devblksize = BLOCK_SIZE;
    946 	msblk->devblksize_log2 = ffz(~msblk->devblksize);
    947         set_blocksize(dev, msblk->devblksize);
    948 	s->s_blocksize = msblk->devblksize;
    949 	s->s_blocksize_bits = msblk->devblksize_log2;
    950 
    951 	init_MUTEX(&msblk->read_data_mutex);
    952 	init_MUTEX(&msblk->read_page_mutex);
    953 	init_MUTEX(&msblk->block_cache_mutex);
    954 	init_MUTEX(&msblk->fragment_mutex);
    955 
    956 	init_waitqueue_head(&msblk->waitq);
    957 	init_waitqueue_head(&msblk->fragment_wait_queue);
    958 
    959 	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
    960 					sizeof(struct squashfs_super_block) |
    961 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
    962 		SERROR("unable to read superblock\n");
    963 		goto failed_mount;
    964 	}
    965 
    966 	/* Check it is a SQUASHFS superblock */
    967 	msblk->swap = 0;
    968 	if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
    969 		if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
    970 			struct squashfs_super_block ssblk;
    971 
    972 			WARNING("Mounting a different endian SQUASHFS "
    973 				"filesystem on %s\n", bdevname(dev));
    974 
    975 			SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
    976 			memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
    977 			msblk->swap = 1;
    978 		} else  {
    979 			SERROR("Can't find a SQUASHFS superblock on %s\n",
    980 							bdevname(dev));
    981 			goto failed_mount;
    982 		}
    983 	}
    984 
    985 	/* Check the MAJOR & MINOR versions */
    986 	if(!supported_squashfs_filesystem(msblk, silent))
    987 		goto failed_mount;
    988 
    989 	TRACE("Found valid superblock on %s\n", bdevname(dev));
    990 	TRACE("Inodes are %scompressed\n",
    991 					SQUASHFS_UNCOMPRESSED_INODES
    992 					(sblk->flags) ? "un" : "");
    993 	TRACE("Data is %scompressed\n",
    994 					SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
    995 					? "un" : "");
    996 	TRACE("Check data is %s present in the filesystem\n",
    997 					SQUASHFS_CHECK_DATA(sblk->flags) ?
    998 					"" : "not");
    999 	TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
   1000 	TRACE("Block size %d\n", sblk->block_size);
   1001 	TRACE("Number of inodes %d\n", sblk->inodes);
   1002 	if (sblk->s_major > 1)
   1003 		TRACE("Number of fragments %d\n", sblk->fragments);
   1004 	TRACE("Number of uids %d\n", sblk->no_uids);
   1005 	TRACE("Number of gids %d\n", sblk->no_guids);
   1006 	TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
   1007 	TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
   1008 	if (sblk->s_major > 1)
   1009 		TRACE("sblk->fragment_table_start %llx\n",
   1010 					sblk->fragment_table_start);
   1011 	TRACE("sblk->uid_start %llx\n", sblk->uid_start);
   1012 
   1013 	s->s_flags |= MS_RDONLY;
   1014 	s->s_op = &squashfs_ops;
   1015 
   1016 	/* Init inode_table block pointer array */
   1017 	if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
   1018 					SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
   1019 		ERROR("Failed to allocate block cache\n");
   1020 		goto failed_mount;
   1021 	}
   1022 
   1023 	for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
   1024 		msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
   1025 
   1026 	msblk->next_cache = 0;
   1027 
   1028 	/* Allocate read_data block */
   1029 	msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?
   1030 					SQUASHFS_METADATA_SIZE :
   1031 					sblk->block_size;
   1032 
   1033 	if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {
   1034 		ERROR("Failed to allocate read_data block\n");
   1035 		goto failed_mount;
   1036 	}
   1037 
   1038 	/* Allocate read_page block */
   1039 	if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
   1040 		ERROR("Failed to allocate read_page block\n");
   1041 		goto failed_mount;
   1042 	}
   1043 
   1044 	/* Allocate uid and gid tables */
   1045 	if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
   1046 					sizeof(unsigned int), GFP_KERNEL))) {
   1047 		ERROR("Failed to allocate uid/gid table\n");
   1048 		goto failed_mount;
   1049 	}
   1050 	msblk->guid = msblk->uid + sblk->no_uids;
   1051 
   1052 	if (msblk->swap) {
   1053 		unsigned int suid[sblk->no_uids + sblk->no_guids];
   1054 
   1055 		if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
   1056 					((sblk->no_uids + sblk->no_guids) *
   1057 					 sizeof(unsigned int)) |
   1058 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
   1059 			ERROR("unable to read uid/gid table\n");
   1060 			goto failed_mount;
   1061 		}
   1062 
   1063 		SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
   1064 			sblk->no_guids), (sizeof(unsigned int) * 8));
   1065 	} else
   1066 		if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
   1067 					((sblk->no_uids + sblk->no_guids) *
   1068 					 sizeof(unsigned int)) |
   1069 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
   1070 			ERROR("unable to read uid/gid table\n");
   1071 			goto failed_mount;
   1072 		}
   1073 
   1074 
   1075 	if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
   1076 		goto allocate_root;
   1077 
   1078 	if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
   1079 				SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
   1080 		ERROR("Failed to allocate fragment block cache\n");
   1081 		goto failed_mount;
   1082 	}
   1083 
   1084 	for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
   1085 		msblk->fragment[i].locked = 0;
   1086 		msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
   1087 		msblk->fragment[i].data = NULL;
   1088 	}
   1089 
   1090 	msblk->next_fragment = 0;
   1091 
   1092 	/* Allocate fragment index table */
   1093 	if(msblk->read_fragment_index_table(s) == 0)
   1094 		goto failed_mount;
   1095 
   1096 allocate_root:
   1097 	if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)
   1098 		goto failed_mount;
   1099 
   1100 	if ((s->s_root = d_alloc_root(root)) == NULL) {
   1101 		ERROR("Root inode create failed\n");
   1102 		iput(root);
   1103 		goto failed_mount;
   1104 	}
   1105 
   1106 	TRACE("Leaving squashfs_read_super\n");
   1107 	return s;
   1108 
   1109 failed_mount:
   1110 	kfree(msblk->fragment_index);
   1111 	kfree(msblk->fragment);
   1112 	kfree(msblk->uid);
   1113 	kfree(msblk->read_page);
   1114 	kfree(msblk->read_data);
   1115 	kfree(msblk->block_cache);
   1116 	kfree(msblk->fragment_index_2);
   1117 	vfree(msblk->stream.workspace);
   1118 	return NULL;
   1119 }
   1120 
   1121 
   1122 static int squashfs_statfs(struct super_block *s, struct statfs *buf)
   1123 {
   1124 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
   1125 	struct squashfs_super_block *sblk = &msblk->sblk;
   1126 
   1127 	TRACE("Entered squashfs_statfs\n");
   1128 
   1129 	buf->f_type = SQUASHFS_MAGIC;
   1130 	buf->f_bsize = sblk->block_size;
   1131 	buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
   1132 	buf->f_bfree = buf->f_bavail = 0;
   1133 	buf->f_files = sblk->inodes;
   1134 	buf->f_ffree = 0;
   1135 	buf->f_namelen = SQUASHFS_NAME_LEN;
   1136 
   1137 	return 0;
   1138 }
   1139 
   1140 
   1141 static int squashfs_symlink_readpage(struct file *file, struct page *page)
   1142 {
   1143 	struct inode *inode = page->mapping->host;
   1144 	int index = page->index << PAGE_CACHE_SHIFT, length, bytes;
   1145 	long long block = SQUASHFS_I(inode)->start_block;
   1146 	int offset = SQUASHFS_I(inode)->offset;
   1147 	void *pageaddr = kmap(page);
   1148 
   1149 	TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
   1150 				"%llx, offset %x\n", page->index,
   1151 				SQUASHFS_I(inode)->start_block,
   1152 				SQUASHFS_I(inode)->offset);
   1153 
   1154 	for (length = 0; length < index; length += bytes) {
   1155 		if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,
   1156 				block, offset, PAGE_CACHE_SIZE, &block,
   1157 				&offset))) {
   1158 			ERROR("Unable to read symbolic link [%llx:%x]\n", block,
   1159 					offset);
   1160 			goto skip_read;
   1161 		}
   1162 	}
   1163 
   1164 	if (length != index) {
   1165 		ERROR("(squashfs_symlink_readpage) length != index\n");
   1166 		bytes = 0;
   1167 		goto skip_read;
   1168 	}
   1169 
   1170 	bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :
   1171 					i_size_read(inode) - length;
   1172 
   1173 	if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,
   1174 					offset, bytes, &block, &offset)))
   1175 		ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);
   1176 
   1177 skip_read:
   1178 	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
   1179 	kunmap(page);
   1180 	SetPageUptodate(page);
   1181 	UnlockPage(page);
   1182 
   1183 	return 0;
   1184 }
   1185 
   1186 
   1187 struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
   1188 {
   1189 	struct meta_index *meta = NULL;
   1190 	struct squashfs_sb_info *msblk = &inode->i_sb->u.squashfs_sb;
   1191 	int i;
   1192 
   1193 	down(&msblk->meta_index_mutex);
   1194 
   1195 	TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
   1196 
   1197 	if(msblk->meta_index == NULL)
   1198 		goto not_allocated;
   1199 
   1200 	for (i = 0; i < SQUASHFS_META_NUMBER; i ++)
   1201 		if (msblk->meta_index[i].inode_number == inode->i_ino &&
   1202 				msblk->meta_index[i].offset >= offset &&
   1203 				msblk->meta_index[i].offset <= index &&
   1204 				msblk->meta_index[i].locked == 0) {
   1205 			TRACE("locate_meta_index: entry %d, offset %d\n", i,
   1206 					msblk->meta_index[i].offset);
   1207 			meta = &msblk->meta_index[i];
   1208 			offset = meta->offset;
   1209 		}
   1210 
   1211 	if (meta)
   1212 		meta->locked = 1;
   1213 
   1214 not_allocated:
   1215 	up(&msblk->meta_index_mutex);
   1216 
   1217 	return meta;
   1218 }
   1219 
   1220 
   1221 struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
   1222 {
   1223 	struct squashfs_sb_info *msblk = &inode->i_sb->u.squashfs_sb;
   1224 	struct meta_index *meta = NULL;
   1225 	int i;
   1226 
   1227 	down(&msblk->meta_index_mutex);
   1228 
   1229 	TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
   1230 
   1231 	if(msblk->meta_index == NULL) {
   1232 		if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *
   1233 					SQUASHFS_META_NUMBER, GFP_KERNEL))) {
   1234 			ERROR("Failed to allocate meta_index\n");
   1235 			goto failed;
   1236 		}
   1237 		for(i = 0; i < SQUASHFS_META_NUMBER; i++) {
   1238 			msblk->meta_index[i].inode_number = 0;
   1239 			msblk->meta_index[i].locked = 0;
   1240 		}
   1241 		msblk->next_meta_index = 0;
   1242 	}
   1243 
   1244 	for(i = SQUASHFS_META_NUMBER; i &&
   1245 			msblk->meta_index[msblk->next_meta_index].locked; i --)
   1246 		msblk->next_meta_index = (msblk->next_meta_index + 1) %
   1247 			SQUASHFS_META_NUMBER;
   1248 
   1249 	if(i == 0) {
   1250 		TRACE("empty_meta_index: failed!\n");
   1251 		goto failed;
   1252 	}
   1253 
   1254 	TRACE("empty_meta_index: returned meta entry %d, %p\n",
   1255 			msblk->next_meta_index,
   1256 			&msblk->meta_index[msblk->next_meta_index]);
   1257 
   1258 	meta = &msblk->meta_index[msblk->next_meta_index];
   1259 	msblk->next_meta_index = (msblk->next_meta_index + 1) %
   1260 			SQUASHFS_META_NUMBER;
   1261 
   1262 	meta->inode_number = inode->i_ino;
   1263 	meta->offset = offset;
   1264 	meta->skip = skip;
   1265 	meta->entries = 0;
   1266 	meta->locked = 1;
   1267 
   1268 failed:
   1269 	up(&msblk->meta_index_mutex);
   1270 	return meta;
   1271 }
   1272 
   1273 
   1274 void release_meta_index(struct inode *inode, struct meta_index *meta)
   1275 {
   1276 	meta->locked = 0;
   1277 }
   1278 
   1279 
   1280 static int read_block_index(struct super_block *s, int blocks, char *block_list,
   1281 		long long *start_block, int *offset)
   1282 {
   1283 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
   1284 	unsigned int *block_listp;
   1285 	int block = 0;
   1286 
   1287 	if (msblk->swap) {
   1288 		char sblock_list[blocks << 2];
   1289 
   1290 		if (!squashfs_get_cached_block(s, sblock_list, *start_block,
   1291 				*offset, blocks << 2, start_block, offset)) {
   1292 			ERROR("Unable to read block list [%llx:%x]\n",
   1293 				*start_block, *offset);
   1294 			goto failure;
   1295 		}
   1296 		SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
   1297 				((unsigned int *)sblock_list), blocks);
   1298 	} else
   1299 		if (!squashfs_get_cached_block(s, block_list, *start_block,
   1300 				*offset, blocks << 2, start_block, offset)) {
   1301 			ERROR("Unable to read block list [%llx:%x]\n",
   1302 				*start_block, *offset);
   1303 			goto failure;
   1304 		}
   1305 
   1306 	for (block_listp = (unsigned int *) block_list; blocks;
   1307 				block_listp++, blocks --)
   1308 		block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
   1309 
   1310 	return block;
   1311 
   1312 failure:
   1313 	return -1;
   1314 }
   1315 
   1316 
   1317 #define SIZE 256
   1318 
   1319 static inline int calculate_skip(int blocks) {
   1320 	int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
   1321 	return skip >= 7 ? 7 : skip + 1;
   1322 }
   1323 
   1324 
   1325 static int get_meta_index(struct inode *inode, int index,
   1326 		long long *index_block, int *index_offset,
   1327 		long long *data_block, char *block_list)
   1328 {
   1329 	struct squashfs_sb_info *msblk = &inode->i_sb->u.squashfs_sb;
   1330 	struct squashfs_super_block *sblk = &msblk->sblk;
   1331 	int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
   1332 	int offset = 0;
   1333 	struct meta_index *meta;
   1334 	struct meta_entry *meta_entry;
   1335 	long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
   1336 	int cur_offset = SQUASHFS_I(inode)->offset;
   1337 	long long cur_data_block = SQUASHFS_I(inode)->start_block;
   1338 	int i;
   1339 
   1340 	index /= SQUASHFS_META_INDEXES * skip;
   1341 
   1342 	while ( offset < index ) {
   1343 		meta = locate_meta_index(inode, index, offset + 1);
   1344 
   1345 		if (meta == NULL) {
   1346 			if ((meta = empty_meta_index(inode, offset + 1,
   1347 							skip)) == NULL)
   1348 				goto all_done;
   1349 		} else {
   1350 			offset = index < meta->offset + meta->entries ? index :
   1351 				meta->offset + meta->entries - 1;
   1352 			meta_entry = &meta->meta_entry[offset - meta->offset];
   1353 			cur_index_block = meta_entry->index_block + sblk->inode_table_start;
   1354 			cur_offset = meta_entry->offset;
   1355 			cur_data_block = meta_entry->data_block;
   1356 			TRACE("get_meta_index: offset %d, meta->offset %d, "
   1357 				"meta->entries %d\n", offset, meta->offset,
   1358 				meta->entries);
   1359 			TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
   1360 				" data_block 0x%llx\n", cur_index_block,
   1361 				cur_offset, cur_data_block);
   1362 		}
   1363 
   1364 		for (i = meta->offset + meta->entries; i <= index &&
   1365 				i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
   1366 			int blocks = skip * SQUASHFS_META_INDEXES;
   1367 
   1368 			while (blocks) {
   1369 				int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :
   1370 					blocks;
   1371 				int res = read_block_index(inode->i_sb, block,
   1372 					block_list, &cur_index_block,
   1373 					&cur_offset);
   1374 
   1375 				if (res == -1)
   1376 					goto failed;
   1377 
   1378 				cur_data_block += res;
   1379 				blocks -= block;
   1380 			}
   1381 
   1382 			meta_entry = &meta->meta_entry[i - meta->offset];
   1383 			meta_entry->index_block = cur_index_block - sblk->inode_table_start;
   1384 			meta_entry->offset = cur_offset;
   1385 			meta_entry->data_block = cur_data_block;
   1386 			meta->entries ++;
   1387 			offset ++;
   1388 		}
   1389 
   1390 		TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
   1391 				meta->offset, meta->entries);
   1392 
   1393 		release_meta_index(inode, meta);
   1394 	}
   1395 
   1396 all_done:
   1397 	*index_block = cur_index_block;
   1398 	*index_offset = cur_offset;
   1399 	*data_block = cur_data_block;
   1400 
   1401 	return offset * SQUASHFS_META_INDEXES * skip;
   1402 
   1403 failed:
   1404 	release_meta_index(inode, meta);
   1405 	return -1;
   1406 }
   1407 
   1408 
   1409 static long long read_blocklist(struct inode *inode, int index,
   1410 				int readahead_blks, char *block_list,
   1411 				unsigned short **block_p, unsigned int *bsize)
   1412 {
   1413 	long long block_ptr;
   1414 	int offset;
   1415 	long long block;
   1416 	int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
   1417 		block_list);
   1418 
   1419 	TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
   1420 		       " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,
   1421 		       block);
   1422 
   1423 	if(res == -1)
   1424 		goto failure;
   1425 
   1426 	index -= res;
   1427 
   1428 	while ( index ) {
   1429 		int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
   1430 		int res = read_block_index(inode->i_sb, blocks, block_list,
   1431 			&block_ptr, &offset);
   1432 		if (res == -1)
   1433 			goto failure;
   1434 		block += res;
   1435 		index -= blocks;
   1436 	}
   1437 
   1438 	if (read_block_index(inode->i_sb, 1, block_list,
   1439 			&block_ptr, &offset) == -1)
   1440 		goto failure;
   1441 	*bsize = *((unsigned int *) block_list);
   1442 
   1443 	return block;
   1444 
   1445 failure:
   1446 	return 0;
   1447 }
   1448 
   1449 
   1450 static int squashfs_readpage(struct file *file, struct page *page)
   1451 {
   1452 	struct inode *inode = page->mapping->host;
   1453 	struct squashfs_sb_info *msblk = &inode->i_sb->u.squashfs_sb;
   1454 	struct squashfs_super_block *sblk = &msblk->sblk;
   1455 	unsigned char block_list[SIZE];
   1456 	long long block;
   1457 	unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;
   1458 	int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
   1459  	void *pageaddr;
   1460 	struct squashfs_fragment_cache *fragment = NULL;
   1461 	char *data_ptr = msblk->read_page;
   1462 
   1463 	int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
   1464 	int start_index = page->index & ~mask;
   1465 	int end_index = start_index | mask;
   1466 
   1467 	TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
   1468 					page->index,
   1469 					SQUASHFS_I(inode)->start_block);
   1470 
   1471 	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
   1472 					PAGE_CACHE_SHIFT))
   1473 		goto skip_read;
   1474 
   1475 	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
   1476 					|| index < (i_size_read(inode) >>
   1477 					sblk->block_log)) {
   1478 		if ((block = (msblk->read_blocklist)(inode, index, 1,
   1479 					block_list, NULL, &bsize)) == 0)
   1480 			goto skip_read;
   1481 
   1482 		down(&msblk->read_page_mutex);
   1483 
   1484 		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
   1485 					block, bsize, NULL))) {
   1486 			ERROR("Unable to read page, block %llx, size %x\n", block,
   1487 					bsize);
   1488 			up(&msblk->read_page_mutex);
   1489 			goto skip_read;
   1490 		}
   1491 	} else {
   1492 		if ((fragment = get_cached_fragment(inode->i_sb,
   1493 					SQUASHFS_I(inode)->
   1494 					u.s1.fragment_start_block,
   1495 					SQUASHFS_I(inode)->u.s1.fragment_size))
   1496 					== NULL) {
   1497 			ERROR("Unable to read page, block %llx, size %x\n",
   1498 					SQUASHFS_I(inode)->
   1499 					u.s1.fragment_start_block,
   1500 					(int) SQUASHFS_I(inode)->
   1501 					u.s1.fragment_size);
   1502 			goto skip_read;
   1503 		}
   1504 		bytes = SQUASHFS_I(inode)->u.s1.fragment_offset +
   1505 					(i_size_read(inode) & (sblk->block_size
   1506 					- 1));
   1507 		byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;
   1508 		data_ptr = fragment->data;
   1509 	}
   1510 
   1511 	for (i = start_index; i <= end_index && byte_offset < bytes;
   1512 					i++, byte_offset += PAGE_CACHE_SIZE) {
   1513 		struct page *push_page;
   1514 		int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ?
   1515 					PAGE_CACHE_SIZE : bytes - byte_offset;
   1516 
   1517 		TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
   1518 					bytes, i, byte_offset, available_bytes);
   1519 
   1520 		if (i == page->index)  {
   1521 			pageaddr = kmap_atomic(page, KM_USER0);
   1522 			memcpy(pageaddr, data_ptr + byte_offset,
   1523 					available_bytes);
   1524 			memset(pageaddr + available_bytes, 0,
   1525 					PAGE_CACHE_SIZE - available_bytes);
   1526 			kunmap_atomic(pageaddr, KM_USER0);
   1527 			flush_dcache_page(page);
   1528 			SetPageUptodate(page);
   1529 			UnlockPage(page);
   1530 		} else if ((push_page =
   1531 				grab_cache_page_nowait(page->mapping, i))) {
   1532  			pageaddr = kmap_atomic(push_page, KM_USER0);
   1533 
   1534 			memcpy(pageaddr, data_ptr + byte_offset,
   1535 					available_bytes);
   1536 			memset(pageaddr + available_bytes, 0,
   1537 					PAGE_CACHE_SIZE - available_bytes);
   1538 			kunmap_atomic(pageaddr, KM_USER0);
   1539 			flush_dcache_page(push_page);
   1540 			SetPageUptodate(push_page);
   1541 			UnlockPage(push_page);
   1542 			page_cache_release(push_page);
   1543 		}
   1544 	}
   1545 
   1546 	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
   1547 					|| index < (i_size_read(inode) >>
   1548 					sblk->block_log))
   1549 		up(&msblk->read_page_mutex);
   1550 	else
   1551 		release_cached_fragment(msblk, fragment);
   1552 
   1553 	return 0;
   1554 
   1555 skip_read:
   1556 	pageaddr = kmap_atomic(page, KM_USER0);
   1557 	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
   1558 	kunmap_atomic(pageaddr, KM_USER0);
   1559 	flush_dcache_page(page);
   1560 	SetPageUptodate(page);
   1561 	UnlockPage(page);
   1562 
   1563 	return 0;
   1564 }
   1565 
   1566 
   1567 static int squashfs_readpage4K(struct file *file, struct page *page)
   1568 {
   1569 	struct inode *inode = page->mapping->host;
   1570 	struct squashfs_sb_info *msblk = &inode->i_sb->u.squashfs_sb;
   1571 	struct squashfs_super_block *sblk = &msblk->sblk;
   1572 	unsigned char block_list[SIZE];
   1573 	long long block;
   1574 	unsigned int bsize, bytes = 0;
   1575  	void *pageaddr;
   1576 
   1577 	TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
   1578 					page->index,
   1579 					SQUASHFS_I(inode)->start_block);
   1580 
   1581 	if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
   1582 					PAGE_CACHE_SHIFT)) {
   1583 		pageaddr = kmap_atomic(page, KM_USER0);
   1584 		goto skip_read;
   1585 	}
   1586 
   1587 	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
   1588 					|| page->index < (i_size_read(inode) >>
   1589 					sblk->block_log)) {
   1590 		block = (msblk->read_blocklist)(inode, page->index, 1,
   1591 					block_list, NULL, &bsize);
   1592 
   1593 		down(&msblk->read_page_mutex);
   1594 		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
   1595 					bsize, NULL);
   1596 		pageaddr = kmap_atomic(page, KM_USER0);
   1597 		if (bytes)
   1598 			memcpy(pageaddr, msblk->read_page, bytes);
   1599 		else
   1600 			ERROR("Unable to read page, block %llx, size %x\n",
   1601 					block, bsize);
   1602 		up(&msblk->read_page_mutex);
   1603 	} else {
   1604 		struct squashfs_fragment_cache *fragment =
   1605 			get_cached_fragment(inode->i_sb,
   1606 					SQUASHFS_I(inode)->
   1607 					u.s1.fragment_start_block,
   1608 					SQUASHFS_I(inode)-> u.s1.fragment_size);
   1609 		pageaddr = kmap_atomic(page, KM_USER0);
   1610 		if (fragment) {
   1611 			bytes = i_size_read(inode) & (sblk->block_size - 1);
   1612 			memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
   1613 					u.s1.fragment_offset, bytes);
   1614 			release_cached_fragment(msblk, fragment);
   1615 		} else
   1616 			ERROR("Unable to read page, block %llx, size %x\n",
   1617 					SQUASHFS_I(inode)->
   1618 					u.s1.fragment_start_block, (int)
   1619 					SQUASHFS_I(inode)-> u.s1.fragment_size);
   1620 	}
   1621 
   1622 skip_read:
   1623 	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
   1624 	kunmap_atomic(pageaddr, KM_USER0);
   1625 	flush_dcache_page(page);
   1626 	SetPageUptodate(page);
   1627 	UnlockPage(page);
   1628 
   1629 	return 0;
   1630 }
   1631 
   1632 
   1633 static int get_dir_index_using_offset(struct super_block *s, long long
   1634 				*next_block, unsigned int *next_offset,
   1635 				long long index_start,
   1636 				unsigned int index_offset, int i_count,
   1637 				long long f_pos)
   1638 {
   1639 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
   1640 	struct squashfs_super_block *sblk = &msblk->sblk;
   1641 	int i, length = 0;
   1642 	struct squashfs_dir_index index;
   1643 
   1644 	TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
   1645 					i_count, (unsigned int) f_pos);
   1646 
   1647 	f_pos -= 3;
   1648 	if (f_pos == 0)
   1649 		goto finish;
   1650 
   1651 	for (i = 0; i < i_count; i++) {
   1652 		if (msblk->swap) {
   1653 			struct squashfs_dir_index sindex;
   1654 			squashfs_get_cached_block(s, (char *) &sindex,
   1655 					index_start, index_offset,
   1656 					sizeof(sindex), &index_start,
   1657 					&index_offset);
   1658 			SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
   1659 		} else
   1660 			squashfs_get_cached_block(s, (char *) &index,
   1661 					index_start, index_offset,
   1662 					sizeof(index), &index_start,
   1663 					&index_offset);
   1664 
   1665 		if (index.index > f_pos)
   1666 			break;
   1667 
   1668 		squashfs_get_cached_block(s, NULL, index_start, index_offset,
   1669 					index.size + 1, &index_start,
   1670 					&index_offset);
   1671 
   1672 		length = index.index;
   1673 		*next_block = index.start_block + sblk->directory_table_start;
   1674 	}
   1675 
   1676 	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
   1677 
   1678 finish:
   1679 	return length + 3;
   1680 }
   1681 
   1682 
   1683 static int get_dir_index_using_name(struct super_block *s, long long
   1684 				*next_block, unsigned int *next_offset,
   1685 				long long index_start,
   1686 				unsigned int index_offset, int i_count,
   1687 				const char *name, int size)
   1688 {
   1689 	struct squashfs_sb_info *msblk = &s->u.squashfs_sb;
   1690 	struct squashfs_super_block *sblk = &msblk->sblk;
   1691 	int i, length = 0;
   1692 	char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1];
   1693 	struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer;
   1694 	char str[SQUASHFS_NAME_LEN + 1];
   1695 
   1696 	TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
   1697 
   1698 	strncpy(str, name, size);
   1699 	str[size] = '\0';
   1700 
   1701 	for (i = 0; i < i_count; i++) {
   1702 		if (msblk->swap) {
   1703 			struct squashfs_dir_index sindex;
   1704 			squashfs_get_cached_block(s, (char *) &sindex,
   1705 					index_start, index_offset,
   1706 					sizeof(sindex), &index_start,
   1707 					&index_offset);
   1708 			SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
   1709 		} else
   1710 			squashfs_get_cached_block(s, (char *) index,
   1711 					index_start, index_offset,
   1712 					sizeof(struct squashfs_dir_index),
   1713 					&index_start, &index_offset);
   1714 
   1715 		squashfs_get_cached_block(s, index->name, index_start,
   1716 					index_offset, index->size + 1,
   1717 					&index_start, &index_offset);
   1718 
   1719 		index->name[index->size + 1] = '\0';
   1720 
   1721 		if (strcmp(index->name, str) > 0)
   1722 			break;
   1723 
   1724 		length = index->index;
   1725 		*next_block = index->start_block + sblk->directory_table_start;
   1726 	}
   1727 
   1728 	*next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
   1729 	return length + 3;
   1730 }
   1731 
   1732 
   1733 static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
   1734 {
   1735 	struct inode *i = file->f_dentry->d_inode;
   1736 	struct squashfs_sb_info *msblk = &i->i_sb->u.squashfs_sb;
   1737 	struct squashfs_super_block *sblk = &msblk->sblk;
   1738 	long long next_block = SQUASHFS_I(i)->start_block +
   1739 		sblk->directory_table_start;
   1740 	int next_offset = SQUASHFS_I(i)->offset, length = 0,
   1741 		dir_count;
   1742 	struct squashfs_dir_header dirh;
   1743 	char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];
   1744 	struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
   1745 
   1746 	TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
   1747 
   1748 	while(file->f_pos < 3) {
   1749 		char *name;
   1750 		int size, i_ino;
   1751 
   1752 		if(file->f_pos == 0) {
   1753 			name = ".";
   1754 			size = 1;
   1755 			i_ino = i->i_ino;
   1756 		} else {
   1757 			name = "..";
   1758 			size = 2;
   1759 			i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
   1760 		}
   1761 		TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
   1762 				(unsigned int) dirent, name, size, (int)
   1763 				file->f_pos, i_ino,
   1764 				squashfs_filetype_table[1]);
   1765 
   1766 		if (filldir(dirent, name, size,
   1767 				file->f_pos, i_ino,
   1768 				squashfs_filetype_table[1]) < 0) {
   1769 				TRACE("Filldir returned less than 0\n");
   1770 				goto finish;
   1771 		}
   1772 		file->f_pos += size;
   1773 	}
   1774 
   1775 	length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
   1776 				SQUASHFS_I(i)->u.s2.directory_index_start,
   1777 				SQUASHFS_I(i)->u.s2.directory_index_offset,
   1778 				SQUASHFS_I(i)->u.s2.directory_index_count,
   1779 				file->f_pos);
   1780 
   1781 	while (length < i_size_read(i)) {
   1782 		/* read directory header */
   1783 		if (msblk->swap) {
   1784 			struct squashfs_dir_header sdirh;
   1785 
   1786 			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
   1787 					next_block, next_offset, sizeof(sdirh),
   1788 					&next_block, &next_offset))
   1789 				goto failed_read;
   1790 
   1791 			length += sizeof(sdirh);
   1792 			SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
   1793 		} else {
   1794 			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
   1795 					next_block, next_offset, sizeof(dirh),
   1796 					&next_block, &next_offset))
   1797 				goto failed_read;
   1798 
   1799 			length += sizeof(dirh);
   1800 		}
   1801 
   1802 		dir_count = dirh.count + 1;
   1803 		while (dir_count--) {
   1804 			if (msblk->swap) {
   1805 				struct squashfs_dir_entry sdire;
   1806 				if (!squashfs_get_cached_block(i->i_sb, (char *)
   1807 						&sdire, next_block, next_offset,
   1808 						sizeof(sdire), &next_block,
   1809 						&next_offset))
   1810 					goto failed_read;
   1811 
   1812 				length += sizeof(sdire);
   1813 				SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
   1814 			} else {
   1815 				if (!squashfs_get_cached_block(i->i_sb, (char *)
   1816 						dire, next_block, next_offset,
   1817 						sizeof(*dire), &next_block,
   1818 						&next_offset))
   1819 					goto failed_read;
   1820 
   1821 				length += sizeof(*dire);
   1822 			}
   1823 
   1824 			if (!squashfs_get_cached_block(i->i_sb, dire->name,
   1825 						next_block, next_offset,
   1826 						dire->size + 1, &next_block,
   1827 						&next_offset))
   1828 				goto failed_read;
   1829 
   1830 			length += dire->size + 1;
   1831 
   1832 			if (file->f_pos >= length)
   1833 				continue;
   1834 
   1835 			dire->name[dire->size + 1] = '\0';
   1836 
   1837 			TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
   1838 					(unsigned int) dirent, dire->name,
   1839 					dire->size + 1, (int) file->f_pos,
   1840 					dirh.start_block, dire->offset,
   1841 					dirh.inode_number + dire->inode_number,
   1842 					squashfs_filetype_table[dire->type]);
   1843 
   1844 			if (filldir(dirent, dire->name, dire->size + 1,
   1845 					file->f_pos,
   1846 					dirh.inode_number + dire->inode_number,
   1847 					squashfs_filetype_table[dire->type])
   1848 					< 0) {
   1849 				TRACE("Filldir returned less than 0\n");
   1850 				goto finish;
   1851 			}
   1852 			file->f_pos = length;
   1853 		}
   1854 	}
   1855 
   1856 finish:
   1857 	return 0;
   1858 
   1859 failed_read:
   1860 	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
   1861 		next_offset);
   1862 	return 0;
   1863 }
   1864 
   1865 
   1866 static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry)
   1867 {
   1868 	const unsigned char *name = dentry->d_name.name;
   1869 	int len = dentry->d_name.len;
   1870 	struct inode *inode = NULL;
   1871 	struct squashfs_sb_info *msblk = &i->i_sb->u.squashfs_sb;
   1872 	struct squashfs_super_block *sblk = &msblk->sblk;
   1873 	long long next_block = SQUASHFS_I(i)->start_block +
   1874 				sblk->directory_table_start;
   1875 	int next_offset = SQUASHFS_I(i)->offset, length = 0,
   1876 				dir_count;
   1877 	struct squashfs_dir_header dirh;
   1878 	char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN];
   1879 	struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
   1880 
   1881 	TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
   1882 
   1883 	if (len > SQUASHFS_NAME_LEN)
   1884 		goto exit_loop;
   1885 
   1886 	length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
   1887 				SQUASHFS_I(i)->u.s2.directory_index_start,
   1888 				SQUASHFS_I(i)->u.s2.directory_index_offset,
   1889 				SQUASHFS_I(i)->u.s2.directory_index_count, name,
   1890 				len);
   1891 
   1892 	while (length < i_size_read(i)) {
   1893 		/* read directory header */
   1894 		if (msblk->swap) {
   1895 			struct squashfs_dir_header sdirh;
   1896 			if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
   1897 					next_block, next_offset, sizeof(sdirh),
   1898 					&next_block, &next_offset))
   1899 				goto failed_read;
   1900 
   1901 			length += sizeof(sdirh);
   1902 			SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
   1903 		} else {
   1904 			if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
   1905 					next_block, next_offset, sizeof(dirh),
   1906 					&next_block, &next_offset))
   1907 				goto failed_read;
   1908 
   1909 			length += sizeof(dirh);
   1910 		}
   1911 
   1912 		dir_count = dirh.count + 1;
   1913 		while (dir_count--) {
   1914 			if (msblk->swap) {
   1915 				struct squashfs_dir_entry sdire;
   1916 				if (!squashfs_get_cached_block(i->i_sb, (char *)
   1917 						&sdire, next_block,next_offset,
   1918 						sizeof(sdire), &next_block,
   1919 						&next_offset))
   1920 					goto failed_read;
   1921 
   1922 				length += sizeof(sdire);
   1923 				SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
   1924 			} else {
   1925 				if (!squashfs_get_cached_block(i->i_sb, (char *)
   1926 						dire, next_block,next_offset,
   1927 						sizeof(*dire), &next_block,
   1928 						&next_offset))
   1929 					goto failed_read;
   1930 
   1931 				length += sizeof(*dire);
   1932 			}
   1933 
   1934 			if (!squashfs_get_cached_block(i->i_sb, dire->name,
   1935 					next_block, next_offset, dire->size + 1,
   1936 					&next_block, &next_offset))
   1937 				goto failed_read;
   1938 
   1939 			length += dire->size + 1;
   1940 
   1941 			if (name[0] < dire->name[0])
   1942 				goto exit_loop;
   1943 
   1944 			if ((len == dire->size + 1) && !strncmp(name,
   1945 						dire->name, len)) {
   1946 				squashfs_inode_t ino =
   1947 					SQUASHFS_MKINODE(dirh.start_block,
   1948 					dire->offset);
   1949 
   1950 				TRACE("calling squashfs_iget for directory "
   1951 					"entry %s, inode %x:%x, %d\n", name,
   1952 					dirh.start_block, dire->offset,
   1953 					dirh.inode_number + dire->inode_number);
   1954 
   1955 				inode = (msblk->iget)(i->i_sb, ino);
   1956 
   1957 				goto exit_loop;
   1958 			}
   1959 		}
   1960 	}
   1961 
   1962 exit_loop:
   1963 	d_add(dentry, inode);
   1964 	return ERR_PTR(0);
   1965 
   1966 failed_read:
   1967 	ERROR("Unable to read directory block [%llx:%x]\n", next_block,
   1968 		next_offset);
   1969 	goto exit_loop;
   1970 }
   1971 
   1972 
   1973 static void squashfs_put_super(struct super_block *s)
   1974 {
   1975 	int i;
   1976 
   1977 		struct squashfs_sb_info *sbi = &s->u.squashfs_sb;
   1978 		if (sbi->block_cache)
   1979 			for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
   1980 				if (sbi->block_cache[i].block !=
   1981 							SQUASHFS_INVALID_BLK)
   1982 					kfree(sbi->block_cache[i].data);
   1983 		if (sbi->fragment)
   1984 			for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
   1985 				SQUASHFS_FREE(sbi->fragment[i].data);
   1986 		kfree(sbi->fragment);
   1987 		kfree(sbi->block_cache);
   1988 		kfree(sbi->read_data);
   1989 		kfree(sbi->read_page);
   1990 		kfree(sbi->uid);
   1991 		kfree(sbi->fragment_index);
   1992 		kfree(sbi->fragment_index_2);
   1993 		kfree(sbi->meta_index);
   1994 		vfree(sbi->stream.workspace);
   1995 		sbi->block_cache = NULL;
   1996 		sbi->uid = NULL;
   1997 		sbi->read_data = NULL;
   1998 		sbi->read_page = NULL;
   1999 		sbi->fragment = NULL;
   2000 		sbi->fragment_index = NULL;
   2001 		sbi->fragment_index_2 = NULL;
   2002 		sbi->meta_index = NULL;
   2003 		sbi->stream.workspace = NULL;
   2004 }
   2005 
   2006 
   2007 static int __init init_squashfs_fs(void)
   2008 {
   2009 
   2010 	printk(KERN_INFO "squashfs: version 3.1 (2006/08/15) "
   2011 		"Phillip Lougher\n");
   2012 
   2013 	return register_filesystem(&squashfs_fs_type);
   2014 }
   2015 
   2016 
   2017 static void __exit exit_squashfs_fs(void)
   2018 {
   2019 	unregister_filesystem(&squashfs_fs_type);
   2020 }
   2021 
   2022 
   2023 EXPORT_NO_SYMBOLS;
   2024 
   2025 module_init(init_squashfs_fs);
   2026 module_exit(exit_squashfs_fs);
   2027 MODULE_DESCRIPTION("squashfs 3.1, a compressed read-only filesystem");
   2028 MODULE_AUTHOR("Phillip Lougher <phillip (at) lougher.demon.co.uk>");
   2029 MODULE_LICENSE("GPL");
   2030