mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 15:19:51 +00:00
btrfs: reflink: make copy_inline_to_page() to be subpage compatible
The modifications are: - Page copy destination For subpage case, one page can contain multiple sectors, thus we can no longer expect the memcpy_to_page()/btrfs_decompress() to copy data into page offset 0. The correct offset is offset_in_page(file_offset) now, which should handle both regular sectorsize and subpage cases well. - Page status update Now we need to use subpage helper to handle the page status update. Tested-by: Ritesh Harjani <riteshh@linux.ibm.com> # [ppc64] Tested-by: Anand Jain <anand.jain@oracle.com> # [aarch64] 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
2d8ec40ee4
commit
3115deb381
@ -7,6 +7,7 @@
|
|||||||
#include "delalloc-space.h"
|
#include "delalloc-space.h"
|
||||||
#include "reflink.h"
|
#include "reflink.h"
|
||||||
#include "transaction.h"
|
#include "transaction.h"
|
||||||
|
#include "subpage.h"
|
||||||
|
|
||||||
#define BTRFS_MAX_DEDUPE_LEN SZ_16M
|
#define BTRFS_MAX_DEDUPE_LEN SZ_16M
|
||||||
|
|
||||||
@ -52,7 +53,8 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
|
|||||||
const u64 datal,
|
const u64 datal,
|
||||||
const u8 comp_type)
|
const u8 comp_type)
|
||||||
{
|
{
|
||||||
const u64 block_size = btrfs_inode_sectorsize(inode);
|
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||||
|
const u32 block_size = fs_info->sectorsize;
|
||||||
const u64 range_end = file_offset + block_size - 1;
|
const u64 range_end = file_offset + block_size - 1;
|
||||||
const size_t inline_size = size - btrfs_file_extent_calc_inline_size(0);
|
const size_t inline_size = size - btrfs_file_extent_calc_inline_size(0);
|
||||||
char *data_start = inline_data + btrfs_file_extent_calc_inline_size(0);
|
char *data_start = inline_data + btrfs_file_extent_calc_inline_size(0);
|
||||||
@ -106,10 +108,12 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
|
|||||||
set_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &inode->runtime_flags);
|
set_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &inode->runtime_flags);
|
||||||
|
|
||||||
if (comp_type == BTRFS_COMPRESS_NONE) {
|
if (comp_type == BTRFS_COMPRESS_NONE) {
|
||||||
memcpy_to_page(page, 0, data_start, datal);
|
memcpy_to_page(page, offset_in_page(file_offset), data_start,
|
||||||
|
datal);
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
} else {
|
} else {
|
||||||
ret = btrfs_decompress(comp_type, data_start, page, 0,
|
ret = btrfs_decompress(comp_type, data_start, page,
|
||||||
|
offset_in_page(file_offset),
|
||||||
inline_size, datal);
|
inline_size, datal);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@ -133,9 +137,9 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
|
|||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPageUptodate(page);
|
btrfs_page_set_uptodate(fs_info, page, file_offset, block_size);
|
||||||
ClearPageChecked(page);
|
ClearPageChecked(page);
|
||||||
set_page_dirty(page);
|
btrfs_page_set_dirty(fs_info, page, file_offset, block_size);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
if (page) {
|
if (page) {
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user