mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 20:14:06 +02:00
btrfs: prepare compression paths for large data folios
All compression algorithms inside btrfs are not supporting large folios due to the following points: - btrfs_calc_input_length() is assuming page sized folio - kmap_local_folio() usages are using offset_in_page() Prepare them to support large data folios by: - Add a folio parameter to btrfs_calc_input_length() And use that folio parameter to calculate the correct length. Since we're here, also add extra ASSERT()s to make sure the parameter @cur is inside the folio range. This affects only zlib and zstd. Lzo compresses at most one block at a time, thus not affected. - Use offset_in_folio() to calculate the kmap_local_folio() offset This affects all 3 algorithms. Reviewed-by: Filipe Manana <fdmanana@suse.com> 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
9a36bad6c3
commit
7bf9bfa946
|
|
@ -11,7 +11,9 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include "bio.h"
|
||||
#include "messages.h"
|
||||
|
||||
struct address_space;
|
||||
struct page;
|
||||
|
|
@ -73,11 +75,14 @@ struct compressed_bio {
|
|||
};
|
||||
|
||||
/* @range_end must be exclusive. */
|
||||
static inline u32 btrfs_calc_input_length(u64 range_end, u64 cur)
|
||||
static inline u32 btrfs_calc_input_length(struct folio *folio, u64 range_end, u64 cur)
|
||||
{
|
||||
u64 page_end = round_down(cur, PAGE_SIZE) + PAGE_SIZE;
|
||||
const u64 folio_end = folio_pos(folio) + folio_size(folio);
|
||||
|
||||
return min(range_end, page_end) - cur;
|
||||
/* @cur must be inside the folio. */
|
||||
ASSERT(folio_pos(folio) <= cur);
|
||||
ASSERT(cur < folio_end);
|
||||
return min(range_end, folio_end) - cur;
|
||||
}
|
||||
|
||||
int __init btrfs_init_compress(void);
|
||||
|
|
|
|||
|
|
@ -252,9 +252,8 @@ int lzo_compress_folios(struct list_head *ws, struct address_space *mapping,
|
|||
/* Compress at most one sector of data each time */
|
||||
in_len = min_t(u32, start + len - cur_in, sectorsize - sector_off);
|
||||
ASSERT(in_len);
|
||||
data_in = kmap_local_folio(folio_in, 0);
|
||||
ret = lzo1x_1_compress(data_in +
|
||||
offset_in_page(cur_in), in_len,
|
||||
data_in = kmap_local_folio(folio_in, offset_in_folio(folio_in, cur_in));
|
||||
ret = lzo1x_1_compress(data_in, in_len,
|
||||
workspace->cbuf, &out_len,
|
||||
workspace->mem);
|
||||
kunmap_local(data_in);
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
|
|||
workspace->strm.next_in = workspace->buf;
|
||||
workspace->strm.avail_in = copy_length;
|
||||
} else {
|
||||
unsigned int pg_off;
|
||||
unsigned int cur_len;
|
||||
|
||||
if (data_in) {
|
||||
|
|
@ -215,9 +214,9 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
|
|||
start, &in_folio);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
pg_off = offset_in_page(start);
|
||||
cur_len = btrfs_calc_input_length(orig_end, start);
|
||||
data_in = kmap_local_folio(in_folio, pg_off);
|
||||
cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
|
||||
data_in = kmap_local_folio(in_folio,
|
||||
offset_in_folio(in_folio, start));
|
||||
start += cur_len;
|
||||
workspace->strm.next_in = data_in;
|
||||
workspace->strm.avail_in = cur_len;
|
||||
|
|
|
|||
|
|
@ -426,8 +426,8 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
|
|||
ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
cur_len = btrfs_calc_input_length(orig_end, start);
|
||||
workspace->in_buf.src = kmap_local_folio(in_folio, offset_in_page(start));
|
||||
cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
|
||||
workspace->in_buf.src = kmap_local_folio(in_folio, offset_in_folio(in_folio, start));
|
||||
workspace->in_buf.pos = 0;
|
||||
workspace->in_buf.size = cur_len;
|
||||
|
||||
|
|
@ -511,9 +511,9 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
|
|||
ret = btrfs_compress_filemap_get_folio(mapping, start, &in_folio);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
cur_len = btrfs_calc_input_length(orig_end, start);
|
||||
cur_len = btrfs_calc_input_length(in_folio, orig_end, start);
|
||||
workspace->in_buf.src = kmap_local_folio(in_folio,
|
||||
offset_in_page(start));
|
||||
offset_in_folio(in_folio, start));
|
||||
workspace->in_buf.pos = 0;
|
||||
workspace->in_buf.size = cur_len;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user