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
= squashfs_block_size(blist
[i
]);
202 block
+= SQUASHFS_COMPRESSED_SIZE_BLOCK(size
);
217 * Each cache index slot has SQUASHFS_META_ENTRIES, each of which
218 * can cache one index -> datablock/blocklist-block mapping. We wish
219 * to distribute these over the length of the file, entry[0] maps index x,
220 * entry[1] maps index x + skip, entry[2] maps index x + 2 * skip, and so on.
221 * The larger the file, the greater the skip factor. The skip factor is
222 * limited to the size of the metadata cache (SQUASHFS_CACHED_BLKS) to ensure
223 * the number of metadata blocks that need to be read fits into the cache.
224 * If the skip factor is limited in this way then the file will use multiple
227 static inline int calculate_skip(int blocks
)
229 int skip
= blocks
/ ((SQUASHFS_META_ENTRIES
+ 1)
230 * SQUASHFS_META_INDEXES
);
231 return min(SQUASHFS_CACHED_BLKS
- 1, skip
+ 1);
236 * Search and grow the index cache for the specified inode, returning the
237 * on-disk locations of the datablock and block list metadata block
238 * <index_block, index_offset> for index (scaled to nearest cache index).
240 static int fill_meta_index(struct inode
*inode
, int index
,
241 u64
*index_block
, int *index_offset
, u64
*data_block
)
243 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
244 int skip
= calculate_skip(i_size_read(inode
) >> msblk
->block_log
);
246 struct meta_index
*meta
;
247 struct meta_entry
*meta_entry
;
248 u64 cur_index_block
= squashfs_i(inode
)->block_list_start
;
249 int cur_offset
= squashfs_i(inode
)->offset
;
250 u64 cur_data_block
= squashfs_i(inode
)->start
;
254 * Scale index to cache index (cache slot entry)
256 index
/= SQUASHFS_META_INDEXES
* skip
;
258 while (offset
< index
) {
259 meta
= locate_meta_index(inode
, offset
+ 1, index
);
262 meta
= empty_meta_index(inode
, offset
+ 1, skip
);
266 offset
= index
< meta
->offset
+ meta
->entries
? index
:
267 meta
->offset
+ meta
->entries
- 1;
268 meta_entry
= &meta
->meta_entry
[offset
- meta
->offset
];
269 cur_index_block
= meta_entry
->index_block
+
271 cur_offset
= meta_entry
->offset
;
272 cur_data_block
= meta_entry
->data_block
;
273 TRACE("get_meta_index: offset %d, meta->offset %d, "
274 "meta->entries %d\n", offset
, meta
->offset
,
276 TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
277 " data_block 0x%llx\n", cur_index_block
,
278 cur_offset
, cur_data_block
);
282 * If necessary grow cache slot by reading block list. Cache
283 * slot is extended up to index or to the end of the slot, in
284 * which case further slots will be used.
286 for (i
= meta
->offset
+ meta
->entries
; i
<= index
&&
287 i
< meta
->offset
+ SQUASHFS_META_ENTRIES
; i
++) {
288 int blocks
= skip
* SQUASHFS_META_INDEXES
;
289 long long res
= read_indexes(inode
->i_sb
, blocks
,
290 &cur_index_block
, &cur_offset
);
293 if (meta
->entries
== 0)
295 * Don't leave an empty slot on read
296 * error allocated to this inode...
298 meta
->inode_number
= 0;
303 cur_data_block
+= res
;
304 meta_entry
= &meta
->meta_entry
[i
- meta
->offset
];
305 meta_entry
->index_block
= cur_index_block
-
307 meta_entry
->offset
= cur_offset
;
308 meta_entry
->data_block
= cur_data_block
;
313 TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
314 meta
->offset
, meta
->entries
);
316 release_meta_index(inode
, meta
);
320 *index_block
= cur_index_block
;
321 *index_offset
= cur_offset
;
322 *data_block
= cur_data_block
;
325 * Scale cache index (cache slot entry) to index
327 return offset
* SQUASHFS_META_INDEXES
* skip
;
330 release_meta_index(inode
, meta
);
336 * Get the on-disk location and compressed size of the datablock
337 * specified by index. Fill_meta_index() does most of the work.
339 static int read_blocklist(struct inode
*inode
, int index
, u64
*block
)
345 int res
= fill_meta_index(inode
, index
, &start
, &offset
, block
);
347 TRACE("read_blocklist: res %d, index %d, start 0x%llx, offset"
348 " 0x%x, block 0x%llx\n", res
, index
, start
, offset
,
355 * res contains the index of the mapping returned by fill_meta_index(),
356 * this will likely be less than the desired index (because the
357 * meta_index cache works at a higher granularity). Read any
358 * extra block indexes needed.
361 blks
= read_indexes(inode
->i_sb
, index
- res
, &start
, &offset
);
368 * Read length of block specified by index.
370 res
= squashfs_read_metadata(inode
->i_sb
, &size
, &start
, &offset
,
374 return squashfs_block_size(size
);
377 void squashfs_fill_page(struct page
*page
, struct squashfs_cache_entry
*buffer
, int offset
, int avail
)
382 pageaddr
= kmap_atomic(page
);
383 copied
= squashfs_copy_data(pageaddr
, buffer
, offset
, avail
);
384 memset(pageaddr
+ copied
, 0, PAGE_SIZE
- copied
);
385 kunmap_atomic(pageaddr
);
387 flush_dcache_page(page
);
389 SetPageUptodate(page
);
394 /* Copy data into page cache */
395 void squashfs_copy_cache(struct page
*page
, struct squashfs_cache_entry
*buffer
,
396 int bytes
, int offset
)
398 struct inode
*inode
= page
->mapping
->host
;
399 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
400 int i
, mask
= (1 << (msblk
->block_log
- PAGE_SHIFT
)) - 1;
401 int start_index
= page
->index
& ~mask
, end_index
= start_index
| mask
;
404 * Loop copying datablock into pages. As the datablock likely covers
405 * many PAGE_SIZE pages (default block size is 128 KiB) explicitly
406 * grab the pages from the page cache, except for the page that we've
407 * been called to fill.
409 for (i
= start_index
; i
<= end_index
&& bytes
> 0; i
++,
410 bytes
-= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
411 struct page
*push_page
;
412 int avail
= buffer
? min_t(int, bytes
, PAGE_SIZE
) : 0;
414 TRACE("bytes %d, i %d, available_bytes %d\n", bytes
, i
, avail
);
416 push_page
= (i
== page
->index
) ? page
:
417 grab_cache_page_nowait(page
->mapping
, i
);
422 if (PageUptodate(push_page
))
425 squashfs_fill_page(push_page
, buffer
, offset
, avail
);
427 unlock_page(push_page
);
428 if (i
!= page
->index
)
433 /* Read datablock stored packed inside a fragment (tail-end packed block) */
434 static int squashfs_readpage_fragment(struct page
*page
, int expected
)
436 struct inode
*inode
= page
->mapping
->host
;
437 struct squashfs_cache_entry
*buffer
= squashfs_get_fragment(inode
->i_sb
,
438 squashfs_i(inode
)->fragment_block
,
439 squashfs_i(inode
)->fragment_size
);
440 int res
= buffer
->error
;
443 ERROR("Unable to read page, block %llx, size %x\n",
444 squashfs_i(inode
)->fragment_block
,
445 squashfs_i(inode
)->fragment_size
);
447 squashfs_copy_cache(page
, buffer
, expected
,
448 squashfs_i(inode
)->fragment_offset
);
450 squashfs_cache_put(buffer
);
454 static int squashfs_readpage_sparse(struct page
*page
, int expected
)
456 squashfs_copy_cache(page
, NULL
, expected
, 0);
460 static int squashfs_readpage(struct file
*file
, struct page
*page
)
462 struct inode
*inode
= page
->mapping
->host
;
463 struct squashfs_sb_info
*msblk
= inode
->i_sb
->s_fs_info
;
464 int index
= page
->index
>> (msblk
->block_log
- PAGE_SHIFT
);
465 int file_end
= i_size_read(inode
) >> msblk
->block_log
;
466 int expected
= index
== file_end
?
467 (i_size_read(inode
) & (msblk
->block_size
- 1)) :
472 TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
473 page
->index
, squashfs_i(inode
)->start
);
475 if (page
->index
>= ((i_size_read(inode
) + PAGE_SIZE
- 1) >>
479 if (index
< file_end
|| squashfs_i(inode
)->fragment_block
==
480 SQUASHFS_INVALID_BLK
) {
482 int bsize
= read_blocklist(inode
, index
, &block
);
487 res
= squashfs_readpage_sparse(page
, expected
);
489 res
= squashfs_readpage_block(page
, block
, bsize
, expected
);
491 res
= squashfs_readpage_fragment(page
, expected
);
499 pageaddr
= kmap_atomic(page
);
500 memset(pageaddr
, 0, PAGE_SIZE
);
501 kunmap_atomic(pageaddr
);
502 flush_dcache_page(page
);
503 if (!PageError(page
))
504 SetPageUptodate(page
);
511 const struct address_space_operations squashfs_aops
= {
512 .readpage
= squashfs_readpage