From 8007b51d6d9caa2a0ee9d5649ea9b869603f8cfa Mon Sep 17 00:00:00 2001 From: yangsheng Date: Thu, 12 Nov 2009 17:14:18 +0000 Subject: [PATCH] Branch b1_8 b=20773 i=adilger, shadow, girish, brian, wangyb Update kernel to RHEL5 U4 2.6.18-164.6.1.el5. --- .../patches/export-ext4-2.6-rhel5.patch | 6 +- .../patches/ext3-extents-2.6.18-vanilla.patch | 4 +- .../kernel_patches/patches/ext3-kill-dx_root.patch | 16 +- .../patches/ext3-osd-iop-common.patch | 3 +- .../patches/ext3-version-2.6-rhel5.patch | 5 + .../patches/ext3_data_in_dirent.patch | 17 +- .../patches/ext4-alloc-policy-2.6-rhel5.patch | 72 ++- .../patches/ext4-big-endian-check-2.6-rhel5.patch | 8 +- .../patches/ext4-convert-group-lock-rhel5.patch | 482 ++++++++------------- .../patches/ext4-extents-mount-option-rhel5.patch | 170 ++++++++ .../patches/ext4-fiemap-2.6-rhel5.patch | 274 +----------- .../patches/ext4-filterdata-rhel5.patch | 12 +- .../ext4-hash-indexed-dir-dotdot-update.patch | 4 +- .../patches/ext4-inode-version-rhel5.patch | 32 -- .../kernel_patches/patches/ext4-kill-dx_root.patch | 45 +- .../patches/ext4-max-dir-size-rhel5.patch | 129 ++---- .../patches/ext4-mballoc-extra-checks-rhel5.patch | 70 +-- .../kernel_patches/patches/ext4-misc-rhel5.patch | 165 ++++--- .../kernel_patches/patches/ext4-mmp-rhel5.patch | 4 +- .../patches/ext4-osd-iop-common.patch | 174 ++++---- .../patches/ext4-prealloc-rhel5.patch | 122 +++--- .../ext4-remove-cond_resched-calls-rhel5.patch | 2 +- .../patches/ext4-version-2.6-rhel5.patch | 9 +- .../patches/ext4-wantedi-2.6-rhel5.patch | 217 ++++++---- .../patches/ext4_data_in_dirent.patch | 34 +- .../patches/iopen-2.6.18-rhel5-ext4.patch | 54 +-- .../series/ldiskfs-2.6-rhel5-ext4.series | 7 +- .../kernel_patches/series/ldiskfs-2.6-rhel5.series | 1 - 28 files changed, 949 insertions(+), 1189 deletions(-) create mode 100644 ldiskfs/kernel_patches/patches/ext4-extents-mount-option-rhel5.patch diff --git a/ldiskfs/kernel_patches/patches/export-ext4-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/export-ext4-2.6-rhel5.patch index 7a97989..c395e00 100644 --- a/ldiskfs/kernel_patches/patches/export-ext4-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/export-ext4-2.6-rhel5.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.18-vanilla.patch b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.18-vanilla.patch index 8131d96..97b5ba1 100644 --- a/ldiskfs/kernel_patches/patches/ext3-extents-2.6.18-vanilla.patch +++ b/ldiskfs/kernel_patches/patches/ext3-extents-2.6.18-vanilla.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/ext3-kill-dx_root.patch b/ldiskfs/kernel_patches/patches/ext3-kill-dx_root.patch index 77c9e99..1161d6d 100644 --- a/ldiskfs/kernel_patches/patches/ext3-kill-dx_root.patch +++ b/ldiskfs/kernel_patches/patches/ext3-kill-dx_root.patch @@ -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) diff --git a/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch b/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch index 30a8184..5dd2fc57 100644 --- a/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch +++ b/ldiskfs/kernel_patches/patches/ext3-osd-iop-common.patch @@ -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; diff --git a/ldiskfs/kernel_patches/patches/ext3-version-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext3-version-2.6-rhel5.patch index e4e8dba..49e985b 100644 --- a/ldiskfs/kernel_patches/patches/ext3-version-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext3-version-2.6-rhel5.patch @@ -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 diff --git a/ldiskfs/kernel_patches/patches/ext3_data_in_dirent.patch b/ldiskfs/kernel_patches/patches/ext3_data_in_dirent.patch index 533e2a0..485aaec 100644 --- a/ldiskfs/kernel_patches/patches/ext3_data_in_dirent.patch +++ b/ldiskfs/kernel_patches/patches/ext3_data_in_dirent.patch @@ -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 + diff --git a/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-rhel5.patch index a1b8375..b5febbf 100644 --- a/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-rhel5.patch @@ -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 *); diff --git a/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-rhel5.patch index 0ec5670..0503d35 100644 --- a/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-rhel5.patch @@ -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}, }; diff --git a/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch index 8f714f8..95609d9 100644 --- a/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-convert-group-lock-rhel5.patch @@ -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 index 0000000..96e964b --- /dev/null +++ b/ldiskfs/kernel_patches/patches/ext4-extents-mount-option-rhel5.patch @@ -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 + */ diff --git a/ldiskfs/kernel_patches/patches/ext4-fiemap-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-fiemap-2.6-rhel5.patch index 7163c94..b9468f8 100644 --- a/ldiskfs/kernel_patches/patches/ext4-fiemap-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-fiemap-2.6-rhel5.patch @@ -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 - #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 diff --git a/ldiskfs/kernel_patches/patches/ext4-filterdata-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-filterdata-rhel5.patch index 25ea28a..2bb1d36 100644 --- a/ldiskfs/kernel_patches/patches/ext4-filterdata-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-filterdata-rhel5.patch @@ -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; } diff --git a/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch b/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch index d354f89..76416c7 100644 --- a/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch +++ b/ldiskfs/kernel_patches/patches/ext4-hash-indexed-dir-dotdot-update.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/ext4-inode-version-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-inode-version-rhel5.patch index d8a31ad..206e159 100644 --- a/ldiskfs/kernel_patches/patches/ext4-inode-version-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-inode-version-rhel5.patch @@ -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 diff --git a/ldiskfs/kernel_patches/patches/ext4-kill-dx_root.patch b/ldiskfs/kernel_patches/patches/ext4-kill-dx_root.patch index 908a6de..4591d3c 100644 --- a/ldiskfs/kernel_patches/patches/ext4-kill-dx_root.patch +++ b/ldiskfs/kernel_patches/patches/ext4-kill-dx_root.patch @@ -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); diff --git a/ldiskfs/kernel_patches/patches/ext4-max-dir-size-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-max-dir-size-rhel5.patch index 295d0d1..3e34f6e 100644 --- a/ldiskfs/kernel_patches/patches/ext4-max-dir-size-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-max-dir-size-rhel5.patch @@ -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; - } diff --git a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch index 7522be2..24d04a2 100644 --- a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-rhel5.patch @@ -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 *); diff --git a/ldiskfs/kernel_patches/patches/ext4-misc-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-misc-rhel5.patch index f8e77c7..af54824 100644 --- a/ldiskfs/kernel_patches/patches/ext4-misc-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-misc-rhel5.patch @@ -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: diff --git a/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch index d01d046..812d9a9 100644 --- a/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-mmp-rhel5.patch @@ -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 diff --git a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch b/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch index bc184c5..cd9a250 100644 --- a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch +++ b/ldiskfs/kernel_patches/patches/ext4-osd-iop-common.patch @@ -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 #include #include -@@ -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); diff --git a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel5.patch index 34d0472..d09f8f5 100644 --- a/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-prealloc-rhel5.patch @@ -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; diff --git a/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-rhel5.patch index bab03d1..b854280 100644 --- a/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-rhel5.patch @@ -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; diff --git a/ldiskfs/kernel_patches/patches/ext4-version-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-version-2.6-rhel5.patch index cff9a12..fe9cfeb 100644 --- a/ldiskfs/kernel_patches/patches/ext4-version-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-version-2.6-rhel5.patch @@ -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 diff --git a/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-rhel5.patch index e0c6f8d..4927dd0 100644 --- a/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-rhel5.patch +++ b/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-rhel5.patch @@ -1,169 +1,194 @@ -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]; + diff --git a/ldiskfs/kernel_patches/patches/ext4_data_in_dirent.patch b/ldiskfs/kernel_patches/patches/ext4_data_in_dirent.patch index bf348ff..9f3ce99 100644 --- a/ldiskfs/kernel_patches/patches/ext4_data_in_dirent.patch +++ b/ldiskfs/kernel_patches/patches/ext4_data_in_dirent.patch @@ -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__, diff --git a/ldiskfs/kernel_patches/patches/iopen-2.6.18-rhel5-ext4.patch b/ldiskfs/kernel_patches/patches/iopen-2.6.18-rhel5-ext4.patch index d7b94fa..eb53ca1 100644 --- a/ldiskfs/kernel_patches/patches/iopen-2.6.18-rhel5-ext4.patch +++ b/ldiskfs/kernel_patches/patches/iopen-2.6.18-rhel5-ext4.patch @@ -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 - #include -+#include - #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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series index aa560d2..521bfee 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5-ext4.series @@ -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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series index 7f61ad5..a4fdac9 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series @@ -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 -- 1.8.3.1