mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 23:00:21 +00:00
e994f5b677
Before commit 93e72b3c612adcaca1 ("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
|