Skip to contentSkip to conversation

ext4: check the free space fragmentation (-f mode)

RFC PATCH In review Akira Fujita 1 participant 1 message May 30, 2008

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

RFC PATCH 6/8 ext4: check the free space fragmentation (-f mode)

ext4: online defrag-- Check the free space fragmentation (-f mode)

From: Akira Fujita <[email protected]>

Check the free space fragmentation in the block group where target file is located.

---
 fs/ext4/balloc.c |    2 +-
 fs/ext4/defrag.c |  275 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/ext4/ext4.h   |   34 +++++++
 fs/ext4/ioctl.c  |    5 +-
 4 files changed, 312 insertions(+), 4 deletions(-)
fs/ext4/balloc.c +1 -1
index b961ad1..a3fb70c 100644
@@ -919,7 +919,7 @@ static int ext4_test_allocatable(ext4_grpblk_t nr, struct buffer_head *bh)
  * bitmap on disk and the last-committed copy in journal, until we find a
  * bit free in both bitmaps.
  */
-static ext4_grpblk_t
+ext4_grpblk_t
 bitmap_search_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh,
 					ext4_grpblk_t maxblocks)
 {
fs/ext4/defrag.c +273 -2

309 lines not on this page · raw message

fs/ext4/ext4.h +34 -0
index 12b3fea..d0b1301 100644
@@ -300,6 +300,9 @@ struct ext4_new_group_data {
 #define EXT4_IOC_MIGRATE		_IO('f', 7)
 #define EXT4_IOC_FIBMAP			_IOW('f', 9, ext4_fsblk_t)
 #define EXT4_IOC_DEFRAG		_IOW('f', 10, struct ext4_ext_defrag_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)
 
 /*
  * ioctl commands in 32 bit emulation
@@ -323,12 +326,41 @@ struct ext4_new_group_data {
  */
 #define DEFRAG_BLOCK_SIZE	4096
 
+/*
+ * The following four macros are used for the defrag force mode.
+ *
+ * DEFRAG_MAX_ENT:	the maximum number of extents for exchanging between
+ *			kernel-space and user-space per an ioctl
+ */
+#define DEFRAG_MAX_ENT		32
+
+struct ext4_extent_data {
+	ext4_lblk_t block;		/* start logical block number */
+	ext4_fsblk_t start;		/* start physical block number */
+	int len;			/* blocks count */
+};
+
 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 */
 };
 
+struct ext4_group_data_info {
+	int s_blocks_per_group;		/* blocks per group */
+	int s_inodes_per_group;		/* inodes per group */
+};
+
+struct ext4_extents_info {
+	unsigned long long ino;		/* inode number */
+	int max_entries;		/* maximum extents count */
+	int entries;			/* extent number/count */
+	ext4_lblk_t f_offset;		/* file offset */
+	ext4_grpblk_t g_offset;		/* group offset */
+	ext4_fsblk_t goal;		/* block offset for allocation */
+	struct ext4_extent_data ext[DEFRAG_MAX_ENT];
+};
+
 #define EXT4_TRANS_META_BLOCKS 4 /* bitmap + group desc + sb + inode */
 
 /*
@@ -1010,6 +1042,8 @@ 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 ext4_grpblk_t bitmap_search_next_usable_block(ext4_grpblk_t,
+				struct buffer_head *, ext4_grpblk_t);
 
 /* dir.c */
 extern int ext4_check_dir_entry(const char *, struct inode *,
fs/ext4/ioctl.c +4 -1
index e1b9c10..e012193 100644
@@ -242,7 +242,10 @@ setversion_out:
 		return err;
 	}
 	case EXT4_IOC_FIBMAP:
-	case EXT4_IOC_DEFRAG: {
+	case EXT4_IOC_DEFRAG:
+	case EXT4_IOC_GROUP_INFO:
+	case EXT4_IOC_FREE_BLOCKS_INFO:
+	case EXT4_IOC_EXTENTS_INFO: {
 		return ext4_defrag_ioctl(inode, filp, cmd, arg);
 	}
 	case EXT4_IOC_GROUP_ADD: {