On Dec 06, 2007  16:10 -0600, Jose R. Santos wrote:
> @@ -600,6 +600,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct 
> super_block *sb,
>       struct ext4_sb_info *sbi;
>       int err = 0, ret;
>       ext4_grpblk_t group_freed;
> +     ext4_group_t flex_group;
>  
>       *pdquot_freed_blocks = 0;
>       sbi = EXT4_SB(sb);
> @@ -745,6 +746,14 @@ do_more:
>       spin_unlock(sb_bgl_lock(sbi, block_group));
>       percpu_counter_add(&sbi->s_freeblocks_counter, count);
>  
> +     if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
> +         sbi->s_groups_per_flex_shift) {
> +             flex_group = ext4_flex_group(sbi, block_group);
> +             spin_lock(sb_bgl_lock(sbi, flex_group));
> +             sbi->s_flex_groups[flex_group].free_blocks += count;
> +             spin_unlock(sb_bgl_lock(sbi, flex_group));
> +     }

In general, I prefer to keep variables in as local a scope as possible.
In this case, flex_group could be declared inside the "if (EXT4_HAS_INCOMPAT"
check.

> @@ -1610,6 +1619,7 @@ ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, 
> struct inode *inode,
>       unsigned short windowsz = 0;
>       ext4_group_t ngroups;
>       unsigned long num = *count;
> +     ext4_group_t flex_group;
>  
>       *errp = -ENOSPC;
>       sb = inode->i_sb;
> @@ -1815,6 +1825,14 @@ allocated:
>       spin_unlock(sb_bgl_lock(sbi, group_no));
>       percpu_counter_sub(&sbi->s_freeblocks_counter, num);
>  
> +     if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
> +         sbi->s_groups_per_flex_shift) {
> +             flex_group = ext4_flex_group(sbi, group_no);
> +             spin_lock(sb_bgl_lock(sbi, flex_group));
> +             sbi->s_flex_groups[flex_group].free_blocks -= num;
> +             spin_unlock(sb_bgl_lock(sbi, flex_group));
> +     }

Same as above.

> @@ -158,6 +158,7 @@ void ext4_free_inode (handle_t *handle, struct inode * 
> inode)
>       struct ext4_super_block * es;
>       struct ext4_sb_info *sbi;
>       int fatal = 0, err;
> +     ext4_group_t flex_group;
>  
>       if (atomic_read(&inode->i_count) > 1) {
>               printk ("ext4_free_inode: inode has count=%d\n",
> @@ -235,6 +236,13 @@ void ext4_free_inode (handle_t *handle, struct inode * 
> inode)
>                       if (is_directory)
>                               percpu_counter_dec(&sbi->s_dirs_counter);
>  
> +                     if (EXT4_HAS_INCOMPAT_FEATURE(sb, 
> EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
> +                         sbi->s_groups_per_flex_shift) {
> +                             flex_group = ext4_flex_group(sbi, block_group);
> +                             spin_lock(sb_bgl_lock(sbi, flex_group));
> +                             sbi->s_flex_groups[flex_group].free_inodes++;
> +                             spin_unlock(sb_bgl_lock(sbi, flex_group));
> +                     }

Same as above... 

> +#define free_block_ratio 10
> +
> +int find_group_flex(struct super_block *sb, struct inode *parent)
> +{
> +     n_fbg_groups = (sbi->s_groups_count + flex_size - 1) / flex_size;
> +     best_flex = parent_fbg_group;
> +
> +find_close_to_parent:
> +     flex_freeb_ratio = 
> flex_group[best_flex].free_blocks*100/blocks_per_flex;

There is no particular reason that this ratio needs to be "*100", it could
just as easily be a fraction of 256 and make the multiply into a shift.
The free_block_ratio would be 26 in that case.

> +     for (i = 0; i < n_fbg_groups; i++) {
> +             if (i == parent_fbg_group || i == parent_fbg_group - 1)
> +                     continue;

It seems this scans flex groups the way we used to scan groups?

> +found_flexbg:
> +     for (i = best_flex * flex_size; i < ngroups &&
> +                  i < (best_flex + 1) * flex_size; i++) {

And now that we've found a suitable flex group, we need to find which
block group therein has some free inodes...

> +static int ext4_fill_flex_info(struct super_block *sb)
> +{

It still seems desirable to have a single per-group array instead of

> @@ -622,7 +631,9 @@ struct ext4_super_block {
>       __le16  s_mmp_interval;         /* # seconds to wait in MMP checking */
>       __le64  s_mmp_block;            /* Block for multi-mount protection */
>       __le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
> -     __u32   s_reserved[163];        /* Padding to the end of the block */
> +     __le16  s_flex_bg_size;         /* FLEX_BG group size */

Shouldn't this be "s_flex_bg_bits"?

> +{
> +     return block_group >> sbi->s_groups_per_flex_shift;
> +}
> +
> +static inline unsigned int ext4_flex_bg_size(struct ext4_sb_info *sbi)
> +{
> +     return 1 << sbi->s_groups_per_flex_shift;
> +}
> +
>  #define ext4_std_error(sb, errno)                            \
>  do {                                                         \
>       if ((errno))                                            \

> diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
> --- a/lib/ext2fs/alloc_tables.c
> +++ b/lib/ext2fs/alloc_tables.c
> +     if (EXT2_HAS_INCOMPAT_FEATURE (fs->super, 
> +                                    EXT4_FEATURE_INCOMPAT_FLEX_BG)) 
> +             ext2fs_allocate_flex_groups(fs);
> +     
> +     else {
> +             for (i = 0; i < fs->group_desc_count; i++) {
> +                     retval = ext2fs_allocate_group_table(fs, i, 
> fs->block_map);
> +                     if (retval)
> +                             return retval;
> +             }
>       }

My preference would be to have "if (EXT2_HAS_INCOMPAT...) { ... } else {"
(i.e. add { } for the first part) since there are { } on the second part,
and it is just easier to read.

> @@ -1045,6 +1046,19 @@ static void PRS(int argc, char *argv[])
> +                     if ((flex_bg_size & (flex_bg_size-1)) != 0) {
> +                             com_err(program_name, 0,
> +                                     _("Flex_BG size must be a power of 2"));
> +                             exit(1);

If flex_bg_size is a power of two then there isn't any need to store anything
except __u8 s_flex_bg_bits in the superblock.

> @@ -1444,6 +1458,10 @@ static void PRS(int argc, char *argv[])
> +     if(flex_bg_size) {
> +             fs_param.s_flex_bg_size = ext2fs_swab16(flex_bg_size);
> +     }

Space between if and (, and no need for braces for a single line body.

It would also be nice to get a m_flexbg test case along with this patch
that (at minimum) creates a filesystem with flexbg enabled, and then
runs e2fsck on it.  This was broken for the lazy_bg feature for a long
time, so it makes sense to add a test to verify each new feature has
some basic functionality.  If the f_random_corruption test is in the
git tree, it would be good to add the flex_bg option to the list of
possible feature combinations to test.

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.

-
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