[kernel] r12360 - in dists/sid/linux-2.6/debian: . patches/bugfix/all patches/series
Martin Michlmayr
tbm at alioth.debian.org
Wed Oct 29 06:27:35 UTC 2008
Author: tbm
Date: Wed Oct 29 06:27:33 2008
New Revision: 12360
Log:
ext3/ext4: Add support for non-native signed/unsigned htree hash
algorithms (Theodore Ts'o). (closes: 493957)
Added:
dists/sid/linux-2.6/debian/patches/bugfix/all/ext3-add-support-for-non-native-signed-unsigned-htr.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/ext4-add-support-for-non-native-signed-unsigned-htr.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/10
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog (original)
+++ dists/sid/linux-2.6/debian/changelog Wed Oct 29 06:27:33 2008
@@ -5,6 +5,8 @@
[ Martin Michlmayr ]
* DNS-323: add support for revision B1 machines (Matthew Palmer).
+ * ext3/ext4: Add support for non-native signed/unsigned htree hash
+ algorithms (Theodore Ts'o). (closes: 493957)
[ Bastian Blank ]
* agp: Fix stolen memory counting on Intel G4X. (closes: #502606)
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/ext3-add-support-for-non-native-signed-unsigned-htr.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/ext3-add-support-for-non-native-signed-unsigned-htr.patch Wed Oct 29 06:27:33 2008
@@ -0,0 +1,230 @@
+From: Theodore Ts'o <tytso at mit.edu>
+Date: Mon, 20 Oct 2008 23:16:21 -0400
+Subject: [PATCH] ext3: Add support for non-native signed/unsigned htree hash algorithms
+
+The original ext3 hash algorithms assumed that variables of type char
+were signed, as God and K&R intended. Unfortunately, this assumption
+is not true on some architectures. Userspace support for marking
+filesystems with non-native signed/unsigned chars was added two years
+ago, but the kernel-side support was never added (until now).
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+
+diff -urN a/fs/ext3/hash.c b/fs/ext3/hash.c
+--- a/fs/ext3/hash.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext3/hash.c 2008-10-28 19:44:22.000000000 +0000
+@@ -35,11 +35,20 @@
+
+
+ /* The old legacy hash */
+-static __u32 dx_hack_hash (const char *name, int len)
++static __u32 dx_hack_hash (const char *name, int len, int unsigned_flag)
+ {
+- __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++ __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++ const unsigned char *ucp = (const unsigned char *) name;
++ const signed char *scp = (const signed char *) name;
++ int c;
++
+ while (len--) {
+- __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++ if (unsigned_flag)
++ c = (int) *ucp++;
++ else
++ c = (int) *scp++;
++
++ hash = hash1 + (hash0 ^ (c * 7152373));
+
+ if (hash & 0x80000000) hash -= 0x7fffffff;
+ hash1 = hash0;
+@@ -48,10 +57,13 @@
+ return (hash0 << 1);
+ }
+
+-static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num,
++ int unsigned_flag)
+ {
+ __u32 pad, val;
+- int i;
++ int i, c;
++ const unsigned char *ucp = (const unsigned char *) msg;
++ const signed char *scp = (const signed char *) msg;
+
+ pad = (__u32)len | ((__u32)len << 8);
+ pad |= pad << 16;
+@@ -62,7 +74,12 @@
+ for (i=0; i < len; i++) {
+ if ((i % 4) == 0)
+ val = pad;
+- val = msg[i] + (val << 8);
++ if (unsigned_flag)
++ c = (int) ucp[i];
++ else
++ c = (int) scp[i];
++
++ val = c + (val << 8);
+ if ((i % 4) == 3) {
+ *buf++ = val;
+ val = pad;
+@@ -95,6 +112,7 @@
+ const char *p;
+ int i;
+ __u32 in[8], buf[4];
++ int unsigned_flag = 0;
+
+ /* Initialize the default seed for the hash checksum functions */
+ buf[0] = 0x67452301;
+@@ -113,13 +131,17 @@
+ }
+
+ switch (hinfo->hash_version) {
++ case DX_HASH_LEGACY_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_LEGACY:
+- hash = dx_hack_hash(name, len);
++ hash = dx_hack_hash(name, len, unsigned_flag);
+ break;
++ case DX_HASH_HALF_MD4_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_HALF_MD4:
+ p = name;
+ while (len > 0) {
+- str2hashbuf(p, len, in, 8);
++ str2hashbuf(p, len, in, 8, unsigned_flag);
+ half_md4_transform(buf, in);
+ len -= 32;
+ p += 32;
+@@ -127,10 +149,12 @@
+ minor_hash = buf[2];
+ hash = buf[1];
+ break;
++ case DX_HASH_TEA_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_TEA:
+ p = name;
+ while (len > 0) {
+- str2hashbuf(p, len, in, 4);
++ str2hashbuf(p, len, in, 4, unsigned_flag);
+ TEA_transform(buf, in);
+ len -= 16;
+ p += 16;
+diff -urN a/fs/ext3/namei.c b/fs/ext3/namei.c
+--- a/fs/ext3/namei.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext3/namei.c 2008-10-28 19:44:22.000000000 +0000
+@@ -369,6 +369,8 @@
+ goto fail;
+ }
+ hinfo->hash_version = root->info.hash_version;
++ if (hinfo->hash_version <= DX_HASH_TEA)
++ hinfo->hash_version += EXT3_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo->seed = EXT3_SB(dir->i_sb)->s_hash_seed;
+ if (dentry)
+ ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
+@@ -637,6 +639,9 @@
+ dir = dir_file->f_path.dentry->d_inode;
+ if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) {
+ hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version;
++ if (hinfo.hash_version <= DX_HASH_TEA)
++ hinfo.hash_version +=
++ EXT3_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed;
+ count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
+ start_hash, start_minor_hash);
+@@ -1413,6 +1418,8 @@
+
+ /* Initialize as for dx_probe */
+ hinfo.hash_version = root->info.hash_version;
++ if (hinfo.hash_version <= DX_HASH_TEA)
++ hinfo.hash_version += EXT3_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed;
+ ext3fs_dirhash(name, namelen, &hinfo);
+ frame = frames;
+diff -urN a/fs/ext3/super.c b/fs/ext3/super.c
+--- a/fs/ext3/super.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext3/super.c 2008-10-28 19:44:22.000000000 +0000
+@@ -1712,6 +1712,21 @@
+ for (i=0; i < 4; i++)
+ sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+ sbi->s_def_hash_version = es->s_def_hash_version;
++ i = le32_to_cpu(es->s_flags);
++ if (i & EXT2_FLAGS_UNSIGNED_HASH)
++ sbi->s_hash_unsigned = 3;
++ else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
++ char c;
++
++ c = (char) 255;
++ if (((int) c) == -1) {
++ es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
++ } else {
++ es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
++ sbi->s_hash_unsigned = 3;
++ }
++ sb->s_dirt = 1;
++ }
+
+ if (sbi->s_blocks_per_group > blocksize * 8) {
+ printk (KERN_ERR
+diff -urN a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
+--- a/include/linux/ext3_fs.h 2008-10-28 19:43:42.000000000 +0000
++++ b/include/linux/ext3_fs.h 2008-10-28 19:44:22.000000000 +0000
+@@ -354,6 +354,13 @@
+ #define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */
+
+ /*
++ * Misc. filesystem flags
++ */
++#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */
++#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */
++#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */
++
++/*
+ * Mount flags
+ */
+ #define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */
+@@ -487,7 +494,23 @@
+ __u16 s_reserved_word_pad;
+ __le32 s_default_mount_opts;
+ __le32 s_first_meta_bg; /* First metablock block group */
+- __u32 s_reserved[190]; /* Padding to the end of the block */
++ __le32 s_mkfs_time; /* When the filesystem was created */
++ __le32 s_jnl_blocks[17]; /* Backup of the journal inode */
++ /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
++/*150*/ __le32 s_blocks_count_hi; /* Blocks count */
++ __le32 s_r_blocks_count_hi; /* Reserved blocks count */
++ __le32 s_free_blocks_count_hi; /* Free blocks count */
++ __le16 s_min_extra_isize; /* All inodes have at least # bytes */
++ __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 */
++ __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 */
++ __u8 s_reserved_char_pad2;
++ __le16 s_reserved_pad;
++ __u32 s_reserved[162]; /* Padding to the end of the block */
+ };
+
+ #ifdef __KERNEL__
+@@ -692,6 +715,9 @@
+ #define DX_HASH_LEGACY 0
+ #define DX_HASH_HALF_MD4 1
+ #define DX_HASH_TEA 2
++#define DX_HASH_LEGACY_UNSIGNED 3
++#define DX_HASH_HALF_MD4_UNSIGNED 4
++#define DX_HASH_TEA_UNSIGNED 5
+
+ #ifdef __KERNEL__
+
+diff -urN a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
+--- a/include/linux/ext3_fs_sb.h 2008-10-28 19:43:42.000000000 +0000
++++ b/include/linux/ext3_fs_sb.h 2008-10-28 19:44:22.000000000 +0000
+@@ -57,6 +57,7 @@
+ u32 s_next_generation;
+ u32 s_hash_seed[4];
+ int s_def_hash_version;
++ int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */
+ struct percpu_counter s_freeblocks_counter;
+ struct percpu_counter s_freeinodes_counter;
+ struct percpu_counter s_dirs_counter;
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/ext4-add-support-for-non-native-signed-unsigned-htr.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/ext4-add-support-for-non-native-signed-unsigned-htr.patch Wed Oct 29 06:27:33 2008
@@ -0,0 +1,191 @@
+From: Theodore Ts'o <tytso at mit.edu>
+Date: Mon, 20 Oct 2008 22:57:37 -0400
+Subject: [PATCH] ext4: Add support for non-native signed/unsigned htree hash algorithms
+
+The original ext3 hash algorithms assumed that variables of type char
+were signed, as God and K&R intended. Unfortunately, this assumption
+is not true on some architectures. Userspace support for marking
+filesystems with non-native signed/unsigned chars was added two years
+ago, but the kernel-side support was never added (until now).
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+
+diff -urN a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+--- a/fs/ext4/ext4.h 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext4/ext4.h 2008-10-28 19:48:22.000000000 +0000
+@@ -872,6 +872,9 @@
+ #define DX_HASH_LEGACY 0
+ #define DX_HASH_HALF_MD4 1
+ #define DX_HASH_TEA 2
++#define DX_HASH_LEGACY_UNSIGNED 3
++#define DX_HASH_HALF_MD4_UNSIGNED 4
++#define DX_HASH_TEA_UNSIGNED 5
+
+ #ifdef __KERNEL__
+
+diff -urN a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h
+--- a/fs/ext4/ext4_sb.h 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext4/ext4_sb.h 2008-10-28 19:48:22.000000000 +0000
+@@ -56,6 +56,7 @@
+ u32 s_next_generation;
+ u32 s_hash_seed[4];
+ int s_def_hash_version;
++ int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */
+ struct percpu_counter s_freeblocks_counter;
+ struct percpu_counter s_freeinodes_counter;
+ struct percpu_counter s_dirs_counter;
+diff -urN a/fs/ext4/hash.c b/fs/ext4/hash.c
+--- a/fs/ext4/hash.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext4/hash.c 2008-10-28 19:59:19.000000000 +0000
+@@ -35,11 +35,20 @@
+
+
+ /* The old legacy hash */
+-static __u32 dx_hack_hash (const char *name, int len)
++static __u32 dx_hack_hash(const char *name, int len, int unsigned_flag)
+ {
+- __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++ __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
++ const unsigned char *ucp = (const unsigned char *) name;
++ const signed char *scp = (const signed char *) name;
++ int c;
++
+ while (len--) {
+- __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
++ if (unsigned_flag)
++ c = (int) *ucp++;
++ else
++ c = (int) *scp++;
++
++ hash = hash1 + (hash0 ^ (c * 7152373));
+
+ if (hash & 0x80000000) hash -= 0x7fffffff;
+ hash1 = hash0;
+@@ -48,10 +57,13 @@
+ return (hash0 << 1);
+ }
+
+-static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
++static void str2hashbuf(const char *msg, int len, __u32 *buf, int num,
++ int unsigned_flag)
+ {
+ __u32 pad, val;
+- int i;
++ int i, c;
++ const unsigned char *ucp = (const unsigned char *) msg;
++ const signed char *scp = (const signed char *) msg;
+
+ pad = (__u32)len | ((__u32)len << 8);
+ pad |= pad << 16;
+@@ -62,7 +74,12 @@
+ for (i=0; i < len; i++) {
+ if ((i % 4) == 0)
+ val = pad;
+- val = msg[i] + (val << 8);
++ if (unsigned_flag)
++ c = (int) ucp[i];
++ else
++ c = (int) scp[i];
++
++ val = c + (val << 8);
+ if ((i % 4) == 3) {
+ *buf++ = val;
+ val = pad;
+@@ -95,6 +112,7 @@
+ const char *p;
+ int i;
+ __u32 in[8], buf[4];
++ int unsigned_flag = 0;
+
+ /* Initialize the default seed for the hash checksum functions */
+ buf[0] = 0x67452301;
+@@ -113,13 +131,17 @@
+ }
+
+ switch (hinfo->hash_version) {
++ case DX_HASH_LEGACY_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_LEGACY:
+- hash = dx_hack_hash(name, len);
++ hash = dx_hack_hash(name, len, unsigned_flag);
+ break;
++ case DX_HASH_HALF_MD4_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_HALF_MD4:
+ p = name;
+ while (len > 0) {
+- str2hashbuf(p, len, in, 8);
++ str2hashbuf(p, len, in, 8, unsigned_flag);
+ half_md4_transform(buf, in);
+ len -= 32;
+ p += 32;
+@@ -127,10 +149,12 @@
+ minor_hash = buf[2];
+ hash = buf[1];
+ break;
++ case DX_HASH_TEA_UNSIGNED:
++ unsigned_flag++;
+ case DX_HASH_TEA:
+ p = name;
+ while (len > 0) {
+- str2hashbuf(p, len, in, 4);
++ str2hashbuf(p, len, in, 4, unsigned_flag);
+ TEA_transform(buf, in);
+ len -= 16;
+ p += 16;
+diff -urN a/fs/ext4/namei.c b/fs/ext4/namei.c
+--- a/fs/ext4/namei.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext4/namei.c 2008-10-28 19:48:22.000000000 +0000
+@@ -361,6 +361,8 @@
+ goto fail;
+ }
+ hinfo->hash_version = root->info.hash_version;
++ if (hinfo->hash_version <= DX_HASH_TEA)
++ hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+ if (dentry)
+ ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
+@@ -639,6 +641,9 @@
+ dir = dir_file->f_path.dentry->d_inode;
+ if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) {
+ hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
++ if (hinfo.hash_version <= DX_HASH_TEA)
++ hinfo.hash_version +=
++ EXT4_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+ count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
+ start_hash, start_minor_hash);
+@@ -1415,6 +1420,8 @@
+
+ /* Initialize as for dx_probe */
+ hinfo.hash_version = root->info.hash_version;
++ if (hinfo.hash_version <= DX_HASH_TEA)
++ hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
+ hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+ ext4fs_dirhash(name, namelen, &hinfo);
+ frame = frames;
+diff -urN a/fs/ext4/super.c b/fs/ext4/super.c
+--- a/fs/ext4/super.c 2008-10-28 19:43:40.000000000 +0000
++++ b/fs/ext4/super.c 2008-10-28 19:48:22.000000000 +0000
+@@ -2071,6 +2071,21 @@
+ for (i=0; i < 4; i++)
+ sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+ sbi->s_def_hash_version = es->s_def_hash_version;
++ i = le32_to_cpu(es->s_flags);
++ if (i & EXT2_FLAGS_UNSIGNED_HASH)
++ sbi->s_hash_unsigned = 3;
++ else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
++ char c;
++
++ c = (char) 255;
++ if (((int) c) == -1) {
++ es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
++ } else {
++ es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
++ sbi->s_hash_unsigned = 3;
++ }
++ sb->s_dirt = 1;
++ }
+
+ if (sbi->s_blocks_per_group > blocksize * 8) {
+ printk (KERN_ERR
Modified: dists/sid/linux-2.6/debian/patches/series/10
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/10 (original)
+++ dists/sid/linux-2.6/debian/patches/series/10 Wed Oct 29 06:27:33 2008
@@ -1,3 +1,5 @@
+ bugfix/all/sctp-fix-kernel-panic-while-process-protocol-violation-parameter.patch
+ features/arm/dns323_revb1.patch
+ bugfix/all/drivers-char-agp-intel-correct-gm4x-stolen.patch
++ bugfix/all/ext3-add-support-for-non-native-signed-unsigned-htr.patch
++ bugfix/all/ext4-add-support-for-non-native-signed-unsigned-htr.patch
More information about the Kernel-svn-changes
mailing list