forked from Minki/linux
btrfs: defrag: replace hard coded PAGE_SIZE with sectorsize
When testing subpage defrag support, I always find some strange inode nbytes error, after a lot of debugging, it turns out that defrag_lookup_extent() is using PAGE_SIZE as size for lookup_extent_mapping(). Since lookup_extent_mapping() is calling __lookup_extent_mapping() with @strict == 1, this means any extent map smaller than one page will be ignored, prevent subpage defrag to grab a correct extent map. There are quite some PAGE_SIZE usage in ioctl.c, but most of them are correct usages, and can be one of the following cases: - ioctl structure size check We want ioctl structure to be contained inside one page. - real page operations The remaining cases in defrag_lookup_extent() and check_defrag_in_cache() will be addressed in this patch. 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
cae7968680
commit
76068cae63
@ -997,10 +997,11 @@ static int check_defrag_in_cache(struct inode *inode, u64 offset, u32 thresh)
|
||||
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
||||
struct extent_map *em = NULL;
|
||||
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
||||
const u32 sectorsize = btrfs_sb(inode->i_sb)->sectorsize;
|
||||
u64 end;
|
||||
|
||||
read_lock(&em_tree->lock);
|
||||
em = lookup_extent_mapping(em_tree, offset, PAGE_SIZE);
|
||||
em = lookup_extent_mapping(em_tree, offset, sectorsize);
|
||||
read_unlock(&em_tree->lock);
|
||||
|
||||
if (em) {
|
||||
@ -1090,23 +1091,23 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start)
|
||||
struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
|
||||
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
|
||||
struct extent_map *em;
|
||||
u64 len = PAGE_SIZE;
|
||||
const u32 sectorsize = BTRFS_I(inode)->root->fs_info->sectorsize;
|
||||
|
||||
/*
|
||||
* hopefully we have this extent in the tree already, try without
|
||||
* the full extent lock
|
||||
*/
|
||||
read_lock(&em_tree->lock);
|
||||
em = lookup_extent_mapping(em_tree, start, len);
|
||||
em = lookup_extent_mapping(em_tree, start, sectorsize);
|
||||
read_unlock(&em_tree->lock);
|
||||
|
||||
if (!em) {
|
||||
struct extent_state *cached = NULL;
|
||||
u64 end = start + len - 1;
|
||||
u64 end = start + sectorsize - 1;
|
||||
|
||||
/* get the big lock and read metadata off disk */
|
||||
lock_extent_bits(io_tree, start, end, &cached);
|
||||
em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, len);
|
||||
em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, start, sectorsize);
|
||||
unlock_extent_cached(io_tree, start, end, &cached);
|
||||
|
||||
if (IS_ERR(em))
|
||||
|
Loading…
Reference in New Issue
Block a user