--- /dev/null
+Index: linux-stage/fs/ext4/dir.c
+===================================================================
+--- linux-stage.orig/fs/ext4/dir.c 2011-03-31 10:35:49.000000000 +0800
++++ linux-stage/fs/ext4/dir.c 2011-04-01 09:33:58.706267179 +0800
+@@ -249,19 +249,32 @@
+ /*
+ * These functions convert from the major/minor hash to an f_pos
+ * value.
+- *
+- * Currently we only use major hash numer. This is unfortunate, but
+- * on 32-bit machines, the same VFS interface is used for lseek and
+- * llseek, so if we use the 64 bit offset, then the 32-bit versions of
+- * lseek/telldir/seekdir will blow out spectacularly, and from within
+- * the ext2 low-level routine, we don't know if we're being called by
+- * a 64-bit version of the system call or the 32-bit version of the
+- * system call. Worse yet, NFSv2 only allows for a 32-bit readdir
+- * cookie. Sigh.
++ * Whether 64-bit or 32-bit hash value is exported as file pos is
++ * controlled by "64bithash" mount option.
+ */
+-#define hash2pos(major, minor) (major >> 1)
+-#define pos2maj_hash(pos) ((pos << 1) & 0xffffffff)
+-#define pos2min_hash(pos) (0)
++static inline loff_t hash2pos(struct super_block *sb, __u32 major, __u32 minor)
++{
++ if (test_opt(sb, 64BITHASH))
++ return (((__u64)(major >> 1) << 32) | (__u64)minor);
++ else
++ return (major >> 1);
++}
++
++static inline __u32 pos2maj_hash(struct super_block *sb, loff_t pos)
++{
++ if (test_opt(sb, 64BITHASH))
++ return (((pos >> 32) << 1) & 0xffffffff);
++ else
++ return ((pos << 1) & 0xffffffff);
++}
++
++static inline __u32 pos2min_hash(struct super_block *sb, loff_t pos)
++{
++ if (test_opt(sb, 64BITHASH))
++ return (pos & 0xffffffff);
++ else
++ return (0);
++}
+
+ /*
+ * This structure holds the nodes of the red-black tree used to store
+@@ -322,15 +335,16 @@
+ }
+
+
+-static struct dir_private_info *ext4_htree_create_dir_info(loff_t pos)
++static struct dir_private_info *ext4_htree_create_dir_info(
++ struct super_block *sb, loff_t pos)
+ {
+ struct dir_private_info *p;
+
+ p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL);
+ if (!p)
+ return NULL;
+- p->curr_hash = pos2maj_hash(pos);
+- p->curr_minor_hash = pos2min_hash(pos);
++ p->curr_hash = pos2maj_hash(sb, pos);
++ p->curr_minor_hash = pos2min_hash(sb, pos);
+ return p;
+ }
+
+@@ -426,7 +440,7 @@
+ "null fname?!?\n");
+ return 0;
+ }
+- curr_pos = hash2pos(fname->hash, fname->minor_hash);
++ curr_pos = hash2pos(sb, fname->hash, fname->minor_hash);
+ while (fname) {
+ error = filldir(dirent, fname->name,
+ fname->name_len, curr_pos,
+@@ -451,7 +465,7 @@
+ int ret;
+
+ if (!info) {
+- info = ext4_htree_create_dir_info(filp->f_pos);
++ info = ext4_htree_create_dir_info(inode->i_sb, filp->f_pos);
+ if (!info)
+ return -ENOMEM;
+ filp->private_data = info;
+@@ -465,8 +479,8 @@
+ free_rb_tree_fname(&info->root);
+ info->curr_node = NULL;
+ info->extra_fname = NULL;
+- info->curr_hash = pos2maj_hash(filp->f_pos);
+- info->curr_minor_hash = pos2min_hash(filp->f_pos);
++ info->curr_hash = pos2maj_hash(inode->i_sb, filp->f_pos);
++ info->curr_minor_hash = pos2min_hash(inode->i_sb, filp->f_pos);
+ }
+
+ /*
+Index: linux-stage/fs/ext4/ext4.h
+===================================================================
+--- linux-stage.orig/fs/ext4/ext4.h 2011-03-31 10:35:50.000000000 +0800
++++ linux-stage/fs/ext4/ext4.h 2011-04-01 09:33:58.740267284 +0800
+@@ -785,6 +785,7 @@
+ #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
+ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
+ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
++#define EXT4_MOUNT_64BITHASH 0x4000000 /* export 64-bit name hash */
+ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
+ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
+ #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
+Index: linux-stage/fs/ext4/super.c
+===================================================================
+--- linux-stage.orig/fs/ext4/super.c 2011-03-31 10:35:50.000000000 +0800
++++ linux-stage/fs/ext4/super.c 2011-04-01 09:35:00.251453404 +0800
+@@ -1540,7 +1540,7 @@
+ Opt_inode_readahead_blks, Opt_journal_ioprio,
+ Opt_discard, Opt_nodiscard,
+ Opt_mballoc, Opt_bigendian_extents, Opt_force_over_16tb,
+- Opt_no_mbcache,
++ Opt_no_mbcache, Opt_64bithash,
+ Opt_extents, Opt_noextents,
+ };
+
+@@ -1614,6 +1614,7 @@
+ {Opt_discard, "discard"},
+ {Opt_nodiscard, "nodiscard"},
+ {Opt_no_mbcache, "no_mbcache"},
++ {Opt_64bithash, "64bithash"},
+ {Opt_extents, "extents"},
+ {Opt_noextents, "noextents"},
+ {Opt_err, NULL},
+@@ -2092,6 +2093,9 @@
+ case Opt_no_mbcache:
+ set_opt(sbi->s_mount_opt, NO_MBCACHE);
+ break;
++ case Opt_64bithash:
++ set_opt(sbi->s_mount_opt, 64BITHASH);
++ break;
+ default:
+ ext4_msg(sb, KERN_ERR,
+ "Unrecognized mount option \"%s\" "
Index: linux-stage/fs/ext4/ext4_jbd2.h
===================================================================
---- linux-stage.orig/fs/ext4/ext4_jbd2.h 2011-03-14 16:33:17.087088010 +0800
-+++ linux-stage/fs/ext4/ext4_jbd2.h 2011-03-14 16:42:28.416591789 +0800
+--- linux-stage.orig/fs/ext4/ext4_jbd2.h 2011-04-01 09:35:54.779619166 +0800
++++ linux-stage/fs/ext4/ext4_jbd2.h 2011-04-01 10:55:10.328938378 +0800
@@ -35,6 +35,8 @@
(EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS) \
? 27U : 8U)
* and the superblock, which are already accounted for. */
Index: linux-stage/fs/ext4/ext4_extents.h
===================================================================
---- linux-stage.orig/fs/ext4/ext4_extents.h 2011-03-14 16:33:17.076087785 +0800
-+++ linux-stage/fs/ext4/ext4_extents.h 2011-03-14 16:43:08.254267525 +0800
+--- linux-stage.orig/fs/ext4/ext4_extents.h 2011-04-01 09:35:55.688621923 +0800
++++ linux-stage/fs/ext4/ext4_extents.h 2011-04-01 09:35:57.573627638 +0800
@@ -58,6 +58,12 @@
*/
#define EXT_STATS_
struct ext4_extent *ex2);
Index: linux-stage/fs/ext4/mballoc.c
===================================================================
---- linux-stage.orig/fs/ext4/mballoc.c 2011-03-14 16:33:27.072292006 +0800
-+++ linux-stage/fs/ext4/mballoc.c 2011-03-14 16:41:02.500138039 +0800
+--- linux-stage.orig/fs/ext4/mballoc.c 2011-04-01 09:35:57.382627058 +0800
++++ linux-stage/fs/ext4/mballoc.c 2011-04-01 10:55:08.194931915 +0800
@@ -4039,6 +4039,7 @@
if (ac)
kmem_cache_free(ext4_ac_cachep, ac);
+
Index: linux-stage/fs/ext4/super.c
===================================================================
---- linux-stage.orig/fs/ext4/super.c 2011-03-14 16:33:17.036086967 +0800
-+++ linux-stage/fs/ext4/super.c 2011-03-14 16:41:14.964348396 +0800
+--- linux-stage.orig/fs/ext4/super.c 2011-04-01 09:35:57.207626528 +0800
++++ linux-stage/fs/ext4/super.c 2011-04-01 10:57:29.490360042 +0800
@@ -127,6 +127,7 @@
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
-@@ -1491,6 +1492,7 @@
+@@ -1486,11 +1487,13 @@
+ Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
+ Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
+ Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
++ Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
+ 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,
Opt_discard, Opt_nodiscard,
};
static const match_table_t tokens = {
-@@ -1557,6 +1559,7 @@
+@@ -1542,6 +1545,9 @@
+ {Opt_noquota, "noquota"},
+ {Opt_quota, "quota"},
+ {Opt_usrquota, "usrquota"},
++ {Opt_iopen, "iopen"},
++ {Opt_noiopen, "noiopen"},
++ {Opt_iopen_nopriv, "iopen_nopriv"},
+ {Opt_barrier, "barrier=%u"},
+ {Opt_barrier, "barrier"},
+ {Opt_nobarrier, "nobarrier"},
+@@ -1557,6 +1563,7 @@
{Opt_auto_da_alloc, "auto_da_alloc=%u"},
{Opt_auto_da_alloc, "auto_da_alloc"},
{Opt_noauto_da_alloc, "noauto_da_alloc"},
{Opt_discard, "discard"},
{Opt_nodiscard, "nodiscard"},
{Opt_err, NULL},
-@@ -1997,6 +2000,8 @@
+@@ -1914,6 +1921,10 @@
+ else
+ clear_opt(sbi->s_mount_opt, BARRIER);
+ break;
++ case Opt_iopen:
++ case Opt_noiopen:
++ case Opt_iopen_nopriv:
++ break;
+ case Opt_ignore:
+ break;
+ case Opt_resize:
+@@ -1997,6 +2008,8 @@
case Opt_nodiscard:
clear_opt(sbi->s_mount_opt, DISCARD);
break;
"Unrecognized mount option \"%s\" "
Index: linux-stage/fs/ext4/ext4_jbd2.c
===================================================================
---- linux-stage.orig/fs/ext4/ext4_jbd2.c 2011-03-14 16:33:17.049087232 +0800
-+++ linux-stage/fs/ext4/ext4_jbd2.c 2011-03-14 16:34:39.849759386 +0800
+--- linux-stage.orig/fs/ext4/ext4_jbd2.c 2011-04-01 09:35:54.145617245 +0800
++++ linux-stage/fs/ext4/ext4_jbd2.c 2011-04-01 09:35:57.678627955 +0800
@@ -31,6 +31,7 @@
}
return err;
+EXPORT_SYMBOL(__ext4_handle_dirty_metadata);
Index: linux-stage/fs/ext4/ext4.h
===================================================================
---- linux-stage.orig/fs/ext4/ext4.h 2011-03-14 16:33:17.056087375 +0800
-+++ linux-stage/fs/ext4/ext4.h 2011-03-14 16:45:40.754870806 +0800
+--- linux-stage.orig/fs/ext4/ext4.h 2011-04-01 09:35:57.349626959 +0800
++++ linux-stage/fs/ext4/ext4.h 2011-04-01 10:55:17.605960429 +0800
@@ -1110,6 +1110,9 @@
#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
struct buffer_head *bh, ext4_fsblk_t blocknr);
Index: linux-stage/fs/ext4/inode.c
===================================================================
---- linux-stage.orig/fs/ext4/inode.c 2011-03-14 16:33:17.063087519 +0800
-+++ linux-stage/fs/ext4/inode.c 2011-03-14 16:34:39.913760434 +0800
+--- linux-stage.orig/fs/ext4/inode.c 2011-04-01 09:35:55.884622516 +0800
++++ linux-stage/fs/ext4/inode.c 2011-04-01 09:35:57.750628175 +0800
@@ -5199,6 +5199,7 @@
iget_failed(inode);
return ERR_PTR(ret);
struct ext4_inode *raw_inode,
Index: linux-stage/fs/ext4/extents.c
===================================================================
---- linux-stage.orig/fs/ext4/extents.c 2011-03-14 16:33:17.070087661 +0800
-+++ linux-stage/fs/ext4/extents.c 2011-03-14 16:41:04.894178430 +0800
+--- linux-stage.orig/fs/ext4/extents.c 2011-04-01 09:35:55.753622118 +0800
++++ linux-stage/fs/ext4/extents.c 2011-04-01 10:55:10.320938356 +0800
@@ -1866,9 +1866,7 @@
while (block < last && block != EXT_MAX_BLOCK) {
num = last - block;