hash.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright (C) 2007 Oracle. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License v2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public
  14. * License along with this program; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 021110-1307, USA.
  17. */
  18. /*
  19. * Original copy from:
  20. * linux/fs/ext3/hash.c
  21. *
  22. * Copyright (C) 2002 by Theodore Ts'o
  23. *
  24. * This file is released under the GPL v2.
  25. *
  26. * This file may be redistributed under the terms of the GNU Public
  27. * License.
  28. */
  29. #include <linux/types.h>
  30. #include "hash.h"
  31. #define DELTA 0x9E3779B9
  32. static void TEA_transform(__u32 buf[2], __u32 const in[])
  33. {
  34. __u32 sum = 0;
  35. __u32 b0 = buf[0], b1 = buf[1];
  36. __u32 a = in[0], b = in[1], c = in[2], d = in[3];
  37. int n = 16;
  38. do {
  39. sum += DELTA;
  40. b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
  41. b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
  42. } while(--n);
  43. buf[0] += b0;
  44. buf[1] += b1;
  45. }
  46. static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
  47. {
  48. __u32 pad, val;
  49. int i;
  50. pad = (__u32)len | ((__u32)len << 8);
  51. pad |= pad << 16;
  52. val = pad;
  53. if (len > num*4)
  54. len = num * 4;
  55. for (i=0; i < len; i++) {
  56. if ((i % 4) == 0)
  57. val = pad;
  58. val = msg[i] + (val << 8);
  59. if ((i % 4) == 3) {
  60. *buf++ = val;
  61. val = pad;
  62. num--;
  63. }
  64. }
  65. if (--num >= 0)
  66. *buf++ = val;
  67. while (--num >= 0)
  68. *buf++ = pad;
  69. }
  70. u64 btrfs_name_hash(const char *name, int len)
  71. {
  72. __u32 hash;
  73. __u32 minor_hash = 0;
  74. const char *p;
  75. __u32 in[8], buf[4];
  76. u64 hash_result;
  77. if (len == 1 && *name == '.') {
  78. return 1;
  79. } else if (len == 2 && name[0] == '.' && name[1] == '.') {
  80. return 2;
  81. }
  82. /* Initialize the default seed for the hash checksum functions */
  83. buf[0] = 0x67452301;
  84. buf[1] = 0xefcdab89;
  85. buf[2] = 0x98badcfe;
  86. buf[3] = 0x10325476;
  87. p = name;
  88. while (len > 0) {
  89. str2hashbuf(p, len, in, 4);
  90. TEA_transform(buf, in);
  91. len -= 16;
  92. p += 16;
  93. }
  94. hash = buf[0];
  95. minor_hash = buf[1];
  96. hash_result = buf[0];
  97. hash_result <<= 32;
  98. hash_result |= buf[1];
  99. return hash_result;
  100. }