reiserfs: Don't call reiserfs_get_acl() with the reiserfs lock
[safe/jmp/linux-2.6] / fs / ext4 / ialloc.c
index 7d502f3..f3624ea 100644 (file)
@@ -470,7 +470,8 @@ void get_orlov_stats(struct super_block *sb, ext4_group_t g,
  */
 
 static int find_group_orlov(struct super_block *sb, struct inode *parent,
-                           ext4_group_t *group, int mode)
+                           ext4_group_t *group, int mode,
+                           const struct qstr *qstr)
 {
        ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -485,6 +486,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
        struct ext4_group_desc *desc;
        struct orlov_stats stats;
        int flex_size = ext4_flex_bg_size(sbi);
+       struct dx_hash_info hinfo;
 
        ngroups = real_ngroups;
        if (flex_size > 1) {
@@ -506,7 +508,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
                int best_ndir = inodes_per_group;
                int ret = -1;
 
-               get_random_bytes(&grp, sizeof(grp));
+               if (qstr) {
+                       hinfo.hash_version = DX_HASH_HALF_MD4;
+                       hinfo.seed = sbi->s_hash_seed;
+                       ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
+                       grp = hinfo.hash;
+               } else
+                       get_random_bytes(&grp, sizeof(grp));
                parent_group = (unsigned)grp % ngroups;
                for (i = 0; i < ngroups; i++) {
                        g = (parent_group + i) % ngroups;
@@ -649,7 +657,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
                *group = parent_group + flex_size;
                if (*group > ngroups)
                        *group = 0;
-               return find_group_orlov(sb, parent, group, mode);
+               return find_group_orlov(sb, parent, group, mode, 0);
        }
 
        /*
@@ -790,7 +798,8 @@ err_ret:
  * For other inodes, search forward from the parent directory's block
  * group to find a free inode.
  */
-struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
+struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
+                            const struct qstr *qstr, __u32 goal)
 {
        struct super_block *sb;
        struct buffer_head *inode_bitmap_bh = NULL;
@@ -821,6 +830,16 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
        ei = EXT4_I(inode);
        sbi = EXT4_SB(sb);
 
+       if (!goal)
+               goal = sbi->s_inode_goal;
+
+       if (goal && goal <= le32_to_cpu(sbi->s_es->s_inodes_count)) {
+               group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
+               ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
+               ret2 = 0;
+               goto got_group;
+       }
+
        if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) {
                ret2 = find_group_flex(sb, dir, &group);
                if (ret2 == -1) {
@@ -839,7 +858,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
                if (test_opt(sb, OLDALLOC))
                        ret2 = find_group_dir(sb, dir, &group);
                else
-                       ret2 = find_group_orlov(sb, dir, &group, mode);
+                       ret2 = find_group_orlov(sb, dir, &group, mode, qstr);
        } else
                ret2 = find_group_other(sb, dir, &group, mode);
 
@@ -849,7 +868,7 @@ got_group:
        if (ret2 == -1)
                goto out;
 
-       for (i = 0; i < ngroups; i++) {
+       for (i = 0; i < ngroups; i++, ino = 0) {
                err = -EIO;
 
                gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
@@ -861,8 +880,6 @@ got_group:
                if (!inode_bitmap_bh)
                        goto fail;
 
-               ino = 0;
-
 repeat_in_this_group:
                ino = ext4_find_next_zero_bit((unsigned long *)
                                              inode_bitmap_bh->b_data,
@@ -1172,7 +1189,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
 
                x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
                printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
-                       i, ext4_free_inodes_count(sb, gdp), x);
+                       (unsigned long) i, ext4_free_inodes_count(sb, gdp), x);
                bitmap_count += x;
        }
        brelse(bitmap_bh);