ChangeSet 1.2229.1.21, 2005/04/04 07:39:47-07:00, [EMAIL PROTECTED]

        [PATCH] ext3: move goal logical block into block allocation info 
structure
        
        Moved i_next_alloc_block and i_next_goal_block out from ext3_inod_info, 
and
        put it together with the reservation structure into the
        ext3_block_alloc_info structure, and dynamically allocate that structure
        whenever need to allocation a block.  This is also apply for 
noreservation
        mount.  Also cleanup ext3_find_goal() code.
        
        Signed-off-by: Mingming Cao <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 fs/ext3/balloc.c          |   42 ++++++++++++++++++++++++++---------
 fs/ext3/ialloc.c          |    4 ---
 fs/ext3/inode.c           |   54 ++++++++++++++++++++++------------------------
 fs/ext3/ioctl.c           |   14 ++++++-----
 fs/ext3/super.c           |    6 ++---
 include/linux/ext3_fs.h   |    2 -
 include/linux/ext3_fs_i.h |   36 +++++++++++++++++-------------
 7 files changed, 91 insertions(+), 67 deletions(-)


diff -Nru a/fs/ext3/balloc.c b/fs/ext3/balloc.c
--- a/fs/ext3/balloc.c  2005-04-04 08:18:07 -07:00
+++ b/fs/ext3/balloc.c  2005-04-04 08:18:07 -07:00
@@ -259,28 +259,47 @@
        /* a valid reservation end block could not be 0 */
        return (rsv->_rsv_end == EXT3_RESERVE_WINDOW_NOT_ALLOCATED);
 }
-void ext3_alloc_init_reservation(struct inode *inode)
+void ext3_init_block_alloc_info(struct inode *inode)
 {
        struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_reserve_window_node *rsv = ei->i_rsv_window;
+       struct ext3_block_alloc_info *block_i = ei->i_block_alloc_info;
+       struct super_block *sb = inode->i_sb;
+
+       block_i = kmalloc(sizeof(*block_i), GFP_NOFS);
+       if (block_i) {
+               struct ext3_reserve_window_node *rsv = 
&block_i->rsv_window_node;
 
-       rsv = kmalloc(sizeof(*rsv), GFP_NOFS);
-       if (rsv) {
                rsv->rsv_start = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
                rsv->rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
-               rsv->rsv_goal_size = EXT3_DEFAULT_RESERVE_BLOCKS;
+
+               /*
+                * if filesystem is mounted with NORESERVATION, the goal
+                * reservation window size is set to zero to indicate
+                * block reservation is off
+                */
+               if (!test_opt(sb, RESERVATION))
+                       rsv->rsv_goal_size = 0;
+               else
+                       rsv->rsv_goal_size = EXT3_DEFAULT_RESERVE_BLOCKS;
                rsv->rsv_alloc_hit = 0;
+               block_i->last_alloc_logical_block = 0;
+               block_i->last_alloc_physical_block = 0;
        }
-       ei->i_rsv_window = rsv;
+       ei->i_block_alloc_info = block_i;
 }
 
 void ext3_discard_reservation(struct inode *inode)
 {
        struct ext3_inode_info *ei = EXT3_I(inode);
-       struct ext3_reserve_window_node *rsv = ei->i_rsv_window;
+       struct ext3_block_alloc_info *block_i = ei->i_block_alloc_info;
+       struct ext3_reserve_window_node *rsv;
        spinlock_t *rsv_lock = &EXT3_SB(inode->i_sb)->s_rsv_window_lock;
 
-       if (rsv && !rsv_is_empty(&rsv->rsv_window)) {
+       if (!block_i)
+               return;
+
+       rsv = &block_i->rsv_window_node;
+       if (!rsv_is_empty(&rsv->rsv_window)) {
                spin_lock(rsv_lock);
                if (!rsv_is_empty(&rsv->rsv_window))
                        rsv_window_remove(inode->i_sb, rsv);
@@ -1161,7 +1180,7 @@
        struct ext3_super_block *es;
        struct ext3_sb_info *sbi;
        struct ext3_reserve_window_node *my_rsv = NULL;
-       struct ext3_reserve_window_node *rsv = EXT3_I(inode)->i_rsv_window;
+       struct ext3_block_alloc_info *block_i;
        unsigned short windowsz = 0;
 #ifdef EXT3FS_DEBUG
        static int goal_hits, goal_attempts;
@@ -1194,8 +1213,9 @@
         * command EXT3_IOC_SETRSVSZ to set the window size to 0 to turn off
         * reservation on that particular file)
         */
-       if (rsv && ((windowsz = rsv->rsv_goal_size) > 0))
-               my_rsv = rsv;
+       block_i = EXT3_I(inode)->i_block_alloc_info;
+       if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 
0))
+               my_rsv = &block_i->rsv_window_node;
 
        if (!ext3_has_free_blocks(sbi)) {
                *errp = -ENOSPC;
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c  2005-04-04 08:18:07 -07:00
+++ b/fs/ext3/ialloc.c  2005-04-04 08:18:07 -07:00
@@ -562,8 +562,6 @@
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 
        memset(ei->i_data, 0, sizeof(ei->i_data));
-       ei->i_next_alloc_block = 0;
-       ei->i_next_alloc_goal = 0;
        ei->i_dir_start_lookup = 0;
        ei->i_disksize = 0;
 
@@ -581,7 +579,7 @@
        ei->i_file_acl = 0;
        ei->i_dir_acl = 0;
        ei->i_dtime = 0;
-       ei->i_rsv_window = NULL;
+       ei->i_block_alloc_info = NULL;
        ei->i_block_group = group;
 
        ext3_set_inode_flags(inode);
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c   2005-04-04 08:18:07 -07:00
+++ b/fs/ext3/inode.c   2005-04-04 08:18:07 -07:00
@@ -462,26 +462,22 @@
 static int ext3_find_goal(struct inode *inode, long block, Indirect chain[4],
                          Indirect *partial, unsigned long *goal)
 {
-       struct ext3_inode_info *ei = EXT3_I(inode);
-       /* Writer: ->i_next_alloc* */
-       if ((block == ei->i_next_alloc_block + 1)&& ei->i_next_alloc_goal) {
-               ei->i_next_alloc_block++;
-               ei->i_next_alloc_goal++;
+       struct ext3_block_alloc_info *block_i =  
EXT3_I(inode)->i_block_alloc_info;
+
+       /*
+        * try the heuristic for sequential allocation,
+        * failing that at least try to get decent locality.
+        */
+       if (block_i && (block == block_i->last_alloc_logical_block + 1)
+               && (block_i->last_alloc_physical_block != 0)) {
+               *goal = block_i->last_alloc_physical_block + 1;
+               return 0;
        }
-       /* Writer: end */
-       /* Reader: pointers, ->i_next_alloc* */
+
        if (verify_chain(chain, partial)) {
-               /*
-                * try the heuristic for sequential allocation,
-                * failing that at least try to get decent locality.
-                */
-               if (block == ei->i_next_alloc_block)
-                       *goal = ei->i_next_alloc_goal;
-               if (!*goal)
-                       *goal = ext3_find_near(inode, partial);
+               *goal = ext3_find_near(inode, partial);
                return 0;
        }
-       /* Reader: end */
        return -EAGAIN;
 }
 
@@ -599,7 +595,7 @@
 {
        int i;
        int err = 0;
-       struct ext3_inode_info *ei = EXT3_I(inode);
+       struct ext3_block_alloc_info *block_i = 
EXT3_I(inode)->i_block_alloc_info;
 
        /*
         * If we're splicing into a [td]indirect block (as opposed to the
@@ -614,7 +610,6 @@
        }
        /* Verify that place we are splicing to is still there and vacant */
 
-       /* Writer: pointers, ->i_next_alloc* */
        if (!verify_chain(chain, where-1) || *where->p)
                /* Writer: end */
                goto changed;
@@ -622,9 +617,16 @@
        /* That's it */
 
        *where->p = where->key;
-       ei->i_next_alloc_block = block;
-       ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key);
-       /* Writer: end */
+
+       /*
+        * update the most recently allocated logical & physical block
+        * in i_block_alloc_info, to assist find the proper goal block for next
+        * allocation
+        */
+       if (block_i) {
+               block_i->last_alloc_logical_block = block;
+               block_i->last_alloc_physical_block = 
le32_to_cpu(where[num-1].key);
+       }
 
        /* We are done with atomic stuff, now do the rest of housekeeping */
 
@@ -708,7 +710,6 @@
        int boundary = 0;
        int depth = ext3_block_to_path(inode, iblock, offsets, &boundary);
        struct ext3_inode_info *ei = EXT3_I(inode);
-       struct super_block *sb = inode->i_sb;
 
        J_ASSERT(handle != NULL || create == 0);
 
@@ -755,9 +756,8 @@
        down(&ei->truncate_sem);
 
        /* lazy initialize the block allocation info here if necessary */
-       if (test_opt(sb, RESERVATION) && S_ISREG(inode->i_mode)
-               &&  (!ei->i_rsv_window)) {
-               ext3_alloc_init_reservation(inode);
+       if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) {
+               ext3_init_block_alloc_info(inode);
        }
 
        if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0) {
@@ -2503,7 +2503,7 @@
        ei->i_acl = EXT3_ACL_NOT_CACHED;
        ei->i_default_acl = EXT3_ACL_NOT_CACHED;
 #endif
-       ei->i_rsv_window = NULL;
+       ei->i_block_alloc_info = NULL;
 
        if (__ext3_get_inode_loc(inode, &iloc, 0))
                goto bad_inode;
@@ -2524,8 +2524,6 @@
        inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 
inode->i_mtime.tv_nsec = 0;
 
        ei->i_state = 0;
-       ei->i_next_alloc_block = 0;
-       ei->i_next_alloc_goal = 0;
        ei->i_dir_start_lookup = 0;
        ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
        /* We now have enough fields to check if the inode was active or not.
diff -Nru a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
--- a/fs/ext3/ioctl.c   2005-04-04 08:18:07 -07:00
+++ b/fs/ext3/ioctl.c   2005-04-04 08:18:07 -07:00
@@ -155,8 +155,8 @@
        case EXT3_IOC_GETRSVSZ:
                if (test_opt(inode->i_sb, RESERVATION)
                        && S_ISREG(inode->i_mode)
-                       && ei->i_rsv_window) {
-                       rsv_window_size = ei->i_rsv_window->rsv_goal_size;
+                       && ei->i_block_alloc_info) {
+                       rsv_window_size = 
ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
                        return put_user(rsv_window_size, (int __user *)arg);
                }
                return -ENOTTY;
@@ -182,11 +182,13 @@
                 * before set the window size
                 */
                down(&ei->truncate_sem);
-               if (!ei->i_rsv_window)
-                       ext3_alloc_init_reservation(inode);
+               if (!ei->i_block_alloc_info)
+                       ext3_init_block_alloc_info(inode);
 
-               if (ei->i_rsv_window)
-                       ei->i_rsv_window->rsv_goal_size = rsv_window_size;
+               if (ei->i_block_alloc_info){
+                       struct ext3_reserve_window_node *rsv = 
&ei->i_block_alloc_info->rsv_window_node;
+                       rsv->rsv_goal_size = rsv_window_size;
+               }
                up(&ei->truncate_sem);
                return 0;
        }
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c   2005-04-04 08:18:07 -07:00
+++ b/fs/ext3/super.c   2005-04-04 08:18:07 -07:00
@@ -441,7 +441,7 @@
        ei->i_acl = EXT3_ACL_NOT_CACHED;
        ei->i_default_acl = EXT3_ACL_NOT_CACHED;
 #endif
-       ei->i_rsv_window = NULL;
+       ei->i_block_alloc_info = NULL;
        ei->vfs_inode.i_version = 1;
        return &ei->vfs_inode;
 }
@@ -485,7 +485,7 @@
 
 static void ext3_clear_inode(struct inode *inode)
 {
-       struct ext3_reserve_window_node *rsv = EXT3_I(inode)->i_rsv_window;
+       struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info;
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
        if (EXT3_I(inode)->i_acl &&
            EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
@@ -499,7 +499,7 @@
        }
 #endif
        ext3_discard_reservation(inode);
-       EXT3_I(inode)->i_rsv_window = NULL;
+       EXT3_I(inode)->i_block_alloc_info = NULL;
        kfree(rsv);
 }
 
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h   2005-04-04 08:18:07 -07:00
+++ b/include/linux/ext3_fs.h   2005-04-04 08:18:07 -07:00
@@ -725,7 +725,7 @@
                                                    unsigned int block_group,
                                                    struct buffer_head ** bh);
 extern int ext3_should_retry_alloc(struct super_block *sb, int *retries);
-extern void ext3_alloc_init_reservation(struct inode *);
+extern void ext3_init_block_alloc_info(struct inode *);
 extern void ext3_rsv_window_add(struct super_block *sb, struct 
ext3_reserve_window_node *rsv);
 
 /* dir.c */
diff -Nru a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
--- a/include/linux/ext3_fs_i.h 2005-04-04 08:18:07 -07:00
+++ b/include/linux/ext3_fs_i.h 2005-04-04 08:18:07 -07:00
@@ -32,6 +32,26 @@
        struct ext3_reserve_window      rsv_window;
 };
 
+struct ext3_block_alloc_info {
+       /* information about reservation window */
+       struct ext3_reserve_window_node rsv_window_node;
+       /*
+        * was i_next_alloc_block in ext3_inode_info
+        * is the logical (file-relative) number of the
+        * most-recently-allocated block in this file.
+        * We use this for detecting linearly ascending allocation requests.
+        */
+       __u32                   last_alloc_logical_block;
+       /*
+        * Was i_next_alloc_goal in ext3_inode_info
+        * is the *physical* companion to i_next_alloc_block.
+        * it the the physical block number of the block which was most-recentl
+        * allocated to this file.  This give us the goal (target) for the next
+        * allocation when we detect linearly ascending requests.
+        */
+       __u32                   last_alloc_physical_block;
+};
+
 #define rsv_start rsv_window._rsv_start
 #define rsv_end rsv_window._rsv_end
 
@@ -60,22 +80,8 @@
        __u32   i_block_group;
        __u32   i_state;                /* Dynamic state flags for ext3 */
 
-       /*
-        * i_next_alloc_block is the logical (file-relative) number of the
-        * most-recently-allocated block in this file.  Yes, it is misnamed.
-        * We use this for detecting linearly ascending allocation requests.
-        */
-       __u32   i_next_alloc_block;
-
-       /*
-        * i_next_alloc_goal is the *physical* companion to i_next_alloc_block.
-        * it the the physical block number of the block which was most-recently
-        * allocated to this file.  This give us the goal (target) for the next
-        * allocation when we detect linearly ascending requests.
-        */
-       __u32   i_next_alloc_goal;
        /* block reservation info */
-       struct ext3_reserve_window_node *i_rsv_window;
+       struct ext3_block_alloc_info *i_block_alloc_info;
 
        __u32   i_dir_start_lookup;
 #ifdef CONFIG_EXT3_FS_XATTR
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to