- Get s_blocks_per_group and s_inodes_per_group of target filesystem.

Signed-off-by: Takashi Sato <[EMAIL PROTECTED]>
Signed-off-by: Akira Fujita <[EMAIL PROTECTED]>
---
diff -X Online-Defrag_linux-2.6.19-rc6-git/Documentation/dontdiff -upNr 
linux-2.6.19-rc6-test1/fs/ext4/balloc.c 
Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/balloc.c
--- linux-2.6.19-rc6-test1/fs/ext4/balloc.c     2007-06-20 15:15:46.000000000 
+0900
+++ Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/balloc.c        
2007-06-20 14:57:04.000000000 +0900
@@ -216,7 +216,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,
                        unsigned int group, struct super_block * sb)
 {
@@ -336,7 +336,7 @@ static void rsv_window_remove(struct sup
  *
  * 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;
@@ -660,7 +660,7 @@ static int ext4_test_allocatable(ext4_gr
  * 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)
 {
@@ -1029,7 +1029,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,
                unsigned int group, struct buffer_head *bitmap_bh)
 {
@@ -1173,7 +1173,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;
diff -X Online-Defrag_linux-2.6.19-rc6-git/Documentation/dontdiff -upNr 
linux-2.6.19-rc6-test1/fs/ext4/extents.c 
Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/extents.c
--- linux-2.6.19-rc6-test1/fs/ext4/extents.c    2007-06-20 15:42:15.000000000 
+0900
+++ Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/extents.c       
2007-06-20 15:50:14.000000000 +0900
@@ -43,7 +43,6 @@
 #include <linux/ext4_fs_extents.h>
 #include <asm/uaccess.h>
 
-
 /*
  * ext_pblock:
  * combine low and high parts of physical block number into ext4_fsblk_t
@@ -206,11 +205,17 @@ static ext4_fsblk_t ext4_ext_find_goal(s
 static ext4_fsblk_t
 ext4_ext_new_block(handle_t *handle, struct inode *inode,
                        struct ext4_ext_path *path,
-                       struct ext4_extent *ex, int *err)
+                       struct ext4_extent *ex, int *err,
+                       ext4_fsblk_t defrag_goal)
 {
        ext4_fsblk_t goal, newblock;
 
-       goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
+       if (defrag_goal) {
+               goal = defrag_goal;
+       } else {
+               goal= ext4_ext_find_goal(inode, path, 
+                               le32_to_cpu(ex->ee_block));
+       }
        newblock = ext4_new_block(handle, inode, goal, err);
        return newblock;
 }
@@ -598,7 +603,8 @@ static int ext4_ext_insert_index(handle_
  */
 static int ext4_ext_split(handle_t *handle, struct inode *inode,
                                struct ext4_ext_path *path,
-                               struct ext4_extent *newext, int at)
+                               struct ext4_extent *newext, int at,
+                               ext4_fsblk_t defrag_goal)
 {
        struct buffer_head *bh = NULL;
        int depth = ext_depth(inode);
@@ -649,7 +655,8 @@ static int ext4_ext_split(handle_t *hand
        /* allocate all needed blocks */
        ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
        for (a = 0; a < depth - at; a++) {
-               newblock = ext4_ext_new_block(handle, inode, path, newext, 
&err);
+               newblock = ext4_ext_new_block(handle, inode, path, newext, &err,
+                                               defrag_goal);
                if (newblock == 0)
                        goto cleanup;
                ablocks[a] = newblock;
@@ -836,7 +843,8 @@ cleanup:
  */
 static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
                                        struct ext4_ext_path *path,
-                                       struct ext4_extent *newext)
+                                       struct ext4_extent *newext,
+                                       ext4_fsblk_t defrag_goal)
 {
        struct ext4_ext_path *curp = path;
        struct ext4_extent_header *neh;
@@ -845,7 +853,8 @@ static int ext4_ext_grow_indepth(handle_
        ext4_fsblk_t newblock;
        int err = 0;
 
-       newblock = ext4_ext_new_block(handle, inode, path, newext, &err);
+       newblock = ext4_ext_new_block(handle, inode, path, newext, &err,
+                               defrag_goal);
        if (newblock == 0)
                return err;
 
@@ -913,7 +922,8 @@ out:
  */
 static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
                                        struct ext4_ext_path *path,
-                                       struct ext4_extent *newext)
+                                       struct ext4_extent *newext,
+                                       ext4_fsblk_t defrag_goal)
 {
        struct ext4_ext_path *curp;
        int depth, i, err = 0;
@@ -933,7 +943,8 @@ repeat:
        if (EXT_HAS_FREE_INDEX(curp)) {
                /* if we found index with free entry, then use that
                 * entry: create all needed subtree and add new leaf */
-               err = ext4_ext_split(handle, inode, path, newext, i);
+               err = ext4_ext_split(handle, inode, path, newext, i,
+                               defrag_goal);
 
                /* refill path */
                ext4_ext_drop_refs(path);
@@ -944,7 +955,8 @@ repeat:
                        err = PTR_ERR(path);
        } else {
                /* tree is full, time to grow in depth */
-               err = ext4_ext_grow_indepth(handle, inode, path, newext);
+               err = ext4_ext_grow_indepth(handle, inode,
+                        path, newext, defrag_goal);
                if (err)
                        goto out;
 
@@ -2517,6 +2529,22 @@ int ext4_ext_ioctl(struct inode *inode, 
                unlock_kernel();
 
                return put_user(block, p);
+       } else if (cmd == EXT4_IOC_GROUP_INFO) {
+               struct ext4_group_data_info grp_data;
+
+               if (copy_from_user(&grp_data,
+                       (struct ext4_group_data_info __user *)arg,
+                       sizeof(grp_data)))
+                       return -EFAULT;
+
+               grp_data.s_blocks_per_group =
+                       EXT4_BLOCKS_PER_GROUP(inode->i_sb);
+               grp_data.s_inodes_per_group =
+                       EXT4_INODES_PER_GROUP(inode->i_sb);
+
+               if (copy_to_user((struct ext4_group_data_info *)arg,
+                       &grp_data, sizeof(grp_data)))
+                       return -EFAULT;
        } else if (cmd == EXT4_IOC_DEFRAG) {
                struct ext4_ext_defrag_data defrag;
 
diff -X Online-Defrag_linux-2.6.19-rc6-git/Documentation/dontdiff -upNr 
linux-2.6.19-rc6-test1/fs/ext4/mballoc.c 
Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/mballoc.c
--- linux-2.6.19-rc6-test1/fs/ext4/mballoc.c    2007-06-20 15:42:08.000000000 
+0900
+++ Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/fs/ext4/mballoc.c       
2007-06-20 15:14:36.000000000 +0900
@@ -3721,6 +3721,13 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t
 
        ext4_mb_poll_new_transaction(sb, handle);
 
+       if ((err = ext4_mb_initialize_context(&ac, ar))) {
+               if (reserved)
+                       ext4_release_blocks(sb, reserved);
+               *errp = err;
+               return err;
+       }
+
        if (!(ac.ac_flags & EXT4_MB_HINT_RESERVED) &&
                !(EXT4_I(ar->inode)->i_state & EXT4_STATE_BLOCKS_RESERVED)) {
                reserved = ar->len;
@@ -3729,12 +3736,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t
                        return err;
        }
 
-       if ((err = ext4_mb_initialize_context(&ac, ar))) {
-               if (reserved)
-                       ext4_release_blocks(sb, reserved);
-               return err;
-       }
-
        if (!ext4_mb_use_preallocated(&ac)) {
                ext4_mb_normalize_request(&ac, ar);
 
diff -X Online-Defrag_linux-2.6.19-rc6-git/Documentation/dontdiff -upNr 
linux-2.6.19-rc6-test1/include/linux/ext4_fs.h 
Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/include/linux/ext4_fs.h
--- linux-2.6.19-rc6-test1/include/linux/ext4_fs.h      2007-06-20 
15:42:08.000000000 +0900
+++ Online-Defrag_linux-2.6.19-rc6-git-FREE_BLOCKS_INFO/include/linux/ext4_fs.h 
2007-06-20 15:16:11.000000000 +0900
@@ -285,6 +285,12 @@ struct ext4_get_buddy_request {
 #define EXT4_IOC_GET_TREE_STATS                _IOR('f', 9, long)
 #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)
+#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', 16)
 
 /*
  * ioctl commands in 32 bit emulation
@@ -303,6 +309,10 @@ struct ext4_get_buddy_request {
 #define EXT4_IOC32_SETVERSION_OLD      FS_IOC32_SETVERSION
 
 /* Used for defrag */
+#define DEFRAG_MAX_ENT 32 
+#define DEFRAG_RESERVE_BLOCKS_FIRST 1
+#define DEFRAG_RESERVE_BLOCKS_SECOND 2
+#define DEFRAG_FIXED_BLOCKS_MODE 3
 
 struct ext4_extent_data {
        unsigned long long block;       /* start logical block number */
@@ -318,6 +328,20 @@ struct ext4_ext_defrag_data {
        struct ext4_extent_data ext;
 };
 
+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 */
+       unsigned long offset;           /* search 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 */
 
 /*
@@ -912,6 +936,14 @@ extern struct ext4_group_desc * ext4_get
 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 struct buffer_head * read_block_bitmap(struct super_block *, unsigned 
int);
+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 *,
+               unsigned int, struct buffer_head *);
+extern ext4_grpblk_t bitmap_search_next_usable_block(ext4_grpblk_t,
+               struct buffer_head *, ext4_grpblk_t);
 
 /* reservation.c */
 int ext4_reserve_init(struct super_block *sb);
-
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

Reply via email to