mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
btrfs: lzo: use folio_iter to handle lzo_decompress_bio()
Currently lzo_decompress_bio() is using compressed_bio->compressed_folios[] array to grab each compressed folio. This is making the code much easier to read, as we only need to maintain a single iterator, @cur_in, and can easily grab any random folio using @cur_in >> min_folio_shift as an index. However lzo_decompress_bio() itself is ensured to only advance to the next folio at one time, and compressed_folios[] is just a pointer to each folio of the compressed bio, thus we have no real random access requirement for lzo_decompress_bio(). Replace the compressed_folios[] access by a helper, get_current_folio(), which uses folio_iter and an external folio counter to properly switch the folio when needed. 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
4b7ecd0984
commit
37cc07cab7
|
|
@ -310,23 +310,43 @@ int lzo_compress_folios(struct list_head *ws, struct btrfs_inode *inode,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct folio *get_current_folio(struct compressed_bio *cb, struct folio_iter *fi,
|
||||||
|
u32 *cur_folio_index, 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;
|
||||||
|
|
||||||
|
ASSERT(cur_folio_index);
|
||||||
|
|
||||||
|
/* Need to switch to the next folio. */
|
||||||
|
if (cur_in >> min_folio_shift != *cur_folio_index) {
|
||||||
|
/* We can only do the switch one folio a time. */
|
||||||
|
ASSERT(cur_in >> min_folio_shift == *cur_folio_index + 1);
|
||||||
|
|
||||||
|
bio_next_folio(fi, &cb->bbio.bio);
|
||||||
|
(*cur_folio_index)++;
|
||||||
|
}
|
||||||
|
return fi->folio;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the compressed segment payload into @dest.
|
* Copy the compressed segment payload into @dest.
|
||||||
*
|
*
|
||||||
* For the payload there will be no padding, just need to do page switching.
|
* For the payload there will be no padding, just need to do page switching.
|
||||||
*/
|
*/
|
||||||
static void copy_compressed_segment(struct compressed_bio *cb,
|
static void copy_compressed_segment(struct compressed_bio *cb,
|
||||||
|
struct folio_iter *fi, u32 *cur_folio_index,
|
||||||
char *dest, u32 len, u32 *cur_in)
|
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;
|
u32 orig_in = *cur_in;
|
||||||
|
|
||||||
while (*cur_in < orig_in + len) {
|
while (*cur_in < orig_in + len) {
|
||||||
struct folio *cur_folio = cb->compressed_folios[*cur_in >> min_folio_shift];
|
struct folio *cur_folio = get_current_folio(cb, fi, cur_folio_index, *cur_in);
|
||||||
u32 copy_len = min_t(u32, orig_in + len - *cur_in,
|
u32 copy_len;
|
||||||
folio_size(cur_folio) - offset_in_folio(cur_folio, *cur_in));
|
|
||||||
|
|
||||||
|
ASSERT(cur_folio);
|
||||||
|
copy_len = min_t(u32, orig_in + len - *cur_in,
|
||||||
|
folio_size(cur_folio) - offset_in_folio(cur_folio, *cur_in));
|
||||||
ASSERT(copy_len);
|
ASSERT(copy_len);
|
||||||
|
|
||||||
memcpy_from_folio(dest + *cur_in - orig_in, cur_folio,
|
memcpy_from_folio(dest + *cur_in - orig_in, cur_folio,
|
||||||
|
|
@ -341,7 +361,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
||||||
struct workspace *workspace = list_entry(ws, struct workspace, list);
|
struct workspace *workspace = list_entry(ws, struct workspace, list);
|
||||||
const struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;
|
const struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;
|
||||||
const u32 sectorsize = fs_info->sectorsize;
|
const u32 sectorsize = fs_info->sectorsize;
|
||||||
const u32 min_folio_shift = PAGE_SHIFT + fs_info->block_min_order;
|
struct folio_iter fi;
|
||||||
char *kaddr;
|
char *kaddr;
|
||||||
int ret;
|
int ret;
|
||||||
/* Compressed data length, can be unaligned */
|
/* Compressed data length, can be unaligned */
|
||||||
|
|
@ -350,8 +370,15 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
||||||
u32 cur_in = 0;
|
u32 cur_in = 0;
|
||||||
/* Bytes decompressed so far */
|
/* Bytes decompressed so far */
|
||||||
u32 cur_out = 0;
|
u32 cur_out = 0;
|
||||||
|
/* The current folio index number inside the bio. */
|
||||||
|
u32 cur_folio_index = 0;
|
||||||
|
|
||||||
kaddr = kmap_local_folio(cb->compressed_folios[0], 0);
|
bio_first_folio(&fi, &cb->bbio.bio, 0);
|
||||||
|
/* There must be a compressed folio and matches the sectorsize. */
|
||||||
|
if (unlikely(!fi.folio))
|
||||||
|
return -EINVAL;
|
||||||
|
ASSERT(folio_size(fi.folio) == sectorsize);
|
||||||
|
kaddr = kmap_local_folio(fi.folio, 0);
|
||||||
len_in = read_compress_length(kaddr);
|
len_in = read_compress_length(kaddr);
|
||||||
kunmap_local(kaddr);
|
kunmap_local(kaddr);
|
||||||
cur_in += LZO_LEN;
|
cur_in += LZO_LEN;
|
||||||
|
|
@ -388,7 +415,7 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
||||||
*/
|
*/
|
||||||
ASSERT(cur_in / sectorsize ==
|
ASSERT(cur_in / sectorsize ==
|
||||||
(cur_in + LZO_LEN - 1) / sectorsize);
|
(cur_in + LZO_LEN - 1) / sectorsize);
|
||||||
cur_folio = cb->compressed_folios[cur_in >> min_folio_shift];
|
cur_folio = get_current_folio(cb, &fi, &cur_folio_index, cur_in);
|
||||||
ASSERT(cur_folio);
|
ASSERT(cur_folio);
|
||||||
kaddr = kmap_local_folio(cur_folio, 0);
|
kaddr = kmap_local_folio(cur_folio, 0);
|
||||||
seg_len = read_compress_length(kaddr + offset_in_folio(cur_folio, cur_in));
|
seg_len = read_compress_length(kaddr + offset_in_folio(cur_folio, cur_in));
|
||||||
|
|
@ -410,7 +437,8 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the compressed segment payload into workspace */
|
/* Copy the compressed segment payload into workspace */
|
||||||
copy_compressed_segment(cb, workspace->cbuf, seg_len, &cur_in);
|
copy_compressed_segment(cb, &fi, &cur_folio_index, workspace->cbuf,
|
||||||
|
seg_len, &cur_in);
|
||||||
|
|
||||||
/* Decompress the data */
|
/* Decompress the data */
|
||||||
ret = lzo1x_decompress_safe(workspace->cbuf, seg_len,
|
ret = lzo1x_decompress_safe(workspace->cbuf, seg_len,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user