2 * Squashfs - a compressed read only filesystem for Linux
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006
5 * Phillip Lougher <phillip@lougher.demon.co.uk>
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.
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.
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.
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>
31 #include <linux/smp_lock.h>
32 #include <linux/locks.h>
33 #include <linux/init.h>
34 #include <linux/dcache.h>
35 #include <linux/wait.h>
36 #include <linux/blkdev.h>
37 #include <linux/vmalloc.h>
38 #include <asm/uaccess.h>
39 #include <asm/semaphore.h>
43 static struct super_block
*squashfs_read_super(struct super_block
*, void *, int);
44 static void squashfs_put_super(struct super_block
*);
45 static int squashfs_statfs(struct super_block
*, struct statfs
*);
46 static int squashfs_symlink_readpage(struct file
*file
, struct page
*page
);
47 static int squashfs_readpage(struct file
*file
, struct page
*page
);
48 static int squashfs_readpage4K(struct file
*file
, struct page
*page
);
49 static int squashfs_readdir(struct file
*, void *, filldir_t
);
50 static struct dentry
*squashfs_lookup(struct inode
*, struct dentry
*);
51 static struct inode
*squashfs_iget(struct super_block
*s
, squashfs_inode_t inode
);
52 static long long read_blocklist(struct inode
*inode
, int index
,
53 int readahead_blks
, char *block_list
,
54 unsigned short **block_p
, unsigned int *bsize
);
56 static DECLARE_FSTYPE_DEV(squashfs_fs_type
, "squashfs", squashfs_read_super
);
58 static unsigned char squashfs_filetype_table
[] = {
59 DT_UNKNOWN
, DT_DIR
, DT_REG
, DT_LNK
, DT_BLK
, DT_CHR
, DT_FIFO
, DT_SOCK
62 static struct super_operations squashfs_ops
= {
63 .statfs
= squashfs_statfs
,
64 .put_super
= squashfs_put_super
,
67 SQSH_EXTERN
struct address_space_operations squashfs_symlink_aops
= {
68 .readpage
= squashfs_symlink_readpage
71 SQSH_EXTERN
struct address_space_operations squashfs_aops
= {
72 .readpage
= squashfs_readpage
75 SQSH_EXTERN
struct address_space_operations squashfs_aops_4K
= {
76 .readpage
= squashfs_readpage4K
79 static struct file_operations squashfs_dir_ops
= {
80 .read
= generic_read_dir
,
81 .readdir
= squashfs_readdir
84 static struct inode_operations squashfs_dir_inode_ops
= {
85 .lookup
= squashfs_lookup
88 static struct buffer_head
*get_block_length(struct super_block
*s
,
89 int *cur_index
, int *offset
, int *c_byte
)
91 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
93 struct buffer_head
*bh
;
95 if (!(bh
= sb_bread(s
, *cur_index
)))
98 if (msblk
->devblksize
- *offset
== 1) {
100 ((unsigned char *) &temp
)[1] = *((unsigned char *)
101 (bh
->b_data
+ *offset
));
103 ((unsigned char *) &temp
)[0] = *((unsigned char *)
104 (bh
->b_data
+ *offset
));
106 if (!(bh
= sb_bread(s
, ++(*cur_index
))))
109 ((unsigned char *) &temp
)[0] = *((unsigned char *)
112 ((unsigned char *) &temp
)[1] = *((unsigned char *)
118 ((unsigned char *) &temp
)[1] = *((unsigned char *)
119 (bh
->b_data
+ *offset
));
120 ((unsigned char *) &temp
)[0] = *((unsigned char *)
121 (bh
->b_data
+ *offset
+ 1));
123 ((unsigned char *) &temp
)[0] = *((unsigned char *)
124 (bh
->b_data
+ *offset
));
125 ((unsigned char *) &temp
)[1] = *((unsigned char *)
126 (bh
->b_data
+ *offset
+ 1));
132 if (SQUASHFS_CHECK_DATA(msblk
->sblk
.flags
)) {
133 if (*offset
== msblk
->devblksize
) {
135 if (!(bh
= sb_bread(s
, ++(*cur_index
))))
139 if (*((unsigned char *) (bh
->b_data
+ *offset
)) !=
140 SQUASHFS_MARKER_BYTE
) {
141 ERROR("Metadata block marker corrupt @ %x\n",
155 SQSH_EXTERN
unsigned int squashfs_read_data(struct super_block
*s
, char *buffer
,
156 long long index
, unsigned int length
,
157 long long *next_index
)
159 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
160 struct buffer_head
*bh
[((SQUASHFS_FILE_MAX_SIZE
- 1) >>
161 msblk
->devblksize_log2
) + 2];
162 unsigned int offset
= index
& ((1 << msblk
->devblksize_log2
) - 1);
163 unsigned int cur_index
= index
>> msblk
->devblksize_log2
;
164 int bytes
, avail_bytes
, b
= 0, k
;
166 unsigned int compressed
;
167 unsigned int c_byte
= length
;
170 bytes
= msblk
->devblksize
- offset
;
171 compressed
= SQUASHFS_COMPRESSED_BLOCK(c_byte
);
172 c_buffer
= compressed
? msblk
->read_data
: buffer
;
173 c_byte
= SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte
);
175 TRACE("Block @ 0x%llx, %scompressed size %d\n", index
, compressed
176 ? "" : "un", (unsigned int) c_byte
);
178 if (!(bh
[0] = sb_getblk(s
, cur_index
)))
181 for (b
= 1; bytes
< c_byte
; b
++) {
182 if (!(bh
[b
] = sb_getblk(s
, ++cur_index
)))
184 bytes
+= msblk
->devblksize
;
186 ll_rw_block(READ
, b
, bh
);
188 if (!(bh
[0] = get_block_length(s
, &cur_index
, &offset
,
192 bytes
= msblk
->devblksize
- offset
;
193 compressed
= SQUASHFS_COMPRESSED(c_byte
);
194 c_buffer
= compressed
? msblk
->read_data
: buffer
;
195 c_byte
= SQUASHFS_COMPRESSED_SIZE(c_byte
);
197 TRACE("Block @ 0x%llx, %scompressed size %d\n", index
, compressed
198 ? "" : "un", (unsigned int) c_byte
);
200 for (b
= 1; bytes
< c_byte
; b
++) {
201 if (!(bh
[b
] = sb_getblk(s
, ++cur_index
)))
203 bytes
+= msblk
->devblksize
;
205 ll_rw_block(READ
, b
- 1, bh
+ 1);
209 down(&msblk
->read_data_mutex
);
211 for (bytes
= 0, k
= 0; k
< b
; k
++) {
212 avail_bytes
= (c_byte
- bytes
) > (msblk
->devblksize
- offset
) ?
213 msblk
->devblksize
- offset
:
215 wait_on_buffer(bh
[k
]);
216 if (!buffer_uptodate(bh
[k
]))
218 memcpy(c_buffer
+ bytes
, bh
[k
]->b_data
+ offset
, avail_bytes
);
219 bytes
+= avail_bytes
;
230 msblk
->stream
.next_in
= c_buffer
;
231 msblk
->stream
.avail_in
= c_byte
;
232 msblk
->stream
.next_out
= buffer
;
233 msblk
->stream
.avail_out
= msblk
->read_size
;
235 if (((zlib_err
= zlib_inflateInit(&msblk
->stream
)) != Z_OK
) ||
236 ((zlib_err
= zlib_inflate(&msblk
->stream
, Z_FINISH
))
237 != Z_STREAM_END
) || ((zlib_err
=
238 zlib_inflateEnd(&msblk
->stream
)) != Z_OK
)) {
239 ERROR("zlib_fs returned unexpected result 0x%x\n",
243 bytes
= msblk
->stream
.total_out
;
245 up(&msblk
->read_data_mutex
);
249 *next_index
= index
+ c_byte
+ (length
? 0 :
250 (SQUASHFS_CHECK_DATA(msblk
->sblk
.flags
)
259 ERROR("sb_bread failed reading block 0x%x\n", cur_index
);
264 SQSH_EXTERN
int squashfs_get_cached_block(struct super_block
*s
, char *buffer
,
265 long long block
, unsigned int offset
,
266 int length
, long long *next_block
,
267 unsigned int *next_offset
)
269 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
270 int n
, i
, bytes
, return_length
= length
;
271 long long next_index
;
273 TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block
, offset
);
276 for (i
= 0; i
< SQUASHFS_CACHED_BLKS
; i
++)
277 if (msblk
->block_cache
[i
].block
== block
)
280 down(&msblk
->block_cache_mutex
);
282 if (i
== SQUASHFS_CACHED_BLKS
) {
283 /* read inode header block */
284 for (i
= msblk
->next_cache
, n
= SQUASHFS_CACHED_BLKS
;
285 n
; n
--, i
= (i
+ 1) %
286 SQUASHFS_CACHED_BLKS
)
287 if (msblk
->block_cache
[i
].block
!=
294 init_waitqueue_entry(&wait
, current
);
295 add_wait_queue(&msblk
->waitq
, &wait
);
296 set_current_state(TASK_UNINTERRUPTIBLE
);
297 up(&msblk
->block_cache_mutex
);
299 set_current_state(TASK_RUNNING
);
300 remove_wait_queue(&msblk
->waitq
, &wait
);
303 msblk
->next_cache
= (i
+ 1) % SQUASHFS_CACHED_BLKS
;
305 if (msblk
->block_cache
[i
].block
==
306 SQUASHFS_INVALID_BLK
) {
307 if (!(msblk
->block_cache
[i
].data
=
308 kmalloc(SQUASHFS_METADATA_SIZE
,
310 ERROR("Failed to allocate cache"
312 up(&msblk
->block_cache_mutex
);
317 msblk
->block_cache
[i
].block
= SQUASHFS_USED_BLK
;
318 up(&msblk
->block_cache_mutex
);
320 if (!(msblk
->block_cache
[i
].length
=
321 squashfs_read_data(s
,
322 msblk
->block_cache
[i
].data
,
323 block
, 0, &next_index
))) {
324 ERROR("Unable to read cache block [%llx:%x]\n",
329 down(&msblk
->block_cache_mutex
);
330 wake_up(&msblk
->waitq
);
331 msblk
->block_cache
[i
].block
= block
;
332 msblk
->block_cache
[i
].next_index
= next_index
;
333 TRACE("Read cache block [%llx:%x]\n", block
, offset
);
336 if (msblk
->block_cache
[i
].block
!= block
) {
337 up(&msblk
->block_cache_mutex
);
341 if ((bytes
= msblk
->block_cache
[i
].length
- offset
) >= length
) {
343 memcpy(buffer
, msblk
->block_cache
[i
].data
+
345 if (msblk
->block_cache
[i
].length
- offset
== length
) {
346 *next_block
= msblk
->block_cache
[i
].next_index
;
350 *next_offset
= offset
+ length
;
352 up(&msblk
->block_cache_mutex
);
356 memcpy(buffer
, msblk
->block_cache
[i
].data
+
360 block
= msblk
->block_cache
[i
].next_index
;
361 up(&msblk
->block_cache_mutex
);
368 return return_length
;
374 static int get_fragment_location(struct super_block
*s
, unsigned int fragment
,
375 long long *fragment_start_block
,
376 unsigned int *fragment_size
)
378 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
379 long long start_block
=
380 msblk
->fragment_index
[SQUASHFS_FRAGMENT_INDEX(fragment
)];
381 int offset
= SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment
);
382 struct squashfs_fragment_entry fragment_entry
;
385 struct squashfs_fragment_entry sfragment_entry
;
387 if (!squashfs_get_cached_block(s
, (char *) &sfragment_entry
,
389 sizeof(sfragment_entry
), &start_block
,
392 SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry
, &sfragment_entry
);
394 if (!squashfs_get_cached_block(s
, (char *) &fragment_entry
,
396 sizeof(fragment_entry
), &start_block
,
400 *fragment_start_block
= fragment_entry
.start_block
;
401 *fragment_size
= fragment_entry
.size
;
410 SQSH_EXTERN
void release_cached_fragment(struct squashfs_sb_info
*msblk
, struct
411 squashfs_fragment_cache
*fragment
)
413 down(&msblk
->fragment_mutex
);
415 wake_up(&msblk
->fragment_wait_queue
);
416 up(&msblk
->fragment_mutex
);
420 SQSH_EXTERN
struct squashfs_fragment_cache
*get_cached_fragment(struct super_block
421 *s
, long long start_block
,
425 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
428 down(&msblk
->fragment_mutex
);
430 for (i
= 0; i
< SQUASHFS_CACHED_FRAGMENTS
&&
431 msblk
->fragment
[i
].block
!= start_block
; i
++);
433 if (i
== SQUASHFS_CACHED_FRAGMENTS
) {
434 for (i
= msblk
->next_fragment
, n
=
435 SQUASHFS_CACHED_FRAGMENTS
; n
&&
436 msblk
->fragment
[i
].locked
; n
--, i
= (i
+ 1) %
437 SQUASHFS_CACHED_FRAGMENTS
);
442 init_waitqueue_entry(&wait
, current
);
443 add_wait_queue(&msblk
->fragment_wait_queue
,
445 set_current_state(TASK_UNINTERRUPTIBLE
);
446 up(&msblk
->fragment_mutex
);
448 set_current_state(TASK_RUNNING
);
449 remove_wait_queue(&msblk
->fragment_wait_queue
,
453 msblk
->next_fragment
= (msblk
->next_fragment
+ 1) %
454 SQUASHFS_CACHED_FRAGMENTS
;
456 if (msblk
->fragment
[i
].data
== NULL
)
457 if (!(msblk
->fragment
[i
].data
= SQUASHFS_ALLOC
458 (SQUASHFS_FILE_MAX_SIZE
))) {
459 ERROR("Failed to allocate fragment "
461 up(&msblk
->fragment_mutex
);
465 msblk
->fragment
[i
].block
= SQUASHFS_INVALID_BLK
;
466 msblk
->fragment
[i
].locked
= 1;
467 up(&msblk
->fragment_mutex
);
469 if (!(msblk
->fragment
[i
].length
= squashfs_read_data(s
,
470 msblk
->fragment
[i
].data
,
471 start_block
, length
, NULL
))) {
472 ERROR("Unable to read fragment cache block "
473 "[%llx]\n", start_block
);
474 msblk
->fragment
[i
].locked
= 0;
478 msblk
->fragment
[i
].block
= start_block
;
479 TRACE("New fragment %d, start block %lld, locked %d\n",
480 i
, msblk
->fragment
[i
].block
,
481 msblk
->fragment
[i
].locked
);
485 msblk
->fragment
[i
].locked
++;
486 up(&msblk
->fragment_mutex
);
487 TRACE("Got fragment %d, start block %lld, locked %d\n", i
,
488 msblk
->fragment
[i
].block
,
489 msblk
->fragment
[i
].locked
);
493 return &msblk
->fragment
[i
];
500 static struct inode
*squashfs_new_inode(struct super_block
*s
,
501 struct squashfs_base_inode_header
*inodeb
)
503 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
504 struct inode
*i
= new_inode(s
);
507 i
->i_ino
= inodeb
->inode_number
;
508 i
->i_mtime
= inodeb
->mtime
;
509 i
->i_atime
= inodeb
->mtime
;
510 i
->i_ctime
= inodeb
->mtime
;
511 i
->i_uid
= msblk
->uid
[inodeb
->uid
];
512 i
->i_mode
= inodeb
->mode
;
514 if (inodeb
->guid
== SQUASHFS_GUIDS
)
517 i
->i_gid
= msblk
->guid
[inodeb
->guid
];
524 static struct inode
*squashfs_iget(struct super_block
*s
, squashfs_inode_t inode
)
527 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
528 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
529 long long block
= SQUASHFS_INODE_BLK(inode
) +
530 sblk
->inode_table_start
;
531 unsigned int offset
= SQUASHFS_INODE_OFFSET(inode
);
532 long long next_block
;
533 unsigned int next_offset
;
534 union squashfs_inode_header id
, sid
;
535 struct squashfs_base_inode_header
*inodeb
= &id
.base
,
536 *sinodeb
= &sid
.base
;
538 TRACE("Entered squashfs_iget\n");
541 if (!squashfs_get_cached_block(s
, (char *) sinodeb
, block
,
542 offset
, sizeof(*sinodeb
), &next_block
,
545 SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb
, sinodeb
,
548 if (!squashfs_get_cached_block(s
, (char *) inodeb
, block
,
549 offset
, sizeof(*inodeb
), &next_block
,
553 switch(inodeb
->inode_type
) {
554 case SQUASHFS_FILE_TYPE
: {
555 unsigned int frag_size
;
557 struct squashfs_reg_inode_header
*inodep
= &id
.reg
;
558 struct squashfs_reg_inode_header
*sinodep
= &sid
.reg
;
561 if (!squashfs_get_cached_block(s
, (char *)
562 sinodep
, block
, offset
,
563 sizeof(*sinodep
), &next_block
,
566 SQUASHFS_SWAP_REG_INODE_HEADER(inodep
, sinodep
);
568 if (!squashfs_get_cached_block(s
, (char *)
569 inodep
, block
, offset
,
570 sizeof(*inodep
), &next_block
,
574 frag_blk
= SQUASHFS_INVALID_BLK
;
575 if (inodep
->fragment
!= SQUASHFS_INVALID_FRAG
&&
576 !get_fragment_location(s
,
577 inodep
->fragment
, &frag_blk
, &frag_size
))
580 if((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
584 i
->i_size
= inodep
->file_size
;
585 i
->i_fop
= &generic_ro_fops
;
586 i
->i_mode
|= S_IFREG
;
587 i
->i_blocks
= ((i
->i_size
- 1) >> 9) + 1;
588 i
->i_blksize
= PAGE_CACHE_SIZE
;
589 SQUASHFS_I(i
)->u
.s1
.fragment_start_block
= frag_blk
;
590 SQUASHFS_I(i
)->u
.s1
.fragment_size
= frag_size
;
591 SQUASHFS_I(i
)->u
.s1
.fragment_offset
= inodep
->offset
;
592 SQUASHFS_I(i
)->start_block
= inodep
->start_block
;
593 SQUASHFS_I(i
)->u
.s1
.block_list_start
= next_block
;
594 SQUASHFS_I(i
)->offset
= next_offset
;
595 if (sblk
->block_size
> 4096)
596 i
->i_data
.a_ops
= &squashfs_aops
;
598 i
->i_data
.a_ops
= &squashfs_aops_4K
;
600 TRACE("File inode %x:%x, start_block %llx, "
601 "block_list_start %llx, offset %x\n",
602 SQUASHFS_INODE_BLK(inode
), offset
,
603 inodep
->start_block
, next_block
,
607 case SQUASHFS_LREG_TYPE
: {
608 unsigned int frag_size
;
610 struct squashfs_lreg_inode_header
*inodep
= &id
.lreg
;
611 struct squashfs_lreg_inode_header
*sinodep
= &sid
.lreg
;
614 if (!squashfs_get_cached_block(s
, (char *)
615 sinodep
, block
, offset
,
616 sizeof(*sinodep
), &next_block
,
619 SQUASHFS_SWAP_LREG_INODE_HEADER(inodep
, sinodep
);
621 if (!squashfs_get_cached_block(s
, (char *)
622 inodep
, block
, offset
,
623 sizeof(*inodep
), &next_block
,
627 frag_blk
= SQUASHFS_INVALID_BLK
;
628 if (inodep
->fragment
!= SQUASHFS_INVALID_FRAG
&&
629 !get_fragment_location(s
,
630 inodep
->fragment
, &frag_blk
, &frag_size
))
633 if((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
636 i
->i_nlink
= inodep
->nlink
;
637 i
->i_size
= inodep
->file_size
;
638 i
->i_fop
= &generic_ro_fops
;
639 i
->i_mode
|= S_IFREG
;
640 i
->i_blocks
= ((i
->i_size
- 1) >> 9) + 1;
641 i
->i_blksize
= PAGE_CACHE_SIZE
;
642 SQUASHFS_I(i
)->u
.s1
.fragment_start_block
= frag_blk
;
643 SQUASHFS_I(i
)->u
.s1
.fragment_size
= frag_size
;
644 SQUASHFS_I(i
)->u
.s1
.fragment_offset
= inodep
->offset
;
645 SQUASHFS_I(i
)->start_block
= inodep
->start_block
;
646 SQUASHFS_I(i
)->u
.s1
.block_list_start
= next_block
;
647 SQUASHFS_I(i
)->offset
= next_offset
;
648 if (sblk
->block_size
> 4096)
649 i
->i_data
.a_ops
= &squashfs_aops
;
651 i
->i_data
.a_ops
= &squashfs_aops_4K
;
653 TRACE("File inode %x:%x, start_block %llx, "
654 "block_list_start %llx, offset %x\n",
655 SQUASHFS_INODE_BLK(inode
), offset
,
656 inodep
->start_block
, next_block
,
660 case SQUASHFS_DIR_TYPE
: {
661 struct squashfs_dir_inode_header
*inodep
= &id
.dir
;
662 struct squashfs_dir_inode_header
*sinodep
= &sid
.dir
;
665 if (!squashfs_get_cached_block(s
, (char *)
666 sinodep
, block
, offset
,
667 sizeof(*sinodep
), &next_block
,
670 SQUASHFS_SWAP_DIR_INODE_HEADER(inodep
, sinodep
);
672 if (!squashfs_get_cached_block(s
, (char *)
673 inodep
, block
, offset
,
674 sizeof(*inodep
), &next_block
,
678 if((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
681 i
->i_nlink
= inodep
->nlink
;
682 i
->i_size
= inodep
->file_size
;
683 i
->i_op
= &squashfs_dir_inode_ops
;
684 i
->i_fop
= &squashfs_dir_ops
;
685 i
->i_mode
|= S_IFDIR
;
686 SQUASHFS_I(i
)->start_block
= inodep
->start_block
;
687 SQUASHFS_I(i
)->offset
= inodep
->offset
;
688 SQUASHFS_I(i
)->u
.s2
.directory_index_count
= 0;
689 SQUASHFS_I(i
)->u
.s2
.parent_inode
= inodep
->parent_inode
;
691 TRACE("Directory inode %x:%x, start_block %x, offset "
692 "%x\n", SQUASHFS_INODE_BLK(inode
),
693 offset
, inodep
->start_block
,
697 case SQUASHFS_LDIR_TYPE
: {
698 struct squashfs_ldir_inode_header
*inodep
= &id
.ldir
;
699 struct squashfs_ldir_inode_header
*sinodep
= &sid
.ldir
;
702 if (!squashfs_get_cached_block(s
, (char *)
703 sinodep
, block
, offset
,
704 sizeof(*sinodep
), &next_block
,
707 SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep
,
710 if (!squashfs_get_cached_block(s
, (char *)
711 inodep
, block
, offset
,
712 sizeof(*inodep
), &next_block
,
716 if((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
719 i
->i_nlink
= inodep
->nlink
;
720 i
->i_size
= inodep
->file_size
;
721 i
->i_op
= &squashfs_dir_inode_ops
;
722 i
->i_fop
= &squashfs_dir_ops
;
723 i
->i_mode
|= S_IFDIR
;
724 SQUASHFS_I(i
)->start_block
= inodep
->start_block
;
725 SQUASHFS_I(i
)->offset
= inodep
->offset
;
726 SQUASHFS_I(i
)->u
.s2
.directory_index_start
= next_block
;
727 SQUASHFS_I(i
)->u
.s2
.directory_index_offset
=
729 SQUASHFS_I(i
)->u
.s2
.directory_index_count
=
731 SQUASHFS_I(i
)->u
.s2
.parent_inode
= inodep
->parent_inode
;
733 TRACE("Long directory inode %x:%x, start_block %x, "
735 SQUASHFS_INODE_BLK(inode
), offset
,
736 inodep
->start_block
, inodep
->offset
);
739 case SQUASHFS_SYMLINK_TYPE
: {
740 struct squashfs_symlink_inode_header
*inodep
=
742 struct squashfs_symlink_inode_header
*sinodep
=
746 if (!squashfs_get_cached_block(s
, (char *)
747 sinodep
, block
, offset
,
748 sizeof(*sinodep
), &next_block
,
751 SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep
,
754 if (!squashfs_get_cached_block(s
, (char *)
755 inodep
, block
, offset
,
756 sizeof(*inodep
), &next_block
,
760 if((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
763 i
->i_nlink
= inodep
->nlink
;
764 i
->i_size
= inodep
->symlink_size
;
765 i
->i_op
= &page_symlink_inode_operations
;
766 i
->i_data
.a_ops
= &squashfs_symlink_aops
;
767 i
->i_mode
|= S_IFLNK
;
768 SQUASHFS_I(i
)->start_block
= next_block
;
769 SQUASHFS_I(i
)->offset
= next_offset
;
771 TRACE("Symbolic link inode %x:%x, start_block %llx, "
773 SQUASHFS_INODE_BLK(inode
), offset
,
774 next_block
, next_offset
);
777 case SQUASHFS_BLKDEV_TYPE
:
778 case SQUASHFS_CHRDEV_TYPE
: {
779 struct squashfs_dev_inode_header
*inodep
= &id
.dev
;
780 struct squashfs_dev_inode_header
*sinodep
= &sid
.dev
;
783 if (!squashfs_get_cached_block(s
, (char *)
784 sinodep
, block
, offset
,
785 sizeof(*sinodep
), &next_block
,
788 SQUASHFS_SWAP_DEV_INODE_HEADER(inodep
, sinodep
);
790 if (!squashfs_get_cached_block(s
, (char *)
791 inodep
, block
, offset
,
792 sizeof(*inodep
), &next_block
,
796 if ((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
799 i
->i_nlink
= inodep
->nlink
;
800 i
->i_mode
|= (inodeb
->inode_type
==
801 SQUASHFS_CHRDEV_TYPE
) ? S_IFCHR
:
803 init_special_inode(i
, i
->i_mode
, inodep
->rdev
);
805 TRACE("Device inode %x:%x, rdev %x\n",
806 SQUASHFS_INODE_BLK(inode
), offset
,
810 case SQUASHFS_FIFO_TYPE
:
811 case SQUASHFS_SOCKET_TYPE
: {
812 struct squashfs_ipc_inode_header
*inodep
= &id
.ipc
;
813 struct squashfs_ipc_inode_header
*sinodep
= &sid
.ipc
;
816 if (!squashfs_get_cached_block(s
, (char *)
817 sinodep
, block
, offset
,
818 sizeof(*sinodep
), &next_block
,
821 SQUASHFS_SWAP_IPC_INODE_HEADER(inodep
, sinodep
);
823 if (!squashfs_get_cached_block(s
, (char *)
824 inodep
, block
, offset
,
825 sizeof(*inodep
), &next_block
,
829 if ((i
= squashfs_new_inode(s
, inodeb
)) == NULL
)
832 i
->i_nlink
= inodep
->nlink
;
833 i
->i_mode
|= (inodeb
->inode_type
== SQUASHFS_FIFO_TYPE
)
834 ? S_IFIFO
: S_IFSOCK
;
835 init_special_inode(i
, i
->i_mode
, 0);
839 ERROR("Unknown inode type %d in squashfs_iget!\n",
844 insert_inode_hash(i
);
848 ERROR("Unable to read inode [%llx:%x]\n", block
, offset
);
855 int read_fragment_index_table(struct super_block
*s
)
857 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
858 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
860 if (!(msblk
->fragment_index
= kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
861 (sblk
->fragments
), GFP_KERNEL
))) {
862 ERROR("Failed to allocate uid/gid table\n");
866 if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk
->fragments
) &&
867 !squashfs_read_data(s
, (char *)
868 msblk
->fragment_index
,
869 sblk
->fragment_table_start
,
870 SQUASHFS_FRAGMENT_INDEX_BYTES
872 SQUASHFS_COMPRESSED_BIT_BLOCK
, NULL
)) {
873 ERROR("unable to read fragment index table\n");
881 for (i
= 0; i
< SQUASHFS_FRAGMENT_INDEXES(sblk
->fragments
);
883 SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment
),
884 &msblk
->fragment_index
[i
], 1);
885 msblk
->fragment_index
[i
] = fragment
;
893 static int supported_squashfs_filesystem(struct squashfs_sb_info
*msblk
, int silent
)
895 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
897 msblk
->iget
= squashfs_iget
;
898 msblk
->read_blocklist
= read_blocklist
;
899 msblk
->read_fragment_index_table
= read_fragment_index_table
;
901 if (sblk
->s_major
== 1) {
902 if (!squashfs_1_0_supported(msblk
)) {
903 SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
904 "are unsupported\n");
905 SERROR("Please recompile with "
906 "Squashfs 1.0 support enabled\n");
909 } else if (sblk
->s_major
== 2) {
910 if (!squashfs_2_0_supported(msblk
)) {
911 SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
912 "are unsupported\n");
913 SERROR("Please recompile with "
914 "Squashfs 2.0 support enabled\n");
917 } else if(sblk
->s_major
!= SQUASHFS_MAJOR
|| sblk
->s_minor
>
919 SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
920 "filesystem\n", sblk
->s_major
, sblk
->s_minor
);
921 SERROR("Please update your kernel\n");
929 static struct super_block
*squashfs_read_super(struct super_block
*s
,
930 void *data
, int silent
)
932 kdev_t dev
= s
->s_dev
;
933 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
934 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
938 if (!(msblk
->stream
.workspace
= vmalloc(zlib_inflate_workspacesize()))) {
939 ERROR("Failed to allocate zlib workspace\n");
943 msblk
->devblksize
= get_hardsect_size(dev
);
944 if(msblk
->devblksize
< BLOCK_SIZE
)
945 msblk
->devblksize
= BLOCK_SIZE
;
946 msblk
->devblksize_log2
= ffz(~msblk
->devblksize
);
947 set_blocksize(dev
, msblk
->devblksize
);
948 s
->s_blocksize
= msblk
->devblksize
;
949 s
->s_blocksize_bits
= msblk
->devblksize_log2
;
951 init_MUTEX(&msblk
->read_data_mutex
);
952 init_MUTEX(&msblk
->read_page_mutex
);
953 init_MUTEX(&msblk
->block_cache_mutex
);
954 init_MUTEX(&msblk
->fragment_mutex
);
956 init_waitqueue_head(&msblk
->waitq
);
957 init_waitqueue_head(&msblk
->fragment_wait_queue
);
959 if (!squashfs_read_data(s
, (char *) sblk
, SQUASHFS_START
,
960 sizeof(struct squashfs_super_block
) |
961 SQUASHFS_COMPRESSED_BIT_BLOCK
, NULL
)) {
962 SERROR("unable to read superblock\n");
966 /* Check it is a SQUASHFS superblock */
968 if ((s
->s_magic
= sblk
->s_magic
) != SQUASHFS_MAGIC
) {
969 if (sblk
->s_magic
== SQUASHFS_MAGIC_SWAP
) {
970 struct squashfs_super_block ssblk
;
972 WARNING("Mounting a different endian SQUASHFS "
973 "filesystem on %s\n", bdevname(dev
));
975 SQUASHFS_SWAP_SUPER_BLOCK(&ssblk
, sblk
);
976 memcpy(sblk
, &ssblk
, sizeof(struct squashfs_super_block
));
979 SERROR("Can't find a SQUASHFS superblock on %s\n",
985 /* Check the MAJOR & MINOR versions */
986 if(!supported_squashfs_filesystem(msblk
, silent
))
989 TRACE("Found valid superblock on %s\n", bdevname(dev
));
990 TRACE("Inodes are %scompressed\n",
991 SQUASHFS_UNCOMPRESSED_INODES
992 (sblk
->flags
) ? "un" : "");
993 TRACE("Data is %scompressed\n",
994 SQUASHFS_UNCOMPRESSED_DATA(sblk
->flags
)
996 TRACE("Check data is %s present in the filesystem\n",
997 SQUASHFS_CHECK_DATA(sblk
->flags
) ?
999 TRACE("Filesystem size %lld bytes\n", sblk
->bytes_used
);
1000 TRACE("Block size %d\n", sblk
->block_size
);
1001 TRACE("Number of inodes %d\n", sblk
->inodes
);
1002 if (sblk
->s_major
> 1)
1003 TRACE("Number of fragments %d\n", sblk
->fragments
);
1004 TRACE("Number of uids %d\n", sblk
->no_uids
);
1005 TRACE("Number of gids %d\n", sblk
->no_guids
);
1006 TRACE("sblk->inode_table_start %llx\n", sblk
->inode_table_start
);
1007 TRACE("sblk->directory_table_start %llx\n", sblk
->directory_table_start
);
1008 if (sblk
->s_major
> 1)
1009 TRACE("sblk->fragment_table_start %llx\n",
1010 sblk
->fragment_table_start
);
1011 TRACE("sblk->uid_start %llx\n", sblk
->uid_start
);
1013 s
->s_flags
|= MS_RDONLY
;
1014 s
->s_op
= &squashfs_ops
;
1016 /* Init inode_table block pointer array */
1017 if (!(msblk
->block_cache
= kmalloc(sizeof(struct squashfs_cache
) *
1018 SQUASHFS_CACHED_BLKS
, GFP_KERNEL
))) {
1019 ERROR("Failed to allocate block cache\n");
1023 for (i
= 0; i
< SQUASHFS_CACHED_BLKS
; i
++)
1024 msblk
->block_cache
[i
].block
= SQUASHFS_INVALID_BLK
;
1026 msblk
->next_cache
= 0;
1028 /* Allocate read_data block */
1029 msblk
->read_size
= (sblk
->block_size
< SQUASHFS_METADATA_SIZE
) ?
1030 SQUASHFS_METADATA_SIZE
:
1033 if (!(msblk
->read_data
= kmalloc(msblk
->read_size
, GFP_KERNEL
))) {
1034 ERROR("Failed to allocate read_data block\n");
1038 /* Allocate read_page block */
1039 if (!(msblk
->read_page
= kmalloc(sblk
->block_size
, GFP_KERNEL
))) {
1040 ERROR("Failed to allocate read_page block\n");
1044 /* Allocate uid and gid tables */
1045 if (!(msblk
->uid
= kmalloc((sblk
->no_uids
+ sblk
->no_guids
) *
1046 sizeof(unsigned int), GFP_KERNEL
))) {
1047 ERROR("Failed to allocate uid/gid table\n");
1050 msblk
->guid
= msblk
->uid
+ sblk
->no_uids
;
1053 unsigned int suid
[sblk
->no_uids
+ sblk
->no_guids
];
1055 if (!squashfs_read_data(s
, (char *) &suid
, sblk
->uid_start
,
1056 ((sblk
->no_uids
+ sblk
->no_guids
) *
1057 sizeof(unsigned int)) |
1058 SQUASHFS_COMPRESSED_BIT_BLOCK
, NULL
)) {
1059 ERROR("unable to read uid/gid table\n");
1063 SQUASHFS_SWAP_DATA(msblk
->uid
, suid
, (sblk
->no_uids
+
1064 sblk
->no_guids
), (sizeof(unsigned int) * 8));
1066 if (!squashfs_read_data(s
, (char *) msblk
->uid
, sblk
->uid_start
,
1067 ((sblk
->no_uids
+ sblk
->no_guids
) *
1068 sizeof(unsigned int)) |
1069 SQUASHFS_COMPRESSED_BIT_BLOCK
, NULL
)) {
1070 ERROR("unable to read uid/gid table\n");
1075 if (sblk
->s_major
== 1 && squashfs_1_0_supported(msblk
))
1078 if (!(msblk
->fragment
= kmalloc(sizeof(struct squashfs_fragment_cache
) *
1079 SQUASHFS_CACHED_FRAGMENTS
, GFP_KERNEL
))) {
1080 ERROR("Failed to allocate fragment block cache\n");
1084 for (i
= 0; i
< SQUASHFS_CACHED_FRAGMENTS
; i
++) {
1085 msblk
->fragment
[i
].locked
= 0;
1086 msblk
->fragment
[i
].block
= SQUASHFS_INVALID_BLK
;
1087 msblk
->fragment
[i
].data
= NULL
;
1090 msblk
->next_fragment
= 0;
1092 /* Allocate fragment index table */
1093 if(msblk
->read_fragment_index_table(s
) == 0)
1097 if ((root
= (msblk
->iget
)(s
, sblk
->root_inode
)) == NULL
)
1100 if ((s
->s_root
= d_alloc_root(root
)) == NULL
) {
1101 ERROR("Root inode create failed\n");
1106 TRACE("Leaving squashfs_read_super\n");
1110 kfree(msblk
->fragment_index
);
1111 kfree(msblk
->fragment
);
1113 kfree(msblk
->read_page
);
1114 kfree(msblk
->read_data
);
1115 kfree(msblk
->block_cache
);
1116 kfree(msblk
->fragment_index_2
);
1117 vfree(msblk
->stream
.workspace
);
1122 static int squashfs_statfs(struct super_block
*s
, struct statfs
*buf
)
1124 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
1125 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1127 TRACE("Entered squashfs_statfs\n");
1129 buf
->f_type
= SQUASHFS_MAGIC
;
1130 buf
->f_bsize
= sblk
->block_size
;
1131 buf
->f_blocks
= ((sblk
->bytes_used
- 1) >> sblk
->block_log
) + 1;
1132 buf
->f_bfree
= buf
->f_bavail
= 0;
1133 buf
->f_files
= sblk
->inodes
;
1135 buf
->f_namelen
= SQUASHFS_NAME_LEN
;
1141 static int squashfs_symlink_readpage(struct file
*file
, struct page
*page
)
1143 struct inode
*inode
= page
->mapping
->host
;
1144 int index
= page
->index
<< PAGE_CACHE_SHIFT
, length
, bytes
;
1145 long long block
= SQUASHFS_I(inode
)->start_block
;
1146 int offset
= SQUASHFS_I(inode
)->offset
;
1147 void *pageaddr
= kmap(page
);
1149 TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
1150 "%llx, offset %x\n", page
->index
,
1151 SQUASHFS_I(inode
)->start_block
,
1152 SQUASHFS_I(inode
)->offset
);
1154 for (length
= 0; length
< index
; length
+= bytes
) {
1155 if (!(bytes
= squashfs_get_cached_block(inode
->i_sb
, NULL
,
1156 block
, offset
, PAGE_CACHE_SIZE
, &block
,
1158 ERROR("Unable to read symbolic link [%llx:%x]\n", block
,
1164 if (length
!= index
) {
1165 ERROR("(squashfs_symlink_readpage) length != index\n");
1170 bytes
= (i_size_read(inode
) - length
) > PAGE_CACHE_SIZE
? PAGE_CACHE_SIZE
:
1171 i_size_read(inode
) - length
;
1173 if (!(bytes
= squashfs_get_cached_block(inode
->i_sb
, pageaddr
, block
,
1174 offset
, bytes
, &block
, &offset
)))
1175 ERROR("Unable to read symbolic link [%llx:%x]\n", block
, offset
);
1178 memset(pageaddr
+ bytes
, 0, PAGE_CACHE_SIZE
- bytes
);
1180 SetPageUptodate(page
);
1187 struct meta_index
*locate_meta_index(struct inode
*inode
, int index
, int offset
)
1189 struct meta_index
*meta
= NULL
;
1190 struct squashfs_sb_info
*msblk
= &inode
->i_sb
->u
.squashfs_sb
;
1193 down(&msblk
->meta_index_mutex
);
1195 TRACE("locate_meta_index: index %d, offset %d\n", index
, offset
);
1197 if(msblk
->meta_index
== NULL
)
1200 for (i
= 0; i
< SQUASHFS_META_NUMBER
; i
++)
1201 if (msblk
->meta_index
[i
].inode_number
== inode
->i_ino
&&
1202 msblk
->meta_index
[i
].offset
>= offset
&&
1203 msblk
->meta_index
[i
].offset
<= index
&&
1204 msblk
->meta_index
[i
].locked
== 0) {
1205 TRACE("locate_meta_index: entry %d, offset %d\n", i
,
1206 msblk
->meta_index
[i
].offset
);
1207 meta
= &msblk
->meta_index
[i
];
1208 offset
= meta
->offset
;
1215 up(&msblk
->meta_index_mutex
);
1221 struct meta_index
*empty_meta_index(struct inode
*inode
, int offset
, int skip
)
1223 struct squashfs_sb_info
*msblk
= &inode
->i_sb
->u
.squashfs_sb
;
1224 struct meta_index
*meta
= NULL
;
1227 down(&msblk
->meta_index_mutex
);
1229 TRACE("empty_meta_index: offset %d, skip %d\n", offset
, skip
);
1231 if(msblk
->meta_index
== NULL
) {
1232 if (!(msblk
->meta_index
= kmalloc(sizeof(struct meta_index
) *
1233 SQUASHFS_META_NUMBER
, GFP_KERNEL
))) {
1234 ERROR("Failed to allocate meta_index\n");
1237 for(i
= 0; i
< SQUASHFS_META_NUMBER
; i
++) {
1238 msblk
->meta_index
[i
].inode_number
= 0;
1239 msblk
->meta_index
[i
].locked
= 0;
1241 msblk
->next_meta_index
= 0;
1244 for(i
= SQUASHFS_META_NUMBER
; i
&&
1245 msblk
->meta_index
[msblk
->next_meta_index
].locked
; i
--)
1246 msblk
->next_meta_index
= (msblk
->next_meta_index
+ 1) %
1247 SQUASHFS_META_NUMBER
;
1250 TRACE("empty_meta_index: failed!\n");
1254 TRACE("empty_meta_index: returned meta entry %d, %p\n",
1255 msblk
->next_meta_index
,
1256 &msblk
->meta_index
[msblk
->next_meta_index
]);
1258 meta
= &msblk
->meta_index
[msblk
->next_meta_index
];
1259 msblk
->next_meta_index
= (msblk
->next_meta_index
+ 1) %
1260 SQUASHFS_META_NUMBER
;
1262 meta
->inode_number
= inode
->i_ino
;
1263 meta
->offset
= offset
;
1269 up(&msblk
->meta_index_mutex
);
1274 void release_meta_index(struct inode
*inode
, struct meta_index
*meta
)
1280 static int read_block_index(struct super_block
*s
, int blocks
, char *block_list
,
1281 long long *start_block
, int *offset
)
1283 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
1284 unsigned int *block_listp
;
1288 char sblock_list
[blocks
<< 2];
1290 if (!squashfs_get_cached_block(s
, sblock_list
, *start_block
,
1291 *offset
, blocks
<< 2, start_block
, offset
)) {
1292 ERROR("Unable to read block list [%llx:%x]\n",
1293 *start_block
, *offset
);
1296 SQUASHFS_SWAP_INTS(((unsigned int *)block_list
),
1297 ((unsigned int *)sblock_list
), blocks
);
1299 if (!squashfs_get_cached_block(s
, block_list
, *start_block
,
1300 *offset
, blocks
<< 2, start_block
, offset
)) {
1301 ERROR("Unable to read block list [%llx:%x]\n",
1302 *start_block
, *offset
);
1306 for (block_listp
= (unsigned int *) block_list
; blocks
;
1307 block_listp
++, blocks
--)
1308 block
+= SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp
);
1319 static inline int calculate_skip(int blocks
) {
1320 int skip
= (blocks
- 1) / ((SQUASHFS_SLOTS
* SQUASHFS_META_ENTRIES
+ 1) * SQUASHFS_META_INDEXES
);
1321 return skip
>= 7 ? 7 : skip
+ 1;
1325 static int get_meta_index(struct inode
*inode
, int index
,
1326 long long *index_block
, int *index_offset
,
1327 long long *data_block
, char *block_list
)
1329 struct squashfs_sb_info
*msblk
= &inode
->i_sb
->u
.squashfs_sb
;
1330 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1331 int skip
= calculate_skip(i_size_read(inode
) >> sblk
->block_log
);
1333 struct meta_index
*meta
;
1334 struct meta_entry
*meta_entry
;
1335 long long cur_index_block
= SQUASHFS_I(inode
)->u
.s1
.block_list_start
;
1336 int cur_offset
= SQUASHFS_I(inode
)->offset
;
1337 long long cur_data_block
= SQUASHFS_I(inode
)->start_block
;
1340 index
/= SQUASHFS_META_INDEXES
* skip
;
1342 while ( offset
< index
) {
1343 meta
= locate_meta_index(inode
, index
, offset
+ 1);
1346 if ((meta
= empty_meta_index(inode
, offset
+ 1,
1350 offset
= index
< meta
->offset
+ meta
->entries
? index
:
1351 meta
->offset
+ meta
->entries
- 1;
1352 meta_entry
= &meta
->meta_entry
[offset
- meta
->offset
];
1353 cur_index_block
= meta_entry
->index_block
+ sblk
->inode_table_start
;
1354 cur_offset
= meta_entry
->offset
;
1355 cur_data_block
= meta_entry
->data_block
;
1356 TRACE("get_meta_index: offset %d, meta->offset %d, "
1357 "meta->entries %d\n", offset
, meta
->offset
,
1359 TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
1360 " data_block 0x%llx\n", cur_index_block
,
1361 cur_offset
, cur_data_block
);
1364 for (i
= meta
->offset
+ meta
->entries
; i
<= index
&&
1365 i
< meta
->offset
+ SQUASHFS_META_ENTRIES
; i
++) {
1366 int blocks
= skip
* SQUASHFS_META_INDEXES
;
1369 int block
= blocks
> (SIZE
>> 2) ? (SIZE
>> 2) :
1371 int res
= read_block_index(inode
->i_sb
, block
,
1372 block_list
, &cur_index_block
,
1378 cur_data_block
+= res
;
1382 meta_entry
= &meta
->meta_entry
[i
- meta
->offset
];
1383 meta_entry
->index_block
= cur_index_block
- sblk
->inode_table_start
;
1384 meta_entry
->offset
= cur_offset
;
1385 meta_entry
->data_block
= cur_data_block
;
1390 TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
1391 meta
->offset
, meta
->entries
);
1393 release_meta_index(inode
, meta
);
1397 *index_block
= cur_index_block
;
1398 *index_offset
= cur_offset
;
1399 *data_block
= cur_data_block
;
1401 return offset
* SQUASHFS_META_INDEXES
* skip
;
1404 release_meta_index(inode
, meta
);
1409 static long long read_blocklist(struct inode
*inode
, int index
,
1410 int readahead_blks
, char *block_list
,
1411 unsigned short **block_p
, unsigned int *bsize
)
1413 long long block_ptr
;
1416 int res
= get_meta_index(inode
, index
, &block_ptr
, &offset
, &block
,
1419 TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
1420 " 0x%x, block 0x%llx\n", res
, index
, block_ptr
, offset
,
1429 int blocks
= index
> (SIZE
>> 2) ? (SIZE
>> 2) : index
;
1430 int res
= read_block_index(inode
->i_sb
, blocks
, block_list
,
1431 &block_ptr
, &offset
);
1438 if (read_block_index(inode
->i_sb
, 1, block_list
,
1439 &block_ptr
, &offset
) == -1)
1441 *bsize
= *((unsigned int *) block_list
);
1450 static int squashfs_readpage(struct file
*file
, struct page
*page
)
1452 struct inode
*inode
= page
->mapping
->host
;
1453 struct squashfs_sb_info
*msblk
= &inode
->i_sb
->u
.squashfs_sb
;
1454 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1455 unsigned char block_list
[SIZE
];
1457 unsigned int bsize
, i
= 0, bytes
= 0, byte_offset
= 0;
1458 int index
= page
->index
>> (sblk
->block_log
- PAGE_CACHE_SHIFT
);
1460 struct squashfs_fragment_cache
*fragment
= NULL
;
1461 char *data_ptr
= msblk
->read_page
;
1463 int mask
= (1 << (sblk
->block_log
- PAGE_CACHE_SHIFT
)) - 1;
1464 int start_index
= page
->index
& ~mask
;
1465 int end_index
= start_index
| mask
;
1467 TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
1469 SQUASHFS_I(inode
)->start_block
);
1471 if (page
->index
>= ((i_size_read(inode
) + PAGE_CACHE_SIZE
- 1) >>
1475 if (SQUASHFS_I(inode
)->u
.s1
.fragment_start_block
== SQUASHFS_INVALID_BLK
1476 || index
< (i_size_read(inode
) >>
1478 if ((block
= (msblk
->read_blocklist
)(inode
, index
, 1,
1479 block_list
, NULL
, &bsize
)) == 0)
1482 down(&msblk
->read_page_mutex
);
1484 if (!(bytes
= squashfs_read_data(inode
->i_sb
, msblk
->read_page
,
1485 block
, bsize
, NULL
))) {
1486 ERROR("Unable to read page, block %llx, size %x\n", block
,
1488 up(&msblk
->read_page_mutex
);
1492 if ((fragment
= get_cached_fragment(inode
->i_sb
,
1494 u
.s1
.fragment_start_block
,
1495 SQUASHFS_I(inode
)->u
.s1
.fragment_size
))
1497 ERROR("Unable to read page, block %llx, size %x\n",
1499 u
.s1
.fragment_start_block
,
1500 (int) SQUASHFS_I(inode
)->
1501 u
.s1
.fragment_size
);
1504 bytes
= SQUASHFS_I(inode
)->u
.s1
.fragment_offset
+
1505 (i_size_read(inode
) & (sblk
->block_size
1507 byte_offset
= SQUASHFS_I(inode
)->u
.s1
.fragment_offset
;
1508 data_ptr
= fragment
->data
;
1511 for (i
= start_index
; i
<= end_index
&& byte_offset
< bytes
;
1512 i
++, byte_offset
+= PAGE_CACHE_SIZE
) {
1513 struct page
*push_page
;
1514 int available_bytes
= (bytes
- byte_offset
) > PAGE_CACHE_SIZE
?
1515 PAGE_CACHE_SIZE
: bytes
- byte_offset
;
1517 TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
1518 bytes
, i
, byte_offset
, available_bytes
);
1520 if (i
== page
->index
) {
1521 pageaddr
= kmap_atomic(page
, KM_USER0
);
1522 memcpy(pageaddr
, data_ptr
+ byte_offset
,
1524 memset(pageaddr
+ available_bytes
, 0,
1525 PAGE_CACHE_SIZE
- available_bytes
);
1526 kunmap_atomic(pageaddr
, KM_USER0
);
1527 flush_dcache_page(page
);
1528 SetPageUptodate(page
);
1530 } else if ((push_page
=
1531 grab_cache_page_nowait(page
->mapping
, i
))) {
1532 pageaddr
= kmap_atomic(push_page
, KM_USER0
);
1534 memcpy(pageaddr
, data_ptr
+ byte_offset
,
1536 memset(pageaddr
+ available_bytes
, 0,
1537 PAGE_CACHE_SIZE
- available_bytes
);
1538 kunmap_atomic(pageaddr
, KM_USER0
);
1539 flush_dcache_page(push_page
);
1540 SetPageUptodate(push_page
);
1541 UnlockPage(push_page
);
1542 page_cache_release(push_page
);
1546 if (SQUASHFS_I(inode
)->u
.s1
.fragment_start_block
== SQUASHFS_INVALID_BLK
1547 || index
< (i_size_read(inode
) >>
1549 up(&msblk
->read_page_mutex
);
1551 release_cached_fragment(msblk
, fragment
);
1556 pageaddr
= kmap_atomic(page
, KM_USER0
);
1557 memset(pageaddr
+ bytes
, 0, PAGE_CACHE_SIZE
- bytes
);
1558 kunmap_atomic(pageaddr
, KM_USER0
);
1559 flush_dcache_page(page
);
1560 SetPageUptodate(page
);
1567 static int squashfs_readpage4K(struct file
*file
, struct page
*page
)
1569 struct inode
*inode
= page
->mapping
->host
;
1570 struct squashfs_sb_info
*msblk
= &inode
->i_sb
->u
.squashfs_sb
;
1571 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1572 unsigned char block_list
[SIZE
];
1574 unsigned int bsize
, bytes
= 0;
1577 TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
1579 SQUASHFS_I(inode
)->start_block
);
1581 if (page
->index
>= ((i_size_read(inode
) + PAGE_CACHE_SIZE
- 1) >>
1582 PAGE_CACHE_SHIFT
)) {
1583 pageaddr
= kmap_atomic(page
, KM_USER0
);
1587 if (SQUASHFS_I(inode
)->u
.s1
.fragment_start_block
== SQUASHFS_INVALID_BLK
1588 || page
->index
< (i_size_read(inode
) >>
1590 block
= (msblk
->read_blocklist
)(inode
, page
->index
, 1,
1591 block_list
, NULL
, &bsize
);
1593 down(&msblk
->read_page_mutex
);
1594 bytes
= squashfs_read_data(inode
->i_sb
, msblk
->read_page
, block
,
1596 pageaddr
= kmap_atomic(page
, KM_USER0
);
1598 memcpy(pageaddr
, msblk
->read_page
, bytes
);
1600 ERROR("Unable to read page, block %llx, size %x\n",
1602 up(&msblk
->read_page_mutex
);
1604 struct squashfs_fragment_cache
*fragment
=
1605 get_cached_fragment(inode
->i_sb
,
1607 u
.s1
.fragment_start_block
,
1608 SQUASHFS_I(inode
)-> u
.s1
.fragment_size
);
1609 pageaddr
= kmap_atomic(page
, KM_USER0
);
1611 bytes
= i_size_read(inode
) & (sblk
->block_size
- 1);
1612 memcpy(pageaddr
, fragment
->data
+ SQUASHFS_I(inode
)->
1613 u
.s1
.fragment_offset
, bytes
);
1614 release_cached_fragment(msblk
, fragment
);
1616 ERROR("Unable to read page, block %llx, size %x\n",
1618 u
.s1
.fragment_start_block
, (int)
1619 SQUASHFS_I(inode
)-> u
.s1
.fragment_size
);
1623 memset(pageaddr
+ bytes
, 0, PAGE_CACHE_SIZE
- bytes
);
1624 kunmap_atomic(pageaddr
, KM_USER0
);
1625 flush_dcache_page(page
);
1626 SetPageUptodate(page
);
1633 static int get_dir_index_using_offset(struct super_block
*s
, long long
1634 *next_block
, unsigned int *next_offset
,
1635 long long index_start
,
1636 unsigned int index_offset
, int i_count
,
1639 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
1640 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1642 struct squashfs_dir_index index
;
1644 TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
1645 i_count
, (unsigned int) f_pos
);
1651 for (i
= 0; i
< i_count
; i
++) {
1653 struct squashfs_dir_index sindex
;
1654 squashfs_get_cached_block(s
, (char *) &sindex
,
1655 index_start
, index_offset
,
1656 sizeof(sindex
), &index_start
,
1658 SQUASHFS_SWAP_DIR_INDEX(&index
, &sindex
);
1660 squashfs_get_cached_block(s
, (char *) &index
,
1661 index_start
, index_offset
,
1662 sizeof(index
), &index_start
,
1665 if (index
.index
> f_pos
)
1668 squashfs_get_cached_block(s
, NULL
, index_start
, index_offset
,
1669 index
.size
+ 1, &index_start
,
1672 length
= index
.index
;
1673 *next_block
= index
.start_block
+ sblk
->directory_table_start
;
1676 *next_offset
= (length
+ *next_offset
) % SQUASHFS_METADATA_SIZE
;
1683 static int get_dir_index_using_name(struct super_block
*s
, long long
1684 *next_block
, unsigned int *next_offset
,
1685 long long index_start
,
1686 unsigned int index_offset
, int i_count
,
1687 const char *name
, int size
)
1689 struct squashfs_sb_info
*msblk
= &s
->u
.squashfs_sb
;
1690 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1692 char buffer
[sizeof(struct squashfs_dir_index
) + SQUASHFS_NAME_LEN
+ 1];
1693 struct squashfs_dir_index
*index
= (struct squashfs_dir_index
*) buffer
;
1694 char str
[SQUASHFS_NAME_LEN
+ 1];
1696 TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count
);
1698 strncpy(str
, name
, size
);
1701 for (i
= 0; i
< i_count
; i
++) {
1703 struct squashfs_dir_index sindex
;
1704 squashfs_get_cached_block(s
, (char *) &sindex
,
1705 index_start
, index_offset
,
1706 sizeof(sindex
), &index_start
,
1708 SQUASHFS_SWAP_DIR_INDEX(index
, &sindex
);
1710 squashfs_get_cached_block(s
, (char *) index
,
1711 index_start
, index_offset
,
1712 sizeof(struct squashfs_dir_index
),
1713 &index_start
, &index_offset
);
1715 squashfs_get_cached_block(s
, index
->name
, index_start
,
1716 index_offset
, index
->size
+ 1,
1717 &index_start
, &index_offset
);
1719 index
->name
[index
->size
+ 1] = '\0';
1721 if (strcmp(index
->name
, str
) > 0)
1724 length
= index
->index
;
1725 *next_block
= index
->start_block
+ sblk
->directory_table_start
;
1728 *next_offset
= (length
+ *next_offset
) % SQUASHFS_METADATA_SIZE
;
1733 static int squashfs_readdir(struct file
*file
, void *dirent
, filldir_t filldir
)
1735 struct inode
*i
= file
->f_dentry
->d_inode
;
1736 struct squashfs_sb_info
*msblk
= &i
->i_sb
->u
.squashfs_sb
;
1737 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1738 long long next_block
= SQUASHFS_I(i
)->start_block
+
1739 sblk
->directory_table_start
;
1740 int next_offset
= SQUASHFS_I(i
)->offset
, length
= 0,
1742 struct squashfs_dir_header dirh
;
1743 char buffer
[sizeof(struct squashfs_dir_entry
) + SQUASHFS_NAME_LEN
+ 1];
1744 struct squashfs_dir_entry
*dire
= (struct squashfs_dir_entry
*) buffer
;
1746 TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block
, next_offset
);
1748 while(file
->f_pos
< 3) {
1752 if(file
->f_pos
== 0) {
1759 i_ino
= SQUASHFS_I(i
)->u
.s2
.parent_inode
;
1761 TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
1762 (unsigned int) dirent
, name
, size
, (int)
1764 squashfs_filetype_table
[1]);
1766 if (filldir(dirent
, name
, size
,
1768 squashfs_filetype_table
[1]) < 0) {
1769 TRACE("Filldir returned less than 0\n");
1772 file
->f_pos
+= size
;
1775 length
= get_dir_index_using_offset(i
->i_sb
, &next_block
, &next_offset
,
1776 SQUASHFS_I(i
)->u
.s2
.directory_index_start
,
1777 SQUASHFS_I(i
)->u
.s2
.directory_index_offset
,
1778 SQUASHFS_I(i
)->u
.s2
.directory_index_count
,
1781 while (length
< i_size_read(i
)) {
1782 /* read directory header */
1784 struct squashfs_dir_header sdirh
;
1786 if (!squashfs_get_cached_block(i
->i_sb
, (char *) &sdirh
,
1787 next_block
, next_offset
, sizeof(sdirh
),
1788 &next_block
, &next_offset
))
1791 length
+= sizeof(sdirh
);
1792 SQUASHFS_SWAP_DIR_HEADER(&dirh
, &sdirh
);
1794 if (!squashfs_get_cached_block(i
->i_sb
, (char *) &dirh
,
1795 next_block
, next_offset
, sizeof(dirh
),
1796 &next_block
, &next_offset
))
1799 length
+= sizeof(dirh
);
1802 dir_count
= dirh
.count
+ 1;
1803 while (dir_count
--) {
1805 struct squashfs_dir_entry sdire
;
1806 if (!squashfs_get_cached_block(i
->i_sb
, (char *)
1807 &sdire
, next_block
, next_offset
,
1808 sizeof(sdire
), &next_block
,
1812 length
+= sizeof(sdire
);
1813 SQUASHFS_SWAP_DIR_ENTRY(dire
, &sdire
);
1815 if (!squashfs_get_cached_block(i
->i_sb
, (char *)
1816 dire
, next_block
, next_offset
,
1817 sizeof(*dire
), &next_block
,
1821 length
+= sizeof(*dire
);
1824 if (!squashfs_get_cached_block(i
->i_sb
, dire
->name
,
1825 next_block
, next_offset
,
1826 dire
->size
+ 1, &next_block
,
1830 length
+= dire
->size
+ 1;
1832 if (file
->f_pos
>= length
)
1835 dire
->name
[dire
->size
+ 1] = '\0';
1837 TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
1838 (unsigned int) dirent
, dire
->name
,
1839 dire
->size
+ 1, (int) file
->f_pos
,
1840 dirh
.start_block
, dire
->offset
,
1841 dirh
.inode_number
+ dire
->inode_number
,
1842 squashfs_filetype_table
[dire
->type
]);
1844 if (filldir(dirent
, dire
->name
, dire
->size
+ 1,
1846 dirh
.inode_number
+ dire
->inode_number
,
1847 squashfs_filetype_table
[dire
->type
])
1849 TRACE("Filldir returned less than 0\n");
1852 file
->f_pos
= length
;
1860 ERROR("Unable to read directory block [%llx:%x]\n", next_block
,
1866 static struct dentry
*squashfs_lookup(struct inode
*i
, struct dentry
*dentry
)
1868 const unsigned char *name
= dentry
->d_name
.name
;
1869 int len
= dentry
->d_name
.len
;
1870 struct inode
*inode
= NULL
;
1871 struct squashfs_sb_info
*msblk
= &i
->i_sb
->u
.squashfs_sb
;
1872 struct squashfs_super_block
*sblk
= &msblk
->sblk
;
1873 long long next_block
= SQUASHFS_I(i
)->start_block
+
1874 sblk
->directory_table_start
;
1875 int next_offset
= SQUASHFS_I(i
)->offset
, length
= 0,
1877 struct squashfs_dir_header dirh
;
1878 char buffer
[sizeof(struct squashfs_dir_entry
) + SQUASHFS_NAME_LEN
];
1879 struct squashfs_dir_entry
*dire
= (struct squashfs_dir_entry
*) buffer
;
1881 TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block
, next_offset
);
1883 if (len
> SQUASHFS_NAME_LEN
)
1886 length
= get_dir_index_using_name(i
->i_sb
, &next_block
, &next_offset
,
1887 SQUASHFS_I(i
)->u
.s2
.directory_index_start
,
1888 SQUASHFS_I(i
)->u
.s2
.directory_index_offset
,
1889 SQUASHFS_I(i
)->u
.s2
.directory_index_count
, name
,
1892 while (length
< i_size_read(i
)) {
1893 /* read directory header */
1895 struct squashfs_dir_header sdirh
;
1896 if (!squashfs_get_cached_block(i
->i_sb
, (char *) &sdirh
,
1897 next_block
, next_offset
, sizeof(sdirh
),
1898 &next_block
, &next_offset
))
1901 length
+= sizeof(sdirh
);
1902 SQUASHFS_SWAP_DIR_HEADER(&dirh
, &sdirh
);
1904 if (!squashfs_get_cached_block(i
->i_sb
, (char *) &dirh
,
1905 next_block
, next_offset
, sizeof(dirh
),
1906 &next_block
, &next_offset
))
1909 length
+= sizeof(dirh
);
1912 dir_count
= dirh
.count
+ 1;
1913 while (dir_count
--) {
1915 struct squashfs_dir_entry sdire
;
1916 if (!squashfs_get_cached_block(i
->i_sb
, (char *)
1917 &sdire
, next_block
,next_offset
,
1918 sizeof(sdire
), &next_block
,
1922 length
+= sizeof(sdire
);
1923 SQUASHFS_SWAP_DIR_ENTRY(dire
, &sdire
);
1925 if (!squashfs_get_cached_block(i
->i_sb
, (char *)
1926 dire
, next_block
,next_offset
,
1927 sizeof(*dire
), &next_block
,
1931 length
+= sizeof(*dire
);
1934 if (!squashfs_get_cached_block(i
->i_sb
, dire
->name
,
1935 next_block
, next_offset
, dire
->size
+ 1,
1936 &next_block
, &next_offset
))
1939 length
+= dire
->size
+ 1;
1941 if (name
[0] < dire
->name
[0])
1944 if ((len
== dire
->size
+ 1) && !strncmp(name
,
1946 squashfs_inode_t ino
=
1947 SQUASHFS_MKINODE(dirh
.start_block
,
1950 TRACE("calling squashfs_iget for directory "
1951 "entry %s, inode %x:%x, %d\n", name
,
1952 dirh
.start_block
, dire
->offset
,
1953 dirh
.inode_number
+ dire
->inode_number
);
1955 inode
= (msblk
->iget
)(i
->i_sb
, ino
);
1963 d_add(dentry
, inode
);
1967 ERROR("Unable to read directory block [%llx:%x]\n", next_block
,
1973 static void squashfs_put_super(struct super_block
*s
)
1977 struct squashfs_sb_info
*sbi
= &s
->u
.squashfs_sb
;
1978 if (sbi
->block_cache
)
1979 for (i
= 0; i
< SQUASHFS_CACHED_BLKS
; i
++)
1980 if (sbi
->block_cache
[i
].block
!=
1981 SQUASHFS_INVALID_BLK
)
1982 kfree(sbi
->block_cache
[i
].data
);
1984 for (i
= 0; i
< SQUASHFS_CACHED_FRAGMENTS
; i
++)
1985 SQUASHFS_FREE(sbi
->fragment
[i
].data
);
1986 kfree(sbi
->fragment
);
1987 kfree(sbi
->block_cache
);
1988 kfree(sbi
->read_data
);
1989 kfree(sbi
->read_page
);
1991 kfree(sbi
->fragment_index
);
1992 kfree(sbi
->fragment_index_2
);
1993 kfree(sbi
->meta_index
);
1994 vfree(sbi
->stream
.workspace
);
1995 sbi
->block_cache
= NULL
;
1997 sbi
->read_data
= NULL
;
1998 sbi
->read_page
= NULL
;
1999 sbi
->fragment
= NULL
;
2000 sbi
->fragment_index
= NULL
;
2001 sbi
->fragment_index_2
= NULL
;
2002 sbi
->meta_index
= NULL
;
2003 sbi
->stream
.workspace
= NULL
;
2007 static int __init
init_squashfs_fs(void)
2010 printk(KERN_INFO
"squashfs: version 3.1 (2006/08/15) "
2011 "Phillip Lougher\n");
2013 return register_filesystem(&squashfs_fs_type
);
2017 static void __exit
exit_squashfs_fs(void)
2019 unregister_filesystem(&squashfs_fs_type
);
2025 module_init(init_squashfs_fs
);
2026 module_exit(exit_squashfs_fs
);
2027 MODULE_DESCRIPTION("squashfs 3.1, a compressed read-only filesystem");
2028 MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
2029 MODULE_LICENSE("GPL");