2 * Squashfs - a compressed read only filesystem for Linux
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@squashfs.org.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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * This file contains code for handling regular files. A regular file
26 * consists of a sequence of contiguous compressed blocks, and/or a
27 * compressed fragment block (tail-end packed block). The compressed size
28 * of each datablock is stored in a block list contained within the
29 * file inode (itself stored in one or more compressed metadata blocks).
31 * To speed up access to datablocks when reading 'large' files (256 Mbytes or
32 * larger), the code implements an index cache that caches the mapping from
33 * block index to datablock location on disk.
35 * The index cache allows Squashfs to handle large files (up to 1.75 TiB) while
36 * retaining a simple and space-efficient block list on disk. The cache
37 * is split into slots, caching up to eight 224 GiB files (128 KiB blocks).
38 * Larger files use multiple slots, with 1.75 TiB files using all 8 slots.
39 * The index cache is designed to be memory efficient, and by default uses
44 #include <linux/vfs.h>
45 #include <linux/kernel.h>
46 #include <linux/slab.h>
47 #include <linux/string.h>
48 #include <linux/pagemap.h>
49 #include <linux/mutex.h>
51 #include "squashfs_fs.h"
52 #include "squashfs_fs_sb.h"
53 #include "squashfs_fs_i.h"
57 * Locate cache slot in range [offset, index] for specified inode. If
58 * there's more than one return the slot closest to index.
60 static struct meta_index
*locate_meta_index(struct inode
*inode
, int offset
,
63 struct meta_index
*meta
= NULL
;
64 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
67 mutex_lock(&msblk
->meta_index_mutex
);
69 TRACE("locate_meta_index: index %d, offset %d\n", index
, offset
);
71 if (msblk
->meta_index
== NULL
)
74 for (i
= 0; i
< SQUASHFS_META_SLOTS
; i
++) {
75 if (msblk
->meta_index
[i
].inode_number
== inode
->i_ino
&&
76 msblk
->meta_index
[i
].offset
>= offset
&&
77 msblk
->meta_index
[i
].offset
<= index
&&
78 msblk
->meta_index
[i
].locked
== 0) {
79 TRACE("locate_meta_index: entry %d, offset %d\n", i
,
80 msblk
->meta_index
[i
].offset
);
81 meta
= &msblk
->meta_index
[i
];
82 offset
= meta
->offset
;
90 mutex_unlock(&msblk
->meta_index_mutex
);
97 * Find and initialise an empty cache slot for index offset.
99 static struct meta_index
*empty_meta_index(struct inode
*inode
, int offset
,
102 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
103 struct meta_index
*meta
= NULL
;
106 mutex_lock(&msblk
->meta_index_mutex
);
108 TRACE("empty_meta_index: offset %d, skip %d\n", offset
, skip
);
110 if (msblk
->meta_index
== NULL
) {
112 * First time cache index has been used, allocate and
113 * initialise. The cache index could be allocated at
114 * mount time but doing it here means it is allocated only
115 * if a 'large' file is read.
117 msblk
->meta_index
= kcalloc(SQUASHFS_META_SLOTS
,
118 sizeof(*(msblk
->meta_index
)), GFP_KERNEL
);
119 if (msblk
->meta_index
== NULL
) {
120 ERROR("Failed to allocate meta_index\n");
123 for (i
= 0; i
< SQUASHFS_META_SLOTS
; i
++) {
124 msblk
->meta_index
[i
].inode_number
= 0;
125 msblk
->meta_index
[i
].locked
= 0;
127 msblk
->next_meta_index
= 0;
130 for (i
= SQUASHFS_META_SLOTS
; i
&&
131 msblk
->meta_index
[msblk
->next_meta_index
].locked
; i
--)
132 msblk
->next_meta_index
= (msblk
->next_meta_index
+ 1) %
136 TRACE("empty_meta_index: failed!\n");
140 TRACE("empty_meta_index: returned meta entry %d, %p\n",
141 msblk
->next_meta_index
,
142 &msblk
->meta_index
[msblk
->next_meta_index
]);
144 meta
= &msblk
->meta_index
[msblk
->next_meta_index
];
145 msblk
->next_meta_index
= (msblk
->next_meta_index
+ 1) %
148 meta
->inode_number
= inode
->i_ino
;
149 meta
->offset
= offset
;
155 mutex_unlock(&msblk
->meta_index_mutex
);
160 static void release_meta_index(struct inode
*inode
, struct meta_index
*meta
)
162 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
163 mutex_lock(&msblk
->meta_index_mutex
);
165 mutex_unlock(&msblk
->meta_index_mutex
);
170 * Read the next n blocks from the block list, starting from
171 * metadata block <start_block, offset>.
173 static long long read_indexes(struct super_block
*sb
, int n
,
174 u64
*start_block
, int *offset
)
178 __le32
*blist
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
181 ERROR("read_indexes: Failed to allocate block_list\n");
186 int blocks
= min_t(int, n
, PAGE_SIZE
>> 2);
188 err
= squashfs_read_metadata(sb
, blist
, start_block
,
189 offset
, blocks
<< 2);
191 ERROR("read_indexes: reading block [%llx:%x]\n",
192 *start_block
, *offset
);
196 for (i
= 0; i
< blocks
; i
++) {
197 int size
= le32_to_cpu(blist
[i
]);
198 block
+= SQUASHFS_COMPRESSED_SIZE_BLOCK(size
);
213 * Each cache index slot has SQUASHFS_META_ENTRIES, each of which
214 * can cache one index -> datablock/blocklist-block mapping. We wish
215 * to distribute these over the length of the file, entry[0] maps index x,
216 * entry[1] maps index x + skip, entry[2] maps index x + 2 * skip, and so on.
217 * The larger the file, the greater the skip factor. The skip factor is
218 * limited to the size of the metadata cache (SQUASHFS_CACHED_BLKS) to ensure
219 * the number of metadata blocks that need to be read fits into the cache.
220 * If the skip factor is limited in this way then the file will use multiple
223 static inline int calculate_skip(int blocks
)
225 int skip
= blocks
/ ((SQUASHFS_META_ENTRIES
+ 1)
226 * SQUASHFS_META_INDEXES
);
227 return min(SQUASHFS_CACHED_BLKS
- 1, skip
+ 1);
232 * Search and grow the index cache for the specified inode, returning the
233 * on-disk locations of the datablock and block list metadata block
234 * <index_block, index_offset> for index (scaled to nearest cache index).
236 static int fill_meta_index(struct inode
*inode
, int index
,
237 u64
*index_block
, int *index_offset
, u64
*data_block
)
239 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
240 int skip
= calculate_skip(i_size_read(inode
) >> msblk
->block_log
);
242 struct meta_index
*meta
;
243 struct meta_entry
*meta_entry
;
244 u64 cur_index_block
= squashfs_i(inode
)->block_list_start
;
245 int cur_offset
= squashfs_i(inode
)->offset
;
246 u64 cur_data_block
= squashfs_i(inode
)->start
;
250 * Scale index to cache index (cache slot entry)
252 index
/= SQUASHFS_META_INDEXES
* skip
;
254 while (offset
< index
) {
255 meta
= locate_meta_index(inode
, offset
+ 1, index
);
258 meta
= empty_meta_index(inode
, offset
+ 1, skip
);
262 offset
= index
< meta
->offset
+ meta
->entries
? index
:
263 meta
->offset
+ meta
->entries
- 1;
264 meta_entry
= &meta
->meta_entry
[offset
- meta
->offset
];
265 cur_index_block
= meta_entry
->index_block
+
267 cur_offset
= meta_entry
->offset
;
268 cur_data_block
= meta_entry
->data_block
;
269 TRACE("get_meta_index: offset %d, meta->offset %d, "
270 "meta->entries %d\n", offset
, meta
->offset
,
272 TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
273 " data_block 0x%llx\n", cur_index_block
,
274 cur_offset
, cur_data_block
);
278 * If necessary grow cache slot by reading block list. Cache
279 * slot is extended up to index or to the end of the slot, in
280 * which case further slots will be used.
282 for (i
= meta
->offset
+ meta
->entries
; i
<= index
&&
283 i
< meta
->offset
+ SQUASHFS_META_ENTRIES
; i
++) {
284 int blocks
= skip
* SQUASHFS_META_INDEXES
;
285 long long res
= read_indexes(inode
->i_sb
, blocks
,
286 &cur_index_block
, &cur_offset
);
289 if (meta
->entries
== 0)
291 * Don't leave an empty slot on read
292 * error allocated to this inode...
294 meta
->inode_number
= 0;
299 cur_data_block
+= res
;
300 meta_entry
= &meta
->meta_entry
[i
- meta
->offset
];
301 meta_entry
->index_block
= cur_index_block
-
303 meta_entry
->offset
= cur_offset
;
304 meta_entry
->data_block
= cur_data_block
;
309 TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
310 meta
->offset
, meta
->entries
);
312 release_meta_index(inode
, meta
);
316 *index_block
= cur_index_block
;
317 *index_offset
= cur_offset
;
318 *data_block
= cur_data_block
;
321 * Scale cache index (cache slot entry) to index
323 return offset
* SQUASHFS_META_INDEXES
* skip
;
326 release_meta_index(inode
, meta
);
332 * Get the on-disk location and compressed size of the datablock
333 * specified by index. Fill_meta_index() does most of the work.
335 static int read_blocklist(struct inode
*inode
, int index
, u64
*block
)
341 int res
= fill_meta_index(inode
, index
, &start
, &offset
, block
);
343 TRACE("read_blocklist: res %d, index %d, start 0x%llx, offset"
344 " 0x%x, block 0x%llx\n", res
, index
, start
, offset
,
351 * res contains the index of the mapping returned by fill_meta_index(),
352 * this will likely be less than the desired index (because the
353 * meta_index cache works at a higher granularity). Read any
354 * extra block indexes needed.
357 blks
= read_indexes(inode
->i_sb
, index
- res
, &start
, &offset
);
364 * Read length of block specified by index.
366 res
= squashfs_read_metadata(inode
->i_sb
, &size
, &start
, &offset
,
370 return le32_to_cpu(size
);
373 /* Copy data into page cache */
374 void squashfs_copy_cache(struct page
*page
, struct squashfs_cache_entry
*buffer
,
375 int bytes
, int offset
)
377 struct inode
*inode
= page
->mapping
->host
;
378 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
380 int i
, mask
= (1 << (msblk
->block_log
- PAGE_SHIFT
)) - 1;
381 int start_index
= page
->index
& ~mask
, end_index
= start_index
| mask
;
384 * Loop copying datablock into pages. As the datablock likely covers
385 * many PAGE_SIZE pages (default block size is 128 KiB) explicitly
386 * grab the pages from the page cache, except for the page that we've
387 * been called to fill.
389 for (i
= start_index
; i
<= end_index
&& bytes
> 0; i
++,
390 bytes
-= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
391 struct page
*push_page
;
392 int avail
= buffer
? min_t(int, bytes
, PAGE_SIZE
) : 0;
394 TRACE("bytes %d, i %d, available_bytes %d\n", bytes
, i
, avail
);
396 push_page
= (i
== page
->index
) ? page
:
397 grab_cache_page_nowait(page
->mapping
, i
);
402 if (PageUptodate(push_page
))
405 pageaddr
= kmap_atomic(push_page
);
406 squashfs_copy_data(pageaddr
, buffer
, offset
, avail
);
407 memset(pageaddr
+ avail
, 0, PAGE_SIZE
- avail
);
408 kunmap_atomic(pageaddr
);
409 flush_dcache_page(push_page
);
410 SetPageUptodate(push_page
);
412 unlock_page(push_page
);
413 if (i
!= page
->index
)
418 /* Read datablock stored packed inside a fragment (tail-end packed block) */
419 static int squashfs_readpage_fragment(struct page
*page
)
421 struct inode
*inode
= page
->mapping
->host
;
422 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
423 struct squashfs_cache_entry
*buffer
= squashfs_get_fragment(inode
->i_sb
,
424 squashfs_i(inode
)->fragment_block
,
425 squashfs_i(inode
)->fragment_size
);
426 int res
= buffer
->error
;
429 ERROR("Unable to read page, block %llx, size %x\n",
430 squashfs_i(inode
)->fragment_block
,
431 squashfs_i(inode
)->fragment_size
);
433 squashfs_copy_cache(page
, buffer
, i_size_read(inode
) &
434 (msblk
->block_size
- 1),
435 squashfs_i(inode
)->fragment_offset
);
437 squashfs_cache_put(buffer
);
441 static int squashfs_readpage_sparse(struct page
*page
, int index
, int file_end
)
443 struct inode
*inode
= page
->mapping
->host
;
444 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
445 int bytes
= index
== file_end
?
446 (i_size_read(inode
) & (msblk
->block_size
- 1)) :
449 squashfs_copy_cache(page
, NULL
, bytes
, 0);
453 static int squashfs_readpage(struct file
*file
, struct page
*page
)
455 struct inode
*inode
= page
->mapping
->host
;
456 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
457 int index
= page
->index
>> (msblk
->block_log
- PAGE_SHIFT
);
458 int file_end
= i_size_read(inode
) >> msblk
->block_log
;
462 TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
463 page
->index
, squashfs_i(inode
)->start
);
465 if (page
->index
>= ((i_size_read(inode
) + PAGE_SIZE
- 1) >>
469 if (index
< file_end
|| squashfs_i(inode
)->fragment_block
==
470 SQUASHFS_INVALID_BLK
) {
472 int bsize
= read_blocklist(inode
, index
, &block
);
477 res
= squashfs_readpage_sparse(page
, index
, file_end
);
479 res
= squashfs_readpage_block(page
, block
, bsize
);
481 res
= squashfs_readpage_fragment(page
);
489 pageaddr
= kmap_atomic(page
);
490 memset(pageaddr
, 0, PAGE_SIZE
);
491 kunmap_atomic(pageaddr
);
492 flush_dcache_page(page
);
493 if (!PageError(page
))
494 SetPageUptodate(page
);
501 const struct address_space_operations squashfs_aops
= {
502 .readpage
= squashfs_readpage