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