From 8e0cd0b9f8cceae10d64c9fed0c59e95789542c1 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 28 Dec 2011 13:00:32 -0500 Subject: [PATCH] LU-335 ldiskfs: SuSE 11 SP1 support for Lustre 2.X Lustre 2.X has been lagging for SuSE server side support. This work brings the code up to date to support the SuSE 11 SP1 kernel 2.6.32.36-0.5. To reduce the maintenance overhead we basically add a patch that modifies the SuSE ext4 code to match very closely to the RHEL6.1 ext4 code base. Signed-off-by: James Simmons Change-Id: I554679c9b0d400eeda1d5d30157c5d86e68793f9 Reviewed-on: http://review.whamcloud.com/575 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger --- build/autoconf/lustre-build-ldiskfs.m4 | 8 + .../patches/ext4-alloc-policy-2.6-sles11.patch | 87 -- .../patches/ext4-big-endian-check-2.6-sles11.patch | 56 - .../patches/ext4-force_over_8tb-sles11.patch | 58 - .../patches/ext4-include-fixes-2.6-sles11.patch | 20 - .../patches/ext4-mballoc-extra-checks-sles11.patch | 280 ---- .../kernel_patches/patches/ext4-mmp-sles11.patch | 491 ------- .../patches/ext4-osd-iop-common-sles11.patch | 237 --- .../ext4-remove-cond_resched-calls-sles11.patch | 29 - .../patches/ext4-update-sles11-rhel6.patch | 1549 ++++++++++++++++++++ .../patches/ext4-wantedi-2.6-sles11.patch | 198 --- .../ext4-xattr-no-update-ctime-sles11.patch | 32 - .../series/ldiskfs-2.6-sles11.series | 68 +- 13 files changed, 1592 insertions(+), 1521 deletions(-) delete mode 100644 ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-force_over_8tb-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-include-fixes-2.6-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-sles11.patch create mode 100644 ldiskfs/kernel_patches/patches/ext4-update-sles11-rhel6.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-sles11.patch delete mode 100644 ldiskfs/kernel_patches/patches/ext4-xattr-no-update-ctime-sles11.patch diff --git a/build/autoconf/lustre-build-ldiskfs.m4 b/build/autoconf/lustre-build-ldiskfs.m4 index 6092418..c02f15a 100644 --- a/build/autoconf/lustre-build-ldiskfs.m4 +++ b/build/autoconf/lustre-build-ldiskfs.m4 @@ -245,6 +245,11 @@ if test $LDISKFS_BACKFS = 'ext4'; then with_ldiskfs_pdo=yes AC_DEFINE(HAVE_LDISKFS_PDO, 1, [have ldiskfs PDO patch]) fi + if test x$SUSE_KERNEL = xyes; then + with_ldiskfs_pdo=yes + AC_DEFINE(HAVE_LDISKFS_PDO, 1, [have ldiskfs PDO patch]) + fi + ;; esac fi @@ -460,6 +465,9 @@ if $1; then if test x$RHEL_KERNEL = xyes; then LDISKFS_SERIES="2.6-rhel6.series" fi + if test x$SUSE_KERNEL = xyes; then + LDISKFS_SERIES="2.6-sles11.series" + fi ;; *) AC_MSG_WARN([Unknown kernel version $LINUXRELEASE]) diff --git a/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-sles11.patch deleted file mode 100644 index b5febbf..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-alloc-policy-2.6-sles11.patch +++ /dev/null @@ -1,87 +0,0 @@ -Index: linux-2.6.27.21-0.1/fs/ext4/ialloc.c -=================================================================== ---- 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); - } - -+unsigned long ext4_find_reverse(struct super_block *sb) -+{ -+ struct ext4_group_desc *desc; -+ struct buffer_head *bitmap_bh = NULL; -+ int group; -+ unsigned long ino, offset; -+ -+ for (offset = (EXT4_INODES_PER_GROUP(sb) >> 1); offset >= 0; -+ offset >>= 1) { -+ for (group = EXT4_SB(sb)->s_groups_count - 1; group >= 0; -+ --group) { -+ desc = ext4_get_group_desc(sb, group, NULL); -+ if (ext4_free_inodes_count(sb, desc) == 0) -+ continue; -+ -+ bitmap_bh = ext4_read_inode_bitmap(sb, group); -+ if (!bitmap_bh) -+ continue; -+ -+ ino = ext4_find_next_zero_bit((unsigned long *) -+ bitmap_bh->b_data, -+ EXT4_INODES_PER_GROUP(sb), offset); -+ if (ino < EXT4_INODES_PER_GROUP(sb)) -+ return (group * EXT4_INODES_PER_GROUP(sb) + -+ ino + 1); -+ } -+ } -+ return 0; -+} -+ - /* 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.27.21-0.1/fs/ext4/namei.c -=================================================================== ---- 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 */ -+typedef enum { -+ DP_GOAL_POLICY = 0, -+ 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); -@@ -1771,8 +1777,14 @@ - if (dentry->d_fsdata != NULL) { - struct lvfs_dentry_params *param = dentry->d_fsdata; - -- 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(sb); -+ else /* DP_GOAL_POLICY */ -+ inum = param->ldp_inum; -+ } -+ - } - return inum; - } -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: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 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-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-sles11.patch deleted file mode 100644 index 27bfee8..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-big-endian-check-2.6-sles11.patch +++ /dev/null @@ -1,56 +0,0 @@ -Index: linux-2.6.27.21-0.1/fs/ext4/super.c -=================================================================== ---- linux-2.6.27.21-0.1.orig/fs/ext4/super.c -+++ linux-2.6.27.21-0.1/fs/ext4/super.c -@@ -74,6 +74,8 @@ static void ext4_write_super_lockfs(stru - - struct proc_dir_entry *proc_root_ext4; - -+static int bigendian_extents; -+ - ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, - struct ext4_group_desc *bg) - { -@@ -1291,7 +1293,7 @@ enum { - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, - Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, - Opt_stripe, Opt_delalloc, Opt_nodelalloc, -- Opt_inode_readahead_blks, -+ Opt_inode_readahead_blks, Opt_bigendian_extents, - Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, - }; - -@@ -1353,6 +1355,7 @@ static const match_table_t tokens = { - {Opt_delalloc, "delalloc"}, - {Opt_nodelalloc, "nodelalloc"}, - {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, -+ {Opt_bigendian_extents, "bigendian_extents"}, - {Opt_err, NULL}, - }; - -@@ -1768,6 +1771,9 @@ set_qf_format: - return 0; - sbi->s_inode_readahead_blks = option; - break; -+ case Opt_bigendian_extents: -+ bigendian_extents = 1; -+ break; - default: - printk(KERN_ERR - "EXT4-fs: Unrecognized mount option \"%s\" " -@@ -2673,6 +2679,15 @@ static int ext4_fill_super(struct super_ - &sbi->s_inode_readahead_blks); - #endif - -+#ifdef __BIG_ENDIAN -+ if (bigendian_extents == 0) { -+ printk(KERN_ERR "EXT4-fs: extents feature is not guaranteed to " -+ "work on big-endian systems. Use \"bigendian_extents\" " -+ "mount option to override.\n"); -+ goto failed_mount; -+ } -+#endif -+ - bgl_lock_init(&sbi->s_blockgroup_lock); - - sbi->s_last_alloc_group = -1; diff --git a/ldiskfs/kernel_patches/patches/ext4-force_over_8tb-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-force_over_8tb-sles11.patch deleted file mode 100644 index c16578e..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-force_over_8tb-sles11.patch +++ /dev/null @@ -1,58 +0,0 @@ -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 15:00:32.000000000 +0530 -+++ linux-2.6.27.21-0.1/fs/ext4/super.c 2009-07-07 15:01:30.000000000 +0530 -@@ -52,6 +52,8 @@ - - struct proc_dir_entry *ext4_proc_root; - -+static int force_over_8tb; -+ - static int ext4_load_journal(struct super_block *, struct ext4_super_block *, - unsigned long journal_devnum); - static int ext4_create_journal(struct super_block *, struct ext4_super_block *, -@@ -1287,7 +1289,7 @@ - Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, - Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, -- Opt_mballoc, -+ Opt_mballoc, Opt_force_over_8tb, - Opt_stripe, Opt_delalloc, Opt_nodelalloc, - Opt_inode_readahead_blks, Opt_bigendian_extents, - Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, -@@ -1349,6 +1351,7 @@ - {Opt_stripe, "stripe=%u"}, - {Opt_resize, "resize"}, - {Opt_mballoc, "mballoc"}, -+ {Opt_force_over_8tb, "force_over_8tb"}, - {Opt_delalloc, "delalloc"}, - {Opt_nodelalloc, "nodelalloc"}, - {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, -@@ -1773,6 +1776,9 @@ - break; - case Opt_mballoc: - break; -+ case Opt_force_over_8tb: -+ force_over_8tb = 1; -+ break; - default: - printk(KERN_ERR - "EXT4-fs: Unrecognized mount option \"%s\" " -@@ -2634,6 +2640,17 @@ - goto failed_mount; - } - -+ if (ext4_blocks_count(es) > -+ ((0x80000000000ULL >> sb->s_blocksize_bits) - 1)) { -+ if (force_over_8tb == 0) { -+ printk(KERN_ERR "EXT4-fs does not support filesystems " -+ "greater than 8TB and can cause data corruption." -+ "Use \"force_over_8tb\" mount option to override." -+ "\n"); -+ goto failed_mount; -+ } -+ } -+ - if (EXT4_BLOCKS_PER_GROUP(sb) == 0) - goto cantfind_ext4; - diff --git a/ldiskfs/kernel_patches/patches/ext4-include-fixes-2.6-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-include-fixes-2.6-sles11.patch deleted file mode 100644 index 0009eaa..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-include-fixes-2.6-sles11.patch +++ /dev/null @@ -1,20 +0,0 @@ -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 -@@ -541,12 +541,13 @@ do { \ - #define EXT4_MOUNT_IOPEN 0x8000000 /* Allow access via iopen */ - #define EXT4_MOUNT_IOPEN_NOPRIV 0x10000000 /* Make iopen world-readable */ - /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ --#ifndef _LINUX_EXT2_FS_H -+#ifndef clear_opt - #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt - #define set_opt(o, opt) o |= EXT4_MOUNT_##opt - #define test_opt(sb, opt) (EXT4_SB(sb)->s_mount_opt & \ - EXT4_MOUNT_##opt) --#else -+#endif -+#ifndef EXT2_MOUNT_NOLOAD - #define EXT2_MOUNT_NOLOAD EXT4_MOUNT_NOLOAD - #define EXT2_MOUNT_ABORT EXT4_MOUNT_ABORT - #define EXT2_MOUNT_DATA_FLAGS EXT4_MOUNT_DATA_FLAGS diff --git a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-sles11.patch deleted file mode 100644 index 590ea77..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-mballoc-extra-checks-sles11.patch +++ /dev/null @@ -1,280 +0,0 @@ -Index: linux-2.6.27.21-0.1/fs/ext4/mballoc.c -=================================================================== ---- linux-2.6.27.21-0.1.orig/fs/ext4/mballoc.c -+++ linux-2.6.27.21-0.1/fs/ext4/mballoc.c -@@ -333,7 +333,7 @@ - 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, -+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); -@@ -672,7 +672,7 @@ static void ext4_mb_mark_free_simple(str - } - } - --static void ext4_mb_generate_buddy(struct super_block *sb, -+static int ext4_mb_generate_buddy(struct super_block *sb, - void *buddy, void *bitmap, ext4_group_t group) - { - struct ext4_group_info *grp = ext4_get_group_info(sb, group); -@@ -704,14 +704,13 @@ static void ext4_mb_generate_buddy(struc - grp->bb_fragments = fragments; - - if (free != grp->bb_free) { -- ext4_grp_locked_error(sb, group, __func__, -- "EXT4-fs: group %u: %u blocks in bitmap, %u in gd\n", -- group, free, grp->bb_free); -- /* -- * If we intent to continue, we consider group descritor -- * corrupt and update bb_free using bitmap value -- */ -- grp->bb_free = free; -+ struct ext4_group_desc *gdp; -+ gdp = ext4_get_group_desc (sb, group, NULL); -+ ext4_grp_locked_error(sb, group, __func__, -+ "group %u: %u blocks in bitmap, %u in bb, " -+ "%u in gd\n", group, free, grp->bb_free, -+ ext4_free_blks_count(sb, gdp)); -+ return -EIO; - } - - clear_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); -@@ -721,6 +720,8 @@ static void ext4_mb_generate_buddy(struc - EXT4_SB(sb)->s_mb_buddies_generated++; - EXT4_SB(sb)->s_mb_generation_time += period; - spin_unlock(&EXT4_SB(sb)->s_bal_lock); -+ -+ return 0; - } - - /* The buddy information is attached the buddy cache inode -@@ -850,7 +851,7 @@ static int ext4_mb_init_cache(struct pag - 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; - -@@ -884,7 +885,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 { -@@ -898,7 +899,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); - -@@ -908,6 +909,7 @@ static int ext4_mb_init_cache(struct pag - incore = data; - } - } -+ if (likely(err == 0)) - SetPageUptodate(page); - - out: -@@ -2217,7 +2219,10 @@ static int ext4_mb_seq_history_show(stru - hs->result.fe_start, hs->result.fe_len); - seq_printf(seq, "%-5u %-8u %-23s free\n", - hs->pid, hs->ino, buf2); -+ } else { -+ seq_printf(seq, "unknown op %d\n", hs->op); - } -+ - return 0; - } - -@@ -2345,9 +2350,11 @@ static void *ext4_mb_seq_groups_next(str - static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) - { - struct super_block *sb = seq->private; -+ struct ext4_group_desc *gdp; - ext4_group_t group = (ext4_group_t) ((unsigned long) v); - int i; - int err; -+ unsigned free = 0; - struct ext4_buddy e4b; - struct sg { - struct ext4_group_info info; -@@ -2356,10 +2363,10 @@ static int ext4_mb_seq_groups_show(struc - - group--; - if (group == 0) -- seq_printf(seq, "#%-5s: %-5s %-5s %-5s " -+ seq_printf(seq, "#%-5s: %-5s %-5s %-5s %-5s %-5s" - "[ %-5s %-5s %-5s %-5s %-5s %-5s %-5s " - "%-5s %-5s %-5s %-5s %-5s %-5s %-5s ]\n", -- "group", "free", "frags", "first", -+ "group", "free", "frags", "first", "first", "pa", - "2^0", "2^1", "2^2", "2^3", "2^4", "2^5", "2^6", - "2^7", "2^8", "2^9", "2^10", "2^11", "2^12", "2^13"); - -@@ -2371,12 +2378,18 @@ static int ext4_mb_seq_groups_show(struc - seq_printf(seq, "#%-5u: I/O error\n", group); - return 0; - } -+ -+ gdp = ext4_get_group_desc(sb, group, NULL); -+ if (gdp != NULL) -+ 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, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free, -+ seq_printf(seq, "#%-5u: %-5u %-5u %-5u %-5u [", group, -+ sg.info.bb_free, free, - sg.info.bb_fragments, sg.info.bb_first_free); - for (i = 0; i <= 13; i++) - seq_printf(seq, " %-5u", i <= sb->s_blocksize_bits + 1 ? -@@ -2474,6 +2487,7 @@ ext4_mb_store_history(struct ext4_alloca - h.tail = ac->ac_tail; - h.buddy = ac->ac_buddy; - h.merged = 0; -+ h.cr = ac->ac_criteria; - if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) { - if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start && - ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group) -@@ -3695,22 +3709,67 @@ static void ext4_mb_generate_from_freeli - } - - /* -+ * check free blocks in bitmap match free block in group descriptor -+ * do this before taking preallocated blocks into account to be able -+ * to detect on-disk corruptions. The group lock should be hold by the -+ * caller. -+ */ -+int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, -+ struct ext4_group_desc *gdp, int group) -+{ -+ unsigned short max = EXT4_BLOCKS_PER_GROUP(sb); -+ unsigned short i, first, free = 0; -+ -+ i = mb_find_next_zero_bit(bitmap, max, 0); -+ -+ while (i < max) { -+ first = i; -+ i = mb_find_next_bit(bitmap, max, i); -+ if (i > max) -+ i = max; -+ free += i - first; -+ if (i < max) -+ i = mb_find_next_zero_bit(bitmap, max, i); -+ } -+ -+ 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, ext4_free_blks_count(sb, gdp)); -+ return -EIO; -+ } -+ return 0; -+} -+ -+/* - * the function goes through all preallocation in this group and marks them - * used in in-core bitmap. buddy must be generated from this bitmap - * Need to be called with ext4 group lock (ext4_lock_group) - */ --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) - { - struct ext4_group_info *grp = ext4_get_group_info(sb, group); - struct ext4_prealloc_space *pa; -+ struct ext4_group_desc *gdp; - struct list_head *cur; - ext4_group_t groupnr; - ext4_grpblk_t start; - int preallocated = 0; - int count = 0; -+ int skip = 0; -+ int err; - int len; - -+ gdp = ext4_get_group_desc (sb, group, NULL); -+ if (gdp == NULL) -+ return -EIO; -+ -+ /* before applying preallocations, check bitmap consistency */ -+ err = ext4_mb_check_ondisk_bitmap(sb, bitmap, gdp, group); -+ if (err) -+ return err; -+ - /* all form of preallocation discards first load group, - * so the only competing code is preallocation use. - * we don't need any locking here -@@ -3720,8 +3778,10 @@ static void ext4_mb_generate_from_pa(str - &groupnr, &start); - len = pa->pa_len; - spin_unlock(&pa->pa_lock); -- if (unlikely(len == 0)) -+ if (unlikely(len == 0)) { -+ skip++; - continue; -+ } - BUG_ON(groupnr != group); - mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group), - bitmap, start, len); -@@ -3729,6 +3789,7 @@ static void ext4_mb_generate_from_pa(str - count++; - } - mb_debug("prellocated %u for group %u\n", preallocated, group); -+ return 0; - } - - static void ext4_mb_pa_callback(struct rcu_head *head) -@@ -3978,6 +4039,7 @@ ext4_mb_release_inode_pa(struct ext4_bud - ac->ac_sb = sb; - ac->ac_inode = pa->pa_inode; - ac->ac_op = EXT4_MB_HISTORY_DISCARD; -+ ac->ac_o_ex.fe_len = 1; - } - - while (bit < end) { -@@ -4260,7 +4322,7 @@ repeat: - __release(e4b->alloc_semp); - ext4_error(sb, __func__, "Error in loading buddy " - "information for %u\n", group); -- continue; -+ return; - } - - bitmap_bh = ext4_read_block_bitmap(sb, group); -Index: linux-2.6.27.21-0.1/fs/ext4/mballoc.h -=================================================================== ---- linux-2.6.27.21-0.1.orig/fs/ext4/mballoc.h -+++ linux-2.6.27.21-0.1/fs/ext4/mballoc.h -@@ -92,7 +92,7 @@ - /* - * for which requests use 2^N search using buddies - */ --#define MB_DEFAULT_ORDER2_REQS 2 -+#define MB_DEFAULT_ORDER2_REQS 8 - - /* - * default group prealloc size 512 blocks -@@ -219,7 +219,7 @@ struct ext4_mb_history { - __u16 tail; /* what tail broke some buddy */ - __u16 buddy; /* buddy the tail ^^^ broke */ - __u16 flags; -- __u8 cr:3; /* which phase the result extent was found at */ -+ __u8 cr:8; /* which phase the result extent was found at */ - __u8 op:4; - __u8 merged:1; - }; diff --git a/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch deleted file mode 100644 index d7d5694..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-mmp-sles11.patch +++ /dev/null @@ -1,491 +0,0 @@ -Index: linux-stage/fs/ext4/super.c -=================================================================== ---- linux-stage.orig/fs/ext4/super.c -+++ linux-stage/fs/ext4/super.c -@@ -39,6 +39,8 @@ - #include - #include - #include -+#include -+#include - - #include "ext4.h" - #include "ext4_jbd2.h" -@@ -600,6 +602,8 @@ static void ext4_put_super(struct super_ - invalidate_bdev(sbi->journal_bdev); - ext4_blkdev_remove(sbi); - } -+ if (sbi->s_mmp_tsk) -+ kthread_stop(sbi->s_mmp_tsk); - sb->s_fs_info = NULL; - kfree(sbi); - return; -@@ -808,7 +812,6 @@ static int ext4_show_options(struct seq_ - if (!test_opt(sb, DELALLOC)) - seq_puts(seq, ",nodelalloc"); - -- - if (sbi->s_stripe) - seq_printf(seq, ",stripe=%lu", sbi->s_stripe); - /* -@@ -831,6 +834,340 @@ static int ext4_show_options(struct seq_ - } - - -+ -+/* -+ * Write the MMP block using WRITE_SYNC to try to get the block on-disk -+ * faster. -+ */ -+static int write_mmp_block(struct buffer_head *bh) -+{ -+ mark_buffer_dirty(bh); -+ lock_buffer(bh); -+ bh->b_end_io = end_buffer_write_sync; -+ get_bh(bh); -+ submit_bh(WRITE_SYNC, bh); -+ wait_on_buffer(bh); -+ if (unlikely(!buffer_uptodate(bh))) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Read the MMP block. It _must_ be read from disk and hence we clear the -+ * uptodate flag on the buffer. -+ */ -+static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, -+ unsigned long mmp_block) -+{ -+ struct mmp_struct *mmp; -+ -+ if (*bh) -+ clear_buffer_uptodate(*bh); -+ -+ /* This would be sb_bread(sb, mmp_block), except we need to be sure -+ * that the MD RAID device cache has been bypassed, and that the read -+ * is not blocked in the elevator. */ -+ if (!*bh) -+ *bh = sb_getblk(sb, mmp_block); -+ if (*bh) { -+ get_bh(*bh); -+ lock_buffer(*bh); -+ (*bh)->b_end_io = end_buffer_read_sync; -+ submit_bh(READ_SYNC, *bh); -+ wait_on_buffer(*bh); -+ if (!buffer_uptodate(*bh)) { -+ brelse(*bh); -+ *bh = NULL; -+ } -+ } -+ if (!*bh) { -+ ext4_warning(sb, __func__, -+ "Error while reading MMP block %lu", mmp_block); -+ return -EIO; -+ } -+ -+ mmp = (struct mmp_struct *)((*bh)->b_data); -+ if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/* -+ * Dump as much information as possible to help the admin. -+ */ -+static void dump_mmp_msg(struct super_block *sb, struct mmp_struct *mmp, -+ const char *function, const char *msg) -+{ -+ ext4_warning(sb, function, "%s", msg); -+ ext4_warning(sb, function, "MMP failure info: last update time: %llu, " -+ "last update node: %s, last update device: %s\n", -+ (long long unsigned int)le64_to_cpu(mmp->mmp_time), -+ mmp->mmp_nodename, mmp->mmp_bdevname); -+} -+ -+/* -+ * kmmpd will update the MMP sequence every s_mmp_update_interval seconds -+ */ -+static int kmmpd(void *data) -+{ -+ struct super_block *sb = (struct super_block *) data; -+ struct ext4_super_block *es = EXT4_SB(sb)->s_es; -+ struct buffer_head *bh = NULL; -+ struct mmp_struct *mmp; -+ unsigned long mmp_block; -+ u32 seq = 0; -+ unsigned long failed_writes = 0; -+ int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval); -+ unsigned mmp_check_interval; -+ unsigned long last_update_time; -+ unsigned long diff; -+ int retval; -+ -+ mmp_block = le64_to_cpu(es->s_mmp_block); -+ retval = read_mmp_block(sb, &bh, mmp_block); -+ if (retval) -+ goto failed; -+ -+ mmp = (struct mmp_struct *)(bh->b_data); -+ mmp->mmp_time = cpu_to_le64(get_seconds()); -+ /* -+ * Start with the higher mmp_check_interval and reduce it if -+ * the MMP block is being updated on time. -+ */ -+ mmp_check_interval = max(5 * mmp_update_interval, -+ EXT4_MMP_MIN_CHECK_INTERVAL); -+ mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); -+ bdevname(bh->b_bdev, mmp->mmp_bdevname); -+ -+ memcpy(mmp->mmp_nodename, init_utsname()->nodename, -+ sizeof(mmp->mmp_nodename)); -+ -+ while (!kthread_should_stop()) { -+ if (++seq > EXT4_MMP_SEQ_MAX) -+ seq = 1; -+ -+ mmp->mmp_seq = cpu_to_le32(seq); -+ mmp->mmp_time = cpu_to_le64(get_seconds()); -+ last_update_time = jiffies; -+ -+ retval = write_mmp_block(bh); -+ /* -+ * Don't spew too many error messages. Print one every -+ * (s_mmp_update_interval * 60) seconds. -+ */ -+ if (retval && (failed_writes % 60) == 0) { -+ ext4_error(sb, __func__, -+ "Error writing to MMP block"); -+ failed_writes++; -+ } -+ -+ if (!(le32_to_cpu(es->s_feature_incompat) & -+ EXT4_FEATURE_INCOMPAT_MMP)) { -+ ext4_warning(sb, __func__, "kmmpd being stopped " -+ "since MMP feature has been disabled."); -+ EXT4_SB(sb)->s_mmp_tsk = 0; -+ goto failed; -+ } -+ -+ if (sb->s_flags & MS_RDONLY) { -+ ext4_warning(sb, __func__, "kmmpd being stopped " -+ "since filesystem has been remounted as " -+ "readonly."); -+ EXT4_SB(sb)->s_mmp_tsk = 0; -+ goto failed; -+ } -+ -+ diff = jiffies - last_update_time; -+ if (diff < mmp_update_interval * HZ) -+ schedule_timeout_interruptible(EXT4_MMP_UPDATE_INTERVAL* -+ HZ - diff); -+ -+ /* -+ * We need to make sure that more than mmp_check_interval -+ * seconds have not passed since writing. If that has happened -+ * we need to check if the MMP block is as we left it. -+ */ -+ diff = jiffies - last_update_time; -+ if (diff > mmp_check_interval * HZ) { -+ struct buffer_head *bh_check = NULL; -+ struct mmp_struct *mmp_check; -+ -+ retval = read_mmp_block(sb, &bh_check, mmp_block); -+ if (retval) { -+ EXT4_SB(sb)->s_mmp_tsk = 0; -+ goto failed; -+ } -+ -+ mmp_check = (struct mmp_struct *)(bh_check->b_data); -+ if (mmp->mmp_time != mmp_check->mmp_time || -+ memcmp(mmp->mmp_nodename, mmp_check->mmp_nodename, -+ sizeof(mmp->mmp_nodename))) -+ dump_mmp_msg(sb, mmp_check, __func__, -+ "Error while updating MMP info. " -+ "The filesystem seems to have " -+ "been multiply mounted."); -+ -+ put_bh(bh_check); -+ } -+ -+ /* -+ * Adjust the mmp_check_interval depending on how much time -+ * it took for the MMP block to be written. -+ */ -+ mmp_check_interval = max(5 * diff / HZ, -+ (unsigned long) EXT4_MMP_MIN_CHECK_INTERVAL); -+ mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval); -+ } -+ -+ /* -+ * Unmount seems to be clean. -+ */ -+ mmp->mmp_seq = cpu_to_le32(EXT4_MMP_SEQ_CLEAN); -+ mmp->mmp_time = cpu_to_le64(get_seconds()); -+ -+ retval = write_mmp_block(bh); -+ -+failed: -+ brelse(bh); -+ return retval; -+} -+ -+/* -+ * Get a random new sequence number but make sure it is not greater than -+ * EXT4_MMP_SEQ_MAX. -+ */ -+static unsigned int mmp_new_seq(void) -+{ -+ u32 new_seq; -+ -+ do { -+ get_random_bytes(&new_seq, sizeof(u32)); -+ } while (new_seq > EXT4_MMP_SEQ_MAX); -+ -+ return new_seq; -+} -+ -+/* -+ * Protect the filesystem from being mounted more than once. -+ */ -+static int ext4_multi_mount_protect(struct super_block *sb, -+ unsigned long mmp_block) -+{ -+ struct ext4_super_block *es = EXT4_SB(sb)->s_es; -+ struct buffer_head *bh = NULL; -+ struct mmp_struct *mmp = NULL; -+ u32 seq; -+ unsigned int mmp_check_interval = le16_to_cpu(es->s_mmp_update_interval); -+ unsigned int wait_time = 0; -+ int retval; -+ -+ if (mmp_block < le32_to_cpu(es->s_first_data_block) || -+ mmp_block >= ext4_blocks_count(es)) { -+ ext4_warning(sb, __func__, -+ "Invalid MMP block in superblock"); -+ goto failed; -+ } -+ -+ retval = read_mmp_block(sb, &bh, mmp_block); -+ if (retval) -+ goto failed; -+ -+ mmp = (struct mmp_struct *)(bh->b_data); -+ -+ if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL) -+ mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL; -+ -+ /* -+ * If check_interval in MMP block is larger, use that instead of -+ * update_interval from the superblock. -+ */ -+ if (mmp->mmp_check_interval > mmp_check_interval) -+ mmp_check_interval = mmp->mmp_check_interval; -+ -+ seq = le32_to_cpu(mmp->mmp_seq); -+ if (seq == EXT4_MMP_SEQ_CLEAN) -+ goto skip; -+ -+ if (seq == EXT4_MMP_SEQ_FSCK) { -+ dump_mmp_msg(sb, mmp, __func__, -+ "fsck is running on the filesystem"); -+ goto failed; -+ } -+ -+ wait_time = min(mmp_check_interval * 2 + 1, -+ mmp_check_interval + 60); -+ -+ /* Print MMP interval if more than 20 secs. */ -+ if (wait_time > EXT4_MMP_MIN_CHECK_INTERVAL * 4) -+ ext4_warning(sb, __func__, "MMP interval %u higher than " -+ "expected, please wait.\n", wait_time * 2); -+ -+ if (schedule_timeout_interruptible(HZ * wait_time) != 0) { -+ ext4_warning(sb, __func__, "MMP startup interrupted, failing mount\n"); -+ goto failed; -+ } -+ -+ retval = read_mmp_block(sb, &bh, mmp_block); -+ if (retval) -+ goto failed; -+ mmp = (struct mmp_struct *)(bh->b_data); -+ if (seq != le32_to_cpu(mmp->mmp_seq)) { -+ dump_mmp_msg(sb, mmp, __func__, -+ "Device is already active on another node."); -+ goto failed; -+ } -+ -+skip: -+ /* -+ * write a new random sequence number. -+ */ -+ mmp->mmp_seq = seq = cpu_to_le32(mmp_new_seq()); -+ -+ retval = write_mmp_block(bh); -+ if (retval) -+ goto failed; -+ -+ /* -+ * wait for MMP interval and check mmp_seq. -+ */ -+ if (schedule_timeout_interruptible(HZ * wait_time) != 0) { -+ ext4_warning(sb, __func__, "MMP startup interrupted, failing mount\n"); -+ goto failed; -+ } -+ -+ retval = read_mmp_block(sb, &bh, mmp_block); -+ if (retval) -+ goto failed; -+ mmp = (struct mmp_struct *)(bh->b_data); -+ if (seq != le32_to_cpu(mmp->mmp_seq)) { -+ dump_mmp_msg(sb, mmp, __func__, -+ "Device is already active on another node."); -+ goto failed; -+ } -+ -+ /* -+ * Start a kernel thread to update the MMP block periodically. -+ */ -+ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, sb, "kmmpd-%02x:%02x", -+ MAJOR(sb->s_dev), -+ MINOR(sb->s_dev)); -+ if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) { -+ EXT4_SB(sb)->s_mmp_tsk = 0; -+ ext4_warning(sb, __func__, "Unable to create kmmpd thread " -+ "for %s.", sb->s_id); -+ goto failed; -+ } -+ -+ brelse(bh); -+ return 0; -+ -+failed: -+ brelse(bh); -+ return 1; -+} -+ - static struct inode *ext4_nfs_get_inode(struct super_block *sb, - u64 ino, u32 generation) - { -@@ -2371,6 +2708,11 @@ static int ext4_fill_super(struct super_ - EXT4_HAS_INCOMPAT_FEATURE(sb, - EXT4_FEATURE_INCOMPAT_RECOVER)); - -+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) && -+ !(sb->s_flags & MS_RDONLY)) -+ if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block))) -+ goto failed_mount3; -+ - /* - * The first inode we look at is the journal inode. Don't try - * root first: it may be modified in the journal! -@@ -2571,6 +2913,8 @@ failed_mount3: - 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]); -@@ -3086,7 +3430,7 @@ static int ext4_remount(struct super_blo - unsigned long old_sb_flags; - struct ext4_mount_options old_opts; - ext4_group_t g; -- int err; -+ int err = 0; - #ifdef CONFIG_QUOTA - int i; - #endif -@@ -3211,6 +3555,13 @@ static int ext4_remount(struct super_blo - goto restore_opts; - if (!ext4_setup_super(sb, es, 0)) - sb->s_flags &= ~MS_RDONLY; -+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, -+ EXT4_FEATURE_INCOMPAT_MMP)) -+ if (ext4_multi_mount_protect(sb, -+ le64_to_cpu(es->s_mmp_block))) { -+ err = -EROFS; -+ goto restore_opts; -+ } - } - } - #ifdef CONFIG_QUOTA -Index: linux-stage/fs/ext4/ext4.h -=================================================================== ---- linux-stage.orig/fs/ext4/ext4.h -+++ linux-stage/fs/ext4/ext4.h -@@ -660,7 +660,7 @@ struct ext4_super_block { - __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ - __le32 s_flags; /* Miscellaneous flags */ - __le16 s_raid_stride; /* RAID stride */ -- __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ -+ __le16 s_mmp_update_interval; /* # seconds to wait in MMP checking */ - __le64 s_mmp_block; /* Block for multi-mount protection */ - __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ - __u8 s_log_groups_per_flex; /* FLEX_BG group size */ -@@ -777,7 +777,8 @@ static inline int ext4_valid_inum(struct - EXT4_FEATURE_INCOMPAT_META_BG| \ - EXT4_FEATURE_INCOMPAT_EXTENTS| \ - EXT4_FEATURE_INCOMPAT_64BIT| \ -- EXT4_FEATURE_INCOMPAT_FLEX_BG) -+ EXT4_FEATURE_INCOMPAT_FLEX_BG| \ -+ EXT4_FEATURE_INCOMPAT_MMP) - #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ -@@ -981,6 +982,39 @@ do { \ - #endif - - /* -+ * This structure will be used for multiple mount protection. It will be -+ * written into the block number saved in the s_mmp_block field in the -+ * superblock. Programs that check MMP should assume that if -+ * SEQ_FSCK (or any unknown code above SEQ_MAX) is present then it is NOT safe -+ * to use the filesystem, regardless of how old the timestamp is. -+ */ -+#define EXT4_MMP_MAGIC 0x004D4D50U /* ASCII for MMP */ -+#define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */ -+#define EXT4_MMP_SEQ_FSCK 0xE24D4D50U /* mmp_seq value when being fscked */ -+#define EXT4_MMP_SEQ_MAX 0xE24D4D4FU /* maximum valid mmp_seq value */ -+ -+struct mmp_struct { -+ __le32 mmp_magic; -+ __le32 mmp_seq; -+ __le64 mmp_time; -+ char mmp_nodename[64]; -+ char mmp_bdevname[32]; -+ __le16 mmp_check_interval; -+ __le16 mmp_pad1; -+ __le32 mmp_pad2[227]; -+}; -+ -+/* -+ * Default interval in seconds to update the MMP sequence number. -+ */ -+#define EXT4_MMP_UPDATE_INTERVAL 1 -+ -+/* -+ * Minimum interval for MMP checking in seconds. -+ */ -+#define EXT4_MMP_MIN_CHECK_INTERVAL 5 -+ -+/* - * Function prototypes - */ - -Index: linux-stage/fs/ext4/ext4_sb.h -=================================================================== ---- linux-stage.orig/fs/ext4/ext4_sb.h -+++ linux-stage/fs/ext4/ext4_sb.h -@@ -149,6 +149,8 @@ struct ext4_sb_info { - - unsigned int s_log_groups_per_flex; - struct flex_groups *s_flex_groups; -+ -+ struct task_struct *s_mmp_tsk; /* Kernel thread for multiple mount protection */ - }; - - #endif /* _EXT4_SB */ diff --git a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch deleted file mode 100644 index 7e9d654..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-osd-iop-common-sles11.patch +++ /dev/null @@ -1,237 +0,0 @@ -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,18 @@ 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); -+extern int ext4_add_entry(handle_t *handle, struct dentry *dentry, -+ 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 inode *dir, -+ const struct qstr *d_name, -+ struct ext4_dir_entry_2 ** res_dir); -+extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir, -+ 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.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 - */ - -+#include - #include - #include - #include -@@ -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 inode *dir, -- const struct qstr *d_name, -- struct ext4_dir_entry_2 ** res_dir) -+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]; -@@ -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 inode *dir, const struct qstr *d_name, - struct ext4_dir_entry_2 **res_dir, int *err) -@@ -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) - { - struct inode *dir = dentry->d_parent->d_inode; - 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); - } -+EXPORT_SYMBOL(ext4_add_entry); - - /* - * Returns 0 for success, or a negative error value -@@ -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) - { - struct ext4_dir_entry_2 *de, *pde; - int i; -@@ -1733,7 +1736,7 @@ static int ext4_delete_entry(handle_t *h - } - return -ENOENT; - } -- -+EXPORT_SYMBOL(ext4_delete_entry); - /* - * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, - * since this indicates that nlinks count was previously 1. -@@ -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); -+ if (!IS_ERR(inode)) { -+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) { -+#ifdef CONFIG_LDISKFS_FS_XATTR -+ inode->i_op = &ext4_special_inode_operations; -+#endif -+ } else { -+ inode->i_op = &ext4_file_inode_operations; -+ inode->i_fop = &ext4_file_operations; -+ ext4_set_aops(inode); -+ } -+ } -+ return inode; -+} -+EXPORT_SYMBOL(ext4_create_inode); -+ - /* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it -@@ -1872,51 +1895,43 @@ retry: - return err; - } - --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) - { -- 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_goal(handle, dir, S_IFDIR | mode, -- ext4_dentry_goal(dir->i_sb, dentry)); -- err = PTR_ERR(inode); -- if (IS_ERR(inode)) -- goto out_stop; -- - 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); -- if (!dir_block) -- goto out_clear_inode; -+ dir_block = ext4_bread (handle, inode, 0, 1, &err); -+ if (!dir_block) { -+ clear_nlink(inode); -+ ext4_mark_inode_dirty(handle, inode); -+ iput (inode); -+ goto get_out; -+ } - 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; - 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); - 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); -@@ -1925,9 +1940,43 @@ retry: - ext4_journal_dirty_metadata(handle, 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) -+{ -+ handle_t *handle; -+ struct inode *inode; -+ int err, retries = 0; -+ -+ if (EXT4_DIR_LINK_MAX(dir)) -+ return -EMLINK; -+ -+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_goal(handle, dir, S_IFDIR | mode, -+ ext4_dentry_goal(dir->i_sb, dentry)); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out_stop; -+ -+ err = ext4_add_dot_dotdot(handle, dir, inode); -+ if (err) -+ goto out_stop; -+ - err = ext4_add_entry(handle, dentry, inode); - if (err) { --out_clear_inode: - clear_nlink(inode); - ext4_mark_inode_dirty(handle, inode); - iput(inode); diff --git a/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-sles11.patch deleted file mode 100644 index db2e1ba..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-remove-cond_resched-calls-sles11.patch +++ /dev/null @@ -1,29 +0,0 @@ -Index: linux-2.6.27.21-0.1/fs/ext4/ialloc.c -=================================================================== ---- linux-2.6.27.21-0.1.orig/fs/ext4/ialloc.c -+++ linux-2.6.27.21-0.1/fs/ext4/ialloc.c -@@ -1120,7 +1120,6 @@ unsigned long ext4_count_free_inodes(str - if (!gdp) - continue; - desc_count += ext4_free_inodes_count(sb, gdp); -- cond_resched(); - } - return desc_count; - #endif -Index: linux-2.6.27.21-0.1/fs/ext4/super.c -=================================================================== ---- linux-2.6.27.21-0.1.orig/fs/ext4/super.c -+++ linux-2.6.27.21-0.1/fs/ext4/super.c -@@ -3263,11 +3263,9 @@ static int ext4_statfs(struct dentry *de - * block group descriptors. If the sparse superblocks - * feature is turned on, then not all groups have this. - */ -- for (i = 0; i < ngroups; i++) { -+ for (i = 0; i < ngroups; i++) - overhead += ext4_bg_has_super(sb, i) + - ext4_bg_num_gdb(sb, i); -- cond_resched(); -- } - - /* - * Every block group has an inode bitmap, a block diff --git a/ldiskfs/kernel_patches/patches/ext4-update-sles11-rhel6.patch b/ldiskfs/kernel_patches/patches/ext4-update-sles11-rhel6.patch new file mode 100644 index 0000000..b431530 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/ext4-update-sles11-rhel6.patch @@ -0,0 +1,1549 @@ +diff -urpN linux-stage.orig/fs/ext4/balloc.c linux-stage/fs/ext4/balloc.c +--- linux-stage.orig/fs/ext4/balloc.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/balloc.c 2011-12-28 11:24:07.000000000 -0500 +@@ -97,7 +97,7 @@ unsigned ext4_init_block_bitmap(struct s + /* If checksum is bad mark all blocks used to prevent allocation + * essentially implementing a per-group read-only flag. */ + if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Checksum bad for group %u", block_group); + ext4_free_blks_set(sb, gdp, 0); + ext4_free_inodes_set(sb, gdp, 0); +@@ -207,10 +207,8 @@ struct ext4_group_desc * ext4_get_group_ + struct ext4_sb_info *sbi = EXT4_SB(sb); + + if (block_group >= ngroups) { +- ext4_error(sb, "ext4_get_group_desc", +- "block_group >= groups_count - " +- "block_group = %u, groups_count = %u", +- block_group, ngroups); ++ ext4_error(sb, "block_group >= groups_count - block_group = %u," ++ " groups_count = %u", block_group, ngroups); + + return NULL; + } +@@ -218,8 +216,7 @@ struct ext4_group_desc * ext4_get_group_ + group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); + offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); + if (!sbi->s_group_desc[group_desc]) { +- ext4_error(sb, "ext4_get_group_desc", +- "Group descriptor not loaded - " ++ ext4_error(sb, "Group descriptor not loaded - " + "block_group = %u, group_desc = %u, desc = %u", + block_group, group_desc, offset); + return NULL; +@@ -280,7 +277,7 @@ static int ext4_valid_block_bitmap(struc + return 1; + + err_out: +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Invalid block bitmap - " + "block_group = %d, block = %llu", + block_group, bitmap_blk); +@@ -309,7 +306,7 @@ ext4_read_block_bitmap(struct super_bloc + bitmap_blk = ext4_block_bitmap(sb, desc); + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Cannot read block bitmap - " + "block_group = %u, block_bitmap = %llu", + block_group, bitmap_blk); +@@ -352,7 +349,7 @@ ext4_read_block_bitmap(struct super_bloc + set_bitmap_uptodate(bh); + if (bh_submit_read(bh) < 0) { + put_bh(bh); +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Cannot read block bitmap - " + "block_group = %u, block_bitmap = %llu", + block_group, bitmap_blk); +@@ -417,7 +414,7 @@ void ext4_add_groupblocks(handle_t *hand + in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || + in_range(block + count - 1, ext4_inode_table(sb, desc), + sbi->s_itb_per_group)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Adding blocks in system zones - " + "Block = %llu, count = %lu", + block, count); +@@ -451,7 +448,7 @@ void ext4_add_groupblocks(handle_t *hand + BUFFER_TRACE(bitmap_bh, "clear bit"); + if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), + bit + i, bitmap_bh->b_data)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "bit already cleared for block %llu", + (ext4_fsblk_t)(block + i)); + BUFFER_TRACE(bitmap_bh, "bit already cleared"); +diff -urpN linux-stage.orig/fs/ext4/dir.c linux-stage/fs/ext4/dir.c +--- linux-stage.orig/fs/ext4/dir.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/dir.c 2011-12-28 11:24:07.000000000 -0500 +@@ -83,7 +83,7 @@ int ext4_check_dir_entry(const char *fun + error_msg = "inode out of bounds"; + + if (error_msg != NULL) +- ext4_error(dir->i_sb, function, ++ ext4_error(dir->i_sb, + "bad entry in directory #%lu: %s - block=%llu" + "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d", + dir->i_ino, error_msg, +@@ -152,7 +152,7 @@ static int ext4_readdir(struct file *fil + */ + if (!bh) { + if (!dir_has_error) { +- ext4_error(sb, __func__, "directory #%lu " ++ ext4_error(sb, "directory #%lu " + "contains a hole at offset %Lu", + inode->i_ino, + (unsigned long long) filp->f_pos); +diff -urpN linux-stage.orig/fs/ext4/ext4_extents.h linux-stage/fs/ext4/ext4_extents.h +--- linux-stage.orig/fs/ext4/ext4_extents.h 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/ext4_extents.h 2011-12-28 11:24:07.000000000 -0500 +@@ -138,7 +138,7 @@ typedef int (*ext_prepare_callback)(stru + #define EXT_REPEAT 2 + + /* Maximum logical block in a file; ext4_extent's ee_block is __le32 */ +-#define EXT_MAX_BLOCK 0xffffffff ++#define EXT_MAX_BLOCKS 0xffffffff + + /* + * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an +diff -urpN linux-stage.orig/fs/ext4/ext4.h linux-stage/fs/ext4/ext4.h +--- linux-stage.orig/fs/ext4/ext4.h 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/ext4.h 2011-12-28 11:24:07.000000000 -0500 +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -56,6 +57,12 @@ + #define ext4_debug(f, a...) do {} while (0) + #endif + ++#define EXT4_ERROR_INODE(inode, fmt, a...) \ ++ ext4_error_inode(__func__, (inode), (fmt), ## a); ++ ++#define EXT4_ERROR_FILE(file, fmt, a...) \ ++ ext4_error_file(__func__, (file), (fmt), ## a); ++ + /* data type for block offset of block group */ + typedef int ext4_grpblk_t; + +@@ -1509,6 +1516,7 @@ extern struct buffer_head *ext4_read_ino + ext4_group_t block_group); + + /* mballoc.c */ ++struct fstrim_range; + extern long ext4_mb_stats; + extern long ext4_mb_max_to_scan; + extern int ext4_mb_init(struct super_block *, int); +@@ -1526,6 +1534,8 @@ extern int ext4_mb_add_groupinfo(struct + 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 int ext4_trim_fs(struct super_block *, struct fstrim_range *); ++ + /* inode.c */ + int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, + struct buffer_head *bh, ext4_fsblk_t blocknr); +@@ -1586,13 +1596,17 @@ extern int ext4_group_extend(struct supe + ext4_fsblk_t n_blocks_count); + + /* super.c */ +-extern void ext4_error(struct super_block *, const char *, const char *, ...) ++extern void __ext4_error(struct super_block *, const char *, const char *, ...) ++ __attribute__ ((format (printf, 3, 4))); ++#define ext4_error(sb, message...) __ext4_error(sb, __func__, ## message) ++extern void ext4_error_inode(const char *, struct inode *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); + extern void __ext4_std_error(struct super_block *, const char *, int); + extern void ext4_abort(struct super_block *, const char *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); +-extern void ext4_warning(struct super_block *, const char *, const char *, ...) ++extern void __ext4_warning(struct super_block *, const char *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); ++#define ext4_warning(sb, message...) __ext4_warning(sb, __func__, ## message) + extern void ext4_msg(struct super_block *, const char *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); + extern void ext4_grp_locked_error(struct super_block *, ext4_group_t, +diff -urpN linux-stage.orig/fs/ext4/ext4_jbd2.c linux-stage/fs/ext4/ext4_jbd2.c +--- linux-stage.orig/fs/ext4/ext4_jbd2.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/ext4_jbd2.c 2011-12-28 11:24:07.000000000 -0500 +@@ -96,7 +96,7 @@ int __ext4_handle_dirty_metadata(const c + if (inode && inode_needs_sync(inode)) { + sync_dirty_buffer(bh); + if (buffer_req(bh) && !buffer_uptodate(bh)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "IO error syncing inode, " + "inode=%lu, block=%llu", + inode->i_ino, +diff -urpN linux-stage.orig/fs/ext4/extents.c linux-stage/fs/ext4/extents.c +--- linux-stage.orig/fs/ext4/extents.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/extents.c 2011-12-28 11:24:07.000000000 -0500 +@@ -437,7 +437,7 @@ static int __ext4_ext_check(const char * + return 0; + + corrupted: +- ext4_error(inode->i_sb, function, ++ ext4_error(inode->i_sb, + "bad header/extent in inode #%lu: %s - magic %x, " + "entries %u, max %u(%u), depth %u(%u)", + inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), +@@ -1329,7 +1329,7 @@ got_index: + + /* + * ext4_ext_next_allocated_block: +- * returns allocated block in subsequent extent or EXT_MAX_BLOCK. ++ * returns allocated block in subsequent extent or EXT_MAX_BLOCKS. + * NOTE: it considers block number from index entry as + * allocated block. Thus, index entries have to be consistent + * with leaves. +@@ -1343,7 +1343,7 @@ ext4_ext_next_allocated_block(struct ext + depth = path->p_depth; + + if (depth == 0 && path->p_ext == NULL) +- return EXT_MAX_BLOCK; ++ return EXT_MAX_BLOCKS; + + while (depth >= 0) { + if (depth == path->p_depth) { +@@ -1360,12 +1360,12 @@ ext4_ext_next_allocated_block(struct ext + depth--; + } + +- return EXT_MAX_BLOCK; ++ return EXT_MAX_BLOCKS; + } + + /* + * ext4_ext_next_leaf_block: +- * returns first allocated block from next leaf or EXT_MAX_BLOCK ++ * returns first allocated block from next leaf or EXT_MAX_BLOCKS + */ + static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode, + struct ext4_ext_path *path) +@@ -1377,7 +1377,7 @@ static ext4_lblk_t ext4_ext_next_leaf_bl + + /* zero-tree has no leaf blocks at all */ + if (depth == 0) +- return EXT_MAX_BLOCK; ++ return EXT_MAX_BLOCKS; + + /* go to index block */ + depth--; +@@ -1390,7 +1390,7 @@ static ext4_lblk_t ext4_ext_next_leaf_bl + depth--; + } + +- return EXT_MAX_BLOCK; ++ return EXT_MAX_BLOCKS; + } + + /* +@@ -1534,7 +1534,7 @@ int ext4_ext_try_to_merge(struct inode * + merge_done = 1; + WARN_ON(eh->eh_entries == 0); + if (!eh->eh_entries) +- ext4_error(inode->i_sb, "ext4_ext_try_to_merge", ++ ext4_error(inode->i_sb, + "inode#%lu, eh->eh_entries = 0!", inode->i_ino); + } + +@@ -1570,13 +1570,13 @@ unsigned int ext4_ext_check_overlap(stru + */ + if (b2 < b1) { + b2 = ext4_ext_next_allocated_block(path); +- if (b2 == EXT_MAX_BLOCK) ++ if (b2 == EXT_MAX_BLOCKS) + goto out; + } + + /* check for wrap through zero on extent logical start block*/ + if (b1 + len1 < b1) { +- len1 = EXT_MAX_BLOCK - b1; ++ len1 = EXT_MAX_BLOCKS - b1; + newext->ee_len = cpu_to_le16(len1); + ret = 1; + } +@@ -1652,7 +1652,7 @@ repeat: + fex = EXT_LAST_EXTENT(eh); + next = ext4_ext_next_leaf_block(inode, path); + if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block) +- && next != EXT_MAX_BLOCK) { ++ && next != EXT_MAX_BLOCKS) { + ext_debug("next leaf block - %d\n", next); + BUG_ON(npath != NULL); + npath = ext4_ext_find_extent(inode, next, NULL); +@@ -1771,7 +1771,7 @@ int ext4_ext_walk_space(struct inode *in + BUG_ON(func == NULL); + BUG_ON(inode == NULL); + +- while (block < last && block != EXT_MAX_BLOCK) { ++ while (block < last && block != EXT_MAX_BLOCKS) { + num = last - block; + /* find extent for this block */ + down_read(&EXT4_I(inode)->i_data_sem); +@@ -1784,7 +1784,11 @@ int ext4_ext_walk_space(struct inode *in + } + + depth = ext_depth(inode); +- BUG_ON(path[depth].p_hdr == NULL); ++ if (unlikely(path[depth].p_hdr == NULL)) { ++ EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth); ++ err = -EIO; ++ break; ++ } + ex = path[depth].p_ext; + next = ext4_ext_next_allocated_block(path); + +@@ -1835,7 +1839,11 @@ int ext4_ext_walk_space(struct inode *in + cbex.ec_type = EXT4_EXT_CACHE_EXTENT; + } + +- BUG_ON(cbex.ec_len == 0); ++ if (unlikely(cbex.ec_len == 0)) { ++ EXT4_ERROR_INODE(inode, "cbex.ec_len == 0"); ++ err = -EIO; ++ break; ++ } + err = func(inode, path, &cbex, ex, cbdata); + ext4_ext_drop_refs(path); + +@@ -1899,7 +1907,7 @@ ext4_ext_put_gap_in_cache(struct inode * + if (ex == NULL) { + /* there is no extent yet, so gap is [0;-] */ + lblock = 0; +- len = EXT_MAX_BLOCK; ++ len = EXT_MAX_BLOCKS; + ext_debug("cache gap(whole file):"); + } else if (block < le32_to_cpu(ex->ee_block)) { + lblock = block; +@@ -2144,8 +2152,8 @@ ext4_ext_rm_leaf(handle_t *handle, struc + path[depth].p_ext = ex; + + a = ex_ee_block > start ? ex_ee_block : start; +- b = ex_ee_block + ex_ee_len - 1 < EXT_MAX_BLOCK ? +- ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCK; ++ b = ex_ee_block + ex_ee_len - 1 < EXT_MAX_BLOCKS ? ++ ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCKS; + + ext_debug(" border %u:%u\n", a, b); + +@@ -3284,7 +3292,7 @@ int ext4_ext_get_blocks(handle_t *handle + * this is why assert can't be put in ext4_ext_find_extent() + */ + if (path[depth].p_ext == NULL && depth != 0) { +- ext4_error(inode->i_sb, __func__, "bad extent address " ++ ext4_error(inode->i_sb, "bad extent address " + "inode: %lu, iblock: %lu, depth: %d", + inode->i_ino, (unsigned long) iblock, depth); + err = -EIO; +@@ -3415,7 +3423,7 @@ int ext4_ext_get_blocks(handle_t *handle + + if (unlikely(ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS))) { + if (unlikely(!eh->eh_entries)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode#%lu, eh->eh_entries = 0 and " + "EOFBLOCKS_FL set", inode->i_ino); + err = -EIO; +@@ -3782,15 +3790,15 @@ static int ext4_ext_fiemap_cb(struct ino + flags |= FIEMAP_EXTENT_UNWRITTEN; + + /* +- * If this extent reaches EXT_MAX_BLOCK, it must be last. ++ * If this extent reaches EXT_MAX_BLOCKS, it must be last. + * +- * Or if ext4_ext_next_allocated_block is EXT_MAX_BLOCK, ++ * Or if ext4_ext_next_allocated_block is EXT_MAX_BLOCKS, + * this also indicates no more allocated blocks. + * +- * XXX this might miss a single-block extent at EXT_MAX_BLOCK ++ * XXX this might miss a single-block extent at EXT_MAX_BLOCKS + */ +- if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK || +- newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) { ++ if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCKS || ++ newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCKS) { + loff_t size = i_size_read(inode); + loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb); + +@@ -3870,8 +3878,8 @@ int ext4_fiemap(struct inode *inode, str + + start_blk = start >> inode->i_sb->s_blocksize_bits; + last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits; +- if (last_blk >= EXT_MAX_BLOCK) +- last_blk = EXT_MAX_BLOCK-1; ++ if (last_blk >= EXT_MAX_BLOCKS) ++ last_blk = EXT_MAX_BLOCKS-1; + len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1; + + /* +diff -urpN linux-stage.orig/fs/ext4/ialloc.c linux-stage/fs/ext4/ialloc.c +--- linux-stage.orig/fs/ext4/ialloc.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/ialloc.c 2011-12-28 11:24:07.000000000 -0500 +@@ -76,7 +76,7 @@ unsigned ext4_init_inode_bitmap(struct s + /* If checksum is bad mark all blocks and inodes use to prevent + * allocation, essentially implementing a per-group read-only flag. */ + if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { +- ext4_error(sb, __func__, "Checksum bad for group %u", ++ ext4_error(sb, "Checksum bad for group %u", + block_group); + ext4_free_blks_set(sb, gdp, 0); + ext4_free_inodes_set(sb, gdp, 0); +@@ -111,7 +111,7 @@ ext4_read_inode_bitmap(struct super_bloc + bitmap_blk = ext4_inode_bitmap(sb, desc); + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Cannot read inode bitmap - " + "block_group = %u, inode_bitmap = %llu", + block_group, bitmap_blk); +@@ -153,7 +153,7 @@ ext4_read_inode_bitmap(struct super_bloc + set_bitmap_uptodate(bh); + if (bh_submit_read(bh) < 0) { + put_bh(bh); +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Cannot read inode bitmap - " + "block_group = %u, inode_bitmap = %llu", + block_group, bitmap_blk); +@@ -230,8 +230,7 @@ void ext4_free_inode(handle_t *handle, s + + es = EXT4_SB(sb)->s_es; + if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { +- ext4_error(sb, "ext4_free_inode", +- "reserved or nonexistent inode %lu", ino); ++ ext4_error(sb, "reserved or nonexistent inode %lu", ino); + goto error_return; + } + block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); +@@ -286,11 +285,10 @@ out: + fatal = err; + sb->s_dirt = 1; + } else +- ext4_error(sb, "ext4_free_inode", +- "bit already cleared for inode %lu", ino); ++ ext4_error(sb, "bit already cleared for inode %lu", ino); + + error_return: +- brelse(bitmap_bh); ++ brelse(bitmap_bh); + ext4_std_error(sb, fatal); + } + +@@ -730,7 +728,7 @@ static int ext4_claim_inode(struct super + if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || + ino > EXT4_INODES_PER_GROUP(sb)) { + ext4_unlock_group(sb, group); +- ext4_error(sb, __func__, ++ ext4_error(sb, + "reserved inode or inode > inodes count - " + "block_group = %u, inode=%lu", group, + ino + group * EXT4_INODES_PER_GROUP(sb)); +@@ -1094,7 +1092,7 @@ struct inode *ext4_orphan_get(struct sup + + /* Error cases - e2fsck has already cleaned up for us */ + if (ino > max_ino) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "bad orphan ino %lu! e2fsck was run?", ino); + goto error; + } +@@ -1103,7 +1101,7 @@ struct inode *ext4_orphan_get(struct sup + bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb); + bitmap_bh = ext4_read_inode_bitmap(sb, block_group); + if (!bitmap_bh) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "inode bitmap error for orphan %lu", ino); + goto error; + } +@@ -1136,7 +1134,7 @@ iget_failed: + err = PTR_ERR(inode); + inode = NULL; + bad_orphan: +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "bad orphan inode %lu! e2fsck was run?", ino); + printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n", + bit, (unsigned long long)bitmap_bh->b_blocknr, +diff -urpN linux-stage.orig/fs/ext4/inode.c linux-stage/fs/ext4/inode.c +--- linux-stage.orig/fs/ext4/inode.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/inode.c 2011-12-28 11:24:07.000000000 -0500 +@@ -246,7 +246,7 @@ void ext4_delete_inode(struct inode *ino + inode->i_size = 0; + err = ext4_mark_inode_dirty(handle, inode); + if (err) { +- ext4_warning(inode->i_sb, __func__, ++ ext4_warning(inode->i_sb, + "couldn't mark inode dirty (err %d)", err); + goto stop_handle; + } +@@ -264,7 +264,7 @@ void ext4_delete_inode(struct inode *ino + if (err > 0) + err = ext4_journal_restart(handle, 3); + if (err != 0) { +- ext4_warning(inode->i_sb, __func__, ++ ext4_warning(inode->i_sb, + "couldn't extend journal (err %d)", err); + stop_handle: + ext4_journal_stop(handle); +@@ -375,8 +375,7 @@ static int ext4_block_to_path(struct ino + offsets[n++] = i_block & (ptrs - 1); + final = ptrs; + } else { +- ext4_warning(inode->i_sb, "ext4_block_to_path", +- "block %lu > max in inode %lu", ++ ext4_warning(inode->i_sb, "block %lu > max in inode %lu", + i_block + direct_blocks + + indirect_blocks + double_blocks, inode->i_ino); + } +@@ -396,7 +395,7 @@ static int __ext4_check_blockref(const c + if (blk && + unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb), + blk, 1))) { +- ext4_error(inode->i_sb, function, ++ ext4_error(inode->i_sb, + "invalid block reference %u " + "in inode #%lu", blk, inode->i_ino); + return -EIO; +@@ -1167,7 +1166,7 @@ static int check_block_validity(struct i + sector_t logical, sector_t phys, int len) + { + if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), phys, len)) { +- ext4_error(inode->i_sb, msg, ++ ext4_error(inode->i_sb, + "inode #%lu logical block %llu mapped to %llu " + "(size %d)", inode->i_ino, + (unsigned long long) logical, +@@ -4316,7 +4315,7 @@ static void ext4_free_data(handle_t *han + if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) + ext4_handle_dirty_metadata(handle, inode, this_bh); + else +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "circular indirect block detected, " + "inode=%lu, block=%llu", + inode->i_ino, +@@ -4364,7 +4363,7 @@ static void ext4_free_branches(handle_t + * (should be rare). + */ + if (!bh) { +- ext4_error(inode->i_sb, "ext4_free_branches", ++ ext4_error(inode->i_sb, + "Read failure, inode=%lu, block=%llu", + inode->i_ino, nr); + continue; +@@ -4680,9 +4679,8 @@ static int __ext4_get_inode_loc(struct i + + bh = sb_getblk(sb, block); + if (!bh) { +- ext4_error(sb, "ext4_get_inode_loc", "unable to read " +- "inode block - inode=%lu, block=%llu", +- inode->i_ino, block); ++ ext4_error(sb, "unable to read inode block - " ++ "inode=%lu, block=%llu", inode->i_ino, block); + return -EIO; + } + if (!buffer_uptodate(bh)) { +@@ -4780,7 +4778,7 @@ make_io: + submit_bh(READ_META, bh); + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "unable to read inode block - inode=%lu, " + "block=%llu", inode->i_ino, block); + brelse(bh); +@@ -4999,7 +4997,7 @@ struct inode *ext4_iget(struct super_blo + ret = 0; + if (ei->i_file_acl && + !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "bad extended attribute block %llu in inode #%lu", + ei->i_file_acl, inode->i_ino); + ret = -EIO; +@@ -5046,7 +5044,7 @@ struct inode *ext4_iget(struct super_blo + new_decode_dev(le32_to_cpu(raw_inode->i_block[1]))); + } else { + ret = -EIO; +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "bogus i_mode (%o) for inode=%lu", + inode->i_mode, inode->i_ino); + goto bad_inode; +@@ -5286,7 +5284,7 @@ int ext4_write_inode(struct inode *inode + if (wait) + sync_dirty_buffer(iloc.bh); + if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "IO error syncing inode, " + "inode=%lu, block=%llu", + inode->i_ino, +@@ -5707,7 +5705,7 @@ int ext4_mark_inode_dirty(handle_t *hand + EXT4_STATE_NO_EXPAND); + if (mnt_count != + le16_to_cpu(sbi->s_es->s_mnt_count)) { +- ext4_warning(inode->i_sb, __func__, ++ ext4_warning(inode->i_sb, + "Unable to expand inode %lu. Delete" + " some EAs or run e2fsck.", + inode->i_ino); +diff -urpN linux-stage.orig/fs/ext4/mballoc.c linux-stage/fs/ext4/mballoc.c +--- linux-stage.orig/fs/ext4/mballoc.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/mballoc.c 2011-12-28 11:24:07.000000000 -0500 +@@ -1862,7 +1862,6 @@ void ext4_mb_scan_aligned(struct ext4_al + } + } + +-/* This is now called BEFORE we load the buddy bitmap. */ + static int ext4_mb_good_group(struct ext4_allocation_context *ac, + ext4_group_t group, int cr) + { +@@ -2162,6 +2161,11 @@ static void *ext4_mb_seq_groups_next(str + return (void *) ((unsigned long) group); + } + ++static inline void ext4_mb_release_desc(struct ext4_buddy *e4b) ++{ ++ ext4_mb_unload_buddy(e4b); ++} ++ + static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) + { + struct super_block *sb = seq->private; +@@ -2193,7 +2197,7 @@ static int ext4_mb_seq_groups_show(struc + ext4_lock_group(sb, group); + memcpy(&sg, ext4_get_group_info(sb, group), i); + ext4_unlock_group(sb, group); +- ext4_mb_unload_buddy(&e4b); ++ ext4_mb_release_desc(&e4b); + + seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free, + sg.info.bb_fragments, sg.info.bb_first_free); +@@ -2562,6 +2566,17 @@ int ext4_mb_release(struct super_block * + return 0; + } + ++static inline int ext4_issue_discard(struct super_block *sb, ++ ext4_group_t block_group, ext4_grpblk_t block, int count) ++{ ++ ext4_fsblk_t discard_block; ++ ++ discard_block = block + ext4_group_first_block_no(sb, block_group); ++ trace_ext4_discard_blocks(sb, ++ (unsigned long long) discard_block, count); ++ return sb_issue_discard(sb, discard_block, count); ++} ++ + /* + * This function is called by the jbd2 layer once the commit has finished, + * so we know we can free the blocks that were released with that commit. +@@ -2583,17 +2598,11 @@ static void release_blocks_on_commit(jou + + if (test_opt(sb, DISCARD)) { + int ret; +- ext4_fsblk_t discard_block; +- +- discard_block = entry->start_blk + +- ext4_group_first_block_no(sb, entry->group); +- trace_ext4_discard_blocks(sb, +- (unsigned long long)discard_block, +- entry->count); +- ret = sb_issue_discard(sb, discard_block, entry->count); +- if (ret == EOPNOTSUPP) { +- ext4_warning(sb, __func__, +- "discard not supported, disabling"); ++ ret = ext4_issue_discard(sb, entry->group, ++ entry->start_blk, entry->count); ++ if (unlikely(ret == -EOPNOTSUPP)) { ++ ext4_warning(sb, "discard not supported, " ++ "disabling"); + clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD); + } + } +@@ -2620,7 +2629,7 @@ static void release_blocks_on_commit(jou + } + ext4_unlock_group(sb, entry->group); + kmem_cache_free(ext4_free_ext_cachep, entry); +- ext4_mb_unload_buddy(&e4b); ++ ext4_mb_release_desc(&e4b); + } + + mb_debug(1, "freed %u blocks in %u structures\n", count, count2); +@@ -2757,7 +2766,7 @@ ext4_mb_mark_diskspace_used(struct ext4_ + + len = ac->ac_b_ex.fe_len; + if (!ext4_data_block_valid(sbi, block, len)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Allocating blocks %llu-%llu which overlap " + "fs metadata\n", block, block+len); + /* File system mounted not to panic on error +@@ -3671,14 +3680,14 @@ ext4_mb_discard_group_preallocations(str + + bitmap_bh = ext4_read_block_bitmap(sb, group); + if (bitmap_bh == NULL) { +- ext4_error(sb, __func__, "Error in reading block " ++ ext4_error(sb, "Error in reading block " + "bitmap for %u", group); + return 0; + } + + err = ext4_mb_load_buddy(sb, group, &e4b); + if (err) { +- ext4_error(sb, __func__, "Error in loading buddy " ++ ext4_error(sb, "Error in loading buddy " + "information for %u", group); + put_bh(bitmap_bh); + return 0; +@@ -3852,14 +3861,14 @@ repeat: + + err = ext4_mb_load_buddy(sb, group, &e4b); + if (err) { +- ext4_error(sb, __func__, "Error in loading buddy " +- "information for %u", group); ++ ext4_error(sb, "Error in loading buddy information for %u", ++ group); + continue; + } + + bitmap_bh = ext4_read_block_bitmap(sb, group); + if (bitmap_bh == NULL) { +- ext4_error(sb, __func__, "Error in reading block " ++ ext4_error(sb, "Error in reading block " + "bitmap for %u", group); + ext4_mb_unload_buddy(&e4b); + continue; +@@ -4125,7 +4134,7 @@ ext4_mb_discard_lg_preallocations(struct + + ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, NULL); + if (ext4_mb_load_buddy(sb, group, &e4b)) { +- ext4_error(sb, __func__, "Error in loading buddy " ++ ext4_error(sb, "Error in loading buddy " + "information for %u", group); + continue; + } +@@ -4516,7 +4525,7 @@ void ext4_mb_free_blocks(handle_t *handl + if (block < le32_to_cpu(es->s_first_data_block) || + block + count < block || + block + count > ext4_blocks_count(es)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Freeing blocks not in datazone - " + "block = %llu, count = %lu", block, count); + goto error_return; +@@ -4561,7 +4570,7 @@ do_more: + in_range(block + count - 1, ext4_inode_table(sb, gdp), + EXT4_SB(sb)->s_itb_per_group)) { + +- ext4_error(sb, __func__, ++ ext4_error(sb, + "Freeing blocks in system zone - " + "Block = %llu, count = %lu", block, count); + /* err = 0. ext4_std_error should be a no op */ +diff -urpN linux-stage.orig/fs/ext4/move_extent.c linux-stage/fs/ext4/move_extent.c +--- linux-stage.orig/fs/ext4/move_extent.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/move_extent.c 2011-12-28 11:24:07.000000000 -0500 +@@ -152,12 +152,12 @@ mext_check_null_inode(struct inode *inod + int ret = 0; + + if (inode1 == NULL) { +- ext4_error(inode2->i_sb, function, ++ ext4_error(inode2->i_sb, + "Both inodes should not be NULL: " + "inode1 NULL inode2 %lu", inode2->i_ino); + ret = -EIO; + } else if (inode2 == NULL) { +- ext4_error(inode1->i_sb, function, ++ ext4_error(inode1->i_sb, + "Both inodes should not be NULL: " + "inode1 %lu inode2 NULL", inode1->i_ino); + ret = -EIO; +@@ -528,7 +528,7 @@ mext_leaf_block(handle_t *handle, struct + * new_ext |-------| + */ + if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) { +- ext4_error(orig_inode->i_sb, __func__, ++ ext4_error(orig_inode->i_sb, + "new_ext_end(%u) should be less than or equal to " + "oext->ee_block(%u) + oext_alen(%d) - 1", + new_ext_end, le32_to_cpu(oext->ee_block), +@@ -691,12 +691,12 @@ mext_replace_branches(handle_t *handle, + while (1) { + /* The extent for donor must be found. */ + if (!dext) { +- ext4_error(donor_inode->i_sb, __func__, ++ ext4_error(donor_inode->i_sb, + "The extent for donor must be found"); + *err = -EIO; + goto out; + } else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) { +- ext4_error(donor_inode->i_sb, __func__, ++ ext4_error(donor_inode->i_sb, + "Donor offset(%u) and the first block of donor " + "extent(%u) should be equal", + donor_off, +@@ -1001,12 +1001,12 @@ mext_check_arguments(struct inode *orig_ + return -EINVAL; + } + +- if ((orig_start > EXT_MAX_BLOCK) || +- (donor_start > EXT_MAX_BLOCK) || +- (*len > EXT_MAX_BLOCK) || +- (orig_start + *len > EXT_MAX_BLOCK)) { ++ if ((orig_start > EXT_MAX_BLOCKS) || ++ (donor_start > EXT_MAX_BLOCKS) || ++ (*len > EXT_MAX_BLOCKS) || ++ (orig_start + *len > EXT_MAX_BLOCKS)) { + ext4_debug("ext4 move extent: Can't handle over [%u] blocks " +- "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCK, ++ "[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCKS, + orig_inode->i_ino, donor_inode->i_ino); + return -EINVAL; + } +@@ -1356,7 +1356,7 @@ ext4_move_extents(struct file *o_filp, s + if (ret1 < 0) + break; + if (*moved_len > len) { +- ext4_error(orig_inode->i_sb, __func__, ++ ext4_error(orig_inode->i_sb, + "We replaced blocks too much! " + "sum of replaced: %llu requested: %llu", + *moved_len, len); +diff -urpN linux-stage.orig/fs/ext4/namei.c linux-stage/fs/ext4/namei.c +--- linux-stage.orig/fs/ext4/namei.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/namei.c 2011-12-28 11:28:51.000000000 -0500 +@@ -394,8 +394,7 @@ dx_probe(const struct qstr *d_name, stru + if (root->info.hash_version != DX_HASH_TEA && + root->info.hash_version != DX_HASH_HALF_MD4 && + root->info.hash_version != DX_HASH_LEGACY) { +- ext4_warning(dir->i_sb, __func__, +- "Unrecognised inode hash code %d", ++ ext4_warning(dir->i_sb, "Unrecognised inode hash code %d", + root->info.hash_version); + brelse(bh); + *err = ERR_BAD_DX_DIR; +@@ -410,8 +409,7 @@ dx_probe(const struct qstr *d_name, stru + hash = hinfo->hash; + + if (root->info.unused_flags & 1) { +- ext4_warning(dir->i_sb, __func__, +- "Unimplemented inode hash flags: %#06x", ++ ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x", + root->info.unused_flags); + brelse(bh); + *err = ERR_BAD_DX_DIR; +@@ -419,8 +417,7 @@ dx_probe(const struct qstr *d_name, stru + } + + if ((indirect = root->info.indirect_levels) > 1) { +- ext4_warning(dir->i_sb, __func__, +- "Unimplemented inode hash depth: %#06x", ++ ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x", + root->info.indirect_levels); + brelse(bh); + *err = ERR_BAD_DX_DIR; +@@ -432,8 +429,7 @@ dx_probe(const struct qstr *d_name, stru + + if (dx_get_limit(entries) != dx_root_limit(dir, + root->info.info_length)) { +- ext4_warning(dir->i_sb, __func__, +- "dx entry: limit != root limit"); ++ ext4_warning(dir->i_sb, "dx entry: limit != root limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; + goto fail; +@@ -444,7 +440,7 @@ dx_probe(const struct qstr *d_name, stru + { + count = dx_get_count(entries); + if (!count || count > dx_get_limit(entries)) { +- ext4_warning(dir->i_sb, __func__, ++ ext4_warning(dir->i_sb, + "dx entry: no count or count > limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; +@@ -489,7 +485,7 @@ dx_probe(const struct qstr *d_name, stru + goto fail2; + at = entries = ((struct dx_node *) bh->b_data)->entries; + if (dx_get_limit(entries) != dx_node_limit (dir)) { +- ext4_warning(dir->i_sb, __func__, ++ ext4_warning(dir->i_sb, + "dx entry: limit != node limit"); + brelse(bh); + *err = ERR_BAD_DX_DIR; +@@ -505,7 +501,7 @@ fail2: + } + fail: + if (*err == ERR_BAD_DX_DIR) +- ext4_warning(dir->i_sb, __func__, ++ ext4_warning(dir->i_sb, + "Corrupt dir inode %ld, running e2fsck is " + "recommended.", dir->i_ino); + return NULL; +@@ -969,7 +965,7 @@ restart: + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) { + /* read error, skip block & hope for the best */ +- ext4_error(sb, __func__, "reading directory #%lu " ++ ext4_error(sb, "reading directory #%lu " + "offset %lu", dir->i_ino, + (unsigned long)block); + brelse(bh); +@@ -1012,8 +1008,9 @@ cleanup_and_exit: + 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) + { +- struct super_block * sb = dir->i_sb; ++ struct super_block * sb; + struct dx_hash_info hinfo; ++ u32 hash; + struct dx_frame frames[2], *frame; + struct ext4_dir_entry_2 *de, *top; + struct buffer_head *bh; +@@ -1022,8 +1019,18 @@ static struct buffer_head * ext4_dx_find + int namelen = d_name->len; + const u8 *name = d_name->name; + +- if (!(frame = dx_probe(d_name, dir, &hinfo, frames, err))) +- return NULL; ++ sb = dir->i_sb; ++ /* NFS may look up ".." - look at dx_root directory block */ ++ if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){ ++ if (!(frame = dx_probe(d_name, dir, &hinfo, frames, err))) ++ return NULL; ++ } else { ++ frame = frames; ++ frame->bh = NULL; /* for dx_release() */ ++ frame->at = (struct dx_entry *)frames; /* hack for zero entry*/ ++ dx_set_block(frame->at, 0); /* dx_root block is 0 */ ++ } ++ hash = hinfo.hash; + do { + block = dx_get_block(frame->at); + if (!(bh = ext4_bread (NULL,dir, block, 0, err))) +@@ -1049,10 +1056,10 @@ static struct buffer_head * ext4_dx_find + } + brelse(bh); + /* Check to see if we should continue to search */ +- retval = ext4_htree_next_block(dir, hinfo.hash, frame, ++ retval = ext4_htree_next_block(dir, hash, frame, + frames, NULL); + if (retval < 0) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "error reading index page in directory #%lu", + dir->i_ino); + *err = retval; +@@ -1082,14 +1089,13 @@ static struct dentry *ext4_lookup(struct + __u32 ino = le32_to_cpu(de->inode); + brelse(bh); + if (!ext4_valid_inum(dir->i_sb, ino)) { +- ext4_error(dir->i_sb, "ext4_lookup", +- "bad inode number: %u", ino); ++ ext4_error(dir->i_sb, "bad inode number: %u", ino); + return ERR_PTR(-EIO); + } + inode = ext4_iget(dir->i_sb, ino); + if (unlikely(IS_ERR(inode))) { + if (PTR_ERR(inode) == -ESTALE) { +- ext4_error(dir->i_sb, __func__, ++ ext4_error(dir->i_sb, + "deleted inode referenced: %u", + ino); + return ERR_PTR(-EIO); +@@ -1121,7 +1127,7 @@ struct dentry *ext4_get_parent(struct de + brelse(bh); + + if (!ext4_valid_inum(child->d_inode->i_sb, ino)) { +- ext4_error(child->d_inode->i_sb, "ext4_get_parent", ++ ext4_error(child->d_inode->i_sb, + "bad inode number: %u", ino); + return ERR_PTR(-EIO); + } +@@ -1421,7 +1427,7 @@ static int make_indexed_dir(handle_t *ha + de = (struct ext4_dir_entry_2 *)((char *)fde + + ext4_rec_len_from_disk(fde->rec_len, blocksize)); + if ((char *) de >= (((char *) root) + blocksize)) { +- ext4_error(dir->i_sb, __func__, ++ ext4_error(dir->i_sb, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); +@@ -1588,8 +1594,7 @@ static int ext4_dx_add_entry(handle_t *h + + if (levels && (dx_get_count(frames->entries) == + dx_get_limit(frames->entries))) { +- ext4_warning(sb, __func__, +- "Directory index full!"); ++ ext4_warning(sb, "Directory index full!"); + err = -ENOSPC; + goto cleanup; + } +@@ -1943,11 +1948,11 @@ static int empty_dir(struct inode *inode + if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) || + !(bh = ext4_bread(NULL, inode, 0, 0, &err))) { + if (err) +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "error %d reading directory #%lu offset 0", + err, inode->i_ino); + else +- ext4_warning(inode->i_sb, __func__, ++ ext4_warning(inode->i_sb, + "bad directory (dir #%lu) - no data block", + inode->i_ino); + return 1; +@@ -1958,7 +1963,7 @@ static int empty_dir(struct inode *inode + !le32_to_cpu(de1->inode) || + strcmp(".", de->name) || + strcmp("..", de1->name)) { +- ext4_warning(inode->i_sb, "empty_dir", ++ ext4_warning(inode->i_sb, + "bad directory (dir #%lu) - no `.' or `..'", + inode->i_ino); + brelse(bh); +@@ -1976,7 +1981,7 @@ static int empty_dir(struct inode *inode + offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err); + if (!bh) { + if (err) +- ext4_error(sb, __func__, ++ ext4_error(sb, + "error %d reading directory" + " #%lu offset %u", + err, inode->i_ino, offset); +@@ -2198,7 +2203,7 @@ static int ext4_rmdir(struct inode *dir, + if (retval) + goto end_rmdir; + if (!EXT4_DIR_LINK_EMPTY(inode)) +- ext4_warning(inode->i_sb, "ext4_rmdir", ++ ext4_warning(inode->i_sb, + "empty directory has too many links (%d)", + inode->i_nlink); + inode->i_version++; +@@ -2250,7 +2255,7 @@ static int ext4_unlink(struct inode *dir + goto end_unlink; + + if (!inode->i_nlink) { +- ext4_warning(inode->i_sb, "ext4_unlink", ++ ext4_warning(inode->i_sb, + "Deleting nonexistent file (%lu), %d", + inode->i_ino, inode->i_nlink); + inode->i_nlink = 1; +@@ -2497,7 +2502,7 @@ static int ext4_rename(struct inode *old + } + } + if (retval) { +- ext4_warning(old_dir->i_sb, "ext4_rename", ++ ext4_warning(old_dir->i_sb, + "Deleting old file (%lu), %d, error=%d", + old_dir->i_ino, old_dir->i_nlink, retval); + } +diff -urpN linux-stage.orig/fs/ext4/resize.c linux-stage/fs/ext4/resize.c +--- linux-stage.orig/fs/ext4/resize.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/resize.c 2011-12-28 11:24:07.000000000 -0500 +@@ -48,63 +48,63 @@ static int verify_group_input(struct sup + + ext4_get_group_no_and_offset(sb, start, NULL, &offset); + if (group != sbi->s_groups_count) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Cannot add at group %u (only %u groups)", + input->group, sbi->s_groups_count); + else if (offset != 0) +- ext4_warning(sb, __func__, "Last group not full"); ++ ext4_warning(sb, "Last group not full"); + else if (input->reserved_blocks > input->blocks_count / 5) +- ext4_warning(sb, __func__, "Reserved blocks too high (%u)", ++ ext4_warning(sb, "Reserved blocks too high (%u)", + input->reserved_blocks); + else if (free_blocks_count < 0) +- ext4_warning(sb, __func__, "Bad blocks count %u", ++ ext4_warning(sb, "Bad blocks count %u", + input->blocks_count); + else if (!(bh = sb_bread(sb, end - 1))) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Cannot read last block (%llu)", + end - 1); + else if (outside(input->block_bitmap, start, end)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Block bitmap not in group (block %llu)", + (unsigned long long)input->block_bitmap); + else if (outside(input->inode_bitmap, start, end)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Inode bitmap not in group (block %llu)", + (unsigned long long)input->inode_bitmap); + else if (outside(input->inode_table, start, end) || + outside(itend - 1, start, end)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Inode table not in group (blocks %llu-%llu)", + (unsigned long long)input->inode_table, itend - 1); + else if (input->inode_bitmap == input->block_bitmap) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Block bitmap same as inode bitmap (%llu)", + (unsigned long long)input->block_bitmap); + else if (inside(input->block_bitmap, input->inode_table, itend)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Block bitmap (%llu) in inode table (%llu-%llu)", + (unsigned long long)input->block_bitmap, + (unsigned long long)input->inode_table, itend - 1); + else if (inside(input->inode_bitmap, input->inode_table, itend)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Inode bitmap (%llu) in inode table (%llu-%llu)", + (unsigned long long)input->inode_bitmap, + (unsigned long long)input->inode_table, itend - 1); + else if (inside(input->block_bitmap, start, metaend)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Block bitmap (%llu) in GDT table" + " (%llu-%llu)", + (unsigned long long)input->block_bitmap, + start, metaend - 1); + else if (inside(input->inode_bitmap, start, metaend)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Inode bitmap (%llu) in GDT table" + " (%llu-%llu)", + (unsigned long long)input->inode_bitmap, + start, metaend - 1); + else if (inside(input->inode_table, start, metaend) || + inside(itend - 1, start, metaend)) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Inode table (%llu-%llu) overlaps" + "GDT table (%llu-%llu)", + (unsigned long long)input->inode_table, +@@ -364,7 +364,7 @@ static int verify_reserved_gdb(struct su + while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) { + if (le32_to_cpu(*p++) != + grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){ +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "reserved GDT %llu" + " missing grp %d (%llu)", + blk, grp, +@@ -420,7 +420,7 @@ static int add_new_gdb(handle_t *handle, + */ + if (EXT4_SB(sb)->s_sbh->b_blocknr != + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "won't resize using backup superblock at %llu", + (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); + return -EPERM; +@@ -444,7 +444,7 @@ static int add_new_gdb(handle_t *handle, + + data = (__le32 *)dind->b_data; + if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "new group %u GDT block %llu not reserved", + input->group, gdblock); + err = -EINVAL; +@@ -468,7 +468,7 @@ static int add_new_gdb(handle_t *handle, + GFP_NOFS); + if (!n_group_desc) { + err = -ENOMEM; +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "not enough memory for %lu groups", gdb_num + 1); + goto exit_inode; + } +@@ -567,7 +567,7 @@ static int reserve_backup_gdb(handle_t * + /* Get each reserved primary GDT block and verify it holds backups */ + for (res = 0; res < reserved_gdb; res++, blk++) { + if (le32_to_cpu(*data) != blk) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "reserved block %llu" + " not at offset %ld", + blk, +@@ -713,7 +713,7 @@ static void update_backups(struct super_ + */ + exit_err: + if (err) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "can't update backup for group %u (err %d), " + "forcing fsck on next reboot", group, err); + sbi->s_mount_state &= ~EXT4_VALID_FS; +@@ -753,20 +753,20 @@ int ext4_group_add(struct super_block *s + + if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb, + EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Can't resize non-sparse filesystem further"); + return -EPERM; + } + + if (ext4_blocks_count(es) + input->blocks_count < + ext4_blocks_count(es)) { +- ext4_warning(sb, __func__, "blocks_count overflow"); ++ ext4_warning(sb, "blocks_count overflow"); + return -EINVAL; + } + + if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) < + le32_to_cpu(es->s_inodes_count)) { +- ext4_warning(sb, __func__, "inodes_count overflow"); ++ ext4_warning(sb, "inodes_count overflow"); + return -EINVAL; + } + +@@ -774,13 +774,13 @@ int ext4_group_add(struct super_block *s + if (!EXT4_HAS_COMPAT_FEATURE(sb, + EXT4_FEATURE_COMPAT_RESIZE_INODE) + || !le16_to_cpu(es->s_reserved_gdt_blocks)) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "No reserved GDT blocks, can't resize"); + return -EPERM; + } + inode = ext4_iget(sb, EXT4_RESIZE_INO); + if (IS_ERR(inode)) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "Error opening resize inode"); + return PTR_ERR(inode); + } +@@ -810,7 +810,7 @@ int ext4_group_add(struct super_block *s + + mutex_lock(&sbi->s_resize_lock); + if (input->group != sbi->s_groups_count) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "multiple resizers run on filesystem!"); + err = -EBUSY; + goto exit_journal; +@@ -998,12 +998,12 @@ int ext4_group_extend(struct super_block + " too large to resize to %llu blocks safely\n", + sb->s_id, n_blocks_count); + if (sizeof(sector_t) < 8) +- ext4_warning(sb, __func__, "CONFIG_LBDAF not enabled"); ++ ext4_warning(sb, "CONFIG_LBDAF not enabled"); + return -EINVAL; + } + + if (n_blocks_count < o_blocks_count) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "can't shrink FS - resize aborted"); + return -EBUSY; + } +@@ -1012,7 +1012,7 @@ int ext4_group_extend(struct super_block + ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last); + + if (last == 0) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "need to use ext2online to resize further"); + return -EPERM; + } +@@ -1020,7 +1020,7 @@ int ext4_group_extend(struct super_block + add = EXT4_BLOCKS_PER_GROUP(sb) - last; + + if (o_blocks_count + add < o_blocks_count) { +- ext4_warning(sb, __func__, "blocks_count overflow"); ++ ext4_warning(sb, "blocks_count overflow"); + return -EINVAL; + } + +@@ -1028,7 +1028,7 @@ int ext4_group_extend(struct super_block + add = n_blocks_count - o_blocks_count; + + if (o_blocks_count + add < n_blocks_count) +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "will only finish group (%llu" + " blocks, %u new)", + o_blocks_count + add, add); +@@ -1036,7 +1036,7 @@ int ext4_group_extend(struct super_block + /* See if the device is actually as big as what was requested */ + bh = sb_bread(sb, o_blocks_count + add - 1); + if (!bh) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "can't read last block, resize aborted"); + return -ENOSPC; + } +@@ -1048,13 +1048,13 @@ int ext4_group_extend(struct super_block + handle = ext4_journal_start_sb(sb, 3); + if (IS_ERR(handle)) { + err = PTR_ERR(handle); +- ext4_warning(sb, __func__, "error %d on journal start", err); ++ ext4_warning(sb, "error %d on journal start", err); + goto exit_put; + } + + mutex_lock(&EXT4_SB(sb)->s_resize_lock); + if (o_blocks_count != ext4_blocks_count(es)) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "multiple resizers run on filesystem!"); + mutex_unlock(&EXT4_SB(sb)->s_resize_lock); + ext4_journal_stop(handle); +@@ -1064,7 +1064,7 @@ int ext4_group_extend(struct super_block + + if ((err = ext4_journal_get_write_access(handle, + EXT4_SB(sb)->s_sbh))) { +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "error %d on journal write access", err); + mutex_unlock(&EXT4_SB(sb)->s_resize_lock); + ext4_journal_stop(handle); +diff -urpN linux-stage.orig/fs/ext4/super.c linux-stage/fs/ext4/super.c +--- linux-stage.orig/fs/ext4/super.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/super.c 2011-12-28 11:24:07.000000000 -0500 +@@ -337,7 +337,7 @@ static void ext4_handle_error(struct sup + sb->s_id); + } + +-void ext4_error(struct super_block *sb, const char *function, ++void __ext4_error(struct super_block *sb, const char *function, + const char *fmt, ...) + { + va_list args; +@@ -351,6 +351,42 @@ void ext4_error(struct super_block *sb, + ext4_handle_error(sb); + } + ++void ext4_error_inode(const char *function, struct inode *inode, ++ const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ", ++ inode->i_sb->s_id, function, inode->i_ino, current->comm); ++ vprintk(fmt, args); ++ printk("\n"); ++ va_end(args); ++ ++ ext4_handle_error(inode->i_sb); ++} ++ ++void ext4_error_file(const char *function, struct file *file, ++ const char *fmt, ...) ++{ ++ va_list args; ++ struct inode *inode = file->f_dentry->d_inode; ++ char pathname[80], *path; ++ ++ va_start(args, fmt); ++ path = d_path(&(file->f_path), pathname, sizeof(pathname)); ++ if (!path) ++ path = "(unknown)"; ++ printk(KERN_CRIT ++ "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ", ++ inode->i_sb->s_id, function, inode->i_ino, current->comm, path); ++ vprintk(fmt, args); ++ printk("\n"); ++ va_end(args); ++ ++ ext4_handle_error(inode->i_sb); ++} ++ + static const char *ext4_decode_error(struct super_block *sb, int errno, + char nbuf[16]) + { +@@ -454,7 +490,7 @@ void ext4_msg (struct super_block * sb, + va_end(args); + } + +-void ext4_warning(struct super_block *sb, const char *function, ++void __ext4_warning(struct super_block *sb, const char *function, + const char *fmt, ...) + { + va_list args; +@@ -511,7 +547,7 @@ void ext4_update_dynamic_rev(struct supe + if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) + return; + +- ext4_warning(sb, __func__, ++ ext4_warning(sb, + "updating to rev %d because of new feature flag, " + "running e2fsck is recommended", + EXT4_DYNAMIC_REV); +@@ -1096,9 +1132,9 @@ enum { + Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, + Opt_data_err_abort, Opt_data_err_ignore, + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, +- 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_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, ++ Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, ++ Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, + Opt_stripe, Opt_delalloc, Opt_nodelalloc, + Opt_block_validity, Opt_noblock_validity, + Opt_inode_readahead_blks, Opt_journal_ioprio, +@@ -2709,6 +2745,21 @@ static int ext4_fill_super(struct super_ + get_random_bytes(&sbi->s_next_generation, sizeof(u32)); + spin_lock_init(&sbi->s_next_gen_lock); + ++ err = percpu_counter_init(&sbi->s_freeblocks_counter, ++ ext4_count_free_blocks(sb)); ++ if (!err) ++ err = percpu_counter_init(&sbi->s_freeinodes_counter, ++ ext4_count_free_inodes(sb)); ++ if (!err) ++ err = percpu_counter_init(&sbi->s_dirs_counter, ++ ext4_count_dirs(sb)); ++ if (!err) ++ err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); ++ if (err) { ++ ext4_msg(sb, KERN_ERR, "insufficient memory"); ++ goto failed_mount3; ++ } ++ + sbi->s_stripe = ext4_get_stripe_size(sbi); + sbi->s_max_writeback_mb_bump = 128; + +@@ -2828,20 +2879,6 @@ static int ext4_fill_super(struct super_ + set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); + + no_journal: +- err = percpu_counter_init(&sbi->s_freeblocks_counter, +- ext4_count_free_blocks(sb)); +- if (!err) +- err = percpu_counter_init(&sbi->s_freeinodes_counter, +- ext4_count_free_inodes(sb)); +- if (!err) +- err = percpu_counter_init(&sbi->s_dirs_counter, +- ext4_count_dirs(sb)); +- if (!err) +- err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); +- if (err) { +- ext4_msg(sb, KERN_ERR, "insufficient memory"); +- goto failed_mount_wq; +- } + if (test_opt(sb, NOBH)) { + if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { + ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " +@@ -2974,10 +3011,6 @@ failed_mount_wq: + jbd2_journal_destroy(sbi->s_journal); + sbi->s_journal = NULL; + } +- 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); + failed_mount3: + if (sbi->s_flex_groups) { + if (is_vmalloc_addr(sbi->s_flex_groups)) +@@ -2985,6 +3018,10 @@ failed_mount3: + else + kfree(sbi->s_flex_groups); + } ++ 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); + failed_mount2: + for (i = 0; i < db_count; i++) + brelse(sbi->s_group_desc[i]); +@@ -3377,9 +3414,9 @@ static void ext4_clear_journal_err(struc + char nbuf[16]; + + errstr = ext4_decode_error(sb, j_errno, nbuf); +- ext4_warning(sb, __func__, "Filesystem error recorded " ++ ext4_warning(sb, "Filesystem error recorded " + "from previous mount: %s", errstr); +- ext4_warning(sb, __func__, "Marking fs in need of " ++ ext4_warning(sb, "Marking fs in need of " + "filesystem check."); + + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; +diff -urpN linux-stage.orig/fs/ext4/xattr.c linux-stage/fs/ext4/xattr.c +--- linux-stage.orig/fs/ext4/xattr.c 2011-12-28 08:18:31.000000000 -0500 ++++ linux-stage/fs/ext4/xattr.c 2011-12-28 11:24:07.000000000 -0500 +@@ -227,7 +227,7 @@ ext4_xattr_block_get(struct inode *inode + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); + if (ext4_xattr_check_block(bh)) { +-bad_block: ext4_error(inode->i_sb, __func__, ++bad_block: ext4_error(inode->i_sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + error = -EIO; +@@ -369,7 +369,7 @@ ext4_xattr_block_list(struct inode *inod + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); + if (ext4_xattr_check_block(bh)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + error = -EIO; +@@ -661,7 +661,7 @@ ext4_xattr_block_find(struct inode *inod + atomic_read(&(bs->bh->b_count)), + le32_to_cpu(BHDR(bs->bh)->h_refcount)); + if (ext4_xattr_check_block(bs->bh)) { +- ext4_error(sb, __func__, ++ ext4_error(sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + error = -EIO; +@@ -875,7 +875,7 @@ cleanup_dquot: + goto cleanup; + + bad_block: +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + goto cleanup; +@@ -1190,7 +1190,7 @@ retry: + if (!bh) + goto cleanup; + if (ext4_xattr_check_block(bh)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + error = -EIO; +@@ -1367,14 +1367,14 @@ ext4_xattr_delete_inode(handle_t *handle + goto cleanup; + bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); + if (!bh) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: block %llu read error", inode->i_ino, + EXT4_I(inode)->i_file_acl); + goto cleanup; + } + if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || + BHDR(bh)->h_blocks != cpu_to_le32(1)) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: bad block %llu", inode->i_ino, + EXT4_I(inode)->i_file_acl); + goto cleanup; +@@ -1501,7 +1501,7 @@ again: + } + bh = sb_bread(inode->i_sb, ce->e_block); + if (!bh) { +- ext4_error(inode->i_sb, __func__, ++ ext4_error(inode->i_sb, + "inode %lu: block %lu read error", + inode->i_ino, (unsigned long) ce->e_block); + } else if (le32_to_cpu(BHDR(bh)->h_refcount) >= diff --git a/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-sles11.patch deleted file mode 100644 index edfa94e..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-wantedi-2.6-sles11.patch +++ /dev/null @@ -1,198 +0,0 @@ -Index: linux-stage/fs/ext4/ialloc.c -=================================================================== ---- 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_goal(handle_t *handle, struct inode *dir, -+ int mode, unsigned goal) - { - struct super_block *sb; - 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 && goal <= le32_to_cpu(es->s_inodes_count)) { -+ group = (goal - 1) / EXT4_INODES_PER_GROUP(sb); -+ ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb); -+ -+ ret2 = 0; -+ goto got_group; -+ } -+ - if (sbi->s_log_groups_per_flex) { - ret2 = find_group_flex(sb, dir, &group); - goto got_group; -@@ -724,7 +733,7 @@ got_group: - if (ret2 == -1) - goto out; - -- 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 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); -@@ -1716,6 +1727,19 @@ static int ext4_add_nondir(handle_t *han - return err; - } - -+static unsigned ext4_dentry_goal(struct super_block *sb, struct dentry *dentry) -+{ -+ unsigned inum = EXT4_SB(sb)->s_inode_goal; -+ -+ if (dentry->d_fsdata != NULL) { -+ struct lvfs_dentry_params *param = dentry->d_fsdata; -+ -+ if (param->ldp_magic == LVFS_DENTRY_PARAM_MAGIC) -+ inum = param->ldp_inum; -+ } -+ return inum; -+} -+ - /* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it -@@ -1741,7 +1766,8 @@ retry: - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - -- 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)) { - inode->i_op = &ext4_file_inode_operations; -@@ -1775,7 +1800,8 @@ retry: - if (IS_DIRSYNC(dir)) - handle->h_sync = 1; - -- 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); -@@ -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_goal(handle, dir, S_IFDIR | mode, -+ ext4_dentry_goal(dir->i_sb, dentry)); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -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_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-stage/fs/ext4/ext4.h -=================================================================== ---- 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_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-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); - } - -@@ -2274,10 +2275,14 @@ static int ext4_fill_super(struct super_ - if (ext4_proc_root) - sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); - -- if (sbi->s_proc) -+ if (sbi->s_proc) { - proc_create_data("inode_readahead_blks", 0644, sbi->s_proc, - &ext4_ui_proc_fops, - &sbi->s_inode_readahead_blks); -+ proc_create_data("inode_goal", 0644, sbi->s_proc, -+ &ext4_ui_proc_fops, -+ &sbi->s_inode_goal); -+ } - #endif - - bgl_lock_init(&sbi->s_blockgroup_lock); -@@ -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-xattr-no-update-ctime-sles11.patch b/ldiskfs/kernel_patches/patches/ext4-xattr-no-update-ctime-sles11.patch deleted file mode 100644 index 66de9df..0000000 --- a/ldiskfs/kernel_patches/patches/ext4-xattr-no-update-ctime-sles11.patch +++ /dev/null @@ -1,32 +0,0 @@ -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 -@@ -995,6 +995,13 @@ struct mmp_struct { - extern struct proc_dir_entry *proc_root_ext4; - - /* -+ * Indicates that ctime should not be updated in ext4_xattr_set_handle() -+ */ -+#ifndef XATTR_NO_CTIME -+#define XATTR_NO_CTIME 0x80 -+#endif -+ -+/* - * Function prototypes - */ - -Index: linux-2.6.18.i386/fs/ext4/xattr.c -=================================================================== ---- linux-2.6.18.i386.orig/fs/ext4/xattr.c -+++ linux-2.6.18.i386/fs/ext4/xattr.c -@@ -1026,7 +1026,8 @@ ext4_xattr_set_handle(handle_t *handle, - } - if (!error) { - ext4_xattr_update_super_block(handle, inode->i_sb); -- inode->i_ctime = ext4_current_time(inode); -+ if (!(flags & XATTR_NO_CTIME)) -+ inode->i_ctime = ext4_current_time(inode); - if (!value) - EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND; - error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series index 9f36eb7..f7e065c 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series @@ -1,35 +1,37 @@ -ext4-wantedi-2.6-sles11.patch -ext4-map_inode_page-sles11.patch -export-ext4-2.6-sles11.patch -ext4-include-fixes-2.6-sles11.patch -ext4-remove-cond_resched-calls-sles11.patch -ext4-mmp-sles11.patch -ext4-fiemap-2.6-sles11.patch -ext4-lookup-dotdot-sles11.patch -ext4-max-dir-size-sles11.patch -ext4-print-inum-in-htree-warning-sles11.patch -ext4-xattr-no-update-ctime-sles11.patch -ext4-prealloc-sles11.patch -ext4-mballoc-extra-checks-sles11.patch -ext4-big-endian-check-2.6-sles11.patch -ext4-misc-sles11.patch +ext4-wantedi-2.6-rhel6.patch +ext4-map_inode_page-2.6.18-rhel5.patch +export-ext4-2.6-rhel5.patch +ext4-remove-cond_resched-calls-rhel5.patch +ext4-nlink-2.6-rhel5.patch ext4-ext_generation-sles11.patch -ext4-super-warning.patch -ext4-alloc-policy-2.6-sles11.patch -ext4-disable-delalloc-sles11.patch -ext4-lustre-i_version.patch -ext4-lock-cached_extent.patch -ext4-convert-group-lock-sles11.patch -ext4-force_over_8tb-sles11.patch -ext4-claim_inode-free_inode-race.patch -ext4_ext_search_right-fix.patch -ext4-pa_lock-typo.patch -ext4-pdir-fix.patch -ext4-osd-iop-common-sles11.patch -ext4-osd-iam-exports.patch -ext4-dynlocks-common-sles11.patch -ext4-dynlocks-2.6-rhel5.patch -ext4-hash-indexed-dir-dotdot-update.patch -ext4-disable-write-bar-by-default.patch -ext4-mballoc-pa_free-mismatch.patch +ext4-inode-version-rhel6.patch +ext4-update-sles11-rhel6.patch +ext4-mmp-rhel6.patch +ext4-lookup-dotdot-rhel5.patch +ext4-max-dir-size-rhel6.patch +ext4-print-inum-in-htree-warning-rhel6.patch +ext4-xattr-no-update-ctime-rhel5.patch +ext4-prealloc-rhel6.patch +ext4-mballoc-extra-checks-rhel6.patch +ext4-misc-rhel6.patch +ext4-big-endian-check-2.6-rhel6.patch +ext4-alloc-policy-2.6-rhel5.patch +ext4-force_over_128tb-rhel6.patch +ext4-pdir-fix-rhel6.patch +ext4-osd-iop-common-rhel6.patch +ext4-osd-iam-exports-rhel6.patch +ext4-dynlocks-common-rhel6.patch +ext4-hash-indexed-dir-dotdot-update-rhel5.patch +ext4-kill-dx_root-rhel6.patch +ext4-extents-mount-option-rhel6.patch +ext4-fiemap-2.6-rhel6.patch +ext4-mballoc-pa_free-mismatch-rhel6.patch +ext4_data_in_dirent-rhel6.patch +ext4-disable-mb-cache-rhel6.patch +ext4-back-dquot-to-rhel6.patch +ext4-nocmtime-2.6-rhel5.patch ext4-export-64bit-name-hash.patch +ext4-vmalloc-rhel6.patch +ext4-journal-callback.patch +ext4-store-tree-generation-at-find.patch +ext4_pdirop-rhel6.patch -- 1.8.3.1