file.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Squashfs - a compressed read only filesystem for Linux
  4. *
  5. * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
  6. * Phillip Lougher <phillip@squashfs.org.uk>
  7. *
  8. * file.c
  9. */
  10. /*
  11. * This file contains code for handling regular files. A regular file
  12. * consists of a sequence of contiguous compressed blocks, and/or a
  13. * compressed fragment block (tail-end packed block). The compressed size
  14. * of each datablock is stored in a block list contained within the
  15. * file inode (itself stored in one or more compressed metadata blocks).
  16. *
  17. * To speed up access to datablocks when reading 'large' files (256 Mbytes or
  18. * larger), the code implements an index cache that caches the mapping from
  19. * block index to datablock location on disk.
  20. *
  21. * The index cache allows Squashfs to handle large files (up to 1.75 TiB) while
  22. * retaining a simple and space-efficient block list on disk. The cache
  23. * is split into slots, caching up to eight 224 GiB files (128 KiB blocks).
  24. * Larger files use multiple slots, with 1.75 TiB files using all 8 slots.
  25. * The index cache is designed to be memory efficient, and by default uses
  26. * 16 KiB.
  27. */
  28. #include <linux/fs.h>
  29. #include <linux/vfs.h>
  30. #include <linux/kernel.h>
  31. #include <linux/slab.h>
  32. #include <linux/string.h>
  33. #include <linux/pagemap.h>
  34. #include <linux/mutex.h>
  35. #include "squashfs_fs.h"
  36. #include "squashfs_fs_sb.h"
  37. #include "squashfs_fs_i.h"
  38. #include "squashfs.h"
  39. #include "page_actor.h"
  40. /*
  41. * Locate cache slot in range [offset, index] for specified inode. If
  42. * there's more than one return the slot closest to index.
  43. */
  44. static struct meta_index *locate_meta_index(struct inode *inode, int offset,
  45. int index)
  46. {
  47. struct meta_index *meta = NULL;
  48. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  49. int i;
  50. mutex_lock(&msblk->meta_index_mutex);
  51. TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
  52. if (msblk->meta_index == NULL)
  53. goto not_allocated;
  54. for (i = 0; i < SQUASHFS_META_SLOTS; i++) {
  55. if (msblk->meta_index[i].inode_number == inode->i_ino &&
  56. msblk->meta_index[i].offset >= offset &&
  57. msblk->meta_index[i].offset <= index &&
  58. msblk->meta_index[i].locked == 0) {
  59. TRACE("locate_meta_index: entry %d, offset %d\n", i,
  60. msblk->meta_index[i].offset);
  61. meta = &msblk->meta_index[i];
  62. offset = meta->offset;
  63. }
  64. }
  65. if (meta)
  66. meta->locked = 1;
  67. not_allocated:
  68. mutex_unlock(&msblk->meta_index_mutex);
  69. return meta;
  70. }
  71. /*
  72. * Find and initialise an empty cache slot for index offset.
  73. */
  74. static struct meta_index *empty_meta_index(struct inode *inode, int offset,
  75. int skip)
  76. {
  77. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  78. struct meta_index *meta = NULL;
  79. int i;
  80. mutex_lock(&msblk->meta_index_mutex);
  81. TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
  82. if (msblk->meta_index == NULL) {
  83. /*
  84. * First time cache index has been used, allocate and
  85. * initialise. The cache index could be allocated at
  86. * mount time but doing it here means it is allocated only
  87. * if a 'large' file is read.
  88. */
  89. msblk->meta_index = kcalloc(SQUASHFS_META_SLOTS,
  90. sizeof(*(msblk->meta_index)), GFP_KERNEL);
  91. if (msblk->meta_index == NULL) {
  92. ERROR("Failed to allocate meta_index\n");
  93. goto failed;
  94. }
  95. for (i = 0; i < SQUASHFS_META_SLOTS; i++) {
  96. msblk->meta_index[i].inode_number = 0;
  97. msblk->meta_index[i].locked = 0;
  98. }
  99. msblk->next_meta_index = 0;
  100. }
  101. for (i = SQUASHFS_META_SLOTS; i &&
  102. msblk->meta_index[msblk->next_meta_index].locked; i--)
  103. msblk->next_meta_index = (msblk->next_meta_index + 1) %
  104. SQUASHFS_META_SLOTS;
  105. if (i == 0) {
  106. TRACE("empty_meta_index: failed!\n");
  107. goto failed;
  108. }
  109. TRACE("empty_meta_index: returned meta entry %d, %p\n",
  110. msblk->next_meta_index,
  111. &msblk->meta_index[msblk->next_meta_index]);
  112. meta = &msblk->meta_index[msblk->next_meta_index];
  113. msblk->next_meta_index = (msblk->next_meta_index + 1) %
  114. SQUASHFS_META_SLOTS;
  115. meta->inode_number = inode->i_ino;
  116. meta->offset = offset;
  117. meta->skip = skip;
  118. meta->entries = 0;
  119. meta->locked = 1;
  120. failed:
  121. mutex_unlock(&msblk->meta_index_mutex);
  122. return meta;
  123. }
  124. static void release_meta_index(struct inode *inode, struct meta_index *meta)
  125. {
  126. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  127. mutex_lock(&msblk->meta_index_mutex);
  128. meta->locked = 0;
  129. mutex_unlock(&msblk->meta_index_mutex);
  130. }
  131. /*
  132. * Read the next n blocks from the block list, starting from
  133. * metadata block <start_block, offset>.
  134. */
  135. static long long read_indexes(struct super_block *sb, int n,
  136. u64 *start_block, int *offset)
  137. {
  138. int err, i;
  139. long long block = 0;
  140. __le32 *blist = kmalloc(PAGE_SIZE, GFP_KERNEL);
  141. if (blist == NULL) {
  142. ERROR("read_indexes: Failed to allocate block_list\n");
  143. return -ENOMEM;
  144. }
  145. while (n) {
  146. int blocks = min_t(int, n, PAGE_SIZE >> 2);
  147. err = squashfs_read_metadata(sb, blist, start_block,
  148. offset, blocks << 2);
  149. if (err < 0) {
  150. ERROR("read_indexes: reading block [%llx:%x]\n",
  151. *start_block, *offset);
  152. goto failure;
  153. }
  154. for (i = 0; i < blocks; i++) {
  155. int size = squashfs_block_size(blist[i]);
  156. if (size < 0) {
  157. err = size;
  158. goto failure;
  159. }
  160. block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
  161. }
  162. n -= blocks;
  163. }
  164. kfree(blist);
  165. return block;
  166. failure:
  167. kfree(blist);
  168. return err;
  169. }
  170. /*
  171. * Each cache index slot has SQUASHFS_META_ENTRIES, each of which
  172. * can cache one index -> datablock/blocklist-block mapping. We wish
  173. * to distribute these over the length of the file, entry[0] maps index x,
  174. * entry[1] maps index x + skip, entry[2] maps index x + 2 * skip, and so on.
  175. * The larger the file, the greater the skip factor. The skip factor is
  176. * limited to the size of the metadata cache (SQUASHFS_CACHED_BLKS) to ensure
  177. * the number of metadata blocks that need to be read fits into the cache.
  178. * If the skip factor is limited in this way then the file will use multiple
  179. * slots.
  180. */
  181. static inline int calculate_skip(u64 blocks)
  182. {
  183. u64 skip = blocks / ((SQUASHFS_META_ENTRIES + 1)
  184. * SQUASHFS_META_INDEXES);
  185. return min((u64) SQUASHFS_CACHED_BLKS - 1, skip + 1);
  186. }
  187. /*
  188. * Search and grow the index cache for the specified inode, returning the
  189. * on-disk locations of the datablock and block list metadata block
  190. * <index_block, index_offset> for index (scaled to nearest cache index).
  191. */
  192. static int fill_meta_index(struct inode *inode, int index,
  193. u64 *index_block, int *index_offset, u64 *data_block)
  194. {
  195. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  196. int skip = calculate_skip(i_size_read(inode) >> msblk->block_log);
  197. int offset = 0;
  198. struct meta_index *meta;
  199. struct meta_entry *meta_entry;
  200. u64 cur_index_block = squashfs_i(inode)->block_list_start;
  201. int cur_offset = squashfs_i(inode)->offset;
  202. u64 cur_data_block = squashfs_i(inode)->start;
  203. int err, i;
  204. /*
  205. * Scale index to cache index (cache slot entry)
  206. */
  207. index /= SQUASHFS_META_INDEXES * skip;
  208. while (offset < index) {
  209. meta = locate_meta_index(inode, offset + 1, index);
  210. if (meta == NULL) {
  211. meta = empty_meta_index(inode, offset + 1, skip);
  212. if (meta == NULL)
  213. goto all_done;
  214. } else {
  215. offset = index < meta->offset + meta->entries ? index :
  216. meta->offset + meta->entries - 1;
  217. meta_entry = &meta->meta_entry[offset - meta->offset];
  218. cur_index_block = meta_entry->index_block +
  219. msblk->inode_table;
  220. cur_offset = meta_entry->offset;
  221. cur_data_block = meta_entry->data_block;
  222. TRACE("get_meta_index: offset %d, meta->offset %d, "
  223. "meta->entries %d\n", offset, meta->offset,
  224. meta->entries);
  225. TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
  226. " data_block 0x%llx\n", cur_index_block,
  227. cur_offset, cur_data_block);
  228. }
  229. /*
  230. * If necessary grow cache slot by reading block list. Cache
  231. * slot is extended up to index or to the end of the slot, in
  232. * which case further slots will be used.
  233. */
  234. for (i = meta->offset + meta->entries; i <= index &&
  235. i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
  236. int blocks = skip * SQUASHFS_META_INDEXES;
  237. long long res = read_indexes(inode->i_sb, blocks,
  238. &cur_index_block, &cur_offset);
  239. if (res < 0) {
  240. if (meta->entries == 0)
  241. /*
  242. * Don't leave an empty slot on read
  243. * error allocated to this inode...
  244. */
  245. meta->inode_number = 0;
  246. err = res;
  247. goto failed;
  248. }
  249. cur_data_block += res;
  250. meta_entry = &meta->meta_entry[i - meta->offset];
  251. meta_entry->index_block = cur_index_block -
  252. msblk->inode_table;
  253. meta_entry->offset = cur_offset;
  254. meta_entry->data_block = cur_data_block;
  255. meta->entries++;
  256. offset++;
  257. }
  258. TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
  259. meta->offset, meta->entries);
  260. release_meta_index(inode, meta);
  261. }
  262. all_done:
  263. *index_block = cur_index_block;
  264. *index_offset = cur_offset;
  265. *data_block = cur_data_block;
  266. /*
  267. * Scale cache index (cache slot entry) to index
  268. */
  269. return offset * SQUASHFS_META_INDEXES * skip;
  270. failed:
  271. release_meta_index(inode, meta);
  272. return err;
  273. }
  274. /*
  275. * Get the on-disk location and compressed size of the datablock
  276. * specified by index. Fill_meta_index() does most of the work.
  277. */
  278. static int read_blocklist(struct inode *inode, int index, u64 *block)
  279. {
  280. u64 start;
  281. long long blks;
  282. int offset;
  283. __le32 size;
  284. int res = fill_meta_index(inode, index, &start, &offset, block);
  285. TRACE("read_blocklist: res %d, index %d, start 0x%llx, offset"
  286. " 0x%x, block 0x%llx\n", res, index, start, offset,
  287. *block);
  288. if (res < 0)
  289. return res;
  290. /*
  291. * res contains the index of the mapping returned by fill_meta_index(),
  292. * this will likely be less than the desired index (because the
  293. * meta_index cache works at a higher granularity). Read any
  294. * extra block indexes needed.
  295. */
  296. if (res < index) {
  297. blks = read_indexes(inode->i_sb, index - res, &start, &offset);
  298. if (blks < 0)
  299. return (int) blks;
  300. *block += blks;
  301. }
  302. /*
  303. * Read length of block specified by index.
  304. */
  305. res = squashfs_read_metadata(inode->i_sb, &size, &start, &offset,
  306. sizeof(size));
  307. if (res < 0)
  308. return res;
  309. return squashfs_block_size(size);
  310. }
  311. void squashfs_fill_page(struct page *page, struct squashfs_cache_entry *buffer, int offset, int avail)
  312. {
  313. int copied;
  314. void *pageaddr;
  315. pageaddr = kmap_atomic(page);
  316. copied = squashfs_copy_data(pageaddr, buffer, offset, avail);
  317. memset(pageaddr + copied, 0, PAGE_SIZE - copied);
  318. kunmap_atomic(pageaddr);
  319. flush_dcache_page(page);
  320. if (copied == avail)
  321. SetPageUptodate(page);
  322. }
  323. /* Copy data into page cache */
  324. void squashfs_copy_cache(struct page *page, struct squashfs_cache_entry *buffer,
  325. int bytes, int offset)
  326. {
  327. struct inode *inode = page->mapping->host;
  328. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  329. int i, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
  330. int start_index = page->index & ~mask, end_index = start_index | mask;
  331. /*
  332. * Loop copying datablock into pages. As the datablock likely covers
  333. * many PAGE_SIZE pages (default block size is 128 KiB) explicitly
  334. * grab the pages from the page cache, except for the page that we've
  335. * been called to fill.
  336. */
  337. for (i = start_index; i <= end_index && bytes > 0; i++,
  338. bytes -= PAGE_SIZE, offset += PAGE_SIZE) {
  339. struct page *push_page;
  340. int avail = buffer ? min_t(int, bytes, PAGE_SIZE) : 0;
  341. TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail);
  342. push_page = (i == page->index) ? page :
  343. grab_cache_page_nowait(page->mapping, i);
  344. if (!push_page)
  345. continue;
  346. if (PageUptodate(push_page))
  347. goto skip_page;
  348. squashfs_fill_page(push_page, buffer, offset, avail);
  349. skip_page:
  350. unlock_page(push_page);
  351. if (i != page->index)
  352. put_page(push_page);
  353. }
  354. }
  355. /* Read datablock stored packed inside a fragment (tail-end packed block) */
  356. static int squashfs_readpage_fragment(struct page *page, int expected)
  357. {
  358. struct inode *inode = page->mapping->host;
  359. struct squashfs_cache_entry *buffer = squashfs_get_fragment(inode->i_sb,
  360. squashfs_i(inode)->fragment_block,
  361. squashfs_i(inode)->fragment_size);
  362. int res = buffer->error;
  363. if (res)
  364. ERROR("Unable to read page, block %llx, size %x\n",
  365. squashfs_i(inode)->fragment_block,
  366. squashfs_i(inode)->fragment_size);
  367. else
  368. squashfs_copy_cache(page, buffer, expected,
  369. squashfs_i(inode)->fragment_offset);
  370. squashfs_cache_put(buffer);
  371. return res;
  372. }
  373. static int squashfs_readpage_sparse(struct page *page, int expected)
  374. {
  375. squashfs_copy_cache(page, NULL, expected, 0);
  376. return 0;
  377. }
  378. static int squashfs_read_folio(struct file *file, struct folio *folio)
  379. {
  380. struct page *page = &folio->page;
  381. struct inode *inode = page->mapping->host;
  382. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  383. int index = page->index >> (msblk->block_log - PAGE_SHIFT);
  384. int file_end = i_size_read(inode) >> msblk->block_log;
  385. int expected = index == file_end ?
  386. (i_size_read(inode) & (msblk->block_size - 1)) :
  387. msblk->block_size;
  388. int res = 0;
  389. void *pageaddr;
  390. TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
  391. page->index, squashfs_i(inode)->start);
  392. if (page->index >= ((i_size_read(inode) + PAGE_SIZE - 1) >>
  393. PAGE_SHIFT))
  394. goto out;
  395. if (index < file_end || squashfs_i(inode)->fragment_block ==
  396. SQUASHFS_INVALID_BLK) {
  397. u64 block = 0;
  398. res = read_blocklist(inode, index, &block);
  399. if (res < 0)
  400. goto out;
  401. if (res == 0)
  402. res = squashfs_readpage_sparse(page, expected);
  403. else
  404. res = squashfs_readpage_block(page, block, res, expected);
  405. } else
  406. res = squashfs_readpage_fragment(page, expected);
  407. if (!res)
  408. return 0;
  409. out:
  410. pageaddr = kmap_atomic(page);
  411. memset(pageaddr, 0, PAGE_SIZE);
  412. kunmap_atomic(pageaddr);
  413. flush_dcache_page(page);
  414. if (res == 0)
  415. SetPageUptodate(page);
  416. unlock_page(page);
  417. return res;
  418. }
  419. static int squashfs_readahead_fragment(struct page **page,
  420. unsigned int pages, unsigned int expected, loff_t start)
  421. {
  422. struct inode *inode = page[0]->mapping->host;
  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. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  427. int i, bytes, copied;
  428. struct squashfs_page_actor *actor;
  429. unsigned int offset;
  430. void *addr;
  431. struct page *last_page;
  432. if (buffer->error)
  433. goto out;
  434. actor = squashfs_page_actor_init_special(msblk, page, pages,
  435. expected, start);
  436. if (!actor)
  437. goto out;
  438. squashfs_actor_nobuff(actor);
  439. addr = squashfs_first_page(actor);
  440. for (copied = offset = 0; offset < expected; offset += PAGE_SIZE) {
  441. int avail = min_t(int, expected - offset, PAGE_SIZE);
  442. if (!IS_ERR(addr)) {
  443. bytes = squashfs_copy_data(addr, buffer, offset +
  444. squashfs_i(inode)->fragment_offset, avail);
  445. if (bytes != avail)
  446. goto failed;
  447. }
  448. copied += avail;
  449. addr = squashfs_next_page(actor);
  450. }
  451. last_page = squashfs_page_actor_free(actor);
  452. if (copied == expected && !IS_ERR(last_page)) {
  453. /* Last page (if present) may have trailing bytes not filled */
  454. bytes = copied % PAGE_SIZE;
  455. if (bytes && last_page)
  456. memzero_page(last_page, bytes, PAGE_SIZE - bytes);
  457. for (i = 0; i < pages; i++) {
  458. flush_dcache_page(page[i]);
  459. SetPageUptodate(page[i]);
  460. }
  461. }
  462. for (i = 0; i < pages; i++) {
  463. unlock_page(page[i]);
  464. put_page(page[i]);
  465. }
  466. squashfs_cache_put(buffer);
  467. return 0;
  468. failed:
  469. squashfs_page_actor_free(actor);
  470. out:
  471. squashfs_cache_put(buffer);
  472. return 1;
  473. }
  474. static void squashfs_readahead(struct readahead_control *ractl)
  475. {
  476. struct inode *inode = ractl->mapping->host;
  477. struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
  478. size_t mask = (1UL << msblk->block_log) - 1;
  479. unsigned short shift = msblk->block_log - PAGE_SHIFT;
  480. loff_t start = readahead_pos(ractl) & ~mask;
  481. size_t len = readahead_length(ractl) + readahead_pos(ractl) - start;
  482. struct squashfs_page_actor *actor;
  483. unsigned int nr_pages = 0;
  484. struct page **pages;
  485. int i;
  486. loff_t file_end = i_size_read(inode) >> msblk->block_log;
  487. unsigned int max_pages = 1UL << shift;
  488. readahead_expand(ractl, start, (len | mask) + 1);
  489. pages = kmalloc_array(max_pages, sizeof(void *), GFP_KERNEL);
  490. if (!pages)
  491. return;
  492. for (;;) {
  493. int res, bsize;
  494. u64 block = 0;
  495. unsigned int expected;
  496. struct page *last_page;
  497. expected = start >> msblk->block_log == file_end ?
  498. (i_size_read(inode) & (msblk->block_size - 1)) :
  499. msblk->block_size;
  500. max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT;
  501. nr_pages = __readahead_batch(ractl, pages, max_pages);
  502. if (!nr_pages)
  503. break;
  504. if (readahead_pos(ractl) >= i_size_read(inode))
  505. goto skip_pages;
  506. if (start >> msblk->block_log == file_end &&
  507. squashfs_i(inode)->fragment_block != SQUASHFS_INVALID_BLK) {
  508. res = squashfs_readahead_fragment(pages, nr_pages,
  509. expected, start);
  510. if (res)
  511. goto skip_pages;
  512. continue;
  513. }
  514. bsize = read_blocklist(inode, start >> msblk->block_log, &block);
  515. if (bsize == 0)
  516. goto skip_pages;
  517. actor = squashfs_page_actor_init_special(msblk, pages, nr_pages,
  518. expected, start);
  519. if (!actor)
  520. goto skip_pages;
  521. res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor);
  522. last_page = squashfs_page_actor_free(actor);
  523. if (res == expected && !IS_ERR(last_page)) {
  524. int bytes;
  525. /* Last page (if present) may have trailing bytes not filled */
  526. bytes = res % PAGE_SIZE;
  527. if (start >> msblk->block_log == file_end && bytes && last_page)
  528. memzero_page(last_page, bytes,
  529. PAGE_SIZE - bytes);
  530. for (i = 0; i < nr_pages; i++) {
  531. flush_dcache_page(pages[i]);
  532. SetPageUptodate(pages[i]);
  533. }
  534. }
  535. for (i = 0; i < nr_pages; i++) {
  536. unlock_page(pages[i]);
  537. put_page(pages[i]);
  538. }
  539. start += readahead_batch_length(ractl);
  540. }
  541. kfree(pages);
  542. return;
  543. skip_pages:
  544. for (i = 0; i < nr_pages; i++) {
  545. unlock_page(pages[i]);
  546. put_page(pages[i]);
  547. }
  548. kfree(pages);
  549. }
  550. const struct address_space_operations squashfs_aops = {
  551. .read_folio = squashfs_read_folio,
  552. .readahead = squashfs_readahead
  553. };