forked from luck/tmp_suning_uos_patched
cfbbcd24a6
We were using the (weak) dcache hash function, but it was leaving lower bits consecutive for consecutive (inode) objects. We really want to make the object to pg mapping random and uniform, so use a proper hash function here. This is Robert Jenkin's public domain hash function (with some minor cleanup): http://burtleburtle.net/bob/hash/evahash.html This is a protocol revision. Signed-off-by: Sage Weil <sage@newdream.net>
152 lines
3.8 KiB
C
152 lines
3.8 KiB
C
/*
|
|
* Some non-inline ceph helpers
|
|
*/
|
|
#include "types.h"
|
|
|
|
/*
|
|
* return true if @layout appears to be valid
|
|
*/
|
|
int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
|
|
{
|
|
__u32 su = le32_to_cpu(layout->fl_stripe_unit);
|
|
__u32 sc = le32_to_cpu(layout->fl_stripe_count);
|
|
__u32 os = le32_to_cpu(layout->fl_object_size);
|
|
|
|
/* stripe unit, object size must be non-zero, 64k increment */
|
|
if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1)))
|
|
return 0;
|
|
if (!os || (os & (CEPH_MIN_STRIPE_UNIT-1)))
|
|
return 0;
|
|
/* object size must be a multiple of stripe unit */
|
|
if (os < su || os % su)
|
|
return 0;
|
|
/* stripe count must be non-zero */
|
|
if (!sc)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
int ceph_flags_to_mode(int flags)
|
|
{
|
|
#ifdef O_DIRECTORY /* fixme */
|
|
if ((flags & O_DIRECTORY) == O_DIRECTORY)
|
|
return CEPH_FILE_MODE_PIN;
|
|
#endif
|
|
#ifdef O_LAZY
|
|
if (flags & O_LAZY)
|
|
return CEPH_FILE_MODE_LAZY;
|
|
#endif
|
|
if ((flags & O_APPEND) == O_APPEND)
|
|
flags |= O_WRONLY;
|
|
|
|
flags &= O_ACCMODE;
|
|
if ((flags & O_RDWR) == O_RDWR)
|
|
return CEPH_FILE_MODE_RDWR;
|
|
if ((flags & O_WRONLY) == O_WRONLY)
|
|
return CEPH_FILE_MODE_WR;
|
|
return CEPH_FILE_MODE_RD;
|
|
}
|
|
|
|
int ceph_caps_for_mode(int mode)
|
|
{
|
|
switch (mode) {
|
|
case CEPH_FILE_MODE_PIN:
|
|
return CEPH_CAP_PIN;
|
|
case CEPH_FILE_MODE_RD:
|
|
return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
|
|
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE;
|
|
case CEPH_FILE_MODE_RDWR:
|
|
return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
|
|
CEPH_CAP_FILE_EXCL |
|
|
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE |
|
|
CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
|
|
CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
|
|
CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
|
|
case CEPH_FILE_MODE_WR:
|
|
return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
|
|
CEPH_CAP_FILE_EXCL |
|
|
CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
|
|
CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
|
|
CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* 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_full_name_hash(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;
|
|
}
|
|
|