move victim files for the target file (-f mode)
Subsystems (2)
RFC PATCH 7/8 move victim files for the target file (-f mode)
ext4: online defrag-- Move victim files for the target file (-f mode)
From: Akira Fujita <[email protected]>
Move victim files to make sufficient space and reallocates the contiguous blocks for the target file.
Signed-off-by Akira Fujita <[email protected]>
Signed-off-by Takashi Sato <[email protected]>
--- fs/ext4/balloc.c | 10 +- fs/ext4/defrag.c | 427 +++++++++++++++++++++++++++++++++++++++++++++--- fs/ext4/ext4.h | 29 +++- fs/ext4/ext4_extents.h | 5 + fs/ext4/extents.c | 54 +++++-- fs/ext4/ioctl.c | 5 +- fs/ext4/mballoc.c | 5 + fs/ext4/mballoc.h | 1 + 8 files changed, 494 insertions(+), 42 deletions(-)
fs/ext4/balloc.c +5 -5
@@ -383,7 +383,7 @@ restart:* If the goal block is within the reservation window, return 1; * otherwise, return 0; */ -static int +int goal_in_my_reservation (struct ext4_reserve_window *rsv,ext4_grpblk_t grp_goal,ext4_group_t group,struct super_block *sb) {
@@ -488,7 +488,7 @@ void ext4_rsv_window_add(struct super_block *sb,* from the filesystem reservation window rb tree. Must be called with * rsv_lock hold. */ -static void rsv_window_remove (struct super_block *sb, +void rsv_window_remove (struct super_block *sb,struct ext4_reserve_window_node *rsv) { rsv->rsv_start =EXT4_RESERVE_WINDOW_NOT_ALLOCATED ;
@@ -503,7 +503,7 @@ static void rsv_window_remove(struct super_block *sb,* * returns 1 if the end block is EXT4_RESERVE_WINDOW_NOT_ALLOCATED. */ -static inline int rsv_is_empty (struct ext4_reserve_window *rsv) +inline int rsv_is_empty (struct ext4_reserve_window *rsv) {/* a valid reservation end block could not be 0 */ return rsv->_rsv_end ==EXT4_RESERVE_WINDOW_NOT_ALLOCATED ;
@@ -1239,7 +1239,7 @@ static int find_next_reservable_window(* @bitmap_bh: the block group block bitmap * */ -static int alloc_new_reservation (struct ext4_reserve_window_node *my_rsv, +int alloc_new_reservation (struct ext4_reserve_window_node *my_rsv,ext4_grpblk_t grp_goal,struct super_block *sb,ext4_group_t group,struct buffer_head *bitmap_bh) {
@@ -1383,7 +1383,7 @@ retry:* expand the reservation window size if necessary on a best-effort * basis before ext4_new_blocks() tries to allocate blocks, */ -static void try_to_extend_reservation (struct ext4_reserve_window_node *my_rsv, +void try_to_extend_reservation (struct ext4_reserve_window_node *my_rsv,struct super_block *sb,int size) {struct ext4_reserve_window_node *next_rsv;
fs/ext4/defrag.c +403 -24
651 lines not on this page · raw message
fs/ext4/ext4.h +28 -1
@@ -94,6 +94,11 @@ struct ext4_allocation_request {unsigned long len;/* flags. see above EXT4_MB_HINT_* */ unsigned long flags; +/* +* for ext4 online defrag: +* the block group which is excepted from allocation target +*/ +long long excepted_group; };/*
@@ -303,6 +308,9 @@ struct ext4_new_group_data {#define EXT4_IOC_GROUP_INFO _IOW('f', 11, struct ext4_group_data_info)#define EXT4_IOC_FREE_BLOCKS_INFO _IOW('f', 12, struct ext4_extents_info)#define EXT4_IOC_EXTENTS_INFO _IOW('f', 13, struct ext4_extents_info) +#define EXT4_IOC_RESERVE_BLOCK _IOW('f', 14, struct ext4_extents_info) +#define EXT4_IOC_MOVE_VICTIM _IOW('f', 15, struct ext4_extents_info) +#define EXT4_IOC_BLOCK_RELEASE _IO('f', 8)/* * ioctl commands in 32 bit emulation
@@ -331,8 +339,15 @@ struct ext4_new_group_data {* * DEFRAG_MAX_ENT: the maximum number of extents for exchanging between * kernel-space and user-space per an ioctl +* DEFRAG_FORCE_TRY: check whether we have free space fragmentation or not +* DEFRAG_FORCE_VICTIM: move victim extents to make sufficient space +* DEFRAG_FORCE_GATHER: move the target file into the free space made in the +* DEFRAG_FORCE_VICTIM phase */ #define DEFRAG_MAX_ENT 32 +#define DEFRAG_FORCE_TRY 1 +#define DEFRAG_FORCE_VICTIM 2 +#define DEFRAG_FORCE_GATHER 3struct ext4_extent_data {ext4_lblk_t block;/* start logical block number */
@@ -344,6 +359,8 @@ struct ext4_ext_defrag_data {ext4_lblk_t start_offset;/* start offset to defrag in blocks */ ext4_lblk_t defrag_size;/* size of defrag in blocks */ ext4_fsblk_t goal;/* block offset for allocation */ +int flag;/* free space mode flag */ +struct ext4_extent_data ext; };struct ext4_group_data_info {
@@ -1037,8 +1054,17 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,extern int ext4_should_retry_alloc (struct super_block *sb,int *retries);extern void ext4_init_block_alloc_info (struct inode *);extern void ext4_rsv_window_add (struct super_block *sb,struct ext4_reserve_window_node *rsv); +extern void try_to_extend_reservation (struct ext4_reserve_window_node *, +struct super_block *,int ); +extern int alloc_new_reservation (struct ext4_reserve_window_node *, +ext4_grpblk_t ,struct super_block *, +ext4_group_t ,struct buffer_head *);extern ext4_grpblk_t bitmap_search_next_usable_block (ext4_grpblk_t ,struct buffer_head *,ext4_grpblk_t ); +extern int rsv_is_empty (struct ext4_reserve_window *rsv); +extern int goal_in_my_reservation (struct ext4_reserve_window *rsv, +ext4_grpblk_t grp_goal,ext4_group_t group, +struct super_block *sb);/* dir.c */ extern int ext4_check_dir_entry(const char *, struct inode *,
@@ -1164,7 +1190,8 @@ extern void ext4_inode_table_set(struct super_block *sb,extern handle_t *ext4_ext_journal_restart (handle_t *handle,int needed);/* defrag.c */ extern int ext4_defrag (struct file *filp,ext4_lblk_t block_start, -ext4_lblk_t defrag_size,ext4_fsblk_t goal); +ext4_lblk_t defrag_size,ext4_fsblk_t goal, +int flag,struct ext4_extent_data *ext);extern int ext4_defrag_ioctl (struct inode *,struct file *,unsigned int ,unsigned long );
fs/ext4/ext4_extents.h +5 -0
@@ -233,5 +233,10 @@ extern void ext4_ext_drop_refs(struct ext4_ext_path *path);extern ext4_fsblk_t ext4_ext_find_goal (struct inode *inode,struct ext4_ext_path *path,ext4_lblk_t block); +extern int ext4_ext_insert_extent_defrag (handle_t *handle,struct inode *inode, +struct ext4_ext_path *path, +struct ext4_extent *newext,int defrag); +extern ext4_lblk_t ext4_ext_next_allocated_block (struct ext4_ext_path *path); +#endif /* _EXT4_EXTENTS */
fs/ext4/extents.c +43 -11
133 lines not on this page · raw message
fs/ext4/ioctl.c +4 -1
@@ -235,7 +235,10 @@ flags_err:case EXT4_IOC_DEFRAG :case EXT4_IOC_GROUP_INFO :case EXT4_IOC_FREE_BLOCKS_INFO : -case EXT4_IOC_EXTENTS_INFO : { +case EXT4_IOC_EXTENTS_INFO : +case EXT4_IOC_RESERVE_BLOCK : +case EXT4_IOC_MOVE_VICTIM : +case EXT4_IOC_BLOCK_RELEASE : {return ext4_defrag_ioctl (inode, filp, cmd, arg); }case EXT4_IOC_GROUP_ADD : {
fs/ext4/mballoc.c +5 -0
@@ -1750,6 +1750,10 @@ repeat:if (group ==EXT4_SB (sb)->s_groups_count) group =0 ; +if (ac->ac_excepted_group !=-1 && + group == ac->ac_excepted_group) +continue ; +/* quick check to skip empty groups */ grp =ext4_get_group_info (ac->ac_sb, group);if (grp->bb_free ==0 )
@@ -3939,6 +3943,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, ac->ac_bitmap_page =NULL ; ac->ac_buddy_page =NULL ; ac->ac_lg =NULL ; + ac->ac_excepted_group = ar->excepted_group;/* we have to define context: we'll we work with a file or * locality group. this is a policy, actually */
fs/ext4/mballoc.h +1 -0
@@ -205,6 +205,7 @@ struct ext4_allocation_context {struct page *ac_buddy_page;struct ext4_prealloc_space *ac_pa;struct ext4_locality_group *ac_lg; +long long ac_excepted_group; };#define AC_STATUS_CONTINUE 1