mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
btrfs: prepare lzo to support bs > ps cases
This involves converting the following functions to use correct folio sizes/shifts: - copy_compress_data_to_page() - lzo_compress_folios() - lzo_decompress_bio() Just like zstd, lzo has some extra incorrect usage of kmap_local_folio() that the offset is always 0. This will not handle HIGHMEM large folios correctly, but those cases are already rejected explicitly so it should not cause problems when bs > ps support is enabled. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
a6452b85b3
commit
4fd188a4fe
|
|
@ -140,12 +140,13 @@ static int copy_compressed_data_to_page(struct btrfs_fs_info *fs_info,
|
|||
u32 *cur_out)
|
||||
{
|
||||
const u32 sectorsize = fs_info->sectorsize;
|
||||
const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
|
||||
u32 sector_bytes_left;
|
||||
u32 orig_out;
|
||||
struct folio *cur_folio;
|
||||
char *kaddr;
|
||||
|
||||
if ((*cur_out / PAGE_SIZE) >= max_nr_folio)
|
||||
if ((*cur_out >> min_folio_shift) >= max_nr_folio)
|
||||
return -E2BIG;
|
||||
|
||||
/*
|
||||
|
|
@ -154,18 +155,17 @@ static int copy_compressed_data_to_page(struct btrfs_fs_info *fs_info,
|
|||
*/
|
||||
ASSERT((*cur_out / sectorsize) == (*cur_out + LZO_LEN - 1) / sectorsize);
|
||||
|
||||
cur_folio = out_folios[*cur_out / PAGE_SIZE];
|
||||
cur_folio = out_folios[*cur_out >> min_folio_shift];
|
||||
/* Allocate a new page */
|
||||
if (!cur_folio) {
|
||||
cur_folio = btrfs_alloc_compr_folio(fs_info);
|
||||
if (!cur_folio)
|
||||
return -ENOMEM;
|
||||
out_folios[*cur_out / PAGE_SIZE] = cur_folio;
|
||||
out_folios[*cur_out >> min_folio_shift] = cur_folio;
|
||||
}
|
||||
|
||||
kaddr = kmap_local_folio(cur_folio, 0);
|
||||
write_compress_length(kaddr + offset_in_page(*cur_out),
|
||||
compressed_size);
|
||||
kaddr = kmap_local_folio(cur_folio, offset_in_folio(cur_folio, *cur_out));
|
||||
write_compress_length(kaddr, compressed_size);
|
||||
*cur_out += LZO_LEN;
|
||||
|
||||
orig_out = *cur_out;
|
||||
|
|
@ -177,20 +177,20 @@ static int copy_compressed_data_to_page(struct btrfs_fs_info *fs_info,
|
|||
|
||||
kunmap_local(kaddr);
|
||||
|
||||
if ((*cur_out / PAGE_SIZE) >= max_nr_folio)
|
||||
if ((*cur_out >> min_folio_shift) >= max_nr_folio)
|
||||
return -E2BIG;
|
||||
|
||||
cur_folio = out_folios[*cur_out / PAGE_SIZE];
|
||||
cur_folio = out_folios[*cur_out >> min_folio_shift];
|
||||
/* Allocate a new page */
|
||||
if (!cur_folio) {
|
||||
cur_folio = btrfs_alloc_compr_folio(fs_info);
|
||||
if (!cur_folio)
|
||||
return -ENOMEM;
|
||||
out_folios[*cur_out / PAGE_SIZE] = cur_folio;
|
||||
out_folios[*cur_out >> min_folio_shift] = cur_folio;
|
||||
}
|
||||
kaddr = kmap_local_folio(cur_folio, 0);
|
||||
|
||||
memcpy(kaddr + offset_in_page(*cur_out),
|
||||
memcpy(kaddr + offset_in_folio(cur_folio, *cur_out),
|
||||
compressed_data + *cur_out - orig_out, copy_len);
|
||||
|
||||
*cur_out += copy_len;
|
||||
|
|
@ -221,6 +221,7 @@ int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
|
|||
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||
struct workspace *workspace = list_entry(ws, struct workspace, list);
|
||||
const u32 sectorsize = fs_info->sectorsize;
|
||||
const u32 min_folio_size = btrfs_min_folio_size(fs_info);
|
||||
struct address_space *mapping = inode->vfs_inode.i_mapping;
|
||||
struct folio *folio_in = NULL;
|
||||
char *sizes_ptr;
|
||||
|
|
@ -287,8 +288,8 @@ int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Check if we have reached page boundary */
|
||||
if (PAGE_ALIGNED(cur_in)) {
|
||||
/* Check if we have reached folio boundary. */
|
||||
if (IS_ALIGNED(cur_in, min_folio_size)) {
|
||||
folio_put(folio_in);
|
||||
folio_in = NULL;
|
||||
}
|
||||
|
|
@ -305,7 +306,7 @@ int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
|
|||
out:
|
||||
if (folio_in)
|
||||
folio_put(folio_in);
|
||||
*out_folios = DIV_ROUND_UP(cur_out, PAGE_SIZE);
|
||||
*out_folios = DIV_ROUND_UP(cur_out, min_folio_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -317,15 +318,16 @@ int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
|
|||
static void copy_compressed_segment(struct compressed_bio *cb,
|
||||
char *dest, u32 len, u32 *cur_in)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = cb_to_fs_info(cb);
|
||||
const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
|
||||
u32 orig_in = *cur_in;
|
||||
|
||||
while (*cur_in < orig_in + len) {
|
||||
struct folio *cur_folio;
|
||||
u32 copy_len = min_t(u32, PAGE_SIZE - offset_in_page(*cur_in),
|
||||
orig_in + len - *cur_in);
|
||||
struct folio *cur_folio = cb->compressed_folios[*cur_in >> min_folio_shift];
|
||||
u32 copy_len = min_t(u32, orig_in + len - *cur_in,
|
||||
folio_size(cur_folio) - offset_in_folio(cur_folio, *cur_in));
|
||||
|
||||
ASSERT(copy_len);
|
||||
cur_folio = cb->compressed_folios[*cur_in / PAGE_SIZE];
|
||||
|
||||
memcpy_from_folio(dest + *cur_in - orig_in, cur_folio,
|
||||
offset_in_folio(cur_folio, *cur_in), copy_len);
|
||||
|
|
@ -339,6 +341,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
|||
struct workspace *workspace = list_entry(ws, struct workspace, list);
|
||||
const struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;
|
||||
const u32 sectorsize = fs_info->sectorsize;
|
||||
const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
|
||||
char *kaddr;
|
||||
int ret;
|
||||
/* Compressed data length, can be unaligned */
|
||||
|
|
@ -385,10 +388,10 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
|||
*/
|
||||
ASSERT(cur_in / sectorsize ==
|
||||
(cur_in + LZO_LEN - 1) / sectorsize);
|
||||
cur_folio = cb->compressed_folios[cur_in / PAGE_SIZE];
|
||||
cur_folio = cb->compressed_folios[cur_in >> min_folio_shift];
|
||||
ASSERT(cur_folio);
|
||||
kaddr = kmap_local_folio(cur_folio, 0);
|
||||
seg_len = read_compress_length(kaddr + offset_in_page(cur_in));
|
||||
seg_len = read_compress_length(kaddr + offset_in_folio(cur_folio, cur_in));
|
||||
kunmap_local(kaddr);
|
||||
cur_in += LZO_LEN;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user