#include #include /* * Robert Jenkin's hash function. * http://burtleburtle.net/bob/hash/evahash.html * This is in the public domain. */ #define mix(a, b, c) \ do { \ a = a - b; a = a - c; a = a ^ (c >> 13); \ b = b - c; b = b - a; b = b ^ (a << 8); \ c = c - a; c = c - b; c = c ^ (b >> 13); \ a = a - b; a = a - c; a = a ^ (c >> 12); \ b = b - c; b = b - a; b = b ^ (a << 16); \ c = c - a; c = c - b; c = c ^ (b >> 5); \ a = a - b; a = a - c; a = a ^ (c >> 3); \ b = b - c; b = b - a; b = b ^ (a << 10); \ c = c - a; c = c - b; c = c ^ (b >> 15); \ } while (0) unsigned int ceph_str_hash_rjenkins(const char *str, unsigned int length) { const unsigned char *k = (const unsigned char *)str; __u32 a, b, c; /* the internal state */ __u32 len; /* how many key bytes still need mixing */ /* Set up the internal state */ len = length; a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ b = a; c = 0; /* variable initialization of internal state */ /* handle most of the key */ while (len >= 12) { a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) + ((__u32)k[3] << 24)); b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) + ((__u32)k[7] << 24)); c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) + ((__u32)k[11] << 24)); mix(a, b, c); k = k + 12; len = len - 12; } /* handle the last 11 bytes */ c = c + length; switch (len) { /* all the case statements fall through */ case 11: c = c + ((__u32)k[10] << 24); case 10: c = c + ((__u32)k[9] << 16); case 9: c = c + ((__u32)k[8] << 8); /* the first byte of c is reserved for the length */ case 8: b = b + ((__u32)k[7] << 24); case 7: b = b + ((__u32)k[6] << 16); case 6: b = b + ((__u32)k[5] << 8); case 5: b = b + k[4]; case 4: a = a + ((__u32)k[3] << 24); case 3: a = a + ((__u32)k[2] << 16); case 2: a = a + ((__u32)k[1] << 8); case 1: a = a + k[0]; /* case 0: nothing left to add */ } mix(a, b, c); return c; } /* * linux dcache hash */ unsigned int ceph_str_hash_linux(const char *str, unsigned int length) { unsigned long hash = 0; unsigned char c; while (length--) { c = *str++; hash = (hash + (c << 4) + (c >> 4)) * 11; } return hash; } unsigned int ceph_str_hash(int type, const char *s, unsigned int len) { switch (type) { case CEPH_STR_HASH_LINUX: return ceph_str_hash_linux(s, len); case CEPH_STR_HASH_RJENKINS: return ceph_str_hash_rjenkins(s, len); default: return -1; } } EXPORT_SYMBOL(ceph_str_hash); const char *ceph_str_hash_name(int type) { switch (type) { case CEPH_STR_HASH_LINUX: return "linux"; case CEPH_STR_HASH_RJENKINS: return "rjenkins"; default: return "unknown"; } } EXPORT_SYMBOL(ceph_str_hash_name); >1space:mode:
authorNeilBrown <neilb@suse.com>2016-10-28 15:59:41 +1100
committerShaohua Li <shli@fb.com>2016-10-28 22:04:05 -0700
commit1217e1d1999ed6c9c1e1b1acae0a74ab70464ae2 (patch)
tree39aa59e668a1a4746bcdaecc0516eb342581008d
parent7449f699b2fb23bdee0a0f03aa4efb5f96fd403f (diff)
md: be careful not lot leak internal curr_resync value into metadata. -- (all)
mddev->curr_resync usually records where the current resync is up to, but during the starting phase it has some "magic" values. 1 - means that the array is trying to start a resync, but has yielded to another array which shares physical devices, and also needs to start a resync 2 - means the array is trying to start resync, but has found another array which shares physical devices and has already started resync. 3 - means that resync has commensed, but it is possible that nothing has actually been resynced yet. It is important that this value not be visible to user-space and particularly that it doesn't get written to the metadata, as the resync or recovery checkpoint. In part, this is because it may be slightly higher than the correct value, though this is very rare. In part, because it is not a multiple of 4K, and some devices only support 4K aligned accesses. There are two places where this value is propagates into either ->curr_resync_completed or ->recovery_cp or ->recovery_offset. These currently avoid the propagation of values 1 and 3, but will allow 3 to leak through. Change them to only propagate the value if it is > 3. As this can cause an array to fail, the patch is suitable for -stable. Cc: stable@vger.kernel.org (v3.7+) Reported-by: Viswesh <viswesh.vichu@gmail.com> Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>