Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / fs / ext4 / balloc.c
index 264f694..f8224ad 100644 (file)
@@ -620,3 +620,51 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
 
 }
 
+/**
+ *     ext4_inode_to_goal_block - return a hint for block allocation
+ *     @inode: inode for block allocation
+ *
+ *     Return the ideal location to start allocating blocks for a
+ *     newly created inode.
+ */
+ext4_fsblk_t ext4_inode_to_goal_block(struct inode *inode)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       ext4_group_t block_group;
+       ext4_grpblk_t colour;
+       int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb));
+       ext4_fsblk_t bg_start;
+       ext4_fsblk_t last_block;
+
+       block_group = ei->i_block_group;
+       if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) {
+               /*
+                * If there are at least EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME
+                * block groups per flexgroup, reserve the first block
+                * group for directories and special files.  Regular
+                * files will start at the second block group.  This
+                * tends to speed up directory access and improves
+                * fsck times.
+                */
+               block_group &= ~(flex_size-1);
+               if (S_ISREG(inode->i_mode))
+                       block_group++;
+       }
+       bg_start = ext4_group_first_block_no(inode->i_sb, block_group);
+       last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1;
+
+       /*
+        * If we are doing delayed allocation, we don't need take
+        * colour into account.
+        */
+       if (test_opt(inode->i_sb, DELALLOC))
+               return bg_start;
+
+       if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block)
+               colour = (current->pid % 16) *
+                       (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+       else
+               colour = (current->pid % 16) * ((last_block - bg_start) / 16);
+       return bg_start + colour;
+}
+