Btrfs: use flag EXTENT_DEFRAG for snapshot-aware defrag
We're going to use this flag EXTENT_DEFRAG to indicate which range belongs to defragment so that we can implement snapshow-aware defrag: We set the EXTENT_DEFRAG flag when dirtying the extents that need defragmented, so later on writeback thread can differentiate between normal writeback and writeback started by defragmentation. Original-Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
This commit is contained in:
parent
3d6b5c3b5c
commit
9e8a4a8b0b
@ -1144,6 +1144,14 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
NULL, cached_state, mask);
|
||||
}
|
||||
|
||||
int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
struct extent_state **cached_state, gfp_t mask)
|
||||
{
|
||||
return set_extent_bit(tree, start, end,
|
||||
EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
|
||||
NULL, cached_state, mask);
|
||||
}
|
||||
|
||||
int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
gfp_t mask)
|
||||
{
|
||||
|
@ -235,6 +235,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
int bits, int clear_bits, gfp_t mask);
|
||||
int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
struct extent_state **cached_state, gfp_t mask);
|
||||
int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
struct extent_state **cached_state, gfp_t mask);
|
||||
int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
|
||||
u64 *start_ret, u64 *end_ret, int bits);
|
||||
struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree,
|
||||
|
@ -1203,8 +1203,8 @@ again:
|
||||
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
|
||||
last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
|
||||
GFP_NOFS);
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
|
||||
0, 0, &cached_state, GFP_NOFS);
|
||||
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
|
||||
start_pos, last_pos - 1, &cached_state,
|
||||
GFP_NOFS);
|
||||
|
@ -3549,7 +3549,8 @@ again:
|
||||
}
|
||||
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
|
||||
EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
|
||||
EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
|
||||
0, 0, &cached_state, GFP_NOFS);
|
||||
|
||||
ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
|
||||
@ -6061,7 +6062,8 @@ unlock:
|
||||
if (lockstart < lockend) {
|
||||
if (create && len < lockend - lockstart) {
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
|
||||
lockstart + len - 1, unlock_bits, 1, 0,
|
||||
lockstart + len - 1,
|
||||
unlock_bits | EXTENT_DEFRAG, 1, 0,
|
||||
&cached_state, GFP_NOFS);
|
||||
/*
|
||||
* Beside unlock, we also need to cleanup reserved space
|
||||
@ -6069,8 +6071,8 @@ unlock:
|
||||
*/
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree,
|
||||
lockstart + len, lockend,
|
||||
unlock_bits | EXTENT_DO_ACCOUNTING,
|
||||
1, 0, NULL, GFP_NOFS);
|
||||
unlock_bits | EXTENT_DO_ACCOUNTING |
|
||||
EXTENT_DEFRAG, 1, 0, NULL, GFP_NOFS);
|
||||
} else {
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
|
||||
lockend, unlock_bits, 1, 0,
|
||||
@ -6635,8 +6637,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
|
||||
*/
|
||||
clear_extent_bit(tree, page_start, page_end,
|
||||
EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
|
||||
&cached_state, GFP_NOFS);
|
||||
EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
|
||||
EXTENT_DEFRAG, 1, 0, &cached_state, GFP_NOFS);
|
||||
/*
|
||||
* whoever cleared the private bit is responsible
|
||||
* for the finish_ordered_io
|
||||
@ -6652,7 +6654,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
|
||||
}
|
||||
clear_extent_bit(tree, page_start, page_end,
|
||||
EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 1,
|
||||
&cached_state, GFP_NOFS);
|
||||
__btrfs_releasepage(page, GFP_NOFS);
|
||||
|
||||
ClearPageChecked(page);
|
||||
@ -6749,7 +6752,8 @@ again:
|
||||
* prepare_pages in the normal write path.
|
||||
*/
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
|
||||
EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
|
||||
EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
|
||||
0, 0, &cached_state, GFP_NOFS);
|
||||
|
||||
ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
|
||||
|
@ -1023,8 +1023,8 @@ again:
|
||||
page_start, page_end - 1, 0, &cached_state);
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
|
||||
page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
|
||||
GFP_NOFS);
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
|
||||
&cached_state, GFP_NOFS);
|
||||
|
||||
if (i_done != page_cnt) {
|
||||
spin_lock(&BTRFS_I(inode)->lock);
|
||||
@ -1035,8 +1035,8 @@ again:
|
||||
}
|
||||
|
||||
|
||||
btrfs_set_extent_delalloc(inode, page_start, page_end - 1,
|
||||
&cached_state);
|
||||
set_extent_defrag(&BTRFS_I(inode)->io_tree, page_start, page_end - 1,
|
||||
&cached_state, GFP_NOFS);
|
||||
|
||||
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
|
||||
page_start, page_end - 1, &cached_state,
|
||||
|
Loading…
Reference in New Issue
Block a user