X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=ldiskfs%2Fkernel_patches%2Fpatches%2Fext4-export-64bit-name-hash.patch;h=c7e01f417a9f61dfb44dc69a630ce11cf16612c4;hb=96a5daa0c08d7b42ec368080a2a7f0dfb110ef98;hp=e920e4eee93e825b37560061ac7e1f5b721c39c2;hpb=cdb698a1a036870b6c9d8e51f69809c558d4823a;p=fs%2Flustre-release.git diff --git a/ldiskfs/kernel_patches/patches/ext4-export-64bit-name-hash.patch b/ldiskfs/kernel_patches/patches/ext4-export-64bit-name-hash.patch index e920e4e..c7e01f4 100644 --- a/ldiskfs/kernel_patches/patches/ext4-export-64bit-name-hash.patch +++ b/ldiskfs/kernel_patches/patches/ext4-export-64bit-name-hash.patch @@ -1,12 +1,24 @@ -Index: linux-2.6.18-194.17.1-ext4/fs/ext4/dir.c +Index: linux-stage/fs/ext4/dir.c =================================================================== ---- linux-2.6.18-194.17.1-ext4.orig/fs/ext4/dir.c 2010-12-02 16:37:05.000000000 +0300 -+++ linux-2.6.18-194.17.1-ext4/fs/ext4/dir.c 2010-12-16 00:06:49.000000000 +0300 -@@ -245,19 +245,32 @@ out: +--- linux-stage.orig/fs/ext4/dir.c 2011-04-19 01:02:34.000000000 +0800 ++++ linux-stage/fs/ext4/dir.c 2011-04-19 01:24:36.000000000 +0800 +@@ -242,22 +242,50 @@ + return ret; + } + ++static inline int is_32bit_api(void) ++{ ++#ifdef HAVE_IS_COMPAT_TASK ++ return is_compat_task(); ++#else ++ return (BITS_PER_LONG == 32); ++#endif ++} ++ /* * 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 @@ -15,45 +27,50 @@ Index: linux-2.6.18-194.17.1-ext4/fs/ext4/dir.c - * 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. ++ * Up layer (OSD) should specify O_32BITHASH or O_64BITHASH explicitly. ++ * On the other hand, we allow ldiskfs to be mounted directly on both 32-bit ++ * and 64-bit nodes, under such case, neither O_32BITHASH nor O_64BITHASH is ++ * specified. */ -#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) ++static inline loff_t hash2pos(struct file *filp, __u32 major, __u32 minor) +{ -+ if (test_opt(sb, 64BITHASH)) -+ return (((__u64)(major >> 1) << 32) | (__u64)minor); -+ else ++ if ((filp->f_flags & O_32BITHASH) || ++ (!(filp->f_flags & O_64BITHASH) && is_32bit_api())) + return (major >> 1); ++ else ++ return (((__u64)(major >> 1) << 32) | (__u64)minor); +} + -+static inline __u32 pos2maj_hash(struct super_block *sb, loff_t pos) ++static inline __u32 pos2maj_hash(struct file *filp, loff_t pos) +{ -+ if (test_opt(sb, 64BITHASH)) -+ return (((pos >> 32) << 1) & 0xffffffff); -+ else ++ if ((filp->f_flags & O_32BITHASH) || ++ (!(filp->f_flags & O_64BITHASH) && is_32bit_api())) + return ((pos << 1) & 0xffffffff); ++ else ++ return (((pos >> 32) << 1) & 0xffffffff); +} + -+static inline __u32 pos2min_hash(struct super_block *sb, loff_t pos) ++static inline __u32 pos2min_hash(struct file *filp, loff_t pos) +{ -+ if (test_opt(sb, 64BITHASH)) -+ return (pos & 0xffffffff); -+ else ++ if ((filp->f_flags & O_32BITHASH) || ++ (!(filp->f_flags & O_64BITHASH) && is_32bit_api())) + return (0); ++ else ++ return (pos & 0xffffffff); +} /* * This structure holds the nodes of the red-black tree used to store -@@ -318,15 +331,16 @@ static void free_rb_tree_fname(struct rb +@@ -318,15 +346,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) ++static struct dir_private_info * ++ext4_htree_create_dir_info(struct file *filp, loff_t pos) { struct dir_private_info *p; @@ -62,79 +79,56 @@ Index: linux-2.6.18-194.17.1-ext4/fs/ext4/dir.c 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); ++ p->curr_hash = pos2maj_hash(filp, pos); ++ p->curr_minor_hash = pos2min_hash(filp, pos); return p; } -@@ -422,7 +436,7 @@ static int call_filldir(struct file *fil +@@ -422,7 +451,7 @@ "null fname?!?\n"); return 0; } - curr_pos = hash2pos(fname->hash, fname->minor_hash); -+ curr_pos = hash2pos(sb, fname->hash, fname->minor_hash); ++ curr_pos = hash2pos(filp, fname->hash, fname->minor_hash); while (fname) { error = filldir(dirent, fname->name, fname->name_len, curr_pos, -@@ -447,7 +461,7 @@ static int ext4_dx_readdir(struct file * +@@ -447,7 +476,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); ++ info = ext4_htree_create_dir_info(filp, filp->f_pos); if (!info) return -ENOMEM; filp->private_data = info; -@@ -461,8 +475,8 @@ static int ext4_dx_readdir(struct file * +@@ -461,8 +490,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); ++ info->curr_hash = pos2maj_hash(filp, filp->f_pos); ++ info->curr_minor_hash = pos2min_hash(filp, filp->f_pos); } /* -Index: linux-2.6.18-194.17.1-ext4/fs/ext4/ext4.h -=================================================================== ---- linux-2.6.18-194.17.1-ext4.orig/fs/ext4/ext4.h 2010-12-03 11:05:04.000000000 +0300 -+++ linux-2.6.18-194.17.1-ext4/fs/ext4/ext4.h 2010-12-16 00:13:32.000000000 +0300 -@@ -741,6 +741,7 @@ struct ext4_inode_info { - #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-2.6.18-194.17.1-ext4/fs/ext4/super.c +Index: linux-stage/fs/ext4/ext4.h =================================================================== ---- linux-2.6.18-194.17.1-ext4.orig/fs/ext4/super.c 2010-12-02 21:10:39.000000000 +0300 -+++ linux-2.6.18-194.17.1-ext4/fs/ext4/super.c 2010-12-15 23:57:43.000000000 +0300 -@@ -1479,6 +1479,7 @@ enum { - Opt_iopen, Opt_noiopen, Opt_iopen_nopriv, Opt_bigendian_extents, - Opt_force_over_16tb, - Opt_no_mbcache, -+ Opt_64bithash, - }; +--- linux-stage.orig/fs/ext4/ext4.h 2011-04-19 01:02:34.000000000 +0800 ++++ linux-stage/fs/ext4/ext4.h 2011-04-19 01:02:34.000000000 +0800 +@@ -55,6 +55,14 @@ + #define ext4_debug(f, a...) do {} while (0) + #endif - static match_table_t tokens = { -@@ -1552,6 +1553,7 @@ static match_table_t tokens = { - {Opt_bigendian_extents, "bigendian_extents"}, - {Opt_force_over_16tb, "force_over_16tb"}, - {Opt_no_mbcache, "no_mbcache"}, -+ {Opt_64bithash, "64bithash"}, - {Opt_err, NULL}, - }; ++#ifndef O_32BITHASH ++# define O_32BITHASH 0x10000000 ++#endif ++ ++#ifndef O_64BITHASH ++# define O_64BITHASH 0x20000000 ++#endif ++ + #define HAVE_DISK_INODE_VERSION -@@ -2004,6 +2006,9 @@ set_qf_format: - 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\" " + /* data type for block offset of block group */