+++ /dev/null
-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 <linux/log2.h>
- #include <linux/crc16.h>
- #include <asm/uaccess.h>
-+#include <linux/kthread.h>
-+#include <linux/utsname.h>
-
- #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 */
--- /dev/null
+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 <linux/quota.h>
+ #include <linux/rwsem.h>
+ #include <linux/rbtree.h>
++#include <linux/kernel.h>
+ #include <linux/seqlock.h>
+ #include <linux/mutex.h>
+ #include <linux/timer.h>
+@@ -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) >=