hash.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Original copy from:
  3. * linux/fs/ext3/hash.c
  4. *
  5. * Copyright (C) 2002 by Theodore Ts'o
  6. *
  7. * This file is released under the GPL v2.
  8. *
  9. * This file may be redistributed under the terms of the GNU Public
  10. * License.
  11. */
  12. #include <linux/types.h>
  13. #include "hash.h"
  14. #define DELTA 0x9E3779B9
  15. static void TEA_transform(__u32 buf[2], __u32 const in[])
  16. {
  17. __u32 sum = 0;
  18. __u32 b0 = buf[0], b1 = buf[1];
  19. __u32 a = in[0], b = in[1], c = in[2], d = in[3];
  20. int n = 16;
  21. do {
  22. sum += DELTA;
  23. b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
  24. b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
  25. } while(--n);
  26. buf[0] += b0;
  27. buf[1] += b1;
  28. }
  29. static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
  30. {
  31. __u32 pad, val;
  32. int i;
  33. pad = (__u32)len | ((__u32)len << 8);
  34. pad |= pad << 16;
  35. val = pad;
  36. if (len > num*4)
  37. len = num * 4;
  38. for (i=0; i < len; i++) {
  39. if ((i % 4) == 0)
  40. val = pad;
  41. val = msg[i] + (val << 8);
  42. if ((i % 4) == 3) {
  43. *buf++ = val;
  44. val = pad;
  45. num--;
  46. }
  47. }
  48. if (--num >= 0)
  49. *buf++ = val;
  50. while (--num >= 0)
  51. *buf++ = pad;
  52. }
  53. int btrfs_name_hash(const char *name, int len, u64 *hash_result)
  54. {
  55. __u32 hash;
  56. __u32 minor_hash = 0;
  57. const char *p;
  58. __u32 in[8], buf[2];
  59. if (len == 1 && *name == '.') {
  60. *hash_result = 1;
  61. return 0;
  62. } else if (len == 2 && name[0] == '.' && name[1] == '.') {
  63. *hash_result = 2;
  64. return 0;
  65. }
  66. /* Initialize the default seed for the hash checksum functions */
  67. buf[0] = 0x67452301;
  68. buf[1] = 0xefcdab89;
  69. buf[2] = 0x98badcfe;
  70. buf[3] = 0x10325476;
  71. p = name;
  72. while (len > 0) {
  73. str2hashbuf(p, len, in, 4);
  74. TEA_transform(buf, in);
  75. len -= 16;
  76. p += 16;
  77. }
  78. hash = buf[0];
  79. minor_hash = buf[1];
  80. *hash_result = buf[0];
  81. *hash_result <<= 32;
  82. *hash_result |= buf[1];
  83. return 0;
  84. }