diff options
| -rw-r--r-- | xlators/cluster/dht/src/dht-helper.c | 87 | 
1 files changed, 82 insertions, 5 deletions
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c index ecd06e394da..9a00fe6481c 100644 --- a/xlators/cluster/dht/src/dht-helper.c +++ b/xlators/cluster/dht/src/dht-helper.c @@ -40,6 +40,43 @@ dht_frame_return (call_frame_t *frame)  } +static uint64_t +dht_bits_for (uint64_t num) +{ +	uint64_t bits = 0, ctrl = 1; + +	while (ctrl < num) { +		ctrl *= 2; +		bits ++; +	} + +	return bits; +} + +/* + * A slightly "updated" version of the algorithm described in the commit log + * is used here. + * + * The only enhancement is that: + * + * - The number of bits used by the backend filesystem for HUGE d_off which + *   is described as 63, and + * - The number of bits used by the d_off presented by the transformation + *   upwards which is described as 64, are both made "configurable." + */ + + +#define BACKEND_D_OFF_BITS 63 +#define PRESENT_D_OFF_BITS 63 + +#define ONE 1ULL +#define MASK (~0ULL) +#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS)) +#define BACKEND_MASK (MASK >> (64 - BACKEND_D_OFF_BITS)) + +#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1)) +#define SHIFT_BITS (max (0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1))) +  int  dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y_p)  { @@ -47,6 +84,9 @@ dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y_p)          int         cnt = 0;          int         max = 0;          uint64_t    y = 0; +        uint64_t    hi_mask = 0; +        uint64_t    off_mask = 0; +        int         max_bits = 0;          if (x == ((uint64_t) -1)) {                  y = (uint64_t) -1; @@ -60,7 +100,23 @@ dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y_p)          max = conf->subvolume_cnt;          cnt = dht_subvol_cnt (this, subvol); -        y = ((x * max) + cnt); +	if (max == 1) { +		y = x; +		goto out; +	} + +        max_bits = dht_bits_for (max); + +        hi_mask = ~(PRESENT_MASK >> (max_bits + 1)); + +        if (x & hi_mask) { +                /* HUGE d_off */ +                off_mask = MASK << max_bits; +                y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | cnt; +        } else { +                /* small d_off */ +                y = ((x * max) + cnt); +        }  out:          if (y_p) @@ -135,16 +191,38 @@ dht_deitransform (xlator_t *this, uint64_t y, xlator_t **subvol_p,          int         max = 0;          uint64_t    x = 0;          xlator_t   *subvol = 0; +        int         max_bits = 0; +        uint64_t    off_mask = 0; +        uint64_t    host_mask = 0;          if (!this->private) -                goto out; +                return -1;          conf = this->private;          max = conf->subvolume_cnt; -        cnt = y % max; -        x   = y / max; +	if (max == 1) { +		x = y; +		cnt = 0; +		goto out; +	} + +        if (y & TOP_BIT) { +                /* HUGE d_off */ +                max_bits = dht_bits_for (max); +                off_mask = (MASK << max_bits); +                host_mask = ~(off_mask); + +                x = ((y & ~TOP_BIT) & off_mask) << SHIFT_BITS; + +                cnt = y & host_mask; +	} else { +                /* small d_off */ +                cnt = y % max; +                x = y / max; +        } +out:          subvol = conf->subvolumes[cnt];          if (subvol_p) @@ -153,7 +231,6 @@ dht_deitransform (xlator_t *this, uint64_t y, xlator_t **subvol_p,          if (x_p)                  *x_p = x; -out:          return 0;  }  | 
