diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2015-04-08 21:42:49 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-04-11 09:11:15 +0000 |
commit | 4797cb1c9dbf3910952f9d28d8272ff83cd25e7b (patch) | |
tree | 8efcdc1b2057166fcd53101824d64a05f095aead /xlators/cluster/ec/src/ec-dir-read.c | |
parent | af569aaf6ee69ed77be8afc82b4c496041a7bd1b (diff) |
cluster/ec: Fix readdir de-itransform
Problem:
gf_deitransform returns the glbal client-id in the complete graph. So except
for the first disperse subvolume under dht, all the other disperse subvolumes
will return a client-id greater than ec->nodes, so readdir will always error
out in those subvolumes.
Fix:
Get the client subvolume whose client-id matches the client-id returned by
gf_deitransform of offset.
Change-Id: I26aa17504352d48d7ff14b390b62f49d7ab2d699
BUG: 1209113
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/10165
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
Diffstat (limited to 'xlators/cluster/ec/src/ec-dir-read.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-dir-read.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/xlators/cluster/ec/src/ec-dir-read.c b/xlators/cluster/ec/src/ec-dir-read.c index 17e1a3d124e..ffc3ed5a7cd 100644 --- a/xlators/cluster/ec/src/ec-dir-read.c +++ b/xlators/cluster/ec/src/ec-dir-read.c @@ -296,6 +296,30 @@ out: } } +/* Returns -1 if client_id is invalid else index of child subvol in xl_list */ +int +ec_deitransform (xlator_t *this, off_t offset) +{ + int idx = -1; + int client_id = -1; + ec_t *ec = this->private; + char id[32] = {0}; + + client_id = gf_deitransform (this, offset); + sprintf (id, "%d", client_id); + if (dict_get_int32 (ec->leaf_to_subvolid, id, &idx)) { + idx = -1; + goto out; + } + +out: + if (idx < 0) { + gf_log (this->name, GF_LOG_ERROR, + "Invalid index %d in readdirp request", client_id); + } + return idx; +} + /* FOP: readdir */ void ec_adjust_readdir(ec_t * ec, int32_t idx, gf_dirent_t * entries) @@ -412,17 +436,11 @@ int32_t ec_manager_readdir(ec_fop_data_t * fop, int32_t state) if (fop->offset != 0) { int32_t idx = -1; - ec_t *ec = fop->xl->private; - - idx = gf_deitransform(fop->xl, fop->offset); - if ((idx < 0) || (idx >= ec->nodes)) { - - gf_log(fop->xl->name, GF_LOG_ERROR, - "Invalid index %d in readdirp request", idx); + idx = ec_deitransform (fop->xl, fop->offset); + if (idx < 0) { fop->error = EIO; - return EC_STATE_REPORT; } fop->mask &= 1ULL << idx; |