Whamcloud - gitweb
Branch b1_8
authoryangsheng <yangsheng>
Thu, 12 Nov 2009 17:14:18 +0000 (17:14 +0000)
committeryangsheng <yangsheng>
Thu, 12 Nov 2009 17:14:18 +0000 (17:14 +0000)
b=20773

i=adilger, shadow, girish, brian, wangyb

Update kernel to RHEL5 U4 2.6.18-164.6.1.el5.

28 files changed:
ldiskfs/kernel_patches/patches/export-ext4-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext3-extents-2.6.18-vanilla.patch
ldiskfs/kernel_patches/patches/ext3-kill-dx_root.patch
ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch
ldiskfs/kernel_patches/patches/ext3-version-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext3_data_in_dirent.patch
ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-extents-mount-option-rhel5.patch [new file with mode: 0644]
ldiskfs/kernel_patches/patches/ext4-fiemap-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-filterdata-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch
ldiskfs/kernel_patches/patches/ext4-inode-version-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-kill-dx_root.patch
ldiskfs/kernel_patches/patches/ext4-max-dir-size-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-misc-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch
ldiskfs/kernel_patches/patches/ext4-prealloc-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-version-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-rhel5.patch
ldiskfs/kernel_patches/patches/ext4_data_in_dirent.patch
ldiskfs/kernel_patches/patches/iopen-2.6.18-rhel5-ext4.patch
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series

index 7a97989..c395e00 100644 (file)
@@ -38,9 +38,9 @@ Index: linux-stage/fs/ext4/ext4.h
 --- linux-stage.orig/fs/ext4/ext4.h
 +++ linux-stage/fs/ext4/ext4.h
 @@ -1024,6 +1024,8 @@ extern unsigned long ext4_count_free_ino
- extern unsigned long ext4_count_dirs (struct super_block *);
- extern void ext4_check_inodes_bitmap (struct super_block *);
- extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+ extern unsigned long ext4_count_dirs(struct super_block *);
+ extern void ext4_check_inodes_bitmap(struct super_block *);
 +extern struct buffer_head *ext4_read_inode_bitmap(struct super_block *sb,
 +                                                ext4_group_t block_group);
  
index 8131d96..97b5ba1 100644 (file)
@@ -2761,9 +2761,9 @@ Index: linux-2.6.18.8/include/linux/ext3_fs.h
                                         EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
 @@ -816,6 +821,9 @@ extern int ext3_get_inode_loc(struct ino
- extern void ext3_truncate (struct inode *);
- extern void ext3_set_inode_flags(struct inode *);
  extern void ext3_set_aops(struct inode *inode);
+ extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+                      u64 start, u64 len);
 +extern int ext3_writepage_trans_blocks(struct inode *);
 +extern int ext3_block_truncate_page(handle_t *handle, struct page *page,
 +              struct address_space *mapping, loff_t from);
index 77c9e99..1161d6d 100644 (file)
@@ -65,7 +65,7 @@ Index: b/fs/ext3/namei.c
        struct buffer_head *bh;
        struct dx_frame *frame = frame_in;
        u32 hash;
-@@ -372,45 +374,45 @@ dx_probe(struct dentry *dentry, struct i
+@@ -372,46 +374,45 @@ dx_probe(struct dentry *dentry, struct i
                dir = dentry->d_parent->d_inode;
        if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
                goto fail;
@@ -117,14 +117,14 @@ Index: b/fs/ext3/namei.c
  
 -      entries = (struct dx_entry *) (((char *)&root->info) +
 -                                     root->info.info_length);
--      assert(dx_get_limit(entries) == dx_root_limit(dir,
--                                                    root->info.info_length));
 +      entries = (struct dx_entry *) (((char *)info) + info->info_length);
-+      assert(dx_get_limit(entries) == dx_root_limit(dir, info->info_length));
-+
-       dxtrace (printk("Look up %x", hash));
-       while (1)
-       {
+-      if (dx_get_limit(entries) != dx_root_limit(dir,
+-                                                 root->info.info_length)) {
++      if (dx_get_limit(entries) != dx_root_limit(dir, info->info_length)) {
+               ext3_warning(dir->i_sb, __FUNCTION__,
+                            "dx entry: limit != root limit");
+               brelse(bh);
 @@ -467,10 +469,12 @@ fail:
  
  static void dx_release (struct dx_frame *frames)
index 30a8184..5dd2fc5 100644 (file)
@@ -204,7 +204,7 @@ diff -rupN linux-2.6.18-128.1.6_1/include/linux/ext3_fs.h linux-2.6.18-128.1.6_2
  extern struct proc_dir_entry *proc_root_ext3;
  extern int __init init_ext3_proc(void);
  extern void exit_ext3_proc(void);
-@@ -1107,6 +1111,19 @@ extern struct inode_operations ext3_file
+@@ -1107,6 +1111,20 @@ extern struct inode_operations ext3_file
  extern const struct file_operations ext3_file_operations;
  
  /* namei.c */
@@ -219,6 +219,7 @@ diff -rupN linux-2.6.18-128.1.6_1/include/linux/ext3_fs.h linux-2.6.18-128.1.6_2
 +extern struct buffer_head * ext3_find_entry(struct dentry *dentry,
 +                                          struct ext3_dir_entry_2
 +                                          ** res_dir);
++#define ll_ext3_find_entry(inode, dentry, res_dir) ext3_find_entry(dentry, res_dir)
 +extern int ext3_add_dot_dotdot(handle_t *handle, struct inode *dir,
 +                             struct inode *inode);
  extern struct inode_operations ext3_dir_inode_operations;
index e4e8dba..49e985b 100644 (file)
@@ -12,3 +12,8 @@ Index: linux-2.6.18-128.1.6/fs/ext3/super.c
        return 0;
  out:
        destroy_inodecache();
+--- /dev/null   2009-09-21 17:11:24.467285554 +0800
++++ linux-2.6.27.21-0.1/fs/ext3/fiemap.h
+@@ -0,0 +1,2 @@
++
++#include_next <fiemap.h>
index 533e2a0..485aaec 100644 (file)
@@ -75,18 +75,17 @@ Index: b/fs/ext3/namei.c
                        names++;
                }
                de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-@@ -411,7 +422,10 @@ dx_probe(struct dentry *dentry, struct i
-       }
+@@ -411,7 +422,9 @@ dx_probe(struct dentry *dentry, struct i
  
        entries = (struct dx_entry *) (((char *)info) + info->info_length);
--      assert(dx_get_limit(entries) == dx_root_limit(dir, info->info_length));
-+      assert(dx_get_limit(entries) == dx_root_limit(dir->i_sb->s_blocksize,
-+                                              (struct ext3_dir_entry_2*)bh->b_data,
-+                                              info->info_length));
-+
  
-       dxtrace (printk("Look up %x", hash));
-       while (1)
+-      if (dx_get_limit(entries) != dx_root_limit(dir, info->info_length)) {
++      if (dx_get_limit(entries) != dx_root_limit(dir->i_sb->s_blocksize,
++                                              (struct ext3_dir_entry_2*)bh->b_data,
++                                              info->info_length)) {
+               ext3_warning(dir->i_sb, __FUNCTION__,
+                            "dx entry: limit != root limit");
+               brelse(bh);
 @@ -583,7 +597,7 @@ static int htree_dirblock_to_tree(struct
        de = (struct ext3_dir_entry_2 *) bh->b_data;
        top = (struct ext3_dir_entry_2 *) ((char *) de +
index a1b8375..b5febbf 100644 (file)
@@ -1,8 +1,8 @@
-Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
+Index: linux-2.6.27.21-0.1/fs/ext4/ialloc.c
 ===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
-+++ linux-2.6.18-128.1.6/fs/ext4/ialloc.c
-@@ -946,6 +946,36 @@ fail_drop:
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ialloc.c  2009-07-07 14:47:04.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ialloc.c       2009-07-07 15:04:02.000000000 +0530
+@@ -953,6 +953,36 @@
        return ERR_PTR(err);
  }
  
@@ -18,7 +18,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
 +              for (group = EXT4_SB(sb)->s_groups_count - 1; group >= 0;
 +                   --group) {
 +                      desc = ext4_get_group_desc(sb, group, NULL);
-+                      if (desc->bg_free_inodes_count == 0)
++                      if (ext4_free_inodes_count(sb, desc) == 0)
 +                              continue;
 +
 +                      bitmap_bh = ext4_read_inode_bitmap(sb, group);
@@ -39,26 +39,12 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
  /* Verify that we are loading a valid orphan from disk */
  struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
  {
-Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
+Index: linux-2.6.27.21-0.1/fs/ext4/namei.c
 ===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/namei.c
-+++ linux-2.6.18-128.1.6/fs/ext4/namei.c
-@@ -151,14 +151,24 @@ struct dx_map_entry
-       u16 size;
- };
-+/*
-+ * dentry_param used by ext4_new_inode_wantedi()
-+ */
- #define LVFS_DENTRY_PARAM_MAGIC               20070216UL
- struct lvfs_dentry_params
- {
--      unsigned long   p_inum;
--      void        *p_ptr;
--      u32          magic;
-+      unsigned long   ldp_inum;
-+      long            ldp_flags;
-+      u32             ldp_magic;
+--- linux-2.6.27.21-0.1.orig/fs/ext4/namei.c   2009-07-07 14:47:05.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/namei.c        2009-07-07 15:04:21.000000000 +0530
+@@ -161,6 +161,12 @@
+       u32             ldp_magic;
  };
  
 +/* Only use the least 3 bits of ldp_flags for goal policy */
@@ -67,35 +53,35 @@ Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
 +      DP_LASTGROUP_REVERSE = 1,
 +} dp_policy_t;
 +
-+
  static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
  static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
- static inline unsigned dx_get_hash (struct dx_entry *entry);
-@@ -1762,8 +1772,13 @@ static struct inode * ext4_new_inode_wan
+ static inline unsigned dx_get_hash(struct dx_entry *entry);
+@@ -1771,8 +1777,14 @@
        if (dentry->d_fsdata != NULL) {
                struct lvfs_dentry_params *param = dentry->d_fsdata;
  
--              if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
--                      inum = param->p_inum;
+-              if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC)
+-                      inum = param->ldp_inum;
 +              if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC) {
 +                      if ((dp_policy_t)(param->ldp_flags & 0x7) ==
 +                          DP_LASTGROUP_REVERSE)
-+                              inum = ext4_find_reverse(dir->i_sb);
-+                        else /* DP_GOAL_POLICY */
++                              inum = ext4_find_reverse(sb);
++                      else /* DP_GOAL_POLICY */
 +                              inum = param->ldp_inum;
-+                }
++              }
++
        }
-       return ext4_new_inode(handle, dir, mode, inum);
+       return inum;
  }
-Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
+Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
 ===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
-+++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -1071,6 +1071,7 @@ extern int ext4fs_dirhash(const char *na
- /* ialloc.c */
- extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
                                    unsigned long);
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h    2009-07-07 14:47:22.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ext4.h 2009-07-07 15:04:02.000000000 +0530
+@@ -1101,6 +1101,7 @@
+                                  EXT4_SB(dir->i_sb)->s_inode_goal);
+ }
extern void ext4_free_inode(handle_t *, struct inode *);
 +extern unsigned long ext4_find_reverse(struct super_block *);
- extern void ext4_free_inode (handle_t *, struct inode *);
- extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext4_count_free_inodes (struct super_block *);
+ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+ extern unsigned long ext4_count_dirs(struct super_block *);
index 0ec5670..0503d35 100644 (file)
@@ -14,16 +14,16 @@ Index: linux-2.6.18-128.1.6/fs/ext4/super.c
 @@ -1222,7 +1224,7 @@ enum {
        Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
        Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
-       Opt_mballoc, Opt_nomballoc, Opt_stripe,
+       Opt_inode_readahead_blks, Opt_journal_ioprio,
 -      Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
 +      Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
  };
  
  static match_table_t tokens = {
 @@ -1284,6 +1286,7 @@ static match_table_t tokens = {
-       {Opt_nomballoc, "nomballoc"},
-       {Opt_stripe, "stripe=%u"},
-       {Opt_resize, "resize"},
+       {Opt_auto_da_alloc, "auto_da_alloc=%u"},
+       {Opt_auto_da_alloc, "auto_da_alloc"},
+       {Opt_noauto_da_alloc, "noauto_da_alloc"},
 +      {Opt_bigendian_extents, "bigendian_extents"},
        {Opt_err, NULL},
  };
index 8f714f8..95609d9 100644 (file)
@@ -2,37 +2,26 @@ Index: linux-2.6.18-128.1.6/fs/ext4/balloc.c
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/balloc.c
 +++ linux-2.6.18-128.1.6/fs/ext4/balloc.c
-@@ -321,15 +321,15 @@ ext4_read_block_bitmap(struct super_bloc
-       if (bh_uptodate_or_lock(bh))
-               return bh;
+@@ -321,16 +321,16 @@ ext4_read_block_bitmap(struct super_bloc
+               unlock_buffer(bh);
+               return bh;
+       }
 -      spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +      ext4_lock_group(sb, block_group);
        if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                ext4_init_block_bitmap(sb, bh, block_group, desc);
+               set_bitmap_uptodate(bh);
                set_buffer_uptodate(bh);
-               unlock_buffer(bh);
 -              spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +              ext4_unlock_group(sb, block_group);
+               unlock_buffer(bh);
                return bh;
        }
 -      spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +      ext4_unlock_group(sb, block_group);
-       if (bh_submit_read(bh) < 0) {
-               put_bh(bh);
-               ext4_error(sb, __func__,
-@@ -778,8 +778,9 @@ do_more:
-               BUFFER_TRACE(bitmap_bh, "set in b_committed_data");
-               J_ASSERT_BH(bitmap_bh,
-                               bh2jh(bitmap_bh)->b_committed_data != NULL);
--              ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i,
--                              bh2jh(bitmap_bh)->b_committed_data);
-+              ext4_set_bit_atomic(ext4_group_lock_ptr(sb, block_group),
-+                                  bit + i,
-+                                  bh2jh(bitmap_bh)->b_committed_data);
-               /*
-                * We clear the bit in the bitmap after setting the committed
+       if (buffer_uptodate(bh)) {
+               /*
+                * if not uninit if bh is uptodate,
 @@ -787,7 +788,7 @@ do_more:
                 * the allocator uses.
                 */
@@ -42,131 +31,76 @@ Index: linux-2.6.18-128.1.6/fs/ext4/balloc.c
                                                bit + i, bitmap_bh->b_data)) {
                        jbd_unlock_bh_state(bitmap_bh);
                        ext4_error(sb, __func__,
-@@ -801,17 +802,17 @@ do_more:
-       }
-       jbd_unlock_bh_state(bitmap_bh);
+@@ -801,18 +802,18 @@ do_more:
+                       blocks_freed++;
+               }
+       }
 -      spin_lock(sb_bgl_lock(sbi, block_group));
 +      ext4_lock_group(sb, block_group);
-       le16_add_cpu(&desc->bg_free_blocks_count, group_freed);
+       blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
+       ext4_free_blks_set(sb, desc, blk_free_count);
        desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
 -      spin_unlock(sb_bgl_lock(sbi, block_group));
 +      ext4_unlock_group(sb, block_group);
-       percpu_counter_add(&sbi->s_freeblocks_counter, count);
+       percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
  
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
 -              spin_lock(sb_bgl_lock(sbi, flex_group));
 +              ext4_lock_group(sb, block_group);
-               sbi->s_flex_groups[flex_group].free_blocks += count;
+               sbi->s_flex_groups[flex_group].free_blocks += blocks_freed;
 -              spin_unlock(sb_bgl_lock(sbi, flex_group));
 +              ext4_unlock_group(sb, block_group);
        }
  
        /* We dirtied the bitmap block */
-@@ -1104,7 +1105,7 @@ repeat:
-       }
-       start = grp_goal;
--      if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-+      if (!claim_block(ext4_group_lock_ptr(sb, group),
-               grp_goal, bitmap_bh)) {
-               /*
-                * The block was allocated by another thread, or it was
-@@ -1120,7 +1121,7 @@ repeat:
-       grp_goal++;
-       while (num < *count && grp_goal < end
-               && ext4_test_allocatable(grp_goal, bitmap_bh)
--              && claim_block(sb_bgl_lock(EXT4_SB(sb), group),
-+              && claim_block(ext4_group_lock_ptr(sb, group),
-                               grp_goal, bitmap_bh)) {
-               num++;
-               grp_goal++;
-@@ -1872,7 +1873,7 @@ allocated:
-               }
-       }
-       jbd_lock_bh_state(bitmap_bh);
--      spin_lock(sb_bgl_lock(sbi, group_no));
-+      ext4_lock_group(sb, group_no);
-       if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) {
-               int i;
-@@ -1885,7 +1886,7 @@ allocated:
-               }
-       }
-       ext4_debug("found bit %d\n", grp_alloc_blk);
--      spin_unlock(sb_bgl_lock(sbi, group_no));
-+      ext4_unlock_group(sb, group_no);
-       jbd_unlock_bh_state(bitmap_bh);
- #endif
-@@ -1902,19 +1903,19 @@ allocated:
-        * list of some description.  We don't know in advance whether
-        * the caller wants to use it as metadata or data.
-        */
--      spin_lock(sb_bgl_lock(sbi, group_no));
-+      ext4_lock_group(sb, group_no);
-       if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
-               gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
-       le16_add_cpu(&gdp->bg_free_blocks_count, -num);
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
--      spin_unlock(sb_bgl_lock(sbi, group_no));
-+      ext4_unlock_group(sb, group_no);
-       percpu_counter_sub(&sbi->s_freeblocks_counter, num);
-       if (sbi->s_log_groups_per_flex) {
-               ext4_group_t flex_group = ext4_flex_group(sbi, group_no);
--              spin_lock(sb_bgl_lock(sbi, flex_group));
-+              ext4_lock_group(sb, flex_group);
-               sbi->s_flex_groups[flex_group].free_blocks -= num;
--              spin_unlock(sb_bgl_lock(sbi, flex_group));
-+              ext4_unlock_group(sb, flex_group);
-       }
-       BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
 Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
 +++ linux-2.6.18-128.1.6/fs/ext4/ialloc.c
-@@ -118,15 +118,15 @@ ext4_read_inode_bitmap(struct super_bloc
-       if (bh_uptodate_or_lock(bh))
-               return bh;
+@@ -118,16 +118,16 @@ ext4_read_inode_bitmap(struct super_bloc
+               unlock_buffer(bh);
+               return bh;
+       }
 -      spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +      ext4_lock_group(sb, block_group);
        if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
                ext4_init_inode_bitmap(sb, bh, block_group, desc);
+               set_bitmap_uptodate(bh);
                set_buffer_uptodate(bh);
-               unlock_buffer(bh);
 -              spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +              ext4_unlock_group(sb, block_group);
+               unlock_buffer(bh);
                return bh;
        }
 -      spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
 +      ext4_unlock_group(sb, block_group);
-       if (bh_submit_read(bh) < 0) {
-               put_bh(bh);
-               ext4_error(sb, __func__,
-@@ -221,8 +221,8 @@ void ext4_free_inode (handle_t *handle, 
+       if (buffer_uptodate(bh)) {
+               /*
+                * if not uninit if bh is uptodate,
+@@ -221,9 +221,9 @@ void ext4_free_inode (handle_t *handle, 
                goto error_return;
  
        /* Ok, now we can actually update the inode bitmaps.. */
--      if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
--                                      bit, bitmap_bh->b_data))
-+      if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group),
-+                                 bit, bitmap_bh->b_data))
-               ext4_error (sb, "ext4_free_inode",
-                             "bit already cleared for inode %lu", ino);
-       else {
-@@ -233,22 +233,22 @@ void ext4_free_inode (handle_t *handle, 
+-      spin_lock(sb_bgl_lock(sbi, block_group));
++      ext4_lock_group(sb, block_group);
+       cleared = ext4_clear_bit(bit, bitmap_bh->b_data);
+-      spin_unlock(sb_bgl_lock(sbi, block_group));
++      ext4_unlock_group(sb, block_group);
+       if (!cleared)
+               ext4_error(sb, "ext4_free_inode",
+                          "bit already cleared for inode %lu", ino);
+@@ -233,7 +233,7 @@ void ext4_free_inode (handle_t *handle, 
                if (fatal) goto error_return;
  
                if (gdp) {
 -                      spin_lock(sb_bgl_lock(sbi, block_group));
 +                      ext4_lock_group(sb, block_group);
-                       le16_add_cpu(&gdp->bg_free_inodes_count, 1);
-                       if (is_directory)
-                               le16_add_cpu(&gdp->bg_used_dirs_count, -1);
+                       count = ext4_free_inodes_count(sb, gdp) + 1;
+                       ext4_free_inodes_set(sb, gdp, count);
+                       if (is_directory) {
+@@ -233,16 +233,16 @@ void ext4_free_inode (handle_t *handle, 
+                       }
                        gdp->bg_checksum = ext4_group_desc_csum(sbi,
                                                        block_group, gdp);
 -                      spin_unlock(sb_bgl_lock(sbi, block_group));
@@ -185,25 +119,34 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
                        }
                }
                BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
-@@ -630,7 +630,7 @@ struct inode *ext4_new_inode(handle_t *h
-               if (err)
-                       goto fail;
--              if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+              if (ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group),
-                                       ino, bitmap_bh->b_data)) {
-                       printk(KERN_ERR "goal inode %lu unavailable\n", goal);
-                       /* Oh well, we tried. */
-@@ -691,7 +691,7 @@ repeat_in_this_group:
-                       if (err)
-                               goto fail;
+@@ -630,7 +630,7 @@
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
+
+-      spin_lock(sb_bgl_lock(sbi, group));
++      ext4_lock_group(sb, group);
+       if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) {
+               /* not a free inode */
+               retval = 1;
+@@ -691,7 +691,7 @@
+       ino++;
+       if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+                       ino > EXT4_INODES_PER_GROUP(sb)) {
+-              spin_unlock(sb_bgl_lock(sbi, group));
++              ext4_unlock_group(sb, group);
+               ext4_error(sb, __func__,
+                          "reserved inode or inode > inodes count - "
+                          "block_group = %u, inode=%lu", group,
+@@ -692,7 +692,7 @@
+       }
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
+ err_ret:
+-      spin_unlock(sb_bgl_lock(sbi, group));
++      ext4_unlock_group(sb, group);
+       return retval;
+ }
  
--                      if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+                      if (!ext4_set_bit_atomic(ext4_group_lock_ptr(sb, group),
-                                               ino, bitmap_bh->b_data)) {
-                               /* we won it */
-                               BUFFER_TRACE(bitmap_bh,
-@@ -751,14 +751,14 @@ got:
+@@ -751,16 +751,16 @@ got:
                }
  
                free = 0;
@@ -211,33 +154,17 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
 +              ext4_lock_group(sb, group);
                /* recheck and clear flag under lock if we still need to */
                if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
-                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
                        free = ext4_free_blocks_after_init(sb, group, gdp);
-                       gdp->bg_free_blocks_count = cpu_to_le16(free);
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+                       ext4_free_blks_set(sb, gdp, free);
+                       gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
+                                                               gdp);
                }
 -              spin_unlock(sb_bgl_lock(sbi, group));
 +              ext4_unlock_group(sb, group);
  
                /* Don't need to dirty bitmap block if we didn't change it */
                if (free) {
-@@ -771,7 +771,7 @@ got:
-                       goto fail;
-       }
--      spin_lock(sb_bgl_lock(sbi, group));
-+      ext4_lock_group(sb, group);
-       /* If we didn't allocate from within the initialized part of the inode
-        * table then we need to initialize up to this inode. */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-@@ -807,7 +807,7 @@ got:
-               le16_add_cpu(&gdp->bg_used_dirs_count, 1);
-       }
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
--      spin_unlock(sb_bgl_lock(sbi, group));
-+      ext4_unlock_group(sb, group);
-       BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
-       err = ext4_journal_dirty_metadata(handle, bh2);
-       if (err) goto fail;
 @@ -819,9 +819,9 @@ got:
  
        if (sbi->s_log_groups_per_flex) {
@@ -279,26 +206,27 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  static inline int mb_find_next_zero_bit(void *addr, int max, int start)
  {
        int fix = 0, ret, tmpmax;
-@@ -789,16 +777,16 @@ static int ext4_mb_init_cache(struct pag
-               if (bh_uptodate_or_lock(bh[i]))
-                       continue;
+@@ -789,17 +777,17 @@ static int ext4_mb_init_cache(struct pag
+                       unlock_buffer(bh[i]);
+                       continue;
+               }
 -              spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
 +              ext4_lock_group(sb, first_group + i);
                if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                        ext4_init_block_bitmap(sb, bh[i],
                                                first_group + i, desc);
+                       set_bitmap_uptodate(bh[i]);
                        set_buffer_uptodate(bh[i]);
-                       unlock_buffer(bh[i]);
 -                      spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
 +                      ext4_unlock_group(sb, first_group + i);
+                       unlock_buffer(bh[i]);
                        continue;
                }
 -              spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
 +              ext4_unlock_group(sb, first_group + i);
-               get_bh(bh[i]);
-               bh[i]->b_end_io = end_buffer_read_sync;
-               submit_bh(READ, bh[i]);
+               if (buffer_uptodate(bh[i])) {
+                       /*
+                        * if not uninit if bh is uptodate,
 @@ -1021,7 +1009,7 @@ static int mb_find_order_for_block(struc
        return 0;
  }
@@ -308,11 +236,14 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  {
        __u32 *addr;
  
-@@ -1034,12 +1022,12 @@ static void mb_clear_bits(spinlock_t *lo
+@@ -1034,15 +1022,12 @@ static void mb_clear_bits(spinlock_t *lo
                        cur += 32;
                        continue;
                }
--              mb_clear_bit_atomic(lock, cur, bm);
+-              if (lock)
+-                      mb_clear_bit_atomic(lock, cur, bm);
+-              else
+-                      mb_clear_bit(cur, bm);
 +              mb_clear_bit(cur, bm);
                cur++;
        }
@@ -323,11 +254,14 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  {
        __u32 *addr;
  
-@@ -1052,7 +1040,7 @@ static void mb_set_bits(spinlock_t *lock
+@@ -1052,10 +1040,7 @@ static void mb_set_bits(spinlock_t *lock
                        cur += 32;
                        continue;
                }
--              mb_set_bit_atomic(lock, cur, bm);
+-              if (lock)
+-                      mb_set_bit_atomic(lock, cur, bm);
+-              else
+-                      mb_set_bit(cur, bm);
 +              mb_set_bit(cur, bm);
                cur++;
        }
@@ -362,7 +296,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +              mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
 +                          ac->ac_b_ex.fe_len);
 +              ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
-               err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+               err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
                if (!err)
                        err = -EAGAIN;
                goto out_err;
@@ -372,27 +306,28 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  #ifdef AGGRESSIVE_CHECK
        {
                int i;
-@@ -3147,10 +3137,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+@@ -3147,9 +3137,7 @@ ext4_mb_mark_diskspace_used(struct ext4_
                }
        }
  #endif
--      mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data,
+-      spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
+-      mb_set_bits(NULL, bitmap_bh->b_data,
 -                              ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
 +      mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,ac->ac_b_ex.fe_len);
--      spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
        if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
                gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
                gdp->bg_free_blocks_count =
-@@ -3160,15 +3148,16 @@ ext4_mb_mark_diskspace_used(struct ext4_
-       }
-       le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len);
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
+@@ -3160,7 +3148,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+       len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
+       ext4_free_blks_set(sb, gdp, len);
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
 -      spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
 +
 +      ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
        percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
+       /*
+        * Now reduce the dirty block count also. Should not go negative
+@@ -3161,9 +3148,9 @@ ext4_mb_mark_diskspace_used(struct ext4_
        if (sbi->s_log_groups_per_flex) {
                ext4_group_t flex_group = ext4_flex_group(sbi,
                                                          ac->ac_b_ex.fe_group);
@@ -404,6 +339,17 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
        }
  
        err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+@@ -3500,9 +3589,7 @@ int ext4_mb_check_ondisk_bitmap(struct s
+       while (n) {
+               entry = rb_entry(n, struct ext4_free_data, node);
+-              mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
+-                              bitmap, entry->start_blk,
+-                              entry->count);
++              mb_set_bits(bitmap, entry->start_blk, entry->count);
+               n = rb_next(n);
+       }
+       return;
 @@ -3600,7 +3589,7 @@ int ext4_mb_check_ondisk_bitmap(struct s
  /*
   * the function goes through all preallocation in this group and marks them
@@ -431,82 +377,33 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  static noinline_for_stack int
  ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
                          ext4_group_t group, ext4_grpblk_t block, int count)
-@@ -4755,7 +4744,6 @@ ext4_mb_free_metadata(handle_t *handle, 
-       BUG_ON(e4b->bd_bitmap_page == NULL);
-       BUG_ON(e4b->bd_buddy_page == NULL);
--      ext4_lock_group(sb, group);
-       for (i = 0; i < count; i++) {
-               md = db->bb_md_cur;
-               if (md && db->bb_tid != handle->h_transaction->t_tid) {
-@@ -4766,8 +4754,10 @@ ext4_mb_free_metadata(handle_t *handle, 
-               if (md == NULL) {
-                       ext4_unlock_group(sb, group);
-                       md = kmalloc(sizeof(*md), GFP_NOFS);
--                      if (md == NULL)
-+                      if (md == NULL) {
-+                              ext4_lock_group(sb, group);
-                               return -ENOMEM;
-+                      }
-                       md->num = 0;
-                       md->group = group;
-@@ -4800,7 +4790,6 @@ ext4_mb_free_metadata(handle_t *handle, 
-                       db->bb_md_cur = NULL;
-               }
-       }
--      ext4_unlock_group(sb, group);
-       return 0;
- }
-@@ -4901,6 +4890,13 @@ do_more:
-       if (err)
-               goto error_return;
-+      if (ac) {
-+              ac->ac_b_ex.fe_group = block_group;
-+              ac->ac_b_ex.fe_start = bit;
-+              ac->ac_b_ex.fe_len = count;
-+              ext4_mb_store_history(ac);
-+      }
-+
-       err = ext4_mb_load_buddy(sb, block_group, &e4b);
-       if (err)
-               goto error_return;
-@@ -4912,42 +4908,31 @@ do_more:
-                       BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
-       }
- #endif
--      mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
--                      bit, count);
--
-+      ext4_lock_group(sb, block_group);
-+      mb_clear_bits(bitmap_bh->b_data, bit, count);
-       /* We dirtied the bitmap block */
-       BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
-       err = ext4_journal_dirty_metadata(handle, bitmap_bh);
--      if (ac) {
--              ac->ac_b_ex.fe_group = block_group;
--              ac->ac_b_ex.fe_start = bit;
--              ac->ac_b_ex.fe_len = count;
--              ext4_mb_store_history(ac);
--      }
--
-       if (metadata) {
-               /* blocks being freed are metadata. these blocks shouldn't
-                * be used until this transaction is committed */
-               ext4_mb_free_metadata(handle, &e4b, block_group, bit, count);
-       } else {
--              ext4_lock_group(sb, block_group);
-               mb_free_blocks(inode, &e4b, bit, count);
-               ext4_mb_return_to_preallocation(inode, &e4b, block, count);
+@@ -4912,35 +4908,30 @@ do_more:
+               new_entry->count = count;
+               new_entry->t_tid = handle->h_transaction->t_tid;
+               ext4_lock_group(sb, block_group);
+-              mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
+-                              bit, count);
++              mb_clear_bits(bitmap_bh->b_data, bit, count);
+               ext4_mb_free_metadata(handle, &e4b, new_entry);
+-              ext4_unlock_group(sb, block_group);
+       } else {
+               ext4_lock_group(sb, block_group);
+               /* need to update group_info->bb_free and bitmap
+                * with group lock held. generate_buddy look at
+                * them with group lock_held
+                */
+-              mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
+-                              bit, count);
++              mb_clear_bits(bitmap_bh->b_data, bit, count);
+               mb_free_blocks(inode, &e4b, bit, count);
+               ext4_mb_return_to_preallocation(inode, &e4b, block, count);
 -              ext4_unlock_group(sb, block_group);
        }
  
 -      spin_lock(sb_bgl_lock(sbi, block_group));
-       le16_add_cpu(&gdp->bg_free_blocks_count, count);
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
+       ret = ext4_free_blks_count(sb, gdp) + count;
+       ext4_free_blks_set(sb, gdp, ret);
+       gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
 -      spin_unlock(sb_bgl_lock(sbi, block_group));
 +      ext4_unlock_group(sb, block_group);
        percpu_counter_add(&sbi->s_freeblocks_counter, count);
@@ -525,22 +422,22 @@ Index: linux-2.6.18-128.1.6/fs/ext4/super.c
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/super.c
 +++ linux-2.6.18-128.1.6/fs/ext4/super.c
-@@ -1934,16 +1934,18 @@ static int ext4_check_descriptors(struct
-                              "(block %llu)!", i, inode_table);
-                       return 0;
-               }
+@@ -1934,18 +1934,18 @@ static int ext4_check_descriptors(struct
+                              "(block %llu)!\n", i, inode_table);
+                       return 0;
+               }
 -              spin_lock(sb_bgl_lock(sbi, i));
 +              ext4_lock_group(sb, i);
-               if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
-                       printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
-                              "Checksum for group %lu failed (%u!=%u)\n",
-                              i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
-                              gdp)), le16_to_cpu(gdp->bg_checksum));
--                      if (!(sb->s_flags & MS_RDONLY))
-+                      if (!(sb->s_flags & MS_RDONLY)) {
+               if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
+                       printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
+                              "Checksum for group %u failed (%u!=%u)\n",
+                              i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
+                              gdp)), le16_to_cpu(gdp->bg_checksum));
+                       if (!(sb->s_flags & MS_RDONLY)) {
+-                              spin_unlock(sb_bgl_lock(sbi, i));
 +                              ext4_unlock_group(sb, i);
                                return 0;
-+                      }
+                       }
                }
 -              spin_unlock(sb_bgl_lock(sbi, i));
 +              ext4_unlock_group(sb, i);
@@ -551,45 +448,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
 +++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -1303,6 +1303,33 @@ extern int ext4_get_blocks_wrap(handle_t
-                       sector_t block, unsigned long max_blocks,
-                       struct buffer_head *bh, int create,
-                       int extend_disksize);
-+
-+static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
-+                                            ext4_group_t group)
-+{
-+      struct blockgroup_lock *bgl = &EXT4_SB(sb)->s_blockgroup_lock;
-+      return &bgl->locks[group & (NR_BG_LOCKS-1)].lock;
-+}
-+
-+static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
-+{
-+      spin_lock(ext4_group_lock_ptr(sb, group));
-+}
-+
-+static inline void ext4_unlock_group(struct super_block *sb,
-+                                      ext4_group_t group)
-+{
-+      spin_unlock(ext4_group_lock_ptr(sb, group));
-+}
-+
-+static inline int ext4_is_group_locked(struct super_block *sb,
-+                                      ext4_group_t group)
-+{
-+      return spin_is_locked(ext4_group_lock_ptr(sb, group));
-+}
-+
-+
-+
- #endif        /* __KERNEL__ */
- #endif        /* _EXT4_H */
-Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h
-+++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h
-@@ -127,7 +127,6 @@ struct ext4_group_info {
+@@ -127,35 +127,9 @@ struct ext4_group_info {
  };
  
  #define EXT4_GROUP_INFO_NEED_INIT_BIT 0
@@ -597,10 +456,6 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
  
  #define EXT4_MB_GRP_NEED_INIT(grp)    \
        (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
-@@ -272,31 +271,6 @@ static void ext4_mb_put_pa(struct ext4_a
- static int ext4_mb_init_per_dev_proc(struct super_block *sb);
- static int ext4_mb_destroy_per_dev_proc(struct super_block *sb);
 -
 -static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
 -{
@@ -626,6 +481,39 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
 -                                              &(grinfo->bb_state));
 -}
 -
- static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
-                                       struct ext4_free_extent *fex)
- {
+ /*
+  * Inodes and files operations
+  */
+@@ -1303,6 +1303,32 @@ extern int ext4_get_blocks_wrap(handle_t
+       set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
+ }
++static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
++                                            ext4_group_t group)
++{
++      struct blockgroup_lock *bgl = &EXT4_SB(sb)->s_blockgroup_lock;
++      return &bgl->locks[group & (NR_BG_LOCKS-1)].lock;
++}
++
++static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
++{
++      spin_lock(ext4_group_lock_ptr(sb, group));
++}
++
++static inline void ext4_unlock_group(struct super_block *sb,
++                                      ext4_group_t group)
++{
++      spin_unlock(ext4_group_lock_ptr(sb, group));
++}
++
++static inline int ext4_is_group_locked(struct super_block *sb,
++                                      ext4_group_t group)
++{
++      return spin_is_locked(ext4_group_lock_ptr(sb, group));
++}
++
++
++
+ #endif        /* __KERNEL__ */
+ #endif        /* _EXT4_H */
diff --git a/ldiskfs/kernel_patches/patches/ext4-extents-mount-option-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-extents-mount-option-rhel5.patch
new file mode 100644 (file)
index 0000000..96e964b
--- /dev/null
@@ -0,0 +1,170 @@
+diff -up linux-2.6.18-164/fs/ext4/ext4.h linux-2.6.18-164/fs/ext4/ext4.h
+--- linux-2.6.18-164/fs/ext4/ext4.h    2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ext4.h    2009-10-16 23:31:41.000000000 +0800
+@@ -539,6 +539,7 @@ do {                                                                              \
+ #define EXT4_MOUNT_QUOTA              0x80000 /* Some quota option set */
+ #define EXT4_MOUNT_USRQUOTA           0x100000 /* "old" user quota */
+ #define EXT4_MOUNT_GRPQUOTA           0x200000 /* "old" group quota */
++#define EXT4_MOUNT_EXTENTS            0x400000 /* Extents support */
+ #define EXT4_MOUNT_JOURNAL_CHECKSUM   0x800000 /* Journal checksums */
+ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT       0x1000000 /* Journal Async Commit */
+ #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
+diff -up linux-2.6.18-164/fs/ext4/ext4_jbd2.h linux-2.6.18-164/fs/ext4/ext4_jbd2.h
+--- linux-2.6.18-164/fs/ext4/ext4_jbd2.h       2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ext4_jbd2.h       2009-10-16 23:32:02.000000000 +0800
+@@ -33,7 +33,7 @@
+ #define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)                              \
+       (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)   \
+-       ? 27U : 8U)
++              || test_opt(sb, EXTENTS) ? 27U : 8U)
+ /* Indicate that EXT4_SINGLEDATA_TRANS_BLOCKS takes the sb as argument */
+ #define EXT4_SINGLEDATA_TRANS_BLOCKS_HAS_SB
+diff -up linux-2.6.18-164/fs/ext4/extents.c linux-2.6.18-164/fs/ext4/extents.c
+--- linux-2.6.18-164/fs/ext4/extents.c 2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/extents.c 2009-10-16 23:33:36.000000000 +0800
+@@ -2313,7 +2313,7 @@ void ext4_ext_init(struct super_block *s
+        * possible initialization would be here
+        */
+-      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++      if (test_opt(sb, EXTENTS)) {
+               printk(KERN_INFO "EXT4-fs: file extents enabled");
+ #ifdef AGGRESSIVE_TEST
+               printk(", aggressive tests");
+@@ -2338,7 +2338,7 @@ void ext4_ext_init(struct super_block *s
+  */
+ void ext4_ext_release(struct super_block *sb)
+ {
+-      if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
++      if (!test_opt(sb, EXTENTS))
+               return;
+ #ifdef EXTENTS_STATS
+diff -up linux-2.6.18-164/fs/ext4/ialloc.c linux-2.6.18-164/fs/ext4/ialloc.c
+--- linux-2.6.18-164/fs/ext4/ialloc.c  2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/ialloc.c  2009-10-16 23:34:38.000000000 +0800
+@@ -938,7 +938,7 @@ got:
+       if (err)
+               goto fail_free_drop;
+-      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++      if (test_opt(sb, EXTENTS)) {
+               /* set extent flag only for directory, file and normal symlink*/
+               if (S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) {
+                       EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+diff -up linux-2.6.18-164/fs/ext4/migrate.c linux-2.6.18-164/fs/ext4/migrate.c
+--- linux-2.6.18-164/fs/ext4/migrate.c 2009-09-28 16:11:26.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/migrate.c 2009-10-16 23:36:49.000000000 +0800
+@@ -459,13 +459,13 @@ int ext4_ext_migrate(struct inode *inode
+       struct list_blocks_struct lb;
+       unsigned long max_entries;
+-      /*
+-       * If the filesystem does not support extents, or the inode
+-       * already is extent-based, error out.
+-       */
+-      if (!EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
+-                                     EXT4_FEATURE_INCOMPAT_EXTENTS) ||
+-          (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
++      if (!test_opt(inode->i_sb, EXTENTS))
++              /*
++               * if mounted with noextents we don't allow the migrate
++               */
++              return -EINVAL;
++
++      if ((EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+               return -EINVAL;
+       if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
+diff -up linux-2.6.18-164/fs/ext4/super.c linux-2.6.18-164/fs/ext4/super.c
+--- linux-2.6.18-164/fs/ext4/super.c   2009-10-16 23:26:25.000000000 +0800
++++ linux-2.6.18-164/fs/ext4/super.c   2009-10-16 23:48:19.000000000 +0800
+@@ -849,6 +849,8 @@ static int ext4_show_options(struct seq_
+               seq_puts(seq, ",journal_async_commit");
+       if (test_opt(sb, NOBH))
+               seq_puts(seq, ",nobh");
++      if (!test_opt(sb, EXTENTS))
++              seq_puts(seq, ",noextents");
+       if (test_opt(sb, I_VERSION))
+               seq_puts(seq, ",i_version");
+       if (!test_opt(sb, DELALLOC))
+@@ -1334,6 +1336,7 @@ enum {
+       Opt_inode_readahead_blks, Opt_journal_ioprio,
+       Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
+       Opt_force_over_8tb,
++      Opt_extents, Opt_noextents,
+ };
+ static match_table_t tokens = {
+@@ -1401,6 +1404,8 @@ static match_table_t tokens = {
+       {Opt_noauto_da_alloc, "noauto_da_alloc"},
+       {Opt_bigendian_extents, "bigendian_extents"},
+       {Opt_force_over_8tb, "force_over_8tb"},
++      {Opt_extents, "extents"},
++      {Opt_noextents, "noextents"},
+       {Opt_err, NULL},
+ };
+@@ -1441,6 +1446,7 @@ static int parse_options(char *options, 
+       int qtype, qfmt;
+       char *qname;
+ #endif
++      ext4_fsblk_t last_block;
+       if (!options)
+               return 1;
+@@ -1829,6 +1835,33 @@ set_qf_format:
+               case Opt_force_over_8tb:
+                       force_over_8tb = 1;
+                       break;
++              case Opt_extents:
++                      if (!EXT4_HAS_INCOMPAT_FEATURE(sb,
++                                      EXT4_FEATURE_INCOMPAT_EXTENTS)) {
++                              ext4_warning(sb, __func__,
++                                      "extents feature not enabled "
++                                      "on this filesystem, use tune2fs");
++                              return 0;
++                      }
++                      set_opt(sbi->s_mount_opt, EXTENTS);
++                      break;
++              case Opt_noextents:
++                      /*
++                       * When e2fsprogs support resizing an already existing
++                       * ext3 file system to greater than 2**32 we need to
++                       * add support to block allocator to handle growing
++                       * already existing block  mapped inode so that blocks
++                       * allocated for them fall within 2**32
++                      */
++                      last_block = ext4_blocks_count(sbi->s_es) - 1;
++                      if (last_block  > 0xffffffffULL) {
++                              printk(KERN_ERR "EXT4-fs: Filesystem too "
++                                      "large to mount with "
++                                      "-o noextents options\n");
++                              return 0;
++                      }
++                      clear_opt(sbi->s_mount_opt, EXTENTS);
++                      break;
+               default:
+                       printk(KERN_ERR
+                              "EXT4-fs: Unrecognized mount option \"%s\" "
+@@ -2501,6 +2534,18 @@ static int ext4_fill_super(struct super_
+       set_opt(sbi->s_mount_opt, BARRIER);
+       /*
++       * turn on extents feature by default in ext4 filesystem
++       * only if feature flag already set by mkfs or tune2fs.
++       * Use -o noextents to turn it off
++      */
++      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
++              set_opt(sbi->s_mount_opt, EXTENTS);
++      else
++              ext4_warning(sb, __func__,
++                      "extents feature not enabled on this filesystem, "
++                      "use tune2fs.");
++
++      /*
+        * enable delayed allocation by default
+        * Use -o nodelalloc to turn it off
+        */
index 7163c94..b9468f8 100644 (file)
@@ -184,13 +184,13 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
 --- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
 +++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
 @@ -300,6 +300,7 @@ struct ext4_new_group_data {
- #define EXT4_IOC_GETRSVSZ             _IOR('f', 5, long)
- #define EXT4_IOC_SETRSVSZ             _IOW('f', 6, long)
- #define EXT4_IOC_MIGRATE              _IO('f', 7)
+ #define EXT4_IOC_GROUP_EXTEND         _IOW('f', 7, unsigned long)
+ #define EXT4_IOC_GROUP_ADD            _IOW('f', 8, struct ext4_new_group_input)
+ #define EXT4_IOC_MIGRATE              _IO('f', 9)
 +#define EXT4_IOC_FIEMAP                       _IOWR('f', 11, struct fiemap)
+  /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
  
  /*
-  * ioctl commands in 32 bit emulation
 @@ -317,6 +318,8 @@ struct ext4_new_group_data {
  #define EXT4_IOC32_GETVERSION_OLD     FS_IOC32_GETVERSION
  #define EXT4_IOC32_SETVERSION_OLD     FS_IOC32_SETVERSION
@@ -203,277 +203,13 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
 @@ -1117,6 +1120,9 @@ extern int ext4_page_mkwrite(struct vm_a
  /* ioctl.c */
  extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
- extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
+ extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
 +struct fiemap_extent_info;
 +extern int ext4_fiemap(struct inode *, struct fiemap_extent_info *, __u64,
 +                     __u64);
  
  /* migrate.c */
  extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
-Index: linux-2.6.18-128.1.6/fs/ext4/ext4_extents.h
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/ext4_extents.h
-+++ linux-2.6.18-128.1.6/fs/ext4/ext4_extents.h
-@@ -128,6 +128,22 @@ struct ext4_ext_path {
- #define EXT_MAX_BLOCK 0xffffffff
- /*
-+ * to be called by ext4_ext_walk_space()
-+ * negative retcode - error
-+ * positive retcode - signal for ext4_ext_walk_space(), see below
-+ * callback must return valid extent (passed or newly created)
-+ */
-+typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
-+                                  struct ext4_ext_cache *,
-+                                  struct ext4_extent *, void *);
-+
-+#define HAVE_EXT_PREPARE_CB_EXTENT
-+
-+#define EXT_CONTINUE   0
-+#define EXT_BREAK      1
-+#define EXT_REPEAT     2
-+
-+/*
-  * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
-  * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
-  * MSB of ee_len field in the extent datastructure to signify if this
-@@ -223,6 +239,8 @@ extern int ext4_ext_try_to_merge(struct 
-                                struct ext4_extent *);
- extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
- extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
-+extern int ext4_ext_walk_space(struct inode *, ext4_lblk_t, ext4_lblk_t,
-+                             ext_prepare_callback, void *);
- extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
-                                                       struct ext4_ext_path *);
- extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *,
-Index: linux-2.6.18-128.1.6/fs/ext4/extents.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/extents.c
-+++ linux-2.6.18-128.1.6/fs/ext4/extents.c
-@@ -44,7 +44,7 @@
- #include <asm/uaccess.h>
- #include "ext4_jbd2.h"
- #include "ext4_extents.h"
--
-+#include "fiemap.h"
- /*
-  * ext_pblock:
-@@ -1597,6 +1597,113 @@ cleanup:
-       return err;
- }
-+int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
-+                      ext4_lblk_t num, ext_prepare_callback func,
-+                      void *cbdata)
-+{
-+      struct ext4_ext_path *path = NULL;
-+      struct ext4_ext_cache cbex;
-+      struct ext4_extent *ex;
-+      ext4_lblk_t next, start = 0, end = 0;
-+      ext4_lblk_t last = block + num;
-+      int depth, exists, err = 0;
-+
-+      BUG_ON(func == NULL);
-+      BUG_ON(inode == NULL);
-+
-+      while (block < last && block != EXT_MAX_BLOCK) {
-+              num = last - block;
-+              /* find extent for this block */
-+              path = ext4_ext_find_extent(inode, block, path);
-+              if (IS_ERR(path)) {
-+                      err = PTR_ERR(path);
-+                      path = NULL;
-+                      break;
-+              }
-+
-+              depth = ext_depth(inode);
-+              BUG_ON(path[depth].p_hdr == NULL);
-+              ex = path[depth].p_ext;
-+              next = ext4_ext_next_allocated_block(path);
-+
-+              exists = 0;
-+              if (!ex) {
-+                      /* there is no extent yet, so try to allocate
-+                       * all requested space */
-+                      start = block;
-+                      end = block + num;
-+              } else if (le32_to_cpu(ex->ee_block) > block) {
-+                      /* need to allocate space before found extent */
-+                      start = block;
-+                      end = le32_to_cpu(ex->ee_block);
-+                      if (block + num < end)
-+                              end = block + num;
-+              } else if (block >= le32_to_cpu(ex->ee_block)
-+                                      + ext4_ext_get_actual_len(ex)) {
-+                      /* need to allocate space after found extent */
-+                      start = block;
-+                      end = block + num;
-+                      if (end >= next)
-+                              end = next;
-+              } else if (block >= le32_to_cpu(ex->ee_block)) {
-+                      /*
-+                       * some part of requested space is covered
-+                       * by found extent
-+                       */
-+                      start = block;
-+                      end = le32_to_cpu(ex->ee_block)
-+                              + ext4_ext_get_actual_len(ex);
-+                      if (block + num < end)
-+                              end = block + num;
-+                      exists = 1;
-+              } else {
-+                      BUG();
-+              }
-+              BUG_ON(end <= start);
-+
-+              if (!exists) {
-+                      cbex.ec_block = start;
-+                      cbex.ec_len = end - start;
-+                      cbex.ec_start = 0;
-+                      cbex.ec_type = EXT4_EXT_CACHE_GAP;
-+              } else {
-+                      cbex.ec_block = le32_to_cpu(ex->ee_block);
-+                      cbex.ec_len = ext4_ext_get_actual_len(ex);
-+                      cbex.ec_start = ext_pblock(ex);
-+                      cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
-+              }
-+
-+              BUG_ON(cbex.ec_len == 0);
-+              err = func(inode, path, &cbex, ex, cbdata);
-+              ext4_ext_drop_refs(path);
-+
-+              if (err < 0)
-+                      break;
-+
-+              if (err == EXT_REPEAT)
-+                      continue;
-+              else if (err == EXT_BREAK) {
-+                      err = 0;
-+                      break;
-+              }
-+
-+              if (ext_depth(inode) != depth) {
-+                      /* depth was changed. we have to realloc path */
-+                      kfree(path);
-+                      path = NULL;
-+              }
-+
-+              block = cbex.ec_block + cbex.ec_len;
-+      }
-+
-+      if (path) {
-+              ext4_ext_drop_refs(path);
-+              kfree(path);
-+      }
-+
-+      return err;
-+}
-+
- static void
- ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
-                       __u32 len, ext4_fsblk_t start, int type)
-@@ -2953,3 +3060,100 @@ retry:
-       return ret > 0 ? ret2 : ret;
- }
- #endif
-+
-+/*
-+ * Callback function called for each extent to gather FIEMAP information.
-+ */
-+int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
-+                     struct ext4_ext_cache *newex, struct ext4_extent *ex,
-+                     void *data)
-+{
-+      struct fiemap_extent_info *fieinfo = data;
-+      unsigned char blksize_bits = inode->i_sb->s_blocksize_bits;
-+      __u64   logical;
-+      __u64   physical;
-+      __u64   length;
-+      __u32   flags = 0;
-+      int     error;
-+
-+      logical =  (__u64)newex->ec_block << blksize_bits;
-+
-+      if (newex->ec_type == EXT4_EXT_CACHE_GAP) {
-+              pgoff_t offset;
-+              struct page *page;
-+              struct buffer_head *bh = NULL;
-+
-+              offset = logical >> PAGE_SHIFT;
-+              page = find_get_page(inode->i_mapping, offset);
-+              if (!page || !page_has_buffers(page))
-+                      return EXT_CONTINUE;
-+
-+              bh = page_buffers(page);
-+
-+              if (!bh)
-+                      return EXT_CONTINUE;
-+
-+              if (buffer_delay(bh)) {
-+                      flags |= FIEMAP_EXTENT_DELALLOC;
-+                      page_cache_release(page);
-+              } else {
-+                      page_cache_release(page);
-+                      return EXT_CONTINUE;
-+              }
-+      }
-+
-+      physical = (__u64)newex->ec_start << blksize_bits;
-+      length =   (__u64)newex->ec_len << blksize_bits;
-+
-+      if (ex && ext4_ext_is_uninitialized(ex))
-+              flags |= FIEMAP_EXTENT_UNWRITTEN;
-+
-+      /*
-+       * If this extent reaches EXT_MAX_BLOCK, it must be last.
-+       *
-+       * Or if ext4_ext_next_allocated_block is EXT_MAX_BLOCK,
-+       * this indicates no more allocated blocks.
-+       *
-+       * XXX this might miss a single-block extent at EXT_MAX_BLOCK
-+       */
-+      if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
-+          newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK)
-+              flags |= FIEMAP_EXTENT_LAST;
-+
-+      error = fiemap_fill_next_extent(fieinfo, logical, physical,
-+                                      length, flags, inode->i_sb->s_dev);
-+      if (error < 0)
-+              return error;
-+      if (error == 1)
-+              return EXT_BREAK;
-+
-+      return EXT_CONTINUE;
-+}
-+
-+int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
-+              __u64 start, __u64 len)
-+{
-+      ext4_fsblk_t start_blk;
-+      ext4_fsblk_t len_blks;
-+      int error = 0;
-+
-+      if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
-+              return -EOPNOTSUPP;
-+
-+      if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS_COMPAT))
-+              return -EBADR;
-+
-+      start_blk = start >> inode->i_sb->s_blocksize_bits;
-+      len_blks = (len + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
-+
-+      /*
-+        * Walk the extent tree gathering extent information.
-+        * ext4_ext_fiemap_cb will push extents back to user.
-+        */
-+      down_write(&EXT4_I(inode)->i_data_sem);
-+      error = ext4_ext_walk_space(inode, start_blk, len_blks,
-+                                ext4_ext_fiemap_cb, fieinfo);
-+      up_write(&EXT4_I(inode)->i_data_sem);
-+
-+      return error;
-+}
 Index: linux-2.6.18-128.1.6/fs/ext4/fiemap.h
 ===================================================================
 --- /dev/null
index 25ea28a..2bb1d36 100644 (file)
@@ -3,9 +3,9 @@ Index: linux-2.6.18.i386/fs/ext4/ext4_i.h
 --- linux-2.6.18.i386.orig/fs/ext4/ext4_i.h
 +++ linux-2.6.18.i386/fs/ext4/ext4_i.h
 @@ -162,6 +162,8 @@ struct ext4_inode_info {
-       /* mballoc */
-       struct list_head i_prealloc_list;
-       spinlock_t i_prealloc_lock;
+       __u16 i_extra_isize;
+
+       spinlock_t i_block_reservation_lock;
 +
 +      void *i_filterdata;
  };
@@ -16,9 +16,9 @@ Index: linux-2.6.18.i386/fs/ext4/super.c
 --- linux-2.6.18.i386.orig/fs/ext4/super.c
 +++ linux-2.6.18.i386/fs/ext4/super.c
 @@ -574,6 +574,7 @@ static struct inode *ext4_alloc_inode(st
-       memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
-       INIT_LIST_HEAD(&ei->i_prealloc_list);
-       spin_lock_init(&ei->i_prealloc_lock);
+       ei->i_allocated_meta_blocks = 0;
+       ei->i_delalloc_reserved_flag = 0;
+       spin_lock_init(&(ei->i_block_reservation_lock));
 +      ei->i_filterdata = NULL;
        return &ei->vfs_inode;
  }
index d354f89..76416c7 100644 (file)
@@ -62,8 +62,8 @@ Index: linux-stage/fs/ext4/namei.c
 +
 +out_journal:
 +      if (journal) {
-+              BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
-+              err = ext4_journal_dirty_metadata(handle, dir_block);
++              BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
++              err = ext4_handle_dirty_metadata(handle, dir, dir_block);
 +              ext4_mark_inode_dirty(handle, dir);
 +      }
 +      brelse (dir_block);
index d8a31ad..206e159 100644 (file)
@@ -59,38 +59,6 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4_i.h
  };
  
  #endif        /* _EXT4_I */
-Index: linux-2.6.18-128.1.6/fs/ext4/xattr.c
-===================================================================
---- linux-2.6.18-128.1.6.orig/fs/ext4/xattr.c
-+++ linux-2.6.18-128.1.6/fs/ext4/xattr.c
-@@ -959,13 +959,18 @@ ext4_xattr_set_handle(handle_t *handle, 
-       struct ext4_xattr_block_find bs = {
-               .s = { .not_found = -ENODATA, },
-       };
-+      unsigned long no_expand;
-       int error;
-       if (!name)
-               return -EINVAL;
-       if (strlen(name) > 255)
-               return -ERANGE;
-+
-       down_write(&EXT4_I(inode)->xattr_sem);
-+      no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND;
-+      EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
-+
-       error = ext4_get_inode_loc(inode, &is.iloc);
-       if (error)
-               goto cleanup;
-@@ -1042,6 +1047,8 @@ ext4_xattr_set_handle(handle_t *handle, 
- cleanup:
-       brelse(is.iloc.bh);
-       brelse(bs.bh);
-+      if (no_expand == 0)
-+              EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
-       up_write(&EXT4_I(inode)->xattr_sem);
-       return error;
- }
 Index: linux-2.6.18-128.1.6/fs/ext4/ialloc.c
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/ialloc.c
index 908a6de..4591d3c 100644 (file)
@@ -61,7 +61,7 @@ Index: b/fs/ext4/namei.c
        struct buffer_head *bh;
        struct dx_frame *frame = frame_in;
        u32 hash;
-@@ -388,46 +389,46 @@ dx_probe(struct dentry *dentry, struct i
+@@ -388,18 +389,19 @@ dx_probe(struct dentry *dentry, struct i
                dir = dentry->d_parent->d_inode;
        if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
                goto fail;
@@ -84,8 +84,10 @@ Index: b/fs/ext4/namei.c
        }
 -      hinfo->hash_version = root->info.hash_version;
 +      hinfo->hash_version = info->hash_version;
+       if (hinfo->hash_version <= DX_HASH_TEA)
+               hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
        hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
-       if (dentry)
+@@ -398,29 +399,28 @@ dx_probe(struct dentry *dentry, struct i
                ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
        hash = hinfo->hash;
  
@@ -163,9 +165,9 @@ Index: b/fs/ext4/namei.c
  
        bh2 = ext4_append (handle, dir, &block, &retval);
        if (!(bh2)) {
-@@ -1460,11 +1461,13 @@ static int make_indexed_dir(handle_t *ha
-       EXT4_I(dir)->i_flags |= EXT4_INDEX_FL;
-       data1 = bh2->b_data;
+@@ -1460,18 +1461,20 @@ static int make_indexed_dir(handle_t *ha
+       }
+       root = (struct dx_root *) bh->b_data;
  
 +      dot_de = (struct ext4_dir_entry_2 *) bh->b_data;
 +      dotdot_de = ext4_next_entry(dot_de);
@@ -174,14 +176,22 @@ Index: b/fs/ext4/namei.c
 -      fde = &root->dotdot;
 -      de = (struct ext4_dir_entry_2 *)((char *)fde +
 -              ext4_rec_len_from_disk(fde->rec_len));
--      len = ((char *) root) + blocksize - (char *) de;
 +      de = (struct ext4_dir_entry_2 *)((char *)dotdot_de +
 +              ext4_rec_len_from_disk(dotdot_de->rec_len));
+-      if ((char *) de >= (((char *) root) + blocksize)) {
++      if ((char *) de >= (((char *) dot_de) + blocksize)) {
+               ext4_error(dir->i_sb, __func__,
+                          "invalid rec_len for '..' in inode %lu",
+                          dir->i_ino);
+               brelse(bh);
+               return -EIO;
+       }
+-      len = ((char *) root) + blocksize - (char *) de;
 +      len = ((char *) dot_de) + blocksize - (char *) de;
-       memcpy (data1, de, len);
-       de = (struct ext4_dir_entry_2 *) data1;
-       top = data1 + len;
-@@ -1472,18 +1475,24 @@ static int make_indexed_dir(handle_t *ha
+       /* Allocate new block for the 0th block's dirents */
+       bh2 = ext4_append(handle, dir, &block, &retval);
+@@ -1472,18 +1475,23 @@ static int make_indexed_dir(handle_t *ha
                de = de2;
        de->rec_len = ext4_rec_len_to_disk(data1 + blocksize - (char *) de);
        /* Initialize the root; the dot dirents already exist */
@@ -191,9 +201,9 @@ Index: b/fs/ext4/namei.c
 -      root->info.info_length = sizeof(root->info);
 -      root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
 -      entries = root->entries;
--      dx_set_block (entries, 1);
--      dx_set_count (entries, 1);
--      dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
+-      dx_set_block(entries, 1);
+-      dx_set_count(entries, 1);
+-      dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info)));
 +      dotdot_de->rec_len = ext4_rec_len_to_disk(blocksize -
 +                      le16_to_cpu(dot_de->rec_len));
 +
@@ -212,18 +222,17 @@ Index: b/fs/ext4/namei.c
        /* Initialize as for dx_probe */
 -      hinfo.hash_version = root->info.hash_version;
 +      hinfo.hash_version = dx_info->hash_version;
-+
+       if (hinfo.hash_version <= DX_HASH_TEA)
+               hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
        hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
-       ext4fs_dirhash(name, namelen, &hinfo);
-       frame = frames;
 @@ -1724,6 +1733,7 @@ static int ext4_dx_add_entry(handle_t *h
                                goto journal_error;
                        brelse (bh2);
                } else {
 +                      struct dx_root_info * info;
-                       dxtrace(printk("Creating second level index...\n"));
+                       dxtrace(printk(KERN_DEBUG
+                                      "Creating second level index...\n"));
                        memcpy((char *) entries2, (char *) entries,
-                              icount * sizeof(struct dx_entry));
 @@ -1732,7 +1742,9 @@ static int ext4_dx_add_entry(handle_t *h
                        /* Set up root */
                        dx_set_count(entries, 1);
index 295d0d1..3e34f6e 100644 (file)
@@ -3,9 +3,9 @@ Index: linux-2.6.18.i386/fs/ext4/ialloc.c
 --- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
 +++ linux-2.6.18.i386/fs/ext4/ialloc.c
 @@ -622,12 +622,15 @@ struct inode *ext4_new_inode(handle_t *h
-               return ERR_PTR(-EPERM);
        sb = dir->i_sb;
+       trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id,
+                  dir->i_ino, mode);
 +      sbi = EXT4_SB(sb);
 +      if (sbi->s_max_dir_size > 0 && i_size_read(dir) >= sbi->s_max_dir_size)
 +              return ERR_PTR(-EFBIG);
@@ -31,29 +31,19 @@ Index: linux-2.6.18.i386/fs/ext4/super.c
  
  #include "ext4.h"
  #include "ext4_jbd2.h"
-@@ -67,6 +68,8 @@ static void ext4_write_super_lockfs(stru
- struct page *ext4_zero_page;
-+struct proc_dir_entry *proc_root_ext4;
-+
- ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
-                              struct ext4_group_desc *bg)
- {
-@@ -551,6 +554,9 @@ static void ext4_put_super(struct super_
-       }
-       if (sbi->s_mmp_tsk)
-               kthread_stop(sbi->s_mmp_tsk);
-+
-+      remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+
-       sb->s_fs_info = NULL;
-       kfree(sbi);
-       return;
-@@ -2185,6 +2191,46 @@ static unsigned long ext4_get_stripe_siz
+@@ -551,6 +554,7 @@ static void ext4_put_super(struct super_
+               ext4_commit_super(sb, es, 1);
+       }
+       if (sbi->s_proc) {
++              remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
+               remove_proc_entry("inode_readahead_blks", sbi->s_proc);
+               remove_proc_entry(sb->s_id, ext4_proc_root);
+       }
+@@ -2185,6 +2191,48 @@ static unsigned long ext4_get_stripe_siz
        return 0;
  }
  
++#ifdef CONFIG_PROC_FS
 +static int ext4_max_dir_size_read(char *page, char **start, off_t off,
 +                                  int count, int *eof, void *data)
 +{
@@ -93,49 +83,32 @@ Index: linux-2.6.18.i386/fs/ext4/super.c
 +      sbi->s_max_dir_size = value;
 +      return count;
 +}
++#endif
 +
  static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                                __releases(kernel_lock)
                                __acquires(kernel_lock)
-@@ -2208,6 +2254,7 @@ static int ext4_fill_super(struct super_
-       int needs_recovery;
-       __le32 features;
-       __u64 blocks_count;
-+      struct proc_dir_entry *proc;
-       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
-@@ -2743,6 +2790,22 @@ static int ext4_fill_super(struct super_
-       ext4_ext_init(sb);
-       ext4_mb_init(sb, needs_recovery);
-+      sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
-+      proc = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
-+                               S_IFREG | S_IRUGO | S_IWUSR, sbi->s_mb_proc);
-+      if (proc == NULL) {
-+              printk(KERN_ERR "EXT4-fs: unable to create %s\n",
-+                     EXT4_MAX_DIR_SIZE_NAME);
-+              remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+              remove_proc_entry(sbi->s_mb_proc->name, proc_root_ext4);
-+              sbi->s_mb_proc = NULL;
-+              ret = -ENOMEM;
-+              goto failed_mount4;
-+      }
-+      proc->data = sbi;
-+      proc->read_proc = ext4_max_dir_size_read;
-+      proc->write_proc = ext4_max_dir_size_write;
+@@ -2743,6 +2790,20 @@ static int ext4_fill_super(struct super_
+                       p->proc_fops = &ext4_ui_proc_fops,
+                       p->data = &sbi->s_inode_goal;
+               }
++              sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
++              p = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
++                                    S_IFREG | S_IRUGO | S_IWUSR, sbi->s_proc);
++              if (p == NULL) {
++                      printk(KERN_ERR "EXT4-fs: unable to create %s\n",
++                             EXT4_MAX_DIR_SIZE_NAME);
++                      remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
++                      ret = -ENOMEM;
++                      goto failed_mount;
++              }
++              p->data = sbi;
++              p->read_proc = ext4_max_dir_size_read;
++              p->write_proc = ext4_max_dir_size_write;
 +
-       lock_kernel();
-       return 0;
-@@ -3082,7 +3145,6 @@ static void ext4_commit_super(struct sup
-               sync_dirty_buffer(sbh);
- }
+       }
+ #endif
  
--
- /*
-  * Have we just finished recovery?  If so, and if we are mounting (or
-  * remounting) the filesystem readonly, then we will end up with a
 Index: linux-2.6.18.i386/fs/ext4/ext4_sb.h
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/ext4_sb.h
@@ -152,12 +125,10 @@ Index: linux-2.6.18.i386/fs/ext4/ext4.h
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/ext4.h
 +++ linux-2.6.18.i386/fs/ext4/ext4.h
-@@ -992,6 +992,14 @@ struct mmp_struct {
+@@ -992,6 +992,12 @@ struct mmp_struct {
   */
  #define EXT4_MMP_MIN_CHECK_INTERVAL   5
  
-+extern struct proc_dir_entry *proc_root_ext4;
-+
 +/*
 + * max directory size tunable
 + */
@@ -167,37 +138,3 @@ Index: linux-2.6.18.i386/fs/ext4/ext4.h
  /*
   * Function prototypes
   */
-Index: linux-2.6.18.i386/fs/ext4/mballoc.h
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.h
-+++ linux-2.6.18.i386/fs/ext4/mballoc.h
-@@ -257,7 +257,6 @@ static void ext4_mb_store_history(struct
- #define in_range(b, first, len)       ((b) >= (first) && (b) <= (first) + (len) - 1)
--static struct proc_dir_entry *proc_root_ext4;
- struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
- static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-Index: linux-2.6.18.i386/fs/ext4/mballoc.c
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.c
-+++ linux-2.6.18.i386/fs/ext4/mballoc.c
-@@ -2821,6 +2821,7 @@ err_out:
-       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-       remove_proc_entry(devname, proc_root_ext4);
-       sbi->s_mb_proc = NULL;
-@@ -2842,7 +2843,9 @@ static int ext4_mb_destroy_per_dev_proc(
-       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-       remove_proc_entry(devname, proc_root_ext4);
-+      sbi->s_mb_proc = NULL;
-       return 0;
- }
index 7522be2..24d04a2 100644 (file)
@@ -1,6 +1,17 @@
 diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c
---- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c  2009-09-28 16:38:04.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c  2009-09-28 16:40:35.000000000 +0530
+--- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c
++++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.c
+@@ -360,8 +360,8 @@ static void ext4_mb_mark_free_simple(str
+ static struct kmem_cache *ext4_pspace_cachep;
+ static struct kmem_cache *ext4_ac_cachep;
+ static struct kmem_cache *ext4_free_ext_cachep;
+-static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
+-                                      ext4_group_t group);
++static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
++                                      ext4_group_t group);
+ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
+                                                ext4_group_t group);
 @@ -660,7 +660,7 @@ static void ext4_mb_mark_free_simple(str
        }
  }
@@ -14,8 +25,8 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
        grp->bb_fragments = fragments;
  
        if (free != grp->bb_free) {
--              ext4_error(sb, __func__,
--                      "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
+-              ext4_grp_locked_error(sb, group,  __func__,
+-                      "EXT4-fs: group %u: %u blocks in bitmap, %u in gd",
 -                      group, free, grp->bb_free);
 -              /*
 -               * If we intent to continue, we consider group descritor
@@ -27,7 +38,7 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
 +              ext4_error(sb, __FUNCTION__,
 +                      "group %lu: %u blocks in bitmap, %u in bb, "
 +                      "%u in gd, %lu pa's\n", group, free, grp->bb_free,
-+                      le16_to_cpu(gdp->bg_free_blocks_count),
++                      ext4_free_blks_count(sb, gdp),
 +                      grp->bb_prealloc_nr);
 +              return -EIO;
        }
@@ -43,32 +54,32 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
  
  /* The buddy information is attached the buddy cache inode
 @@ -814,7 +816,7 @@ static int ext4_mb_init_cache(struct pag
-       err = 0;
        first_block = page->index * blocks_per_page;
+       /* init the page  */
+       memset(page_address(page), 0xff, PAGE_CACHE_SIZE);
 -      for (i = 0; i < blocks_per_page; i++) {
 +      for (i = 0; i < blocks_per_page && err == 0; i++) {
                int group;
                struct ext4_group_info *grinfo;
  
 @@ -848,7 +850,7 @@ static int ext4_mb_init_cache(struct pag
-                       /*
                         * incore got set to the group block bitmap below
                         */
+                       ext4_lock_group(sb, group);
 -                      ext4_mb_generate_buddy(sb, data, incore, group);
 +                      err = ext4_mb_generate_buddy(sb, data, incore, group);
+                       ext4_unlock_group(sb, group);
                        incore = NULL;
                } else {
-                       /* this is block of bitmap */
 @@ -861,7 +863,7 @@ static int ext4_mb_init_cache(struct pag
                        memcpy(data, bitmap, blocksize);
  
                        /* mark all preallocated blks used in in-core bitmap */
 -                      ext4_mb_generate_from_pa(sb, data, group);
 +                      err = ext4_mb_generate_from_pa(sb, data, group);
+                       ext4_mb_generate_from_freelist(sb, data, group);
                        ext4_unlock_group(sb, group);
  
-                       /* set incore so that the buddy information can be
 @@ -870,6 +872,7 @@ static int ext4_mb_init_cache(struct pag
                        incore = data;
                }
@@ -93,7 +104,7 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
  {
        struct super_block *sb = seq->private;
 +      struct ext4_group_desc *gdp;
-       long group = (long) v;
+       ext4_group_t group = (ext4_group_t) ((unsigned long) v);
        int i;
        int err;
 +      int free = 0;
@@ -120,14 +131,14 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
 +
 +      gdp = ext4_get_group_desc(sb, group, NULL);
 +      if (gdp != NULL)
-+              free = le16_to_cpu(gdp->bg_free_blocks_count);
++              free = ext4_free_blks_count(sb, gdp);
 +
        ext4_lock_group(sb, group);
        memcpy(&sg, ext4_get_group_info(sb, group), i);
        ext4_unlock_group(sb, group);
        ext4_mb_release_desc(&e4b);
  
--      seq_printf(seq, "#%-5lu: %-5u %-5u %-5u [", group, sg.info.bb_free,
+-      seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free,
 -                      sg.info.bb_fragments, sg.info.bb_first_free);
 +      seq_printf(seq, "#%-5lu: %-5u %-5u %-5u %-5u %-5lu [", group,
 +                      sg.info.bb_free, free,
@@ -171,10 +182,10 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
 +                      i = mb_find_next_zero_bit(bitmap, max, i);
 +      }
 +
-+      if (free != le16_to_cpu(gdp->bg_free_blocks_count)) {
++      if (free != ext4_free_blks_count(sb, gdp)) {
 +              ext4_error(sb, __FUNCTION__, "on-disk bitmap for group %d"
 +                      "corrupted: %u blocks free in bitmap, %u - in gd\n",
-+                      group, free, le16_to_cpu(gdp->bg_free_blocks_count));
++                      group, free, ext4_free_blks_count(sb, gdp));
 +              return -EIO;
 +      }
 +      return 0;
@@ -234,7 +245,7 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
 +                         count, grp->bb_prealloc_nr, skip);
 +              return -EIO;
 +      }
-       mb_debug("prellocated %u for group %lu\n", preallocated, group);
+       mb_debug("prellocated %u for group %u\n", preallocated, group);
 +      return 0;
  }
  
@@ -283,7 +294,7 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
 @@ -4107,7 +4183,7 @@ repeat:
                if (err) {
                        ext4_error(sb, __func__, "Error in loading buddy "
-                                       "information for %lu\n", group);
+                                       "information for %u", group);
 -                      continue;
 +                      return;
                }
@@ -306,17 +317,21 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.c linux-2.6.18-128.1.6_2//fs/
                ext4_mb_release_group_pa(&e4b, pa, ac);
                ext4_unlock_group(sb, group);
  
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.h linux-2.6.18-128.1.6_2//fs/ext4/mballoc.h
---- linux-2.6.18-128.1.6_1//fs/ext4/mballoc.h  2009-09-28 16:38:04.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/mballoc.h  2009-09-28 16:38:43.000000000 +0530
+diff -rupN linux-2.6.18-128.1.6/fs/ext4/ext4.h
+--- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
++++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
 @@ -119,6 +119,7 @@ struct ext4_group_info {
-       unsigned short  bb_free;
-       unsigned short  bb_fragments;
-       struct          list_head bb_prealloc_list;
+       unsigned short  bb_free;
+       unsigned short  bb_fragments;
+       struct          list_head bb_prealloc_list;
 +      unsigned long   bb_prealloc_nr;
  #ifdef DOUBLE_CHECK
        void            *bb_bitmap;
  #endif
+Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.h
+===================================================================
+--- linux-2.6.18-128.1.6.orig/fs/ext4/mballoc.h
++++ linux-2.6.18-128.1.6/fs/ext4/mballoc.h
 @@ -228,7 +229,7 @@ struct ext4_mb_history {
        __u16 tail;     /* what tail broke some buddy */
        __u16 buddy;    /* buddy the tail ^^^ broke */
@@ -326,12 +341,3 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/mballoc.h linux-2.6.18-128.1.6_2//fs/
        __u8 op:4;
        __u8 merged:1;
  };
-@@ -259,7 +260,7 @@ static void ext4_mb_store_history(struct
- struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
--static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-+static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-                                       ext4_group_t group);
- static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *);
- static void ext4_mb_free_committed_blocks(struct super_block *);
index f8e77c7..af54824 100644 (file)
@@ -2,13 +2,15 @@ Index: linux-2.6.18.i386/fs/ext4/ext4_jbd2.h
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/ext4_jbd2.h
 +++ linux-2.6.18.i386/fs/ext4/ext4_jbd2.h
-@@ -35,6 +35,9 @@
+@@ -35,6 +35,11 @@
        (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)   \
                || test_opt(sb, EXTENTS) ? 27U : 8U)
  
 +/* Indicate that EXT4_SINGLEDATA_TRANS_BLOCKS takes the sb as argument */
 +#define EXT4_SINGLEDATA_TRANS_BLOCKS_HAS_SB
 +
++#define ext4_journal_dirty_metadata(handle, bh)  \
++                ext4_handle_dirty_metadata(handle, NULL, bh)
  /* Extended attribute operations touch at most two data buffers,
   * two bitmap buffers, and two group summaries, in addition to the inode
   * and the superblock, which are already accounted for. */
@@ -118,7 +120,7 @@ Index: linux-2.6.18.i386/fs/ext4/extents.c
   * ext4_ext_calc_credits_for_single_extent:
   * This routine returns max. credits that needed to insert an extent
   * to the extent tree.
-@@ -3157,3 +3207,14 @@ int ext4_fiemap(struct inode *inode, str
+@@ -3157,4 +3207,14 @@ int ext4_fiemap(struct inode *inode, str
  
        return error;
  }
@@ -132,12 +134,12 @@ Index: linux-2.6.18.i386/fs/ext4/extents.c
 +EXPORT_SYMBOL(ext4_ext_walk_space);
 +EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert);
 +EXPORT_SYMBOL(ext4_mark_inode_dirty);
-+
 Index: linux-2.6.18.i386/fs/ext4/ext4_extents.h
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/ext4_extents.h
 +++ linux-2.6.18.i386/fs/ext4/ext4_extents.h
-@@ -59,6 +59,11 @@
+@@ -59,6 +59,12 @@
   */
  #define EXT_STATS_
  
@@ -146,6 +148,7 @@ Index: linux-2.6.18.i386/fs/ext4/ext4_extents.h
 + * are now accounted in ext4_ext_calc_credits_for_insert()
 + */
 +#define EXT4_ALLOC_NEEDED 0
++#define HAVE_EXT_PREPARE_CB_EXTENT
  
  /*
   * ext4_inode has i_block array (60 bytes total).
@@ -157,12 +160,11 @@ Index: linux-2.6.18.i386/fs/ext4/ext4_extents.h
  
  #define EXT_MAX_BLOCK 0xffffffff
  
-@@ -228,9 +234,13 @@ static inline int ext4_ext_get_actual_le
-               (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
+@@ -228,9 +234,12 @@ static inline int ext4_ext_get_actual_le
  }
  
+ extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks);
 +extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex);
-+extern void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb);
  extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
  extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t);
  extern int ext4_extent_tree_init(handle_t *, struct inode *);
@@ -175,13 +177,26 @@ Index: linux-2.6.18.i386/fs/ext4/mballoc.c
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/mballoc.c
 +++ linux-2.6.18.i386/fs/ext4/mballoc.c
-@@ -4965,3 +4965,7 @@ error_return:
+@@ -4355,6 +4355,13 @@
+               kmem_cache_free(ext4_ac_cachep, ac);
+ }
++/* For backward compatibility, since Lustre uses this symbol */
++void ext4_mb_discard_inode_preallocations(struct inode *inode)
++{
++      ext4_discard_preallocations(inode);
++}
++EXPORT_SYMBOL(ext4_mb_discard_inode_preallocations);
++
+ /*
+  * finds all preallocated spaces and return blocks being freed to them
+  * if preallocated space becomes full (no block is used from the space)
+@@ -4965,3 +4965,6 @@ error_return:
                kmem_cache_free(ext4_ac_cachep, ac);
        return;
  }
 +
 +EXPORT_SYMBOL(ext4_free_blocks);
-+EXPORT_SYMBOL(ext4_mb_discard_inode_preallocations);
 +
 Index: linux-2.6.18.i386/fs/ext4/super.c
 ===================================================================
@@ -195,63 +210,14 @@ Index: linux-2.6.18.i386/fs/ext4/super.c
  
  ext4_fsblk_t ext4_inode_table(struct super_block *sb,
                              struct ext4_group_desc *bg)
-@@ -513,7 +514,8 @@ static void ext4_put_super(struct super_
-       struct ext4_super_block *es = sbi->s_es;
-       int i;
--      ext4_mb_release(sb);
-+      if (test_opt(sb, MBALLOC))
-+              ext4_mb_release(sb);
-       ext4_ext_release(sb);
-       ext4_xattr_put_super(sb);
-       jbd2_journal_destroy(sbi->s_journal);
-@@ -2373,16 +2375,6 @@ static int ext4_fill_super(struct super_
-                      "running e2fsck is recommended\n");
-       /*
--       * Since ext4 is still considered development code, we require
--       * that the TEST_FILESYS flag in s->flags be set.
--       */
--      if (!(le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)) {
--              printk(KERN_WARNING "EXT4-fs: %s: not marked "
--                     "OK to use with test code.\n", sb->s_id);
--              goto failed_mount;
--      }
--
--      /*
-        * Check feature flags regardless of the revision level, since we
-        * previously didn't change the revision level when setting the flags,
-        * so there is a chance incompat flags are set on a rev 0 filesystem.
-@@ -3835,9 +3827,9 @@ static int ext4_get_sb(struct file_syste
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt);
+@@ -113,6 +118,7 @@
+               (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+               (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
  }
--static struct file_system_type ext4dev_fs_type = {
-+static struct file_system_type ext4_fs_type = {
-       .owner          = THIS_MODULE,
--      .name           = "ext4dev",
-+      .name           = "ext4",
-       .get_sb         = ext4_get_sb,
-       .kill_sb        = kill_block_super,
- #ifdef HAVE_FALLOCATE
-@@ -3867,7 +3859,7 @@ static int __init init_ext4_fs(void)
-       err = init_inodecache();
-       if (err)
-               goto out1;
--      err = register_filesystem(&ext4dev_fs_type);
-+      err = register_filesystem(&ext4_fs_type);
-       if (err)
-               goto out;
-       return 0;
-@@ -3884,7 +3876,7 @@ out3:
- static void __exit exit_ext4_fs(void)
- {
--      unregister_filesystem(&ext4dev_fs_type);
-+      unregister_filesystem(&ext4_fs_type);
-       destroy_inodecache();
-       exit_ext4_xattr();
-       exit_ext4_mballoc();
++EXPORT_SYMBOL(ext4_itable_unused_count);
+
+ void ext4_block_bitmap_set(struct super_block *sb,
+                          struct ext4_group_desc *bg, ext4_fsblk_t blk)
 Index: linux-2.6.18.i386/fs/ext4/ext4_jbd2.c
 ===================================================================
 --- linux-2.6.18.i386.orig/fs/ext4/ext4_jbd2.c
@@ -268,4 +234,71 @@ Index: linux-2.6.18.i386/fs/ext4/ext4_jbd2.c
                ext4_journal_abort_handle(where, __func__, bh, handle, err);
        return err;
  }
-+EXPORT_SYMBOL(__ext4_journal_dirty_metadata);
++EXPORT_SYMBOL(__ext4_handle_dirty_metadata);
+Index: linux-2.6.27.21-0.1/fs/ext4/ext4.h
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/ext4.h    2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/ext4.h 2009-07-07 14:47:22.000000000 +0530
+@@ -1123,6 +1128,8 @@
+ extern int ext4_mb_get_buddy_cache_lock(struct super_block *, ext4_group_t);
+ extern void ext4_mb_put_buddy_cache_lock(struct super_block *,
+                                               ext4_group_t, int);
++extern void ext4_mb_discard_inode_preallocations(struct inode *);
++
+ /* inode.c */
+ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
+               struct buffer_head *bh, ext4_fsblk_t blocknr);
+Index: linux-2.6.27.21-0.1/fs/ext4/inode.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/inode.c   2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/inode.c        2009-07-07 14:47:22.000000000 +0530
+@@ -4240,6 +4240,7 @@
+       iget_failed(inode);
+       return ERR_PTR(ret);
+ }
++EXPORT_SYMBOL(ext4_iget);
+ static int ext4_inode_blocks_set(handle_t *handle,
+                               struct ext4_inode *raw_inode,
+Index: linux-2.6.27.21-0.1/fs/ext4/super.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/super.c   2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/super.c        2009-07-07 14:48:53.000000000 +0530
+@@ -1286,6 +1287,7 @@
+       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
+       Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
+       Opt_usrquota, Opt_grpquota, Opt_i_version,
++      Opt_mballoc,
+       Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+       Opt_inode_readahead_blks, Opt_journal_ioprio,
+       Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents,
+@@ -1346,6 +1348,7 @@
+       {Opt_barrier, "barrier"},
+       {Opt_nobarrier, "nobarrier"},
+       {Opt_i_version, "i_version"},
++      {Opt_mballoc, "mballoc"},
+       {Opt_stripe, "stripe=%u"},
+       {Opt_resize, "resize"},
+       {Opt_delalloc, "delalloc"},
+@@ -1768,6 +1771,8 @@
+               case Opt_bigendian_extents:
+                       bigendian_extents = 1;
+                       break;
++              case Opt_mballoc:
++                      break;
+               default:
+                       printk(KERN_ERR
+                              "EXT4-fs: Unrecognized mount option \"%s\" "
+Index: linux-2.6.27.21-0.1/fs/ext4/fsync.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/fsync.c   2009-07-07 14:47:19.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/fsync.c        2009-07-07 14:48:53.000000000 +0530
+@@ -1768,7 +1771,7 @@
+       trace_mark(ext4_sync_file, "dev %s datasync %d ino %ld parent %ld",
+                  inode->i_sb->s_id, datasync, inode->i_ino,
+-                 dentry->d_parent->d_inode->i_ino);
++                 0L);
+
+       /*
+        * data=writeback:
index d01d046..812d9a9 100644 (file)
@@ -370,18 +370,18 @@ Index: linux-2.6.18-128.1.6/fs/ext4/super.c
         * The first inode we look at is the journal inode.  Don't try
         * root first: it may be modified in the journal!
 @@ -2445,6 +2775,8 @@ failed_mount3:
-       percpu_counter_destroy(&sbi->s_freeblocks_counter);
        percpu_counter_destroy(&sbi->s_freeinodes_counter);
        percpu_counter_destroy(&sbi->s_dirs_counter);
+       percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
 +      if (sbi->s_mmp_tsk)
 +              kthread_stop(sbi->s_mmp_tsk);
  failed_mount2:
        for (i = 0; i < db_count; i++)
                brelse(sbi->s_group_desc[i]);
 @@ -2918,7 +3250,7 @@ static int ext4_remount(struct super_blo
-       unsigned long old_sb_flags;
        struct ext4_mount_options old_opts;
        ext4_group_t g;
+       unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
 -      int err;
 +      int err = 0;
  #ifdef CONFIG_QUOTA
index bc184c5..cd9a250 100644 (file)
@@ -1,39 +1,29 @@
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/ext4.h linux-2.6.18-128.1.6_2//fs/ext4/ext4.h
---- linux-2.6.18-128.1.6_1//fs/ext4/ext4.h     2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/ext4.h     2009-08-24 15:54:52.000000000 +0530
-@@ -1144,6 +1144,18 @@ extern int ext4_fiemap(struct inode *, s
- extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
                     unsigned long);
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/ext4.h linux-2.6.27.21-0.1_2//fs/ext4/ext4.h
+--- linux-2.6.27.21-0.1_1//fs/ext4/ext4.h      2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/ext4.h      2009-08-24 15:32:55.000000000 +0530
+@@ -1171,6 +1171,19 @@ extern int ext4_fiemap(struct inode *, s
+ /* migrate.c */
extern int ext4_ext_migrate(struct inode *);
  /* namei.c */
 +extern struct inode *ext4_create_inode(handle_t *handle,
-+                                     struct inode * dir, int mode);
++                                        struct inode * dir, int mode);
 +extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
-+                        struct inode *inode);
++                           struct inode *inode);
 +extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
-+                           struct ext4_dir_entry_2 * de_del,
-+                           struct buffer_head * bh);
-+extern struct buffer_head * ext4_find_entry(struct dentry *dentry,
-+                                          struct ext4_dir_entry_2
-+                                          ** res_dir);
++                              struct ext4_dir_entry_2 * de_del,
++                              struct buffer_head * bh);
++extern struct buffer_head * ext4_find_entry(struct inode *dir,
++                                          const struct qstr *d_name,
++                                          struct ext4_dir_entry_2 ** res_dir);
++#define ll_ext4_find_entry(inode, dentry, res_dir) ext4_find_entry(dir, &(dentry)->d_name, res_dir)
 +extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
-+                             struct inode *inode);
++                                struct inode *inode);
  extern int ext4_orphan_add(handle_t *, struct inode *);
  extern int ext4_orphan_del(handle_t *, struct inode *);
  extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/inode.c linux-2.6.18-128.1.6_2//fs/ext4/inode.c
---- linux-2.6.18-128.1.6_1//fs/ext4/inode.c    2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/inode.c    2009-08-24 15:54:52.000000000 +0530
-@@ -2891,6 +2891,7 @@ bad_inode:
-       iput(inode);
-       return ERR_PTR(ret);
- }
-+EXPORT_SYMBOL(ext4_iget);
- static int ext4_inode_blocks_set(handle_t *handle,
-                               struct ext4_inode *raw_inode,
-diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ext4/namei.c
---- linux-2.6.18-128.1.6_1//fs/ext4/namei.c    2009-08-24 15:54:11.000000000 +0530
-+++ linux-2.6.18-128.1.6_2//fs/ext4/namei.c    2009-08-24 15:55:18.000000000 +0530
+diff -rupN linux-2.6.27.21-0.1_1//fs/ext4/namei.c linux-2.6.27.21-0.1_2//fs/ext4/namei.c
+--- linux-2.6.27.21-0.1_1//fs/ext4/namei.c     2009-08-24 15:32:00.000000000 +0530
++++ linux-2.6.27.21-0.1_2//fs/ext4/namei.c     2009-08-24 15:43:56.000000000 +0530
 @@ -24,6 +24,7 @@
   *    Theodore Ts'o, 2002
   */
@@ -42,37 +32,39 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
  #include <linux/fs.h>
  #include <linux/pagemap.h>
  #include <linux/jbd2.h>
-@@ -878,8 +879,8 @@ static inline int search_dirblock(struct
+@@ -882,9 +883,9 @@ static inline int search_dirblock(struct
   * The returned buffer_head has ->b_count elevated.  The caller is expected
   * to brelse() it when appropriate.
   */
--static struct buffer_head * ext4_find_entry (struct dentry *dentry,
+-static struct buffer_head * ext4_find_entry (struct inode *dir,
+-                                      const struct qstr *d_name,
 -                                      struct ext4_dir_entry_2 ** res_dir)
-+struct buffer_head * ext4_find_entry (struct dentry *dentry,
++struct buffer_head * ext4_find_entry(struct inode *dir,
++                                    const struct qstr *d_name,
 +                                    struct ext4_dir_entry_2 ** res_dir)
  {
-       struct super_block * sb;
-       struct buffer_head * bh_use[NAMEI_RA_SIZE];
-@@ -986,6 +987,7 @@ cleanup_and_exit:
-               brelse (bh_use[ra_ptr]);
+       struct super_block *sb;
+       struct buffer_head *bh_use[NAMEI_RA_SIZE];
+@@ -991,6 +992,7 @@ cleanup_and_exit:
+               brelse(bh_use[ra_ptr]);
        return ret;
  }
 +EXPORT_SYMBOL(ext4_find_entry);
  
- static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
+ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
                       struct ext4_dir_entry_2 **res_dir, int *err)
-@@ -1506,8 +1508,8 @@ static int make_indexed_dir(handle_t *ha
+@@ -1511,8 +1513,8 @@ static int make_indexed_dir(handle_t *ha
   * may not sleep between calling this and putting something into
   * the entry, as someone else might have used it while you slept.
   */
--static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
--      struct inode *inode)
-+int ext4_add_entry (handle_t *handle, struct dentry *dentry,
-+                  struct inode *inode)
+-static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
+-                        struct inode *inode)
++int ext4_add_entry(handle_t *handle, struct dentry *dentry,
++                 struct inode *inode)
  {
        struct inode *dir = dentry->d_parent->d_inode;
-       unsigned long offset;
-@@ -1553,6 +1555,7 @@ static int ext4_add_entry (handle_t *han
+       struct buffer_head *bh;
+@@ -1557,6 +1559,7 @@ static int ext4_add_entry(handle_t *hand
        de->rec_len = ext4_rec_len_to_disk(blocksize);
        return add_dirent_to_buf(handle, dentry, inode, de, bh);
  }
@@ -80,22 +72,22 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
  
  /*
   * Returns 0 for success, or a negative error value
-@@ -1693,10 +1696,10 @@ cleanup:
+@@ -1699,10 +1702,10 @@ cleanup:
   * ext4_delete_entry deletes a directory entry by merging it with the
   * previous entry
   */
--static int ext4_delete_entry (handle_t *handle,
--                            struct inode * dir,
--                            struct ext4_dir_entry_2 * de_del,
--                            struct buffer_head * bh)
-+int ext4_delete_entry (handle_t *handle,
-+                     struct inode * dir,
-+                     struct ext4_dir_entry_2 * de_del,
-+                     struct buffer_head * bh)
+-static int ext4_delete_entry(handle_t *handle,
+-                           struct inode *dir,
+-                           struct ext4_dir_entry_2 *de_del,
+-                           struct buffer_head *bh)
++int ext4_delete_entry(handle_t *handle,
++                    struct inode *dir,
++                    struct ext4_dir_entry_2 *de_del,
++                    struct buffer_head *bh)
  {
-       struct ext4_dir_entry_2 * de, * pde;
+       struct ext4_dir_entry_2 *de, *pde;
        int i;
-@@ -1727,7 +1730,7 @@ static int ext4_delete_entry (handle_t *
+@@ -1733,7 +1736,7 @@ static int ext4_delete_entry(handle_t *h
        }
        return -ENOENT;
  }
@@ -104,15 +96,15 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
  /*
   * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
   * since this indicates that nlinks count was previously 1.
-@@ -1790,6 +1793,26 @@ static struct inode * ext4_new_inode_wan
-       return ext4_new_inode(handle, dir, mode, inum);
+@@ -1796,6 +1799,26 @@ static unsigned ext4_dentry_goal(struct
+       return inum;
  }
  
 +struct inode * ext4_create_inode(handle_t *handle, struct inode * dir, int mode)
 +{
 +      struct inode *inode;
 +
-+      inode = ext4_new_inode(handle, dir, mode, 0);
++      inode = ext4_new_inode(handle, dir, mode);
 +      if (!IS_ERR(inode)) {
 +              if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
 +#ifdef CONFIG_LDISKFS_FS_XATTR
@@ -131,46 +123,48 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
  /*
   * By the time this is called, we already have created
   * the directory cache entry for the new file, but it
-@@ -1864,38 +1887,25 @@ retry:
+@@ -1872,39 +1895,31 @@ retry:
        return err;
  }
  
--static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
--{
--      handle_t *handle;
--      struct inode * inode;
+-static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 +/* Initialize @inode as a subdirectory of @dir, and add the
 + * "." and ".." entries into the first directory block. */
 +int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
-+                       struct inode *inode)
-+ {
-       struct buffer_head * dir_block;
-       struct ext4_dir_entry_2 * de;
++                      struct inode *inode)
+ {
+-      handle_t *handle;
+-      struct inode *inode;
+-      struct buffer_head *dir_block;
+-      struct ext4_dir_entry_2 *de;
 -      int err, retries = 0;
 -
 -      if (EXT4_DIR_LINK_MAX(dir))
 -              return -EMLINK;
--
++      struct buffer_head * dir_block;
++      struct ext4_dir_entry_2 * de;
++      int err = 0;
 -retry:
 -      handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
 -                                      EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
 -                                      2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
--      if (IS_ERR(handle))
--              return PTR_ERR(handle);
--
--      if (IS_DIRSYNC(dir))
--              handle->h_sync = 1;
--
--      inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (IS_DIRSYNC(dir))
+               ext4_handle_sync(handle);
+-      inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
+-                                  ext4_dentry_goal(dir->i_sb, dentry));
 -      err = PTR_ERR(inode);
 -      if (IS_ERR(inode))
 -              goto out_stop;
-+      int err = 0;
+-
        inode->i_op = &ext4_dir_inode_operations;
        inode->i_fop = &ext4_dir_operations;
        inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-       dir_block = ext4_bread (handle, inode, 0, 1, &err);
+       dir_block = ext4_bread(handle, inode, 0, 1, &err);
 -      if (!dir_block)
 -              goto out_clear_inode;
 +      if (!dir_block) {
@@ -182,28 +176,20 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
        BUFFER_TRACE(dir_block, "get_write_access");
        ext4_journal_get_write_access(handle, dir_block);
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
-@@ -1907,7 +1917,7 @@ retry:
-       de = ext4_next_entry(de);
-       de->inode = cpu_to_le32(dir->i_ino);
-       de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
--                                              EXT4_DIR_REC_LEN(1));
-+                                            EXT4_DIR_REC_LEN(1));
-       de->name_len = 2;
-       strcpy (de->name, "..");
-       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
-@@ -1916,9 +1926,41 @@ retry:
+@@ -1925,9 +1940,43 @@ retry:
        ext4_journal_dirty_metadata(handle, dir_block);
-       brelse (dir_block);
+       brelse(dir_block);
        ext4_mark_inode_dirty(handle, inode);
 +get_out:
 +      return err;
 +}
 +EXPORT_SYMBOL(ext4_add_dot_dotdot);
 +
-+static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
++
++static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 +{
 +      handle_t *handle;
-+      struct inode * inode;
++      struct inode *inode;
 +      int err, retries = 0;
 +
 +      if (EXT4_DIR_LINK_MAX(dir))
@@ -219,7 +205,8 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
 +      if (IS_DIRSYNC(dir))
 +              handle->h_sync = 1;
 +
-+      inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
++      inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
 +      err = PTR_ERR(inode);
 +      if (IS_ERR(inode))
 +              goto out_stop;
@@ -228,10 +215,9 @@ diff -rupN linux-2.6.18-128.1.6_1//fs/ext4/namei.c linux-2.6.18-128.1.6_2//fs/ex
 +      if (err)
 +              goto out_stop;
 +
-       err = ext4_add_entry (handle, dentry, inode);
+       err = ext4_add_entry(handle, dentry, inode);
        if (err) {
 -out_clear_inode:
                clear_nlink(inode);
                ext4_mark_inode_dirty(handle, inode);
-               iput (inode);
-
+               iput(inode);
index 34d0472..d09f8f5 100644 (file)
@@ -6,16 +6,16 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4_sb.h
  
        /* tunables */
        unsigned long s_stripe;
--      unsigned long s_mb_stream_request;
+-      unsigned int s_mb_stream_request;
 +      unsigned long s_mb_small_req;
 +      unsigned long s_mb_large_req;
-       unsigned long s_mb_max_to_scan;
-       unsigned long s_mb_min_to_scan;
-       unsigned long s_mb_stats;
-       unsigned long s_mb_order2_reqs;
+       unsigned int s_mb_max_to_scan;
+       unsigned int s_mb_min_to_scan;
+       unsigned int s_mb_stats;
+       unsigned int s_mb_order2_reqs;
 +      unsigned long *s_mb_prealloc_table;
 +      unsigned long s_mb_prealloc_table_size;
-       unsigned long s_mb_group_prealloc;
+       unsigned int s_mb_group_prealloc;
        /* where last allocation was done - for stream allocation */
        unsigned long s_mb_last_group;
 Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
@@ -58,7 +58,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  int ext4_mb_init(struct super_block *sb, int needs_recovery)
  {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-@@ -2542,15 +2562,59 @@
+@@ -2542,13 +2562,55 @@
        sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN;
        sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN;
        sbi->s_mb_stats = MB_DEFAULT_STATS;
@@ -72,7 +72,6 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +              i = sbi->s_mb_prealloc_table_size * sizeof(unsigned long);
 +              sbi->s_mb_prealloc_table = kmalloc(i, GFP_NOFS);
 +              if (sbi->s_mb_prealloc_table == NULL) {
-+                              clear_opt(sbi->s_mount_opt, MBALLOC);
 +                              kfree(sbi->s_mb_offsets);
 +                              kfree(sbi->s_mb_maxs);
 +                              return -ENOMEM;
@@ -96,7 +95,6 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +              i = sbi->s_mb_prealloc_table_size * sizeof(unsigned long);
 +              sbi->s_mb_prealloc_table = kmalloc(i, GFP_NOFS);
 +              if (sbi->s_mb_prealloc_table == NULL) {
-+                      clear_opt(sbi->s_mount_opt, MBALLOC);
 +                      kfree(sbi->s_mb_offsets);
 +                      kfree(sbi->s_mb_maxs);
 +                      return -ENOMEM;
@@ -112,15 +110,13 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +              sbi->s_mb_group_prealloc = sbi->s_stripe * 4;
 +      }
  
-       i = sizeof(struct ext4_locality_group) * num_possible_cpus();
-       sbi->s_locality_groups = kmalloc(i, GFP_KERNEL);
+       sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
        if (sbi->s_locality_groups == NULL) {
-               clear_opt(sbi->s_mount_opt, MBALLOC);
 +              kfree(sbi->s_mb_prealloc_table);
                kfree(sbi->s_mb_offsets);
                kfree(sbi->s_mb_maxs);
                return -ENOMEM;
-@@ -2725,10 +2789,82 @@
+@@ -2725,8 +2789,82 @@
  #define EXT4_MB_MAX_TO_SCAN_NAME      "max_to_scan"
  #define EXT4_MB_MIN_TO_SCAN_NAME      "min_to_scan"
  #define EXT4_MB_ORDER2_REQ            "order2_req"
@@ -129,7 +125,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +#define EXT4_MB_LARGE_REQ             "large_req"
 +#define EXT4_MB_PREALLOC_TABLE          "prealloc_table"
  #define EXT4_MB_GROUP_PREALLOC                "group_prealloc"
++
 +static int ext4_mb_prealloc_table_proc_read(char *page, char **start, off_t off,
 +                                          int count, int *eof, void *data)
 +{
@@ -182,7 +178,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 +              prev = value;
 +              num++;
 +      }
++
 +      new_table = kmalloc(num * sizeof(*new_table), GFP_KERNEL);
 +      if (new_table == NULL)
 +              return -ENOMEM;
@@ -204,35 +200,25 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
  
  #define MB_PROC_FOPS(name)                                    \
  static int ext4_mb_##name##_proc_show(struct seq_file *m, void *v)    \
-@@ -2774,7 +2910,8 @@
- MB_PROC_FOPS(max_to_scan);
- MB_PROC_FOPS(min_to_scan);
- MB_PROC_FOPS(order2_reqs);
--MB_PROC_FOPS(stream_request);
-+MB_PROC_FOPS(small_req);
-+MB_PROC_FOPS(large_req);
- MB_PROC_FOPS(group_prealloc);
- #define       MB_PROC_HANDLER(name, var)                                      \
 @@ -2795,6 +2932,7 @@
        mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct proc_dir_entry *proc;
 +      struct proc_dir_entry *proc_entry;
-       char devname[64];
-       if (proc_root_ext4 == NULL) {
-@@ -2808,15 +2946,29 @@
-       MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan);
-       MB_PROC_HANDLER(EXT4_MB_MIN_TO_SCAN_NAME, min_to_scan);
-       MB_PROC_HANDLER(EXT4_MB_ORDER2_REQ, order2_reqs);
--      MB_PROC_HANDLER(EXT4_MB_STREAM_REQ, stream_request);
-+      MB_PROC_HANDLER(EXT4_MB_SMALL_REQ, small_req);
-+      MB_PROC_HANDLER(EXT4_MB_LARGE_REQ, large_req);
-       MB_PROC_HANDLER(EXT4_MB_GROUP_PREALLOC, group_prealloc);
  
+       if (sbi->s_proc == NULL)
+               return -EINVAL;
+@@ -2808,13 +2946,28 @@
+       EXT4_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, mb_max_to_scan);
+       EXT4_PROC_HANDLER(EXT4_MB_MIN_TO_SCAN_NAME, mb_min_to_scan);
+       EXT4_PROC_HANDLER(EXT4_MB_ORDER2_REQ, mb_order2_reqs);
+-      EXT4_PROC_HANDLER(EXT4_MB_STREAM_REQ, mb_stream_request);
++      EXT4_PROC_HANDLER(EXT4_MB_SMALL_REQ, mb_small_req);
++      EXT4_PROC_HANDLER(EXT4_MB_LARGE_REQ, mb_large_req);
+       EXT4_PROC_HANDLER(EXT4_MB_GROUP_PREALLOC, mb_group_prealloc);
++
 +      proc_entry = create_proc_entry(EXT4_MB_PREALLOC_TABLE, S_IFREG |
-+                                     S_IRUGO | S_IWUSR, sbi->s_mb_proc);
++                                     S_IRUGO | S_IWUSR, sbi->s_proc);
 +      if (proc_entry == NULL) {
 +              printk(KERN_ERR "EXT4-fs: unable to create %s\n",
 +                     EXT4_MB_PREALLOC_TABLE);
@@ -245,26 +231,25 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
        return 0;
  
  err_out:
-       printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
-       remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
--      remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
+       remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_proc);
+-      remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
 @@ -2838,7 +2990,9 @@
  
-       bdevname(sb->s_bdev, devname);
-       remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
--      remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_mb_proc);
-+      remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
-       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
+       remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_proc);
+-      remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_PREALLOC_TABLE, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_LARGE_REQ, sbi->s_proc);
++      remove_proc_entry(EXT4_MB_SMALL_REQ, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc);
+       remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
 @@ -3032,11 +3186,12 @@
  ext4_mb_normalize_request(struct ext4_allocation_context *ac,
                                struct ext4_allocation_request *ar)
@@ -358,8 +343,8 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
 @@ -3185,7 +3326,6 @@
        }
        BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
-                       start > ac->ac_o_ex.fe_logical);
--      BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+                       start > ac->ac_o_ex.fe_logical);
+-      BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
  
        /* now prepare goal request */
  
@@ -403,3 +388,26 @@ Index: linux-2.6.18-128.1.6/fs/ext4/mballoc.c
        BUG_ON(ac->ac_lg != NULL);
        /*
         * locality group prealloc space are per cpu. The reason for having
+Index: linux-2.6.27.21-0.1/fs/ext4/inode.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/ext4/inode.c   2009-05-28 11:12:42.000000000 +0530
++++ linux-2.6.27.21-0.1/fs/ext4/inode.c        2009-05-28 11:16:48.000000000 +0530
+@@ -2442,14 +2442,14 @@
+               return -EROFS;
+       /*
+-       * Make sure nr_to_write is >= sbi->s_mb_stream_request
++       * Make sure nr_to_write is >= sbi->s_mb_small_req
+        * This make sure small files blocks are allocated in
+        * single attempt. This ensure that small files
+        * get less fragmented.
+        */
+-      if (wbc->nr_to_write < sbi->s_mb_stream_request) {
+-              nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write;
+-              wbc->nr_to_write = sbi->s_mb_stream_request;
++      if (wbc->nr_to_write < sbi->s_mb_small_req) {
++              nr_to_writebump = sbi->s_mb_small_req - wbc->nr_to_write;
++              wbc->nr_to_write = sbi->s_mb_small_req;
+       }
+       if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+               range_whole = 1;
index bab03d1..b854280 100644 (file)
@@ -5,7 +5,7 @@ Index: linux-2.6.18.i386/fs/ext4/ialloc.c
 @@ -1057,7 +1057,6 @@ unsigned long ext4_count_free_inodes (st
                if (!gdp)
                        continue;
-               desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+               desc_count += ext4_free_inodes_count(sb, gdp);
 -              cond_resched();
        }
        return desc_count;
index cff9a12..fe9cfeb 100644 (file)
@@ -3,11 +3,16 @@ Index: linux-2.6.18-128.1.6/fs/ext4/super.c
 --- linux-2.6.18-128.1.6.orig/fs/ext4/super.c  2009-07-24 01:33:54.000000000 -0400
 +++ linux-2.6.18-128.1.6/fs/ext4/super.c       2009-07-24 01:35:28.000000000 -0400
 @@ -3461,6 +3461,8 @@ static int __init init_ext4_fs(void)
-       err = register_filesystem(&ext4dev_fs_type);
-       if (err)
                goto out;
+       }
+ #endif
 +
 +      printk(KERN_INFO "ldiskfs created from ""ext""4-2.6-rhel5\n");
        return 0;
  out:
        destroy_inodecache();
+--- /dev/null   2009-09-21 17:11:24.467285554 +0800
++++ linux-2.6.27.21-0.1/fs/ext4/fiemap.h
+@@ -0,0 +1,2 @@
++
++#include_next <fiemap.h>
index e0c6f8d..4927dd0 100644 (file)
-Index: linux-2.6.18.i386/fs/ext4/ialloc.c
+Index: linux-stage/fs/ext4/ialloc.c
 ===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
-+++ linux-2.6.18.i386/fs/ext4/ialloc.c
-@@ -576,7 +576,8 @@ static int find_group_other(struct super
+--- linux-stage.orig/fs/ext4/ialloc.c
++++ linux-stage/fs/ext4/ialloc.c
+@@ -675,7 +675,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,
-+                           unsigned long goal)
+-struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
++                                int mode, unsigned goal)
  {
        struct super_block *sb;
-       struct buffer_head *bitmap_bh = NULL;
-@@ -607,6 +608,43 @@ struct inode *ext4_new_inode(handle_t *h
+       struct buffer_head *inode_bitmap_bh = NULL;
+@@ -706,6 +707,14 @@ struct inode *ext4_new_inode(handle_t *h
        sbi = EXT4_SB(sb);
        es = sbi->s_es;
  
-+      if (goal) {
++      if (goal && goal <= le32_to_cpu(es->s_inodes_count)) {
 +              group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
 +              ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
-+              err = -EIO;
 +
-+              gdp = ext4_get_group_desc(sb, group, &bh2);
-+              if (!gdp)
-+                      goto fail;
-+
-+              bitmap_bh = ext4_read_inode_bitmap(sb, group);
-+              if (!bitmap_bh)
-+                      goto fail;
-+
-+              BUFFER_TRACE(bh, "get_write_access");
-+              err = ext4_journal_get_write_access(handle, bitmap_bh);
-+              if (err)
-+                      goto fail;
-+
-+              if (ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
-+                                      ino, bitmap_bh->b_data)) {
-+                      printk(KERN_ERR "goal inode %lu unavailable\n", goal);
-+                      /* Oh well, we tried. */
-+                      goto continue_allocation;
-+              }
-+
-+              BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
-+              err = ext4_journal_dirty_metadata(handle, bitmap_bh);
-+              if (err)
-+                      goto fail;
-+
-+              /* We've shortcircuited the allocation system successfully,
-+               * now finish filling in the inode.
-+               */
-+              goto got;
++              ret2 = 0;
++              goto got_group;
 +      }
 +
-+continue_allocation:
        if (sbi->s_log_groups_per_flex) {
                ret2 = find_group_flex(sb, dir, &group);
                goto got_group;
-Index: linux-2.6.18.i386/fs/ext4/namei.c
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/namei.c
-+++ linux-2.6.18.i386/fs/ext4/namei.c
-@@ -104,6 +104,7 @@ struct dx_entry
-       __le32 block;
- };
+@@ -724,7 +733,7 @@ got_group:
+       if (ret2 == -1)
+               goto out;
  
-+
- /*
-  * dx_root_info is laid out so that if it should somehow get overlaid by a
-  * dirent the two low bits of the hash version will be zero.  Therefore, the
-@@ -149,6 +150,14 @@ struct dx_map_entry
+-      for (i = 0; i < sbi->s_groups_count; i++) {
++      for (i = 0; i < sbi->s_groups_count; i++, ino = 0) {
+               err = -EIO;
+               gdp = ext4_get_group_desc(sb, group, &group_desc_bh);
+@@ -736,8 +745,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,
+Index: linux-stage/fs/ext4/namei.c
+===================================================================
+--- linux-stage.orig/fs/ext4/namei.c
++++ linux-stage/fs/ext4/namei.c
+@@ -149,6 +149,17 @@ struct dx_map_entry
        u16 size;
  };
  
++/*
++ * dentry_param used by ext4_new_inode_wantedi()
++ */
 +#define LVFS_DENTRY_PARAM_MAGIC               20070216UL
 +struct lvfs_dentry_params
 +{
-+      unsigned long   p_inum;
-+      void        *p_ptr;
-+      u32          magic;
++      unsigned long   ldp_inum;
++      unsigned long   ldp_flags;
++      u32             ldp_magic;
 +};
 +
  static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
  static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
- static inline unsigned dx_get_hash (struct dx_entry *entry);
-@@ -1708,6 +1717,20 @@ static int ext4_add_nondir(handle_t *han
+ static inline unsigned dx_get_hash(struct dx_entry *entry);
+@@ -1716,6 +1727,19 @@ static int ext4_add_nondir(handle_t *han
        return err;
  }
  
-+static struct inode * ext4_new_inode_wantedi(handle_t *handle, struct inode *dir,
-+                                              int mode, struct dentry *dentry)
++static unsigned ext4_dentry_goal(struct super_block *sb, struct dentry *dentry)
 +{
-+      unsigned long inum = 0;
++      unsigned inum = EXT4_SB(sb)->s_inode_goal;
 +
 +      if (dentry->d_fsdata != NULL) {
 +              struct lvfs_dentry_params *param = dentry->d_fsdata;
 +
-+              if (param->magic == LVFS_DENTRY_PARAM_MAGIC)
-+                      inum = param->p_inum;
++              if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC)
++                      inum = param->ldp_inum;
 +      }
-+      return ext4_new_inode(handle, dir, mode, inum);
++      return inum;
 +}
 +
  /*
   * By the time this is called, we already have created
   * the directory cache entry for the new file, but it
-@@ -1733,7 +1756,7 @@ retry:
+@@ -1741,7 +1766,8 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
  
 -      inode = ext4_new_inode (handle, dir, mode);
-+      inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
++      inode = ext4_new_inode_goal(handle, dir, mode,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                inode->i_op = &ext4_file_inode_operations;
-@@ -1767,7 +1790,7 @@ retry:
+@@ -1775,7 +1800,8 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
  
--      inode = ext4_new_inode (handle, dir, mode);
-+      inode = ext4_new_inode_wantedi (handle, dir, mode, dentry);
+-      inode = ext4_new_inode(handle, dir, mode);
++      inode = ext4_new_inode_goal(handle, dir, mode,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
        err = PTR_ERR(inode);
        if (!IS_ERR(inode)) {
                init_special_inode(inode, inode->i_mode, rdev);
-@@ -1803,7 +1826,7 @@ retry:
+@@ -1811,7 +1836,8 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
  
--      inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
-+      inode = ext4_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry);
+-      inode = ext4_new_inode(handle, dir, S_IFDIR | mode);
++      inode = ext4_new_inode_goal(handle, dir, S_IFDIR | mode,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
-@@ -2203,7 +2226,7 @@ retry:
+@@ -2211,7 +2236,8 @@ retry:
        if (IS_DIRSYNC(dir))
                handle->h_sync = 1;
  
--      inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
-+      inode = ext4_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry);
+-      inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO);
++      inode = ext4_new_inode_goal(handle, dir, S_IFLNK|S_IRWXUGO,
++                                  ext4_dentry_goal(dir->i_sb, dentry));
        err = PTR_ERR(inode);
        if (IS_ERR(inode))
                goto out_stop;
-Index: linux-2.6.18.i386/fs/ext4/ext4.h
+Index: linux-stage/fs/ext4/ext4.h
 ===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/ext4.h
-+++ linux-2.6.18.i386/fs/ext4/ext4.h
-@@ -1013,7 +1013,8 @@ extern int ext4fs_dirhash(const char *na
+--- linux-stage.orig/fs/ext4/ext4.h
++++ linux-stage/fs/ext4/ext4.h
+@@ -1032,7 +1032,14 @@ extern int ext4fs_dirhash(const char *na
                          dx_hash_info *hinfo);
  
  /* ialloc.c */
--extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
-+extern struct inode * ext4_new_inode (handle_t *, struct inode *, int,
-+                                    unsigned long);
- extern void ext4_free_inode (handle_t *, struct inode *);
- extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
- extern unsigned long ext4_count_free_inodes (struct super_block *);
-Index: linux-2.6.18.i386/fs/ext4/migrate.c
+-extern struct inode * ext4_new_inode(handle_t *, struct inode *, int);
++extern struct inode *ext4_new_inode_goal(handle_t *handle, struct inode *dir,
++                                       int mode, unsigned goal);
++static inline struct inode *ext4_new_inode(handle_t *handle, struct inode *dir,
++                                         int mode)
++{
++      return ext4_new_inode_goal(handle, dir, mode,
++                                 EXT4_SB(dir->i_sb)->s_inode_goal);
++}
+ extern void ext4_free_inode(handle_t *, struct inode *);
+ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
+ extern unsigned long ext4_count_free_inodes(struct super_block *);
+Index: linux-stage/fs/ext4/super.c
 ===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/migrate.c
-+++ linux-2.6.18.i386/fs/ext4/migrate.c
-@@ -485,7 +485,7 @@ int ext4_ext_migrate(struct inode *inode
+--- linux-stage.orig/fs/ext4/super.c
++++ linux-stage/fs/ext4/super.c
+@@ -560,6 +560,7 @@ static void ext4_put_super(struct super_
+       }
+       if (sbi->s_proc) {
+               remove_proc_entry("inode_readahead_blks", sbi->s_proc);
++              remove_proc_entry("inode_goal", sbi->s_proc);
+               remove_proc_entry(sb->s_id, ext4_proc_root);
        }
-       tmp_inode = ext4_new_inode(handle,
-                               inode->i_sb->s_root->d_inode,
--                              S_IFREG);
-+                              S_IFREG, 0);
-       if (IS_ERR(tmp_inode)) {
-               retval = -ENOMEM;
-               ext4_journal_stop(handle);
+@@ -2274,6 +2275,11 @@ static int ext4_fill_super(struct super_
+                       p->proc_fops = &ext4_ui_proc_fops;
+                       p->data = &sbi->s_inode_readahead_blks;
+               }
++              p = create_proc_entry("inode_goal", 0644, sbi->s_proc);
++              if (p) {
++                      p->proc_fops = &ext4_ui_proc_fops,
++                      p->data = &sbi->s_inode_goal;
++              }
+       }
+ #endif
+@@ -2553,6 +2558,7 @@ failed_mount2:
+ failed_mount:
+       if (sbi->s_proc) {
+               remove_proc_entry("inode_readahead_blks", sbi->s_proc);
++              remove_proc_entry("inode_goal", sbi->s_proc);
+               remove_proc_entry(sb->s_id, ext4_proc_root);
+       }
+ #ifdef CONFIG_QUOTA
+Index: linux-stage/fs/ext4/ext4_sb.h
+===================================================================
+--- linux-stage.orig/fs/ext4/ext4_sb.h
++++ linux-stage/fs/ext4/ext4_sb.h
+@@ -53,6 +53,7 @@ struct ext4_sb_info {
+       int s_inode_size;
+       int s_first_ino;
+       unsigned int s_inode_readahead_blks;
++      unsigned int s_inode_goal;
+       spinlock_t s_next_gen_lock;
+       u32 s_next_generation;
+       u32 s_hash_seed[4];
+
index bf348ff..9f3ce99 100644 (file)
@@ -167,7 +167,7 @@ Index: b/fs/ext4/ext4.h
                                            struct ext4_dir_entry_2
                                            ** res_dir);
  extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
--                             struct inode *inode);
+-                                struct inode *inode);
 +                        struct inode *inode, const void *, const void *);
  extern int ext4_orphan_add(handle_t *, struct inode *);
  extern int ext4_orphan_del(handle_t *, struct inode *);
@@ -208,12 +208,12 @@ Index: b/fs/ext4/namei.c
 +++ b/fs/ext4/namei.c
 @@ -177,7 +177,8 @@ static unsigned dx_get_count (struct dx_
  static unsigned dx_get_limit (struct dx_entry *entries);
- static void dx_set_count (struct dx_entry *entries, unsigned value);
- static void dx_set_limit (struct dx_entry *entries, unsigned value);
--static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
+ static void dx_set_count(struct dx_entry *entries, unsigned value);
+ static void dx_set_limit(struct dx_entry *entries, unsigned value);
+-static unsigned dx_root_limit(struct inode *dir, unsigned infosize);
 +static inline unsigned dx_root_limit(__u32 blocksize,
 +              struct ext4_dir_entry_2 *dot_de, unsigned infosize);
- static unsigned dx_node_limit (struct inode *dir);
+ static unsigned dx_node_limit(struct inode *dir);
  static struct dx_frame *dx_probe(struct dentry *dentry,
                                 struct inode *dir,
 @@ -218,11 +219,12 @@ ext4_next_entry(struct ext4_dir_entry_2 
@@ -237,7 +237,7 @@ Index: b/fs/ext4/namei.c
        ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
  }
  
--static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
+-static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
 +static inline unsigned dx_root_limit(__u32 blocksize,
 +              struct ext4_dir_entry_2 *dot_de, unsigned infosize)
  {
@@ -254,7 +254,7 @@ Index: b/fs/ext4/namei.c
        return entry_space / sizeof(struct dx_entry);
  }
  
- static inline unsigned dx_node_limit (struct inode *dir)
+ static inline unsigned dx_node_limit(struct inode *dir)
  {
 -      unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
 +      unsigned entry_space = dir->i_sb->s_blocksize - __EXT4_DIR_REC_LEN(0);
@@ -356,7 +356,7 @@ Index: b/fs/ext4/namei.c
 @@ -1399,6 +1415,12 @@ static int add_dirent_to_buf(handle_t *h
                de->inode = 0;
        de->name_len = namelen;
-       memcpy (de->name, name, namelen);
+       memcpy(de->name, name, namelen);
 +      if (data) {
 +              de->name[namelen] = 0;
 +              memcpy(&de->name[namelen + 1], data, *(char *) data);
@@ -436,23 +436,23 @@ Index: b/fs/ext4/namei.c
  /* Initialize @inode as a subdirectory of @dir, and add the
   * "." and ".." entries into the first directory block. */
  int ext4_add_dot_dotdot(handle_t *handle, struct inode * dir,
--                       struct inode *inode)
+-                      struct inode *inode)
 +                       struct inode *inode,
 +                       const void *data1, const void *data2)
 {
+ {
        struct buffer_head * dir_block;
-       struct ext4_dir_entry_2 * de;
+       struct ext4_dir_entry_2 * de;
 -      int err = 0;
 +      int err = 0, dot_reclen;
  
-       inode->i_op = &ext4_dir_inode_operations;
-       inode->i_fop = &ext4_dir_operations;
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
 @@ -1993,16 +2029,34 @@ int ext4_add_dot_dotdot(handle_t *handle
        de = (struct ext4_dir_entry_2 *) dir_block->b_data;
        de->inode = cpu_to_le32(inode->i_ino);
        de->name_len = 1;
 -      de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len));
-       strcpy (de->name, ".");
+       strcpy(de->name, ".");
        ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 +      /* get packed fid data*/
 +      data1 = ext4_dentry_get_data(dir->i_sb,
@@ -468,10 +468,10 @@ Index: b/fs/ext4/namei.c
        de = ext4_next_entry(de);
        de->inode = cpu_to_le32(dir->i_ino);
        de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
--                                            EXT4_DIR_REC_LEN(1));
+-                                              EXT4_DIR_REC_LEN(1));
 +                                              dot_reclen);
        de->name_len = 2;
-       strcpy (de->name, "..");
+       strcpy(de->name, "..");
        ext4_set_de_type(dir->i_sb, de, S_IFDIR);
 +      data2 = ext4_dentry_get_data(dir->i_sb,
 +                      (struct ext4_dentry_param *) data2);
@@ -499,6 +499,6 @@ Index: b/fs/ext4/namei.c
        sb = inode->i_sb;
 -      if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
 +      if (inode->i_size < __EXT4_DIR_REC_LEN(1) + __EXT4_DIR_REC_LEN(2) ||
-           !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
+           !(bh = ext4_bread(NULL, inode, 0, 0, &err))) {
                if (err)
                        ext4_error(inode->i_sb, __func__,
index d7b94fa..eb53ca1 100644 (file)
@@ -332,9 +332,9 @@ Index: linux-2.6.18-128.1.6/fs/ext4/inode.c
  
  /*
 @@ -2764,6 +2765,8 @@ struct inode *ext4_iget(struct super_blo
+       ei->i_acl = EXT4_ACL_NOT_CACHED;
        ei->i_default_acl = EXT4_ACL_NOT_CACHED;
  #endif
-       ei->i_block_alloc_info = NULL;
 +      if (ext4_iopen_get_inode(inode))
 +              return inode;
  
@@ -344,10 +344,12 @@ Index: linux-2.6.18-128.1.6/fs/ext4/super.c
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/super.c
 +++ linux-2.6.18-128.1.6/fs/ext4/super.c
-@@ -888,6 +888,7 @@ enum {
-       Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
-       Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
-       Opt_mballoc, Opt_nomballoc, Opt_stripe,
+@@ -888,7 +888,8 @@ enum {
+
+       Opt_usrquota, Opt_grpquota, Opt_i_version,
+       Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+-      Opt_inode_readahead_blks, Opt_journal_ioprio
++      Opt_inode_readahead_blks, Opt_journal_ioprio,
 +      Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
  };
  
@@ -400,7 +402,7 @@ Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
 +      if (ext4_check_for_iopen(dir, dentry))
 +              return NULL;
 +
-       bh = ext4_find_entry(dentry, &de);
+       bh = ext4_find_entry(dir, &dentry->d_name, &de);
        inode = NULL;
        if (bh) {
 @@ -1062,7 +1066,8 @@ static struct dentry *ext4_lookup(struct
@@ -419,18 +421,18 @@ Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
                ext4_mark_inode_dirty(handle, inode);
 -              d_instantiate(dentry, inode);
 +              iopen_d_instantiate(dentry, inode);
+               unlock_new_inode(inode);
                return 0;
        }
-       drop_nlink(inode);
 @@ -1868,7 +1873,7 @@ out_clear_inode:
        ext4_inc_count(handle, dir);
        ext4_update_dx_flag(dir);
        ext4_mark_inode_dirty(handle, dir);
 -      d_instantiate(dentry, inode);
 +      iopen_d_instantiate(dentry, inode);
+       unlock_new_inode(inode);
  out_stop:
        ext4_journal_stop(handle);
-       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
 @@ -2134,10 +2139,6 @@ static int ext4_rmdir (struct inode * di
                              inode->i_nlink);
        inode->i_version++;
@@ -463,14 +465,21 @@ Index: linux-2.6.18-128.1.6/fs/ext4/namei.c
 +      return err;
 +}
 +
- static int ext4_link (struct dentry * old_dentry,
-               struct inode * dir, struct dentry *dentry)
+ static int ext4_link(struct dentry *old_dentry,
+                    struct inode *dir, struct dentry *dentry)
  {
-@@ -2293,7 +2311,8 @@ retry:
+@@ -2293,14 +2311,8 @@ retry:
        ext4_inc_count(handle, inode);
        atomic_inc(&inode->i_count);
  
--      err = ext4_add_nondir(handle, dentry, inode);
+-      err = ext4_add_entry(handle, dentry, inode);
+-      if (!err) {
+-              ext4_mark_inode_dirty(handle, inode);
+-              d_instantiate(dentry, inode);
+-      } else {
+-              drop_nlink(inode);
+-              iput(inode);
+-      }
 +      err = ext4_add_link(handle, dentry, inode);
 +      ext4_orphan_del(handle, inode);
        ext4_journal_stop(handle);
@@ -484,8 +493,8 @@ Index: linux-2.6.18-128.1.6/fs/ext4/Makefile
  
  obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
  
--ext4dev-y     := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
-+ext4dev-y     := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+-ext4-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
++ext4-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
                   ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
                   ext4_jbd2.o migrate.o mballoc.o
  
@@ -493,20 +502,13 @@ Index: linux-2.6.18-128.1.6/fs/ext4/ext4.h
 ===================================================================
 --- linux-2.6.18-128.1.6.orig/fs/ext4/ext4.h
 +++ linux-2.6.18-128.1.6/fs/ext4/ext4.h
-@@ -18,6 +18,7 @@
- #include <linux/types.h>
- #include <linux/blkdev.h>
-+#include <linux/jbd2.h>
- #include "ext4_i.h"
- #define EXT4_SUPER_MAGIC      0xEF53
 @@ -537,6 +538,8 @@ do {                                                                              \
  #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT       0x1000000 /* Journal Async Commit */
  #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
- #define EXT4_MOUNT_MBALLOC            0x4000000 /* Buddy allocation support */
-+#define EXT4_MOUNT_IOPEN              0x8000000 /* Allow access via iopen */
-+#define EXT4_MOUNT_IOPEN_NOPRIV               0x10000000 /* Make iopen world-readable */
+ #define EXT4_MOUNT_DELALLOC           0x8000000 /* Delalloc support */
+ #define EXT4_MOUNT_DATA_ERR_ABORT     0x10000000 /* Abort on file data write */
++#define EXT4_MOUNT_IOPEN              0x20000000 /* Allow access via iopen */
++#define EXT4_MOUNT_IOPEN_NOPRIV               0x40000000 /* Make iopen world-readable */
  /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
  #ifndef _LINUX_EXT2_FS_H
- #define clear_opt(o, opt)             o &= ~EXT4_MOUNT_##opt
index aa560d2..521bfee 100644 (file)
@@ -8,27 +8,24 @@ ext4-remove-cond_resched-calls-rhel5.patch
 ext4-filterdata-rhel5.patch
 ext4-inode-version-rhel5.patch
 ext4-mmp-rhel5.patch
-ext4-fiemap-2.6-rhel5.patch
 ext4-lookup-dotdot-rhel5.patch
 ext4-max-dir-size-rhel5.patch
 ext4-print-inum-in-htree-warning-rhel5.patch
 ext4-xattr-no-update-ctime-rhel5.patch
 ext4-prealloc-rhel5.patch
 ext4-mballoc-extra-checks-rhel5.patch
-ext4-mballoc-handle-dev-paths-rhel5.patch
 ext4-big-endian-check-2.6-rhel5.patch
 ext4-alloc-policy-2.6-rhel5.patch
 ext4-misc-rhel5.patch
 ext4-convert-group-lock-rhel5.patch
 ext4-force_over_8tb-rhel5.patch
-ext4_ext_search_right-fix.patch
-ext4-pa_lock-typo.patch
 ext4-pdir-fix.patch
 ext4-osd-iop-common.patch
 ext4-osd-iam-exports.patch
 ext4-dynlocks-common.patch
 ext4-dynlocks-2.6-rhel5.patch
 ext4-hash-indexed-dir-dotdot-update.patch
+ext4-ext_generation-sles11.patch
 ext4-kill-dx_root.patch
 ext4_data_in_dirent.patch
-ext4-add-ext4_itable_unused_count.patch
+ext4-extents-mount-option-rhel5.patch
index 7f61ad5..a4fdac9 100644 (file)
@@ -15,7 +15,6 @@ ext3-nanosecond-2.6.18-vanilla.patch
 ext3-inode-version-2.6.18-vanilla.patch
 ext3-ea-expand-lose-block.patch
 ext3-mmp-2.6.18-vanilla.patch
-ext3-fiemap-2.6-rhel5.patch
 ext3-statfs-2.6-rhel5.patch
 ext3-lookup-dotdot-2.6.9.patch
 ext3-max-dir-size.patch