Whamcloud - gitweb
Branch b1_6
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-ialloc-2.6.patch
1 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/fs/ext3/ialloc.c 2005-05-16 14:10:54.000000000 -0600
4 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/ialloc.c      2005-05-16 14:18:29.000000000 -0600
5 @@ -352,13 +352,17 @@
6         return -1;
7  }
8  
9 -static int find_group_other(struct super_block *sb, struct inode *parent)
10 +static int find_group_other(struct super_block *sb, struct inode *parent,
11 +                           int mode)
12  {
13         int parent_group = EXT3_I(parent)->i_block_group;
14 +       struct ext3_sb_info *sbi = EXT3_SB(sb);
15         int ngroups = EXT3_SB(sb)->s_groups_count;
16         struct ext3_group_desc *desc;
17         struct buffer_head *bh;
18         int group, i;
19 +       int best_group = -1;
20 +       int avefreeb, freeb, best_group_freeb = 0;
21  
22         /*
23          * Try to place the inode in its parent directory
24 @@ -366,9 +370,9 @@
25         group = parent_group;
26         desc = ext3_get_group_desc (sb, group, &bh);
27         if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
28 -                       le16_to_cpu(desc->bg_free_blocks_count))
29 +           (!S_ISREG(mode) || le16_to_cpu(desc->bg_free_blocks_count)))
30                 return group;
31 -
32 +       avefreeb = le32_to_cpu(sbi->s_es->s_free_blocks_count) / ngroups;
33         /*
34          * We're going to place this inode in a different blockgroup from its
35          * parent.  We want to cause files in a common directory to all land in
36 @@ -381,33 +385,47 @@
37         group = (group + parent->i_ino) % ngroups;
38  
39         /*
40 -        * Use a quadratic hash to find a group with a free inode and some free
41 -        * blocks.
42 +        * Use a quadratic hash to find a group with a free inode and
43 +        * average number of free blocks.
44          */
45         for (i = 1; i < ngroups; i <<= 1) {
46                 group += i;
47                 if (group >= ngroups)
48                         group -= ngroups;
49                 desc = ext3_get_group_desc (sb, group, &bh);
50 -               if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
51 -                               le16_to_cpu(desc->bg_free_blocks_count))
52 +               if (!desc || !desc->bg_free_inodes_count)
53 +                       continue;
54 +               if (!S_ISREG(mode))
55 +                       return group;
56 +               if (le16_to_cpu(desc->bg_free_blocks_count) >= avefreeb)
57                         return group;
58         }
59  
60         /*
61 -        * That failed: try linear search for a free inode, even if that group
62 -        * has no free blocks.
63 +        * That failed: start from last group used to allocate inode
64 +        * try linear search for a free inode and prefereably
65 +        * free blocks.
66          */
67 -       group = parent_group;
68 +       group = sbi->s_last_alloc_group;
69 +       if (group == -1)
70 +               group = parent_group;
71 +
72         for (i = 0; i < ngroups; i++) {
73                 if (++group >= ngroups)
74                         group = 0;
75                 desc = ext3_get_group_desc (sb, group, &bh);
76 -               if (desc && le16_to_cpu(desc->bg_free_inodes_count))
77 -                       return group;
78 +               if (!desc || !desc->bg_free_inodes_count)
79 +                       continue;
80 +               freeb = le16_to_cpu(desc->bg_free_blocks_count);
81 +               if (freeb > best_group_freeb) {
82 +                       best_group_freeb = freeb;
83 +                       best_group = group;
84 +                       if (freeb >= avefreeb || !S_ISREG(mode))
85 +                               break;
86 +               }
87         }
88 -
89 -       return -1;
90 +       sbi->s_last_alloc_group = best_group;
91 +       return best_group;
92  }
93  
94  /*
95 @@ -454,7 +472,7 @@
96                 else
97                         group = find_group_orlov(sb, dir);
98         } else 
99 -               group = find_group_other(sb, dir);
100 +               group = find_group_other(sb, dir, mode);
101  
102         err = -ENOSPC;
103         if (group == -1)
104 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/super.c
105 ===================================================================
106 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/fs/ext3/super.c  2005-05-16 14:10:54.000000000 -0600
107 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/super.c       2005-05-16 14:17:14.000000000 -0600
108 @@ -1297,6 +1297,7 @@
109         percpu_counter_init(&sbi->s_dirs_counter);
110         bgl_lock_init(&sbi->s_blockgroup_lock);
111  
112 +       sbi->s_last_alloc_group = -1;
113         for (i = 0; i < db_count; i++) {
114                 block = descriptor_loc(sb, logic_sb_block, i);
115                 sbi->s_group_desc[i] = sb_bread(sb, block);
116 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/include/linux/ext3_fs_sb.h
117 ===================================================================
118 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/include/linux/ext3_fs_sb.h       2005-05-16 14:10:54.000000000 -0600
119 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/include/linux/ext3_fs_sb.h    2005-05-16 14:17:14.000000000 -0600
120 @@ -59,6 +59,8 @@
121         struct percpu_counter s_freeinodes_counter;
122         struct percpu_counter s_dirs_counter;
123         struct blockgroup_lock s_blockgroup_lock;
124 +       /* Last group used to allocate inode */
125 +       int s_last_alloc_group;
126  
127         /* root of the per fs reservation window tree */
128         spinlock_t s_rsv_window_lock;