e994f5b677
Before commit 93e72b3c61
("squashfs: migrate from ll_rw_block
usage to BIO"), compressed blocks read by squashfs were cached in the page
cache, but that is not the case after that commit. That has lead to
squashfs having to re-read a lot of sectors from disk/flash.
For example, the first sectors of every metadata block need to be read
twice from the disk. Once partially to read the length, and a second time
to read the block itself. Also, in linear reads of large files, the last
sectors of one data block are re-read from disk when reading the next data
block, since the compressed blocks are of variable sizes and not aligned
to device blocks. This extra I/O results in a degrade in read performance
of, for example, ~16% in one scenario on my ARM platform using squashfs
with dm-verity and NAND.
Since the decompressed data is cached in the page cache or squashfs'
internal metadata and fragment caches, caching _all_ compressed pages
would lead to a lot of double caching and is undesirable. But make the
code cache any disk blocks which were only partially requested, since
these are the ones likely to include data which is needed by other file
system blocks. This restores read performance in my test scenario.
The compressed block caching is only applied when the disk block size is
equal to the page size, to avoid having to deal with caching sub-page
reads.
[akpm@linux-foundation.org: fs/squashfs/block.c needs linux/pagemap.h]
[vincent.whitchurch@axis.com: fix page update race]
Link: https://lkml.kernel.org/r/20230526-squashfs-cache-fixup-v1-1-d54a7fa23e7b@axis.com
[vincent.whitchurch@axis.com: fix page indices]
Link: https://lkml.kernel.org/r/20230526-squashfs-cache-fixup-v1-2-d54a7fa23e7b@axis.com
[akpm@linux-foundation.org: fix layout, per hch]
Link: https://lkml.kernel.org/r/20230510-squashfs-cache-v4-1-3bd394e1ee71@axis.com
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Phillip Lougher <phillip@squashfs.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
74 lines
1.6 KiB
C
74 lines
1.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
#ifndef SQUASHFS_FS_SB
|
|
#define SQUASHFS_FS_SB
|
|
/*
|
|
* Squashfs
|
|
*
|
|
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
|
* Phillip Lougher <phillip@squashfs.org.uk>
|
|
*
|
|
* squashfs_fs_sb.h
|
|
*/
|
|
|
|
#include "squashfs_fs.h"
|
|
|
|
struct squashfs_cache {
|
|
char *name;
|
|
int entries;
|
|
int curr_blk;
|
|
int next_blk;
|
|
int num_waiters;
|
|
int unused;
|
|
int block_size;
|
|
int pages;
|
|
spinlock_t lock;
|
|
wait_queue_head_t wait_queue;
|
|
struct squashfs_cache_entry *entry;
|
|
};
|
|
|
|
struct squashfs_cache_entry {
|
|
u64 block;
|
|
int length;
|
|
int refcount;
|
|
u64 next_index;
|
|
int pending;
|
|
int error;
|
|
int num_waiters;
|
|
wait_queue_head_t wait_queue;
|
|
struct squashfs_cache *cache;
|
|
void **data;
|
|
struct squashfs_page_actor *actor;
|
|
};
|
|
|
|
struct squashfs_sb_info {
|
|
const struct squashfs_decompressor *decompressor;
|
|
int devblksize;
|
|
int devblksize_log2;
|
|
struct squashfs_cache *block_cache;
|
|
struct squashfs_cache *fragment_cache;
|
|
struct squashfs_cache *read_page;
|
|
struct address_space *cache_mapping;
|
|
int next_meta_index;
|
|
__le64 *id_table;
|
|
__le64 *fragment_index;
|
|
__le64 *xattr_id_table;
|
|
struct mutex meta_index_mutex;
|
|
struct meta_index *meta_index;
|
|
void *stream;
|
|
__le64 *inode_lookup_table;
|
|
u64 inode_table;
|
|
u64 directory_table;
|
|
u64 xattr_table;
|
|
unsigned int block_size;
|
|
unsigned short block_log;
|
|
long long bytes_used;
|
|
unsigned int inodes;
|
|
unsigned int fragments;
|
|
unsigned int xattr_ids;
|
|
unsigned int ids;
|
|
bool panic_on_errors;
|
|
const struct squashfs_decompressor_thread_ops *thread_ops;
|
|
int max_thread_num;
|
|
};
|
|
#endif
|