-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\" "