Skip to contentSkip to conversation

ext4: move victim files for the target file (-f mode)

RFC PATCH In review Akira Fujita 2 participants 3 messages May 30, 2008 – Jun 16, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 7/8 ext4: 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.

---
 fs/ext4/balloc.c       |   10 +-
 fs/ext4/defrag.c       |  460 +++++++++++++++++++++++++++++++++++++++++++++---
 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, 522 insertions(+), 47 deletions(-)
fs/ext4/balloc.c +5 -5
index a3fb70c..32e4e7e 100644
@@ -433,7 +433,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)
 {
@@ -538,7 +538,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;
@@ -553,7 +553,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;
@@ -1289,7 +1289,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)
 {
@@ -1433,7 +1433,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 +431 -29

730 lines not on this page · raw message

fs/ext4/ext4.h +28 -1
index d0b1301..88fd100 100644
@@ -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	3
 
 struct 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 {
@@ -1042,8 +1059,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 *,
@@ -1169,7 +1195,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
index 734c1c7..d9a6a73 100644
@@ -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
index e012193..9daa40a 100644
@@ -245,7 +245,10 @@ setversion_out:
 	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
index 5302ac6..e273279 100644
@@ -1765,6 +1765,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)
@@ -3956,6 +3960,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
index bfe6add..1141ad5 100644
@@ -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
#1 lore raw

Akira Fujita Wrote:

Quoted 20 lines

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.

---
 fs/ext4/balloc.c       |   10 +-
 fs/ext4/defrag.c       |  460 +++++++++++++++++++++++++++++++++++++++++++++---
 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, 522 insertions(+), 47 deletions(-)

...snip...

Quoted 6 lines
fs/ext4/ext4.h +0 -0
index d0b1301..88fd100 100644

fs/ext4/ext4.h struct ext4_allocation_request { · line 102

Quoted 9 lines
fs/ext4/ext4.h +5 -0
@@ -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;
 };

Why not ext4_group_t for excepted_group here?

Quoted 10 lines
fs/ext4/ext4.h +3 -0
 /*
@@ -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)
 

...snip...

fs/ext4/mballoc.h struct ext4_allocation_context { · line 208

Quoted 9 lines
fs/ext4/mballoc.h +1 -0
index bfe6add..1141ad5 100644
@@ -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;

ditto

Quoted 10 lines
fs/ext4/mballoc.h +0 -1
 };
 
 #define AC_STATUS_CONTINUE	1
 
--

To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw

Shen Feng Wrote:

Quoted 25 lines

Akira Fujita Wrote:

Quoted 20 lines

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.

---
 fs/ext4/balloc.c       |   10 +-
 fs/ext4/defrag.c       |  460 +++++++++++++++++++++++++++++++++++++++++++++---
 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, 522 insertions(+), 47 deletions(-)

...snip...

Quoted 16 lines
Quoted 5 lines
fs/ext4/ext4.h +0 -0
index d0b1301..88fd100 100644

fs/ext4/ext4.h struct ext4_allocation_request { · line 102

Quoted 9 lines
fs/ext4/ext4.h +5 -0
@@ -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;
 };

Why not ext4_group_t for excepted_group here?

ac_excepted_group has not only excepted block group number but also -1 (it means any block groups are accepted). So we should keep it as long long variable to show the special status correctly in large ext4.

Regards,
Akira Fujita