diff options
| -rw-r--r-- | xlators/cluster/ec/src/ec-combine.c | 241 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec.c | 5 | 
2 files changed, 141 insertions, 105 deletions
diff --git a/xlators/cluster/ec/src/ec-combine.c b/xlators/cluster/ec/src/ec-combine.c index f949dbd0c9f..e09381b9f8a 100644 --- a/xlators/cluster/ec/src/ec-combine.c +++ b/xlators/cluster/ec/src/ec-combine.c @@ -22,6 +22,8 @@  #define EC_QUOTA_PREFIX "trusted.glusterfs.quota." +#define EC_MISSING_DATA ((data_t *)1ULL) +  struct _ec_dict_info;  typedef struct _ec_dict_info ec_dict_info_t; @@ -270,35 +272,45 @@ ec_dict_compare (dict_t *dict1, dict_t *dict2)          return 0;  } -int32_t ec_dict_list(data_t ** list, int32_t * count, ec_cbk_data_t * cbk, -                     int32_t which, char * key) +static uint32_t +ec_dict_list(data_t **list, ec_cbk_data_t *cbk, int32_t which, char *key, +             gf_boolean_t global)  { -    ec_cbk_data_t *ans = NULL; -    dict_t *dict = NULL; -    int32_t i, max; - -    max = *count; -    i = 0; -    for (ans = cbk; ans != NULL; ans = ans->next) { -        if (i >= max) { -            gf_msg (cbk->fop->xl->name, GF_LOG_ERROR, EINVAL, -                    EC_MSG_INVALID_DICT_NUMS, -                    "Unexpected number of " -                    "dictionaries"); - -            return -EINVAL; +        ec_t *ec = cbk->fop->xl->private; +        ec_cbk_data_t *ans = NULL; +        dict_t *dict = NULL; +        data_t *data; +        uint32_t count; +        int32_t i; + +        for (i = 0; i < ec->nodes; i++) { +                /* We initialize the list with EC_MISSING_DATA if we are +                 * returning a global list or the current subvolume belongs +                 * to the group of the accepted answer. Note that if some +                 * subvolume is known to be down before issuing the request, +                 * we won't have any answer from it, so we set here the +                 * appropriate default value. */ +                if (global || ((cbk->mask & (1ULL << i)) != 0)) { +                        list[i] = EC_MISSING_DATA; +                } else { +                        list[i] = NULL; +                }          } -        dict = (which == EC_COMBINE_XDATA) ? ans->xdata : ans->dict; -        list[i] = dict_get(dict, key); -        if (list[i] != NULL) { -            i++; +        count = 0; +        list_for_each_entry(ans, &cbk->fop->answer_list, answer_list) { +                if (global || ((cbk->mask & ans->mask) != 0)) { +                        dict = (which == EC_COMBINE_XDATA) ? ans->xdata +                                                           : ans->dict; +                        data = dict_get(dict, key); +                        if (data != NULL) { +                                list[ans->idx] = data; +                                count++; +                        } +                }          } -    } - -    *count = i; -    return 0; +        return count;  }  int32_t ec_concat_prepare(xlator_t *xl, char **str, char **sep, char **post, @@ -337,23 +349,21 @@ out:      return -EINVAL;  } -int32_t ec_dict_data_concat(const char * fmt, ec_cbk_data_t * cbk, -                            int32_t which, char * key, ...) +static int32_t +ec_dict_data_concat(const char *fmt, ec_cbk_data_t *cbk, int32_t which, +                    char *key, const char *def, gf_boolean_t global, ...)  { -    data_t * data[cbk->count]; -    char * str = NULL, * pre = NULL, * sep, * post; -    dict_t * dict; +    ec_t *ec = cbk->fop->xl->private; +    data_t *data[ec->nodes]; +    char *str = NULL, *pre = NULL, *sep, *post; +    dict_t *dict;      va_list args; -    int32_t i, num, len, prelen, postlen, seplen, tmp; +    int32_t i, num, len, deflen, prelen, postlen, seplen, tmp;      int32_t err; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } +    ec_dict_list(data, cbk, which, key, global); -    va_start(args, key); +    va_start(args, global);      err = ec_concat_prepare(cbk->fop->xl, &pre, &sep, &post, fmt, args);      va_end(args); @@ -365,9 +375,29 @@ int32_t ec_dict_data_concat(const char * fmt, ec_cbk_data_t * cbk,      seplen = strlen(sep);      postlen = strlen(post); -    len = prelen + (num - 1) * seplen + postlen + 1; -    for (i = 0; i < num; i++) { -        len += data[i]->len - 1; +    deflen = 0; +    if (def != NULL) { +        deflen = strlen(def); +    } + +    len = prelen + postlen + 1; +    num = -1; +    for (i = 0; i < ec->nodes; i++) { +        if (data[i] == NULL) { +            continue; +        } +        if (data[i] == EC_MISSING_DATA) { +            if (def == NULL) { +                continue; +            } +            len += deflen; +        } else { +            len += data[i]->len - 1; +        } +        if (num >= 0) { +            len += seplen; +        } +        num++;      }      err = -ENOMEM; @@ -379,14 +409,25 @@ int32_t ec_dict_data_concat(const char * fmt, ec_cbk_data_t * cbk,      memcpy(str, pre, prelen);      len = prelen; -    for (i = 0; i < num; i++) { -        if (i > 0) { +    for (i = 0; i < ec->nodes; i++) { +        if (data[i] == NULL) { +            continue; +        } +        if (data[i] == EC_MISSING_DATA) { +            if (deflen == 0) { +                continue; +            } +            tmp = deflen; +            memcpy(str + len, def, tmp); +        } else { +            tmp = data[i]->len - 1; +            memcpy(str + len, data[i]->data, tmp); +        } +        len += tmp; +        if (i < num) {              memcpy(str + len, sep, seplen);              len += seplen;          } -        tmp = data[i]->len - 1; -        memcpy(str + len, data[i]->data, tmp); -        len += tmp;      }      memcpy(str + len, post, postlen + 1); @@ -407,30 +448,26 @@ out:  int32_t ec_dict_data_merge(ec_cbk_data_t *cbk, int32_t which, char *key)  { -    data_t *data[cbk->count]; +    ec_t *ec = cbk->fop->xl->private; +    data_t *data[ec->nodes];      dict_t *dict, *lockinfo, *tmp = NULL;      char *ptr = NULL; -    int32_t i, num, len; +    int32_t i, len;      int32_t err; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } + +    ec_dict_list(data, cbk, which, key, _gf_false);      lockinfo = dict_new();      if (lockinfo == NULL) {          return -ENOMEM;      } -    err = dict_unserialize(data[0]->data, data[0]->len, &lockinfo); -    if (err != 0) { -        goto out; -    } +    for (i = 0; i < ec->nodes; i++) { +        if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { +            continue; +        } -    for (i = 1; i < num; i++) -    {          tmp = dict_new();          if (tmp == NULL) {              err = -ENOMEM; @@ -517,19 +554,20 @@ int32_t ec_dict_data_uuid(ec_cbk_data_t * cbk, int32_t which, char * key)  int32_t ec_dict_data_max32(ec_cbk_data_t *cbk, int32_t which, char *key)  { -    data_t * data[cbk->count]; -    dict_t * dict; -    int32_t i, num, err; +    ec_t *ec = cbk->fop->xl->private; +    data_t *data[ec->nodes]; +    dict_t *dict; +    int32_t i;      uint32_t max, tmp; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } +    ec_dict_list(data, cbk, which, key, _gf_false); + +    max = 0; +    for (i = 0; i < ec->nodes; i++) { +        if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { +            continue; +        } -    max = data_to_uint32(data[0]); -    for (i = 1; i < num; i++) {          tmp = data_to_uint32(data[i]);          if (max < tmp) {              max = tmp; @@ -542,19 +580,20 @@ int32_t ec_dict_data_max32(ec_cbk_data_t *cbk, int32_t which, char *key)  int32_t ec_dict_data_max64(ec_cbk_data_t *cbk, int32_t which, char *key)  { -    data_t *data[cbk->count]; +    ec_t *ec = cbk->fop->xl->private; +    data_t *data[ec->nodes];      dict_t *dict; -    int32_t i, num, err; +    int32_t i;      uint64_t max, tmp; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } +    ec_dict_list(data, cbk, which, key, _gf_false); + +    max = 0; +    for (i = 0; i < ec->nodes; i++) { +        if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { +            continue; +        } -    max = data_to_uint64(data[0]); -    for (i = 1; i < num; i++) {          tmp = data_to_uint64(data[i]);          if (max < tmp) {              max = tmp; @@ -567,22 +606,14 @@ int32_t ec_dict_data_max64(ec_cbk_data_t *cbk, int32_t which, char *key)  int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key)  { -    data_t      *data[cbk->count]; +    ec_t        *ec               = cbk->fop->xl->private; +    data_t      *data[ec->nodes];      dict_t      *dict             = NULL; -    ec_t        *ec               = NULL;      int32_t      i                = 0; -    int32_t      num              = 0; -    int32_t      err              = 0;      quota_meta_t size             = {0, };      quota_meta_t max_size         = {0, }; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } - -    if (num == 0) { +    if (ec_dict_list(data, cbk, which, key, _gf_false) == 0) {          return 0;      } @@ -591,8 +622,9 @@ int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key)       * bricks and we can receive slightly different values. If that's the       * case, we take the maximum of all received values.       */ -    for (i = 0; i < num; i++) { -        if (quota_data_to_meta (data[i], QUOTA_SIZE_KEY, &size) < 0) { +    for (i = 0; i < ec->nodes; i++) { +        if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA) || +            (quota_data_to_meta (data[i], QUOTA_SIZE_KEY, &size) < 0)) {                  continue;          } @@ -604,7 +636,6 @@ int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key)                  max_size.dir_count = size.dir_count;      } -    ec = cbk->fop->xl->private;      max_size.size *= ec->fragments;      dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; @@ -613,18 +644,18 @@ int32_t ec_dict_data_quota(ec_cbk_data_t *cbk, int32_t which, char *key)  int32_t ec_dict_data_stime(ec_cbk_data_t * cbk, int32_t which, char * key)  { -    data_t * data[cbk->count]; -    dict_t * dict; -    int32_t i, num, err; +    ec_t *ec = cbk->fop->xl->private; +    data_t *data[ec->nodes]; +    dict_t *dict; +    int32_t i, err; -    num = cbk->count; -    err = ec_dict_list(data, &num, cbk, which, key); -    if (err != 0) { -        return err; -    } +    ec_dict_list(data, cbk, which, key, _gf_false);      dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict; -    for (i = 1; i < num; i++) { +    for (i = 0; i < ec->nodes; i++) { +        if ((data[i] == NULL) || (data[i] == EC_MISSING_DATA)) { +            continue; +        }          err = gf_get_max_stime(cbk->fop->xl, dict, key, data[i]);          if (err != 0) {              gf_msg (cbk->fop->xl->name, GF_LOG_ERROR, -err, @@ -646,12 +677,14 @@ int32_t ec_dict_data_combine(dict_t * dict, char * key, data_t * value,          (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0))      {          return ec_dict_data_concat("(<EC:%s> { })", data->cbk, data->which, -                                   key, data->cbk->fop->xl->name); +                                   key, NULL, _gf_false, +                                   data->cbk->fop->xl->name);      }      if (strncmp(key, GF_XATTR_CLRLK_CMD, strlen(GF_XATTR_CLRLK_CMD)) == 0)      { -        return ec_dict_data_concat("{\n}", data->cbk, data->which, key); +        return ec_dict_data_concat("{\n}", data->cbk, data->which, key, NULL, +                                   _gf_false);      }      if (strncmp(key, GF_XATTR_LOCKINFO_KEY, @@ -681,9 +714,9 @@ int32_t ec_dict_data_combine(dict_t * dict, char * key, data_t * value,          return 0;      } -    if (XATTR_IS_NODE_UUID(key)) -    { -        return ec_dict_data_uuid(data->cbk, data->which, key); +    if (XATTR_IS_NODE_UUID(key)) { +        return ec_dict_data_concat("{ }", data->cbk, data->which, key, +                                   UUID0_STR, _gf_true);      }      if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index e628183190e..2009faccbaf 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -863,8 +863,11 @@ ec_gf_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,                                              NULL, ec_marker_populate_args) == 0)                  return 0; -        if (name && (fnmatch (GF_XATTR_STIME_PATTERN, name, 0) == 0)) +        if (name && +            ((fnmatch (GF_XATTR_STIME_PATTERN, name, 0) == 0) || +             (XATTR_IS_NODE_UUID(name)))) {                  minimum = EC_MINIMUM_ALL; +        }          ec_getxattr (frame, this, -1, minimum, default_getxattr_cbk,                       NULL, loc, name, xdata);  | 
