diff options
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.c')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 18101 | 
1 files changed, 8704 insertions, 9397 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 129acbef0b5..f43a10bec2f 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -8,7 +8,6 @@    cases as published by the Free Software Foundation.  */ -  /* TODO: add NS locking */  #include "glusterfs.h" @@ -27,258 +26,237 @@  int run_defrag = 0; - - -int dht_link2 (xlator_t *this, xlator_t *dst_node, call_frame_t *frame, -               int ret); -  int -dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, -                  int ret); +dht_link2(xlator_t *this, xlator_t *dst_node, call_frame_t *frame, int ret);  int -dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, -               int ret); - +dht_removexattr2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, +                 int ret);  int -dht_rmdir_readdirp_do (call_frame_t *readdirp_frame, xlator_t *this); - +dht_setxattr2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret);  int -dht_common_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                        int32_t op_ret, int32_t op_errno, dict_t *dict, -                        dict_t *xdata); +dht_rmdir_readdirp_do(call_frame_t *readdirp_frame, xlator_t *this);  int -dht_set_file_xattr_req (xlator_t *this, loc_t *loc, dict_t *xattr_req); +dht_common_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                       int32_t op_ret, int32_t op_errno, dict_t *dict, +                       dict_t *xdata);  int -dht_set_dir_xattr_req (xlator_t *this,  loc_t *loc, dict_t *xattr_req); +dht_set_file_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req);  int -dht_do_fresh_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc); +dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req); +int +dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc);  /* Sets the blocks and size values to fixed values. This is to be called   * only for dirs. The caller is responsible for checking the type   */ -int32_t dht_set_fixed_dir_stat (struct iatt *stat) +int32_t +dht_set_fixed_dir_stat(struct iatt *stat)  { -        if (stat) { -                stat->ia_blocks = DHT_DIR_STAT_BLOCKS; -                stat->ia_size = DHT_DIR_STAT_SIZE; -                return 0; -        } -        return -1; +    if (stat) { +        stat->ia_blocks = DHT_DIR_STAT_BLOCKS; +        stat->ia_size = DHT_DIR_STAT_SIZE; +        return 0; +    } +    return -1;  } -  /* Set both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY   * Use DHT_MODE_IN_XDATA_KEY if available. Else fall back to   * DHT_IATT_IN_XDATA_KEY   */ -int dht_request_iatt_in_xdata (xlator_t *this, dict_t *xattr_req) +int +dht_request_iatt_in_xdata(xlator_t *this, dict_t *xattr_req)  { -        int ret = -1; +    int ret = -1; -        ret = dict_set_int8 (xattr_req, DHT_MODE_IN_XDATA_KEY, 1); -        ret = dict_set_int8 (xattr_req, DHT_IATT_IN_XDATA_KEY, 1); +    ret = dict_set_int8(xattr_req, DHT_MODE_IN_XDATA_KEY, 1); +    ret = dict_set_int8(xattr_req, DHT_IATT_IN_XDATA_KEY, 1); -        /* At least one call succeeded */ -        return ret; +    /* At least one call succeeded */ +    return ret;  } -  /* Get both DHT_IATT_IN_XDATA_KEY and DHT_MODE_IN_XDATA_KEY   * Use DHT_MODE_IN_XDATA_KEY if available, else fall back to   * DHT_IATT_IN_XDATA_KEY   * This will return a dummy iatt with only the mode and type set   */ -int dht_read_iatt_from_xdata (xlator_t *this, dict_t *xdata, -                              struct iatt *stbuf) +int +dht_read_iatt_from_xdata(xlator_t *this, dict_t *xdata, struct iatt *stbuf)  { -        int ret = -1; -        int32_t mode = 0; +    int ret = -1; +    int32_t mode = 0; -        ret = dict_get_int32 (xdata, DHT_MODE_IN_XDATA_KEY, &mode); +    ret = dict_get_int32(xdata, DHT_MODE_IN_XDATA_KEY, &mode); -        if (ret) { -                ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, -                                    (void **)&stbuf); -        } else { -                stbuf->ia_prot = ia_prot_from_st_mode (mode); -                stbuf->ia_type = ia_type_from_st_mode (mode); -        } +    if (ret) { +        ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); +    } else { +        stbuf->ia_prot = ia_prot_from_st_mode(mode); +        stbuf->ia_type = ia_type_from_st_mode(mode); +    } -        return ret; +    return ret;  } - -  int -dht_rmdir_unlock (call_frame_t *frame, xlator_t *this); - -char *xattrs_to_heal[] = { -        "user.", -        POSIX_ACL_ACCESS_XATTR, -        POSIX_ACL_DEFAULT_XATTR, -        QUOTA_LIMIT_KEY, -        QUOTA_LIMIT_OBJECTS_KEY, -        GF_SELINUX_XATTR_KEY, -        NULL -}; +dht_rmdir_unlock(call_frame_t *frame, xlator_t *this); +char *xattrs_to_heal[] = {"user.", +                          POSIX_ACL_ACCESS_XATTR, +                          POSIX_ACL_DEFAULT_XATTR, +                          QUOTA_LIMIT_KEY, +                          QUOTA_LIMIT_OBJECTS_KEY, +                          GF_SELINUX_XATTR_KEY, +                          NULL}; -char *dht_dbg_vxattrs[] = { -        DHT_DBG_HASHED_SUBVOL_PATTERN, -        NULL -}; +char *dht_dbg_vxattrs[] = {DHT_DBG_HASHED_SUBVOL_PATTERN, NULL};  /* Return true if key exists in array -*/ + */  static gf_boolean_t -dht_match_xattr (const char *key) +dht_match_xattr(const char *key)  { -        return gf_get_index_by_elem (xattrs_to_heal, (char *)key) >= 0; +    return gf_get_index_by_elem(xattrs_to_heal, (char *)key) >= 0;  }  int -dht_aggregate_quota_xattr (dict_t *dst, char *key, data_t *value) +dht_aggregate_quota_xattr(dict_t *dst, char *key, data_t *value)  { -        int              ret            = -1; -        quota_meta_t    *meta_dst       = NULL; -        quota_meta_t    *meta_src       = NULL; -        int64_t         *size           = NULL; -        int64_t          dst_dir_count  = 0; -        int64_t          src_dir_count  = 0; - -        if (value == NULL) { -                gf_msg ("dht", GF_LOG_WARNING, 0, -                        DHT_MSG_DATA_NULL, "data value is NULL"); -                ret = -1; -                goto out; -        } +    int ret = -1; +    quota_meta_t *meta_dst = NULL; +    quota_meta_t *meta_src = NULL; +    int64_t *size = NULL; +    int64_t dst_dir_count = 0; +    int64_t src_dir_count = 0; -        ret = dict_get_bin (dst, key, (void **)&meta_dst); +    if (value == NULL) { +        gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DATA_NULL, +               "data value is NULL"); +        ret = -1; +        goto out; +    } + +    ret = dict_get_bin(dst, key, (void **)&meta_dst); +    if (ret < 0) { +        meta_dst = GF_CALLOC(1, sizeof(quota_meta_t), gf_common_quota_meta_t); +        if (meta_dst == NULL) { +            gf_msg("dht", GF_LOG_WARNING, ENOMEM, DHT_MSG_NO_MEMORY, +                   "Memory allocation failed"); +            ret = -1; +            goto out; +        } +        ret = dict_set_bin(dst, key, meta_dst, sizeof(quota_meta_t));          if (ret < 0) { -                meta_dst = GF_CALLOC (1, sizeof (quota_meta_t), -                                      gf_common_quota_meta_t); -                if (meta_dst == NULL) { -                        gf_msg ("dht", GF_LOG_WARNING, ENOMEM, -                                DHT_MSG_NO_MEMORY, -                                "Memory allocation failed"); -                        ret = -1; -                        goto out; -                } -                ret = dict_set_bin (dst, key, meta_dst, -                                    sizeof (quota_meta_t)); -                if (ret < 0) { -                        gf_msg ("dht", GF_LOG_WARNING, EINVAL, -                                DHT_MSG_DICT_SET_FAILED, -                                "dht aggregate dict set failed"); -                        GF_FREE (meta_dst); -                        ret = -1; -                        goto out; -                } +            gf_msg("dht", GF_LOG_WARNING, EINVAL, DHT_MSG_DICT_SET_FAILED, +                   "dht aggregate dict set failed"); +            GF_FREE(meta_dst); +            ret = -1; +            goto out;          } +    } -        if (value->len > sizeof (int64_t)) { -                meta_src = data_to_bin (value); +    if (value->len > sizeof(int64_t)) { +        meta_src = data_to_bin(value); -                meta_dst->size = hton64 (ntoh64 (meta_dst->size) + -                                         ntoh64 (meta_src->size)); -                meta_dst->file_count = hton64 (ntoh64 (meta_dst->file_count) + -                                               ntoh64 (meta_src->file_count)); +        meta_dst->size = hton64(ntoh64(meta_dst->size) + +                                ntoh64(meta_src->size)); +        meta_dst->file_count = hton64(ntoh64(meta_dst->file_count) + +                                      ntoh64(meta_src->file_count)); -                if (value->len > (2 * sizeof (int64_t))) { -                        dst_dir_count = ntoh64 (meta_dst->dir_count); -                        src_dir_count = ntoh64 (meta_src->dir_count); +        if (value->len > (2 * sizeof(int64_t))) { +            dst_dir_count = ntoh64(meta_dst->dir_count); +            src_dir_count = ntoh64(meta_src->dir_count); -                        if (src_dir_count > dst_dir_count) -                                meta_dst->dir_count = meta_src->dir_count; -                } else { -                        meta_dst->dir_count = 0; -                } +            if (src_dir_count > dst_dir_count) +                meta_dst->dir_count = meta_src->dir_count;          } else { -                size = data_to_bin (value); -                meta_dst->size = hton64 (ntoh64 (meta_dst->size) + -                                         ntoh64 (*size)); +            meta_dst->dir_count = 0;          } +    } else { +        size = data_to_bin(value); +        meta_dst->size = hton64(ntoh64(meta_dst->size) + ntoh64(*size)); +    } -        ret = 0; +    ret = 0;  out: -        return ret; +    return ret;  } - -int add_opt(char **optsp, const char *opt) +int +add_opt(char **optsp, const char *opt)  { -        char *newopts = NULL; -        unsigned oldsize = 0; -        unsigned newsize = 0; +    char *newopts = NULL; +    unsigned oldsize = 0; +    unsigned newsize = 0; -        if (*optsp == NULL) -                newopts = gf_strdup (opt); -        else { -                oldsize = strlen (*optsp); -                newsize = oldsize + 1 + strlen (opt) + 1; -                newopts = GF_REALLOC (*optsp, newsize); -                if (newopts) -                        sprintf (newopts + oldsize, ",%s", opt); -        } -        if (newopts == NULL) { -                gf_msg ("dht", GF_LOG_WARNING, 0, -                        DHT_MSG_NO_MEMORY, -                        "Error to add choices in buffer in add_opt"); -                return -1; -        } -        *optsp = newopts; -        return 0; +    if (*optsp == NULL) +        newopts = gf_strdup(opt); +    else { +        oldsize = strlen(*optsp); +        newsize = oldsize + 1 + strlen(opt) + 1; +        newopts = GF_REALLOC(*optsp, newsize); +        if (newopts) +            sprintf(newopts + oldsize, ",%s", opt); +    } +    if (newopts == NULL) { +        gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +               "Error to add choices in buffer in add_opt"); +        return -1; +    } +    *optsp = newopts; +    return 0;  }  /* Return Choice list from Split brain status */  static char * -getChoices (const char *value) +getChoices(const char *value)  { -        int i = 0; -        char *ptr = NULL; -        char *tok = NULL; -        char *result = NULL; -        char *newval = NULL; +    int i = 0; +    char *ptr = NULL; +    char *tok = NULL; +    char *result = NULL; +    char *newval = NULL; -        ptr = strstr (value, "Choices:"); -        if (!ptr) { -                result = ptr; -                goto out; -        } +    ptr = strstr(value, "Choices:"); +    if (!ptr) { +        result = ptr; +        goto out; +    } -        newval = gf_strdup (ptr); -        if (!newval) { -                result = newval; -                goto out; -        } +    newval = gf_strdup(ptr); +    if (!newval) { +        result = newval; +        goto out; +    } -        tok = strtok (newval, ":"); -        if (!tok) { -                result = tok; -                goto out; -        } +    tok = strtok(newval, ":"); +    if (!tok) { +        result = tok; +        goto out; +    } -        while (tok) { -                i++; -                if (i == 2) -                        break; -                tok = strtok (NULL, ":"); -        } +    while (tok) { +        i++; +        if (i == 2) +            break; +        tok = strtok(NULL, ":"); +    } -        result = gf_strdup (tok); +    result = gf_strdup(tok);  out: -        if (newval) -                GF_FREE (newval); +    if (newval) +        GF_FREE(newval); -        return result; +    return result;  }  /* This function prepare a list of choices for key @@ -291,248 +269,226 @@ out:  */  int -dht_aggregate_split_brain_xattr (dict_t *dst, char *key, data_t *value) +dht_aggregate_split_brain_xattr(dict_t *dst, char *key, data_t *value)  { +    int ret = 0; +    char *oldvalue = NULL; +    char *old_choice = NULL; +    char *new_choice = NULL; +    char *full_choice = NULL; +    char *status = NULL; -        int              ret            = 0; -        char            *oldvalue       = NULL; -        char            *old_choice     = NULL; -        char            *new_choice     = NULL; -        char            *full_choice    = NULL; -        char            *status         = NULL; +    if (value == NULL) { +        gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DATA_NULL, +               "GF_AFR_SBRAIN_STATUS value is NULL"); +        ret = -1; +        goto out; +    } + +    ret = dict_get_str(dst, key, &oldvalue); +    if (ret) +        goto out; -        if (value == NULL) { -                gf_msg ("dht", GF_LOG_WARNING, 0, -                        DHT_MSG_DATA_NULL, -                        "GF_AFR_SBRAIN_STATUS value is NULL"); +    /* skip code that is irrelevant if !oldvalue */ +    if (!oldvalue) +        goto out; + +    if (strstr(oldvalue, "not")) { +        gf_msg_debug("dht", 0, "Need to update split-brain status in dict"); +        ret = -1; +        goto out; +    } +    if (strstr(oldvalue, "metadata-split-brain:yes") && +        (strstr(oldvalue, "data-split-brain:no"))) { +        if (strstr(value->data, "not")) { +            gf_msg_debug("dht", 0, "No need to update split-brain status"); +            ret = 0; +            goto out; +        } +        if (strstr(value->data, "yes") && +            (strncmp(oldvalue, value->data, strlen(oldvalue)))) { +            old_choice = getChoices(oldvalue); +            if (!old_choice) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +                       "Error to get choices");                  ret = -1;                  goto out; -        } +            } -        ret = dict_get_str (dst, key, &oldvalue); -        if (ret) +            ret = add_opt(&full_choice, old_choice); +            if (ret) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +                       "Error to add choices"); +                ret = -1;                  goto out; +            } -        /* skip code that is irrelevant if !oldvalue */ -        if (!oldvalue) +            new_choice = getChoices(value->data); +            if (!new_choice) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +                       "Error to get choices"); +                ret = -1;                  goto out; +            } -        if (strstr (oldvalue, "not")) { -                gf_msg_debug ("dht", 0, -                              "Need to update split-brain status in dict"); +            ret = add_opt(&full_choice, new_choice); +            if (ret) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +                       "Error to add choices ");                  ret = -1;                  goto out; +            } +            ret = gf_asprintf(&status, +                              "data-split-brain:%s    " +                              "metadata-split-brain:%s   Choices:%s", +                              "no", "yes", full_choice); + +            if (-1 == ret) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_NO_MEMORY, +                       "Error to prepare status "); +                goto out; +            } +            ret = dict_set_dynstr(dst, key, status); +            if (ret) { +                gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +                       "Failed to set full choice"); +            }          } -        if (strstr (oldvalue, "metadata-split-brain:yes") -            && (strstr (oldvalue, "data-split-brain:no"))) { -                if (strstr (value->data, "not")) { -                        gf_msg_debug ("dht", 0, -                                      "No need to update split-brain status"); -                        ret = 0; -                        goto out; -                } -                if (strstr (value->data, "yes") && -                        (strncmp (oldvalue, value->data, strlen(oldvalue)))) { -                        old_choice = getChoices (oldvalue); -                        if (!old_choice) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                        DHT_MSG_NO_MEMORY, -                                        "Error to get choices"); -                                ret = -1; -                                goto out; -                        } - -                        ret = add_opt (&full_choice, old_choice); -                        if (ret) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                         DHT_MSG_NO_MEMORY, -                                         "Error to add choices"); -                                ret = -1; -                                goto out; -                        } - -                        new_choice = getChoices (value->data); -                        if (!new_choice) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                        DHT_MSG_NO_MEMORY, -                                        "Error to get choices"); -                                ret = -1; -                                goto out; -                        } - -                        ret = add_opt (&full_choice, new_choice); -                        if (ret) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                       DHT_MSG_NO_MEMORY, -                                       "Error to add choices "); -                                ret = -1; -                                goto out; -                        } -                        ret = gf_asprintf (&status, -                                           "data-split-brain:%s    " -                                           "metadata-split-brain:%s   Choices:%s", -                                           "no", "yes", full_choice); - -                        if (-1 == ret) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                                 DHT_MSG_NO_MEMORY, -                                                "Error to prepare status "); -                                        goto out; -                                } -                        ret = dict_set_dynstr (dst, key, status); -                        if (ret) { -                                gf_msg ("dht", GF_LOG_WARNING, 0, -                                        DHT_MSG_DICT_SET_FAILED, -                                        "Failed to set full choice"); -                        } -                } -        } +    }  out: -        if (old_choice) -                GF_FREE (old_choice); -        if (new_choice) -                GF_FREE (new_choice); -        if (full_choice) -                GF_FREE (full_choice); +    if (old_choice) +        GF_FREE(old_choice); +    if (new_choice) +        GF_FREE(new_choice); +    if (full_choice) +        GF_FREE(full_choice); -        return ret; +    return ret;  } - -  int -dht_aggregate (dict_t *this, char *key, data_t *value, void *data) +dht_aggregate(dict_t *this, char *key, data_t *value, void *data)  { -        dict_t          *dst            = NULL; -        int32_t          ret            = -1; -        data_t          *dict_data      = NULL; +    dict_t *dst = NULL; +    int32_t ret = -1; +    data_t *dict_data = NULL; -        dst = data; +    dst = data; -        /* compare split brain xattr only */ -        if (strcmp (key, GF_AFR_SBRAIN_STATUS) == 0) { -                ret = dht_aggregate_split_brain_xattr(dst, key, value); +    /* compare split brain xattr only */ +    if (strcmp(key, GF_AFR_SBRAIN_STATUS) == 0) { +        ret = dht_aggregate_split_brain_xattr(dst, key, value); +        if (!ret) +            goto out; +    } else if (strcmp(key, QUOTA_SIZE_KEY) == 0) { +        ret = dht_aggregate_quota_xattr(dst, key, value); +        if (ret) { +            gf_msg("dht", GF_LOG_WARNING, 0, +                   DHT_MSG_AGGREGATE_QUOTA_XATTR_FAILED, +                   "Failed to aggregate quota xattr"); +        } +        goto out; +    } else if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) { +        ret = gf_get_min_stime(THIS, dst, key, value); +        goto out; +    } else { +        /* compare user xattrs only */ +        if (!strncmp(key, "user.", SLEN("user."))) { +            ret = dict_lookup(dst, key, &dict_data); +            if (!ret && dict_data && value) { +                ret = is_data_equal(dict_data, value);                  if (!ret) -                        goto out; -        } else if (strcmp (key, QUOTA_SIZE_KEY) == 0) { -                ret = dht_aggregate_quota_xattr (dst, key, value); -                if (ret) { -                        gf_msg ("dht", GF_LOG_WARNING, 0, -                                DHT_MSG_AGGREGATE_QUOTA_XATTR_FAILED, -                                "Failed to aggregate quota xattr"); -                } -                goto out; -        } else if (fnmatch (GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0) { -                ret = gf_get_min_stime (THIS, dst, key, value); -                goto out; -        } else { -                /* compare user xattrs only */ -                if (!strncmp (key, "user.", SLEN ("user."))) { -                        ret = dict_lookup (dst, key, &dict_data); -                        if (!ret && dict_data && value) { -                                ret = is_data_equal (dict_data, value); -                                if (!ret) -                                        gf_msg_debug ("dht", 0, -                                                      "xattr mismatch for %s", -                                                      key); -                        } -                } +                    gf_msg_debug("dht", 0, "xattr mismatch for %s", key); +            }          } +    } -        ret = dict_set (dst, key, value); -        if (ret) { -                gf_msg ("dht", GF_LOG_WARNING, 0, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value: key = %s", -                        key); -        } +    ret = dict_set(dst, key, value); +    if (ret) { +        gf_msg("dht", GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value: key = %s", key); +    }  out: -        return ret; +    return ret;  } -  void -dht_aggregate_xattr (dict_t *dst, dict_t *src) +dht_aggregate_xattr(dict_t *dst, dict_t *src)  { -        if ((dst == NULL) || (src == NULL)) { -                goto out; -        } +    if ((dst == NULL) || (src == NULL)) { +        goto out; +    } -        dict_foreach (src, dht_aggregate, dst); +    dict_foreach(src, dht_aggregate, dst);  out: -        return; +    return;  }  /* Code to save hashed subvol on inode ctx as a mds subvol -*/ + */  int -dht_inode_ctx_mdsvol_set (inode_t *inode, xlator_t *this, xlator_t *mds_subvol) +dht_inode_ctx_mdsvol_set(inode_t *inode, xlator_t *this, xlator_t *mds_subvol)  { -        dht_inode_ctx_t         *ctx            = NULL; -        int                      ret            = -1; -        uint64_t                 ctx_int        = 0; -        gf_boolean_t             ctx_free       = _gf_false; - +    dht_inode_ctx_t *ctx = NULL; +    int ret = -1; +    uint64_t ctx_int = 0; +    gf_boolean_t ctx_free = _gf_false; -        LOCK (&inode->lock); -        { -                ret = __inode_ctx_get (inode, this , &ctx_int); -                if (ctx_int) { -                        ctx = (dht_inode_ctx_t *)ctx_int; -                        ctx->mds_subvol = mds_subvol; -                } else { -                        ctx = GF_CALLOC (1, sizeof(*ctx), gf_dht_mt_inode_ctx_t); -                        if (!ctx) -                                goto unlock; -                        ctx->mds_subvol = mds_subvol; -                        ctx_free        = _gf_true; -                        ctx_int = (long) ctx; -                        ret =  __inode_ctx_set (inode, this, &ctx_int); -                } -        } +    LOCK(&inode->lock); +    { +        ret = __inode_ctx_get(inode, this, &ctx_int); +        if (ctx_int) { +            ctx = (dht_inode_ctx_t *)ctx_int; +            ctx->mds_subvol = mds_subvol; +        } else { +            ctx = GF_CALLOC(1, sizeof(*ctx), gf_dht_mt_inode_ctx_t); +            if (!ctx) +                goto unlock; +            ctx->mds_subvol = mds_subvol; +            ctx_free = _gf_true; +            ctx_int = (long)ctx; +            ret = __inode_ctx_set(inode, this, &ctx_int); +        } +    }  unlock: -        UNLOCK (&inode->lock); -        if (ret && ctx_free) -                GF_FREE (ctx); -        return ret; +    UNLOCK(&inode->lock); +    if (ret && ctx_free) +        GF_FREE(ctx); +    return ret;  }  /*Code to get mds subvol from inode ctx */  int -dht_inode_ctx_mdsvol_get (inode_t *inode, xlator_t *this, xlator_t **mdsvol) +dht_inode_ctx_mdsvol_get(inode_t *inode, xlator_t *this, xlator_t **mdsvol)  { -        dht_inode_ctx_t         *ctx            = NULL; -        int                      ret            = -1; +    dht_inode_ctx_t *ctx = NULL; +    int ret = -1; -        if (!mdsvol) -                return ret; +    if (!mdsvol) +        return ret; -        if (__is_root_gfid(inode->gfid)) { -                (*mdsvol) = FIRST_CHILD (this); -                return 0; -        } +    if (__is_root_gfid(inode->gfid)) { +        (*mdsvol) = FIRST_CHILD(this); +        return 0; +    } -        ret = dht_inode_ctx_get (inode, this, &ctx); +    ret = dht_inode_ctx_get(inode, this, &ctx); -        if (!ret && ctx) { -                if (ctx->mds_subvol) { -                        *mdsvol = ctx->mds_subvol; -                        ret = 0; -                } else { -                        ret = -1; -                } +    if (!ret && ctx) { +        if (ctx->mds_subvol) { +            *mdsvol = ctx->mds_subvol; +            ret = 0; +        } else { +            ret = -1;          } +    } -        return ret; +    return ret;  } - - - -  /* TODO:     - use volumename in xattr instead of "dht"     - use NS locks @@ -540,293 +496,277 @@ dht_inode_ctx_mdsvol_get (inode_t *inode, xlator_t *this, xlator_t **mdsvol)     - complete linkfile selfheal  */ -  int -dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie, -                         xlator_t *this, -                         int op_ret, int op_errno, dict_t *xdata) +dht_lookup_selfheal_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        dht_layout_t *layout = NULL; -        dht_conf_t   *conf   = NULL; -        int           ret = -1; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); -        local = frame->local; -        conf  = this->private; -        ret = op_ret; +    local = frame->local; +    conf = this->private; +    ret = op_ret; -        FRAME_SU_UNDO (frame, dht_local_t); +    FRAME_SU_UNDO(frame, dht_local_t); -        if (ret == 0) { -                layout = local->selfheal.layout; -                ret = dht_layout_set (this, local->inode, layout); -        } +    if (ret == 0) { +        layout = local->selfheal.layout; +        ret = dht_layout_set(this, local->inode, layout); +    } -        dht_inode_ctx_time_update (local->inode, this, &local->stbuf, 1); -        if (local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           &local->postparent, 1); -        } +    dht_inode_ctx_time_update(local->inode, this, &local->stbuf, 1); +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, &local->postparent, +                                  1); +    } -        DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -        dht_set_fixed_dir_stat (&local->postparent); -        /* Delete mds xattr at the time of STACK UNWIND */ -        GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr); +    DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +    dht_set_fixed_dir_stat(&local->postparent); +    /* Delete mds xattr at the time of STACK UNWIND */ +    GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); -        DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode, -                          &local->stbuf, local->xattr, &local->postparent); +    DHT_STACK_UNWIND(lookup, frame, ret, local->op_errno, local->inode, +                     &local->stbuf, local->xattr, &local->postparent);  out: -        return ret; -} - -int -dht_discover_complete (xlator_t *this, call_frame_t *discover_frame) -{ -        dht_local_t     *local           = NULL; -        dht_local_t     *heal_local      = NULL; -        call_frame_t    *main_frame      = NULL; -        call_frame_t    *heal_frame      = NULL; -        int              op_errno        = 0; -        int              ret             = -1; -        dht_layout_t    *layout          = NULL; -        dht_conf_t      *conf            = NULL; -        uint32_t         vol_commit_hash = 0; -        xlator_t        *source          = NULL; -        int              heal_path       = 0; -        int              error_while_marking_mds   = 0; -        int              i               = 0; -        loc_t            loc             = {0 }; -        int8_t           is_read_only    = 0, layout_anomalies = 0; -        char             gfid_local[GF_UUID_BUF_SIZE] = {0}; - -        local = discover_frame->local; -        layout = local->layout; -        conf = this->private; -        gf_uuid_unparse(local->gfid, gfid_local); - -        LOCK(&discover_frame->lock); -        { -                main_frame = local->main_frame; -                local->main_frame = NULL; -        } -        UNLOCK(&discover_frame->lock); - -        if (!main_frame) -                return 0; - -        /* Code to update all extended attributed from -           subvol to local->xattr on that internal xattr has found -        */ -        if (conf->subvolume_cnt == 1) -                local->need_xattr_heal = 0; -        if (local->need_xattr_heal && (local->mds_xattr)) { -                dht_dir_set_heal_xattr (this, local, local->xattr, -                                        local->mds_xattr, NULL, NULL); -                dict_unref (local->mds_xattr); -                local->mds_xattr = NULL; -        } - -        ret = dict_get_int8 (local->xattr_req, QUOTA_READ_ONLY_KEY, -                             &is_read_only); -        if (ret < 0) -                gf_msg_debug (this->name, 0, "key = %s not present in dict", -                              QUOTA_READ_ONLY_KEY); - -        if (local->file_count && local->dir_count) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_FILE_TYPE_MISMATCH, -                        "path %s exists as a file on one subvolume " -                        "and directory on another. " -                        "Please fix it manually", -                        local->loc.path); -                op_errno = EIO; -                goto out; -        } - -        if (local->cached_subvol) { -                ret = dht_layout_preset (this, local->cached_subvol, -                                         local->inode); -                if (ret < 0) { -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_LAYOUT_SET_FAILED, -                                "failed to set layout for subvolume %s", -                                local->cached_subvol ? local->cached_subvol->name : "<nil>"); -                        op_errno = EINVAL; -                        goto out; -                } -        } else { -                ret = dht_layout_normalize (this, &local->loc, layout); -                if ((ret < 0) || ((ret > 0) && (local->op_ret != 0))) { -                        /* either the layout is incorrect or the directory is -                         * not found even in one subvolume. -                         */ -                        gf_msg_debug (this->name, 0, -                                      "normalizing failed on %s " -                                      "(overlaps/holes present: %s, " -                                      "ENOENT errors: %d)", local->loc.path, -                                      (ret < 0) ? "yes" : "no", (ret > 0) ? ret : 0); -                        layout_anomalies = 1; -                } else if (local->inode) { -                        dht_layout_set (this, local->inode, layout); -                } -        } +    return ret; +} + +int +dht_discover_complete(xlator_t *this, call_frame_t *discover_frame) +{ +    dht_local_t *local = NULL; +    dht_local_t *heal_local = NULL; +    call_frame_t *main_frame = NULL; +    call_frame_t *heal_frame = NULL; +    int op_errno = 0; +    int ret = -1; +    dht_layout_t *layout = NULL; +    dht_conf_t *conf = NULL; +    uint32_t vol_commit_hash = 0; +    xlator_t *source = NULL; +    int heal_path = 0; +    int error_while_marking_mds = 0; +    int i = 0; +    loc_t loc = {0}; +    int8_t is_read_only = 0, layout_anomalies = 0; +    char gfid_local[GF_UUID_BUF_SIZE] = {0}; + +    local = discover_frame->local; +    layout = local->layout; +    conf = this->private; +    gf_uuid_unparse(local->gfid, gfid_local); + +    LOCK(&discover_frame->lock); +    { +        main_frame = local->main_frame; +        local->main_frame = NULL; +    } +    UNLOCK(&discover_frame->lock); + +    if (!main_frame) +        return 0; + +    /* Code to update all extended attributed from +       subvol to local->xattr on that internal xattr has found +    */ +    if (conf->subvolume_cnt == 1) +        local->need_xattr_heal = 0; +    if (local->need_xattr_heal && (local->mds_xattr)) { +        dht_dir_set_heal_xattr(this, local, local->xattr, local->mds_xattr, +                               NULL, NULL); +        dict_unref(local->mds_xattr); +        local->mds_xattr = NULL; +    } + +    ret = dict_get_int8(local->xattr_req, QUOTA_READ_ONLY_KEY, &is_read_only); +    if (ret < 0) +        gf_msg_debug(this->name, 0, "key = %s not present in dict", +                     QUOTA_READ_ONLY_KEY); + +    if (local->file_count && local->dir_count) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_FILE_TYPE_MISMATCH, +               "path %s exists as a file on one subvolume " +               "and directory on another. " +               "Please fix it manually", +               local->loc.path); +        op_errno = EIO; +        goto out; +    } -        if (!conf->vch_forced) { -                ret = dict_get_uint32 (local->xattr, -                                       conf->commithash_xattr_name, -                                       &vol_commit_hash); -                if (ret == 0) { -                        conf->vol_commit_hash = vol_commit_hash; -                } +    if (local->cached_subvol) { +        ret = dht_layout_preset(this, local->cached_subvol, local->inode); +        if (ret < 0) { +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_SET_FAILED, +                   "failed to set layout for subvolume %s", +                   local->cached_subvol ? local->cached_subvol->name : "<nil>"); +            op_errno = EINVAL; +            goto out; +        } +    } else { +        ret = dht_layout_normalize(this, &local->loc, layout); +        if ((ret < 0) || ((ret > 0) && (local->op_ret != 0))) { +            /* either the layout is incorrect or the directory is +             * not found even in one subvolume. +             */ +            gf_msg_debug(this->name, 0, +                         "normalizing failed on %s " +                         "(overlaps/holes present: %s, " +                         "ENOENT errors: %d)", +                         local->loc.path, (ret < 0) ? "yes" : "no", +                         (ret > 0) ? ret : 0); +            layout_anomalies = 1; +        } else if (local->inode) { +            dht_layout_set(this, local->inode, layout); +        } +    } + +    if (!conf->vch_forced) { +        ret = dict_get_uint32(local->xattr, conf->commithash_xattr_name, +                              &vol_commit_hash); +        if (ret == 0) { +            conf->vol_commit_hash = vol_commit_hash;          } +    } -        if (IA_ISDIR (local->stbuf.ia_type) && !is_read_only) { -                for (i = 0; i < layout->cnt; i++) { -                       if (!source && !layout->list[i].err) -                                source = layout->list[i].xlator; -                        if (layout->list[i].err == ENOENT || -                            layout->list[i].err == ESTALE) { -                                heal_path = 1; -                        } - -                        if (source && heal_path) -                                break; -                } -        } +    if (IA_ISDIR(local->stbuf.ia_type) && !is_read_only) { +        for (i = 0; i < layout->cnt; i++) { +            if (!source && !layout->list[i].err) +                source = layout->list[i].xlator; +            if (layout->list[i].err == ENOENT || +                layout->list[i].err == ESTALE) { +                heal_path = 1; +            } -        if (IA_ISDIR (local->stbuf.ia_type)) { -                /* Call function to save hashed subvol on inode ctx if -                   internal mds xattr is not present and all subvols are up -                */ -                if (!local->op_ret && !__is_root_gfid (local->stbuf.ia_gfid)) -                        (void) dht_common_mark_mdsxattr (discover_frame, -                                                         &error_while_marking_mds, 1); - -                if (local->need_xattr_heal && !heal_path) { -                        local->need_xattr_heal = 0; -                        ret =  dht_dir_xattr_heal (this, local); -                        if (ret) -                                gf_msg (this->name, GF_LOG_ERROR, -                                        ret, -                                        DHT_MSG_DIR_XATTR_HEAL_FAILED, -                                        "xattr heal failed for " -                                        "directory  gfid is %s ", -                                        gfid_local); -                } +            if (source && heal_path) +                break;          } +    } -        if (source && (heal_path || layout_anomalies || error_while_marking_mds)) { -                gf_uuid_copy (loc.gfid, local->gfid); -                if (gf_uuid_is_null (loc.gfid)) { -                        goto done; -                } - -                if (local->inode) -                        loc.inode = inode_ref (local->inode); -                else -                        goto done; - -               heal_frame = create_frame (this, this->ctx->pool); -               if (heal_frame) { -                        heal_local = dht_local_init (heal_frame, &loc, -                                                     NULL, 0); -                        if (!heal_local) -                                goto cleanup; - -                        gf_uuid_copy (heal_local->gfid, local->gfid); -                        heal_frame->cookie = source; -                        heal_local->xattr = dict_ref (local->xattr); -                        heal_local->stbuf = local->stbuf; -                        heal_local->postparent = local->postparent; -                        heal_local->inode = inode_ref (loc.inode); -                        heal_local->main_frame = main_frame; -                        FRAME_SU_DO (heal_frame, dht_local_t); -                        ret = synctask_new (this->ctx->env, -                                            dht_heal_full_path, -                                            dht_heal_full_path_done, -                                            heal_frame, heal_frame); -                        if (!ret) { -                                loc_wipe (&loc); -                                return 0; -                        } -                        /* -                         * Failed to spawn the synctask. Returning -                         * with out doing heal. -                         */ -cleanup: -                        loc_wipe (&loc); -                        DHT_STACK_DESTROY (heal_frame); -                } - -        } +    if (IA_ISDIR(local->stbuf.ia_type)) { +        /* Call function to save hashed subvol on inode ctx if +           internal mds xattr is not present and all subvols are up +        */ +        if (!local->op_ret && !__is_root_gfid(local->stbuf.ia_gfid)) +            (void)dht_common_mark_mdsxattr(discover_frame, +                                           &error_while_marking_mds, 1); + +        if (local->need_xattr_heal && !heal_path) { +            local->need_xattr_heal = 0; +            ret = dht_dir_xattr_heal(this, local); +            if (ret) +                gf_msg(this->name, GF_LOG_ERROR, ret, +                       DHT_MSG_DIR_XATTR_HEAL_FAILED, +                       "xattr heal failed for " +                       "directory  gfid is %s ", +                       gfid_local); +        } +    } + +    if (source && (heal_path || layout_anomalies || error_while_marking_mds)) { +        gf_uuid_copy(loc.gfid, local->gfid); +        if (gf_uuid_is_null(loc.gfid)) { +            goto done; +        } + +        if (local->inode) +            loc.inode = inode_ref(local->inode); +        else +            goto done; + +        heal_frame = create_frame(this, this->ctx->pool); +        if (heal_frame) { +            heal_local = dht_local_init(heal_frame, &loc, NULL, 0); +            if (!heal_local) +                goto cleanup; + +            gf_uuid_copy(heal_local->gfid, local->gfid); +            heal_frame->cookie = source; +            heal_local->xattr = dict_ref(local->xattr); +            heal_local->stbuf = local->stbuf; +            heal_local->postparent = local->postparent; +            heal_local->inode = inode_ref(loc.inode); +            heal_local->main_frame = main_frame; +            FRAME_SU_DO(heal_frame, dht_local_t); +            ret = synctask_new(this->ctx->env, dht_heal_full_path, +                               dht_heal_full_path_done, heal_frame, heal_frame); +            if (!ret) { +                loc_wipe(&loc); +                return 0; +            } +            /* +             * Failed to spawn the synctask. Returning +             * with out doing heal. +             */ +        cleanup: +            loc_wipe(&loc); +            DHT_STACK_DESTROY(heal_frame); +        } +    }  done: -        dht_set_fixed_dir_stat (&local->postparent); -        /* Delete mds xattr at the time of STACK UNWIND */ -        if (local->xattr) -                GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr); +    dht_set_fixed_dir_stat(&local->postparent); +    /* Delete mds xattr at the time of STACK UNWIND */ +    if (local->xattr) +        GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); -        DHT_STACK_UNWIND (lookup, main_frame, local->op_ret, local->op_errno, -                          local->inode, &local->stbuf, local->xattr, -                          &local->postparent); -        return 0; +    DHT_STACK_UNWIND(lookup, main_frame, local->op_ret, local->op_errno, +                     local->inode, &local->stbuf, local->xattr, +                     &local->postparent); +    return 0;  out: -        DHT_STACK_UNWIND (lookup, main_frame, -1, op_errno, NULL, NULL, NULL, -                          NULL); +    DHT_STACK_UNWIND(lookup, main_frame, -1, op_errno, NULL, NULL, NULL, NULL); -        return ret; +    return ret;  }  int -dht_common_mark_mdsxattr_cbk (call_frame_t *frame, void *cookie, -                              xlator_t *this, int op_ret, int op_errno, -                              dict_t *xdata) +dht_common_mark_mdsxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                             int op_ret, int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        xlator_t     *prev  = cookie; -        int           ret   = -1; -        dht_conf_t   *conf  = 0; -        dht_layout_t *layout = NULL; +    dht_local_t *local = NULL; +    xlator_t *prev = cookie; +    int ret = -1; +    dht_conf_t *conf = 0; +    dht_layout_t *layout = NULL; -        GF_VALIDATE_OR_GOTO (this->name, frame, out); -        GF_VALIDATE_OR_GOTO (this->name, frame->local, out); +    GF_VALIDATE_OR_GOTO(this->name, frame, out); +    GF_VALIDATE_OR_GOTO(this->name, frame->local, out); -        local = frame->local; -        conf = this->private; -        layout = local->selfheal.layout; +    local = frame->local; +    conf = this->private; +    layout = local->selfheal.layout; -        if (op_ret) { -                gf_msg_debug (this->name, op_ret, -                              "Failed to set %s on the MDS %s for path %s. ", -                               conf->mds_xattr_key, prev->name, local->loc.path); -        } else { -                /* Save mds subvol on inode ctx */ -                ret = dht_inode_ctx_mdsvol_set (local->inode, this, prev); -                if (ret) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_SET_INODE_CTX_FAILED, -                                "Failed to set mds subvol on inode ctx" -                                " %s for %s ", prev->name, -                                local->loc.path); -                } -        } -        if (!local->mds_heal_fresh_lookup && layout) { -                dht_selfheal_dir_setattr (frame, &local->loc, &local->stbuf, -                                          0xffffffff, layout); -        } +    if (op_ret) { +        gf_msg_debug(this->name, op_ret, +                     "Failed to set %s on the MDS %s for path %s. ", +                     conf->mds_xattr_key, prev->name, local->loc.path); +    } else { +        /* Save mds subvol on inode ctx */ +        ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); +        if (ret) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, +                   "Failed to set mds subvol on inode ctx" +                   " %s for %s ", +                   prev->name, local->loc.path); +        } +    } +    if (!local->mds_heal_fresh_lookup && layout) { +        dht_selfheal_dir_setattr(frame, &local->loc, &local->stbuf, 0xffffffff, +                                 layout); +    }  out: -        if (local && local->mds_heal_fresh_lookup) -                DHT_STACK_DESTROY (frame); -        return 0; +    if (local && local->mds_heal_fresh_lookup) +        DHT_STACK_DESTROY(frame); +    return 0;  } - -  /* Common function call by revalidate/selfheal code path to populate     internal xattr if it is not present, mark_during_fresh_lookup value     determines either function is call by revalidate_cbk(discover_complete) @@ -842,1508 +782,1416 @@ out:     penalty.  */  int -dht_common_mark_mdsxattr (call_frame_t *frame, int *errst, int mark_during_fresh_lookup) -{ -        dht_local_t  *local          = NULL; -        xlator_t     *this           = NULL; -        xlator_t     *hashed_subvol  = NULL; -        int           ret            = 0; -        int           i              = 0; -        dict_t       *xattrs         = NULL; -        char          gfid_local[GF_UUID_BUF_SIZE] = {0,}; -        int32_t       zero[1]        = {0}; -        dht_conf_t   *conf           = 0; -        dht_layout_t *layout         = NULL; -        dht_local_t  *copy_local     = NULL; -        call_frame_t *xattr_frame    = NULL; -        gf_boolean_t  vol_down       = _gf_false; - -        this = frame->this; - -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO (this->name, frame->local, out); -        GF_VALIDATE_OR_GOTO (this->name, this->private, out); - -        local = frame->local; -        conf = this->private; -        layout = local->selfheal.layout; -        local->mds_heal_fresh_lookup = mark_during_fresh_lookup; -        gf_uuid_unparse(local->gfid, gfid_local); - -        /* Code to update hashed subvol consider as a mds subvol -           and wind a setxattr call on hashed subvol to update -           internal xattr +dht_common_mark_mdsxattr(call_frame_t *frame, int *errst, +                         int mark_during_fresh_lookup) +{ +    dht_local_t *local = NULL; +    xlator_t *this = NULL; +    xlator_t *hashed_subvol = NULL; +    int ret = 0; +    int i = 0; +    dict_t *xattrs = NULL; +    char gfid_local[GF_UUID_BUF_SIZE] = { +        0, +    }; +    int32_t zero[1] = {0}; +    dht_conf_t *conf = 0; +    dht_layout_t *layout = NULL; +    dht_local_t *copy_local = NULL; +    call_frame_t *xattr_frame = NULL; +    gf_boolean_t vol_down = _gf_false; + +    this = frame->this; + +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO(this->name, frame->local, out); +    GF_VALIDATE_OR_GOTO(this->name, this->private, out); + +    local = frame->local; +    conf = this->private; +    layout = local->selfheal.layout; +    local->mds_heal_fresh_lookup = mark_during_fresh_lookup; +    gf_uuid_unparse(local->gfid, gfid_local); + +    /* Code to update hashed subvol consider as a mds subvol +       and wind a setxattr call on hashed subvol to update +       internal xattr +    */ +    if (!local->xattr || !dict_get(local->xattr, conf->mds_xattr_key)) { +        /* It means no internal MDS xattr has been set yet +         */ +        /* Check the status of all subvol are up while call +           this function call by lookup code path          */ -        if (!local->xattr || !dict_get (local->xattr, conf->mds_xattr_key)) { -                /* It means no internal MDS xattr has been set yet -                */ -                /* Check the status of all subvol are up while call -                   this function call by lookup code path -                */ -                if (mark_during_fresh_lookup) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                if (!conf->subvolume_status[i]) { -                                        vol_down = _gf_true; -                                        break; -                                } -                        } -                        if (vol_down) { -                                gf_msg_debug (this->name, 0, -                                              "subvol %s is down. Unable to " -                                              " save mds subvol on inode for " -                                              " path %s gfid is %s " , -                                              conf->subvolumes[i]->name, -                                              local->loc.path, gfid_local); -                                goto out; -                        } +        if (mark_during_fresh_lookup) { +            for (i = 0; i < conf->subvolume_cnt; i++) { +                if (!conf->subvolume_status[i]) { +                    vol_down = _gf_true; +                    break;                  } +            } +            if (vol_down) { +                gf_msg_debug(this->name, 0, +                             "subvol %s is down. Unable to " +                             " save mds subvol on inode for " +                             " path %s gfid is %s ", +                             conf->subvolumes[i]->name, local->loc.path, +                             gfid_local); +                goto out; +            } +        } -                /* Calculate hashed subvol based on inode and parent node -                */ -                hashed_subvol = dht_inode_get_hashed_subvol (local->inode, this, -                                                             &local->loc); -                if (!hashed_subvol) { -                        gf_msg (this->name, GF_LOG_DEBUG, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Failed to get hashed subvol for path %s" -                                "gfid is %s ", -                                local->loc.path, gfid_local); -                        (*errst) = 1; -                        ret = -1; -                        goto out; -                } -                xattrs = dict_new (); -                if (!xattrs) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                DHT_MSG_NO_MEMORY, "dict_new failed"); -                        ret = -1; -                        goto out; -                } -                /* Add internal MDS xattr on disk for hashed subvol -                */ -                ret = dht_dict_set_array (xattrs, conf->mds_xattr_key, -                                          zero, 1); -                if (ret) { -                        gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                                DHT_MSG_DICT_SET_FAILED, -                                "Failed to set dictionary" -                                "  value:key = %s for " -                                "path %s", conf->mds_xattr_key, -                                local->loc.path); -                        ret = -1; -                        goto out; -                } -                /* Create a new frame to wind a call only while -                   this function call by revalidate_cbk code path -                   To wind a call parallel need to create a new frame -                */ -                if (mark_during_fresh_lookup) { -                        xattr_frame = create_frame (this, this->ctx->pool); -                        if (!xattr_frame) { -                                ret = -1; -                                goto out; -                        } -                        copy_local = dht_local_init (xattr_frame, &(local->loc), -                                                     NULL, 0); -                        if (!copy_local) { -                                ret = -1; -                                DHT_STACK_DESTROY (xattr_frame); -                                goto out; -                        } -                        copy_local->stbuf = local->stbuf; -                        copy_local->mds_heal_fresh_lookup = mark_during_fresh_lookup; -                        if (!copy_local->inode) -                                copy_local->inode = inode_ref (local->inode); -                        gf_uuid_copy (copy_local->loc.gfid, local->gfid); -                        FRAME_SU_DO (xattr_frame, dht_local_t); -                        STACK_WIND_COOKIE (xattr_frame, dht_common_mark_mdsxattr_cbk, -                                           hashed_subvol, hashed_subvol, -                                           hashed_subvol->fops->setxattr, -                                           &local->loc, xattrs, 0, NULL); -                } else { -                        STACK_WIND_COOKIE (frame, -                                           dht_common_mark_mdsxattr_cbk, -                                           (void *)hashed_subvol, -                                           hashed_subvol, -                                           hashed_subvol->fops->setxattr, -                                           &local->loc, xattrs, 0, -                                           NULL); -                } -        } else { -                gf_msg_debug (this->name, 0, -                              "internal xattr %s is present on subvol" -                              "on path %s gfid is %s " , conf->mds_xattr_key, -                               local->loc.path, gfid_local); -                if (!mark_during_fresh_lookup) -                        dht_selfheal_dir_setattr (frame, &local->loc, -                                                  &local->stbuf, 0xffffffff, -                                                  layout); +        /* Calculate hashed subvol based on inode and parent node +         */ +        hashed_subvol = dht_inode_get_hashed_subvol(local->inode, this, +                                                    &local->loc); +        if (!hashed_subvol) { +            gf_msg(this->name, GF_LOG_DEBUG, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Failed to get hashed subvol for path %s" +                   "gfid is %s ", +                   local->loc.path, gfid_local); +            (*errst) = 1; +            ret = -1; +            goto out; +        } +        xattrs = dict_new(); +        if (!xattrs) { +            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +                   "dict_new failed"); +            ret = -1; +            goto out;          } +        /* Add internal MDS xattr on disk for hashed subvol +         */ +        ret = dht_dict_set_array(xattrs, conf->mds_xattr_key, zero, 1); +        if (ret) { +            gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +                   "Failed to set dictionary" +                   "  value:key = %s for " +                   "path %s", +                   conf->mds_xattr_key, local->loc.path); +            ret = -1; +            goto out; +        } +        /* Create a new frame to wind a call only while +           this function call by revalidate_cbk code path +           To wind a call parallel need to create a new frame +        */ +        if (mark_during_fresh_lookup) { +            xattr_frame = create_frame(this, this->ctx->pool); +            if (!xattr_frame) { +                ret = -1; +                goto out; +            } +            copy_local = dht_local_init(xattr_frame, &(local->loc), NULL, 0); +            if (!copy_local) { +                ret = -1; +                DHT_STACK_DESTROY(xattr_frame); +                goto out; +            } +            copy_local->stbuf = local->stbuf; +            copy_local->mds_heal_fresh_lookup = mark_during_fresh_lookup; +            if (!copy_local->inode) +                copy_local->inode = inode_ref(local->inode); +            gf_uuid_copy(copy_local->loc.gfid, local->gfid); +            FRAME_SU_DO(xattr_frame, dht_local_t); +            STACK_WIND_COOKIE(xattr_frame, dht_common_mark_mdsxattr_cbk, +                              hashed_subvol, hashed_subvol, +                              hashed_subvol->fops->setxattr, &local->loc, +                              xattrs, 0, NULL); +        } else { +            STACK_WIND_COOKIE(frame, dht_common_mark_mdsxattr_cbk, +                              (void *)hashed_subvol, hashed_subvol, +                              hashed_subvol->fops->setxattr, &local->loc, +                              xattrs, 0, NULL); +        } +    } else { +        gf_msg_debug(this->name, 0, +                     "internal xattr %s is present on subvol" +                     "on path %s gfid is %s ", +                     conf->mds_xattr_key, local->loc.path, gfid_local); +        if (!mark_during_fresh_lookup) +            dht_selfheal_dir_setattr(frame, &local->loc, &local->stbuf, +                                     0xffffffff, layout); +    }  out: -        if (xattrs) -                dict_unref (xattrs); -        return ret; -} - - -int -dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                  int op_ret, int op_errno, -                  inode_t *inode, struct iatt *stbuf, dict_t *xattr, -                  struct iatt *postparent) -{ -        dht_local_t  *local                   = NULL; -        int           this_call_cnt           = 0; -        xlator_t     *prev                    = NULL; -        dht_layout_t *layout                  = NULL; -        int           ret                     = -1; -        int           is_dir                  = 0; -        int32_t       check_mds               = 0; -        int           is_linkfile             = 0; -        int           attempt_unwind          = 0; -        dht_conf_t   *conf                    = 0; -        char          gfid_local[GF_UUID_BUF_SIZE] = {0}; -        char          gfid_node[GF_UUID_BUF_SIZE]  = {0}; -        int32_t       mds_xattr_val[1]             = {0}; -        int           errst                        = 0; - - -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); -        GF_VALIDATE_OR_GOTO ("dht", cookie, out); +    if (xattrs) +        dict_unref(xattrs); +    return ret; +} + +int +dht_discover_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                 int op_errno, inode_t *inode, struct iatt *stbuf, +                 dict_t *xattr, struct iatt *postparent) +{ +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    dht_layout_t *layout = NULL; +    int ret = -1; +    int is_dir = 0; +    int32_t check_mds = 0; +    int is_linkfile = 0; +    int attempt_unwind = 0; +    dht_conf_t *conf = 0; +    char gfid_local[GF_UUID_BUF_SIZE] = {0}; +    char gfid_node[GF_UUID_BUF_SIZE] = {0}; +    int32_t mds_xattr_val[1] = {0}; +    int errst = 0; + +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); +    GF_VALIDATE_OR_GOTO("dht", cookie, out); + +    local = frame->local; +    prev = cookie; +    conf = this->private; + +    layout = local->layout; + +    /* Check if the gfid is different for file from other node */ +    if (!op_ret && gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { +        gf_uuid_unparse(stbuf->ia_gfid, gfid_node); +        gf_uuid_unparse(local->gfid, gfid_local); -        local = frame->local; -        prev  = cookie; -        conf = this->private; +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, +               "%s: gfid different on %s, gfid local = %s" +               "gfid other = %s", +               local->loc.path, prev->name, gfid_local, gfid_node); +    } -        layout = local->layout; +    LOCK(&frame->lock); +    { +        /* TODO: assert equal mode on stbuf->st_mode and +           local->stbuf->st_mode +           else mkdir/chmod/chown and fix +        */ -        /* Check if the gfid is different for file from other node */ -        if (!op_ret && gf_uuid_compare (local->gfid, stbuf->ia_gfid)) { +        ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); +        if (ret) +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, +                   "%s: failed to merge layouts for subvol %s", local->loc.path, +                   prev->name); -                gf_uuid_unparse(stbuf->ia_gfid, gfid_node); -                gf_uuid_unparse(local->gfid, gfid_local); +        if (op_ret == -1) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, +                         "lookup of %s on %s returned error", local->loc.path, +                         prev->name); -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_GFID_MISMATCH, -                        "%s: gfid different on %s, gfid local = %s" -                        "gfid other = %s", -                        local->loc.path, prev->name, -                        gfid_local, gfid_node); +            goto unlock;          } +        is_linkfile = check_is_linkfile(inode, stbuf, xattr, +                                        conf->link_xattr_name); +        is_dir = check_is_dir(inode, stbuf, xattr); -        LOCK (&frame->lock); -        { -                /* TODO: assert equal mode on stbuf->st_mode and -                   local->stbuf->st_mode - -                   else mkdir/chmod/chown and fix -                */ - -                ret = dht_layout_merge (this, layout, prev, -                                        op_ret, op_errno, xattr); -                if (ret) -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_LAYOUT_MERGE_FAILED, -                                "%s: failed to merge layouts for subvol %s", -                                local->loc.path, prev->name); - -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "lookup of %s on %s returned error", -                                      local->loc.path, prev->name); - -                        goto unlock; -                } - -                is_linkfile = check_is_linkfile (inode, stbuf, xattr, -                                                 conf->link_xattr_name); -                is_dir = check_is_dir (inode, stbuf, xattr); - -                if (is_dir) { -                        local->dir_count ++; -                } else { -                        local->file_count ++; - -                        if (!is_linkfile && !local->cached_subvol) { -                                /* real file */ -                                /* Ok, we somehow managed to find a file on -                                 * more than one subvol. ignore this or we -                                 * will end up overwriting information while a -                                 * a thread is potentially unwinding from -                                 * dht_discover_complete -                                 */ -                                local->cached_subvol = prev; -                                attempt_unwind = 1; -                        } else { -                                goto unlock; -                        } -                } - -                local->op_ret = 0; - -                if (local->xattr == NULL) { -                        local->xattr = dict_ref (xattr); -                } else { -                        /* Don't aggregate for files. See BZ#1484113 */ -                        if (is_dir) -                                dht_aggregate_xattr (local->xattr, xattr); -                } +        if (is_dir) { +            local->dir_count++; +        } else { +            local->file_count++; + +            if (!is_linkfile && !local->cached_subvol) { +                /* real file */ +                /* Ok, we somehow managed to find a file on +                 * more than one subvol. ignore this or we +                 * will end up overwriting information while a +                 * a thread is potentially unwinding from +                 * dht_discover_complete +                 */ +                local->cached_subvol = prev; +                attempt_unwind = 1; +            } else { +                goto unlock; +            } +        } -                if (local->inode == NULL) -                        local->inode = inode_ref (inode); +        local->op_ret = 0; -                dht_iatt_merge (this, &local->stbuf, stbuf); -                dht_iatt_merge (this, &local->postparent, postparent); +        if (local->xattr == NULL) { +            local->xattr = dict_ref(xattr); +        } else { +            /* Don't aggregate for files. See BZ#1484113 */ +            if (is_dir) +                dht_aggregate_xattr(local->xattr, xattr); +        } -                if (!dict_get (xattr, conf->mds_xattr_key)) { -                        goto unlock; -                } else { -                        gf_msg_debug (this->name, 0, -                                      "internal xattr %s is present on subvol" -                                      "on path %s gfid is %s " , -                                      conf->mds_xattr_key, -                                      local->loc.path, gfid_local); -                } -                check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key, -                                                mds_xattr_val, 1, &errst); -                /* save mds subvol on inode ctx */ -                ret = dht_inode_ctx_mdsvol_set (local->inode, this, -                                                prev); -                if (ret) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_SET_INODE_CTX_FAILED, -                                "Failed to set hashed subvol for %s vol is %s", -                                local->loc.path, prev->name); -                } +        if (local->inode == NULL) +            local->inode = inode_ref(inode); -                if ((check_mds < 0) && !errst) { -                        local->mds_xattr = dict_ref (xattr); -                        gf_msg_debug (this->name, 0, -                                      "Value of %s is not zero on mds subvol" -                                      "so xattr needs to be healed on non mds" -                                      " path is %s and vol name is %s " -                                      " gfid is %s" , -                                      conf->mds_xattr_key, -                                      local->loc.path, -                                      prev->name, gfid_local); -                        local->need_xattr_heal = 1; -                        local->mds_subvol  = prev; -                } +        dht_iatt_merge(this, &local->stbuf, stbuf); +        dht_iatt_merge(this, &local->postparent, postparent); -        } +        if (!dict_get(xattr, conf->mds_xattr_key)) { +            goto unlock; +        } else { +            gf_msg_debug(this->name, 0, +                         "internal xattr %s is present on subvol" +                         "on path %s gfid is %s ", +                         conf->mds_xattr_key, local->loc.path, gfid_local); +        } +        check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, +                                       mds_xattr_val, 1, &errst); +        /* save mds subvol on inode ctx */ +        ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); +        if (ret) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, +                   "Failed to set hashed subvol for %s vol is %s", +                   local->loc.path, prev->name); +        } + +        if ((check_mds < 0) && !errst) { +            local->mds_xattr = dict_ref(xattr); +            gf_msg_debug(this->name, 0, +                         "Value of %s is not zero on mds subvol" +                         "so xattr needs to be healed on non mds" +                         " path is %s and vol name is %s " +                         " gfid is %s", +                         conf->mds_xattr_key, local->loc.path, prev->name, +                         gfid_local); +            local->need_xattr_heal = 1; +            local->mds_subvol = prev; +        } +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock);  out: -        /* Make sure, the thread executing dht_discover_complete is the one -         * which calls STACK_DESTROY (frame). In the case of "attempt_unwind", -         * this makes sure that the thread don't call dht_frame_return, till -         * call to dht_discover_complete is done. -         */ -        if (attempt_unwind) { -                dht_discover_complete (this, frame); -        } +    /* Make sure, the thread executing dht_discover_complete is the one +     * which calls STACK_DESTROY (frame). In the case of "attempt_unwind", +     * this makes sure that the thread don't call dht_frame_return, till +     * call to dht_discover_complete is done. +     */ +    if (attempt_unwind) { +        dht_discover_complete(this, frame); +    } -        this_call_cnt = dht_frame_return (frame); +    this_call_cnt = dht_frame_return(frame); -        if (is_last_call (this_call_cnt) && !attempt_unwind) { -                dht_discover_complete (this, frame); -        } +    if (is_last_call(this_call_cnt) && !attempt_unwind) { +        dht_discover_complete(this, frame); +    } -        if (is_last_call (this_call_cnt)) -                DHT_STACK_DESTROY (frame); +    if (is_last_call(this_call_cnt)) +        DHT_STACK_DESTROY(frame); -        return 0; +    return 0;  } -  int -dht_do_discover (call_frame_t *frame, xlator_t *this, loc_t *loc) +dht_do_discover(call_frame_t *frame, xlator_t *this, loc_t *loc)  { -        int          ret; -        dht_local_t *local = NULL; -        dht_conf_t  *conf = NULL; -        int          call_cnt = 0; -        int          op_errno = EINVAL; -        int          i = 0; -        call_frame_t *discover_frame = NULL; +    int ret; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int call_cnt = 0; +    int op_errno = EINVAL; +    int i = 0; +    call_frame_t *discover_frame = NULL; -        conf = this->private; -        local = frame->local; +    conf = this->private; +    local = frame->local; -        ret = dht_set_file_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                goto err; -        } +    ret = dht_set_file_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        goto err; +    } -        ret = dht_set_dir_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                goto err; -        } +    ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        goto err; +    } -        if (loc_is_root (loc)) { -                ret = dict_set_uint32 (local->xattr_req, -                                       conf->commithash_xattr_name, -                                       sizeof(uint32_t)); -        } +    if (loc_is_root(loc)) { +        ret = dict_set_uint32(local->xattr_req, conf->commithash_xattr_name, +                              sizeof(uint32_t)); +    } -        call_cnt        = conf->subvolume_cnt; -        local->call_cnt = call_cnt; +    call_cnt = conf->subvolume_cnt; +    local->call_cnt = call_cnt; -        local->layout = dht_layout_new (this, conf->subvolume_cnt); +    local->layout = dht_layout_new(this, conf->subvolume_cnt); -        if (!local->layout) { -                op_errno = ENOMEM; -                goto err; -        } +    if (!local->layout) { +        op_errno = ENOMEM; +        goto err; +    } -        gf_uuid_copy (local->gfid, loc->gfid); +    gf_uuid_copy(local->gfid, loc->gfid); -        discover_frame = copy_frame (frame); -        if (!discover_frame) { -                op_errno = ENOMEM; -                goto err; -        } +    discover_frame = copy_frame(frame); +    if (!discover_frame) { +        op_errno = ENOMEM; +        goto err; +    } -        discover_frame->local = local; -        frame->local = NULL; -        local->main_frame = frame; +    discover_frame->local = local; +    frame->local = NULL; +    local->main_frame = frame; -        for (i = 0; i < call_cnt; i++) { -                STACK_WIND_COOKIE (discover_frame, dht_discover_cbk, -                                   conf->subvolumes[i], conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->lookup, -                                   &local->loc, local->xattr_req); -        } +    for (i = 0; i < call_cnt; i++) { +        STACK_WIND_COOKIE(discover_frame, dht_discover_cbk, conf->subvolumes[i], +                          conf->subvolumes[i], +                          conf->subvolumes[i]->fops->lookup, &local->loc, +                          local->xattr_req); +    } -        return 0; +    return 0;  err: -        DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL); +    DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  }  /* Get the value of key from dict in the bytewise and save in array after     convert from network byte order to host byte order  */  int32_t -dht_dict_get_array (dict_t *dict, char *key, int32_t value[], int32_t size, int *errst) -{ -        void    *ptr          = NULL; -        int32_t len           = -1; -        int32_t vindex        = -1; -        int32_t err           = -1; -        int     ret          = 0; - -        if (dict == NULL) { -                (*errst) = -1; -                return -EINVAL; -        } -        err = dict_get_ptr_and_len(dict, key, &ptr, &len); -        if (err != 0) { -                (*errst) = -1; -                return err; -        } - -        if (len != (size * sizeof (int32_t))) { -                (*errst) = -1; -                return -EINVAL; -        } - -        for (vindex = 0; vindex < size; vindex++) { -                value[vindex] = ntoh32(*((int32_t *)ptr + vindex)); -                if (value[vindex] < 0) -                        ret = -1; -        } - -        return ret; +dht_dict_get_array(dict_t *dict, char *key, int32_t value[], int32_t size, +                   int *errst) +{ +    void *ptr = NULL; +    int32_t len = -1; +    int32_t vindex = -1; +    int32_t err = -1; +    int ret = 0; + +    if (dict == NULL) { +        (*errst) = -1; +        return -EINVAL; +    } +    err = dict_get_ptr_and_len(dict, key, &ptr, &len); +    if (err != 0) { +        (*errst) = -1; +        return err; +    } + +    if (len != (size * sizeof(int32_t))) { +        (*errst) = -1; +        return -EINVAL; +    } + +    for (vindex = 0; vindex < size; vindex++) { +        value[vindex] = ntoh32(*((int32_t *)ptr + vindex)); +        if (value[vindex] < 0) +            ret = -1; +    } + +    return ret;  } -  /* Code to call syntask to heal custom xattr from hashed subvol     to non hashed subvol  */  int -dht_dir_xattr_heal (xlator_t *this, dht_local_t *local) +dht_dir_xattr_heal(xlator_t *this, dht_local_t *local)  { -        dht_local_t  *copy_local                  = NULL; -        call_frame_t *copy                        = NULL; -        int          ret                          = -1; -        char         gfid_local[GF_UUID_BUF_SIZE] = {0}; +    dht_local_t *copy_local = NULL; +    call_frame_t *copy = NULL; +    int ret = -1; +    char gfid_local[GF_UUID_BUF_SIZE] = {0}; -        if (gf_uuid_is_null (local->gfid)) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_DIR_XATTR_HEAL_FAILED, -                        "No gfid exists for path %s " -                        "so healing xattr is not possible", -                        local->loc.path); -                goto out; -        } - -        gf_uuid_unparse(local->gfid, gfid_local); -        copy = create_frame (this, this->ctx->pool); -        if (copy) { -                copy_local = dht_local_init (copy, &(local->loc), NULL, 0); -                if (!copy_local) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                DHT_MSG_DIR_XATTR_HEAL_FAILED, -                                "Memory allocation failed " -                                "for path %s gfid %s ", -                                local->loc.path, gfid_local); -                        DHT_STACK_DESTROY (copy); -                } else { -                        copy_local->stbuf = local->stbuf; -                        gf_uuid_copy (copy_local->loc.gfid, local->gfid); -                        copy_local->mds_subvol = local->mds_subvol; -                        FRAME_SU_DO (copy, dht_local_t); -                        ret = synctask_new (this->ctx->env, dht_dir_heal_xattrs, -                                            dht_dir_heal_xattrs_done, -                                            copy, copy); -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_DIR_XATTR_HEAL_FAILED, -                                        "Synctask creation failed to heal xattr " -                                        "for path %s gfid %s ", -                                        local->loc.path, gfid_local); -                                DHT_STACK_DESTROY (copy); -                        } -                } +    if (gf_uuid_is_null(local->gfid)) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DIR_XATTR_HEAL_FAILED, +               "No gfid exists for path %s " +               "so healing xattr is not possible", +               local->loc.path); +        goto out; +    } + +    gf_uuid_unparse(local->gfid, gfid_local); +    copy = create_frame(this, this->ctx->pool); +    if (copy) { +        copy_local = dht_local_init(copy, &(local->loc), NULL, 0); +        if (!copy_local) { +            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, +                   DHT_MSG_DIR_XATTR_HEAL_FAILED, +                   "Memory allocation failed " +                   "for path %s gfid %s ", +                   local->loc.path, gfid_local); +            DHT_STACK_DESTROY(copy); +        } else { +            copy_local->stbuf = local->stbuf; +            gf_uuid_copy(copy_local->loc.gfid, local->gfid); +            copy_local->mds_subvol = local->mds_subvol; +            FRAME_SU_DO(copy, dht_local_t); +            ret = synctask_new(this->ctx->env, dht_dir_heal_xattrs, +                               dht_dir_heal_xattrs_done, copy, copy); +            if (ret) { +                gf_msg(this->name, GF_LOG_ERROR, ENOMEM, +                       DHT_MSG_DIR_XATTR_HEAL_FAILED, +                       "Synctask creation failed to heal xattr " +                       "for path %s gfid %s ", +                       local->loc.path, gfid_local); +                DHT_STACK_DESTROY(copy); +            }          } +    }  out: -        return ret; -} - +    return ret; +} + +int +dht_lookup_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                   int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, +                   dict_t *xattr, struct iatt *postparent) +{ +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    dht_layout_t *layout = NULL; +    int ret = -1; +    int is_dir = 0; +    int32_t check_mds = 0; +    int errst = 0; +    char gfid_local[GF_UUID_BUF_SIZE] = {0}; +    char gfid_node[GF_UUID_BUF_SIZE] = {0}; +    int32_t mds_xattr_val[1] = {0}; +    call_frame_t *copy = NULL; +    dht_local_t *copy_local = NULL; + +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); +    GF_VALIDATE_OR_GOTO("dht", cookie, out); + +    local = frame->local; +    prev = cookie; +    conf = this->private; + +    layout = local->layout; + +    if (!op_ret && gf_uuid_is_null(local->gfid)) { +        memcpy(local->gfid, stbuf->ia_gfid, 16); +    } +    if (!gf_uuid_is_null(local->gfid)) { +        gf_uuid_unparse(local->gfid, gfid_local); +    } +    /* Check if the gfid is different for file from other node */ +    if (!op_ret && gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { +        gf_uuid_unparse(stbuf->ia_gfid, gfid_node); -int -dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, -                    inode_t *inode, struct iatt *stbuf, dict_t *xattr, -                    struct iatt *postparent) -{ -        dht_local_t  *local                   = NULL; -        dht_conf_t   *conf                    = NULL; -        int           this_call_cnt           = 0; -        xlator_t     *prev                    = NULL; -        dht_layout_t *layout                  = NULL; -        int           ret                     = -1; -        int           is_dir                  = 0; -        int32_t       check_mds               = 0; -        int           errst                   = 0; -        char          gfid_local[GF_UUID_BUF_SIZE] = {0}; -        char          gfid_node[GF_UUID_BUF_SIZE]  = {0}; -        int32_t       mds_xattr_val[1]                 = {0}; -        call_frame_t *copy                         = NULL; -        dht_local_t  *copy_local                   = NULL; +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, +               "%s: gfid different on %s." +               " gfid local = %s, gfid subvol = %s", +               local->loc.path, prev->name, gfid_local, gfid_node); +    } -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); -        GF_VALIDATE_OR_GOTO ("dht", cookie, out); +    LOCK(&frame->lock); +    { +        /* TODO: assert equal mode on stbuf->st_mode and +           local->stbuf->st_mode -        local = frame->local; -        prev  = cookie; -        conf  = this->private; +           else mkdir/chmod/chown and fix +        */ +        ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); -        layout = local->layout; +        if (op_ret == -1) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, +                         "lookup of %s on %s returned error", local->loc.path, +                         prev->name); -        if (!op_ret && gf_uuid_is_null (local->gfid)) { -                memcpy (local->gfid, stbuf->ia_gfid, 16); +            goto unlock;          } -        if (!gf_uuid_is_null(local->gfid)) { -                gf_uuid_unparse(local->gfid, gfid_local); -        } - -        /* Check if the gfid is different for file from other node */ -        if (!op_ret && gf_uuid_compare (local->gfid, stbuf->ia_gfid)) { -                gf_uuid_unparse(stbuf->ia_gfid, gfid_node); +        is_dir = check_is_dir(inode, stbuf, xattr); +        if (!is_dir) { +            gf_msg_debug(this->name, 0, +                         "lookup of %s on %s returned non" +                         "dir 0%o" +                         "calling lookup_everywhere", +                         local->loc.path, prev->name, stbuf->ia_type); -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_GFID_MISMATCH, -                        "%s: gfid different on %s." -                        " gfid local = %s, gfid subvol = %s", -                        local->loc.path, prev->name, -                        gfid_local, gfid_node); +            local->need_selfheal = 1; +            goto unlock;          } -        LOCK (&frame->lock); -        { -                /* TODO: assert equal mode on stbuf->st_mode and -                   local->stbuf->st_mode - -                   else mkdir/chmod/chown and fix -                */ -                ret = dht_layout_merge (this, layout, prev, op_ret, op_errno, -                                        xattr); - -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "lookup of %s on %s returned error", -                                      local->loc.path, prev->name); - -                        goto unlock; -                } - -                is_dir = check_is_dir (inode, stbuf, xattr); -                if (!is_dir) { - -                        gf_msg_debug (this->name, 0, -                                      "lookup of %s on %s returned non" -                                      "dir 0%o" -                                      "calling lookup_everywhere", -                                      local->loc.path, prev->name, -                                      stbuf->ia_type); - -                        local->need_selfheal = 1; -                        goto unlock; -                } - -                local->op_ret = 0; -                if (local->xattr == NULL) { -                        local->xattr = dict_ref (xattr); -                } else { -                        dht_aggregate_xattr (local->xattr, xattr); -                } - -                if (dict_get (xattr, conf->mds_xattr_key)) { -                        local->mds_subvol  = prev; -                        local->mds_stbuf.ia_gid = stbuf->ia_gid; -                        local->mds_stbuf.ia_uid = stbuf->ia_uid; -                        local->mds_stbuf.ia_prot = stbuf->ia_prot; -                } +        local->op_ret = 0; +        if (local->xattr == NULL) { +            local->xattr = dict_ref(xattr); +        } else { +            dht_aggregate_xattr(local->xattr, xattr); +        } -                if (local->stbuf.ia_type != IA_INVAL) { -                        if (!__is_root_gfid (stbuf->ia_gfid) && -                            ((local->stbuf.ia_gid != stbuf->ia_gid) || -                            (local->stbuf.ia_uid != stbuf->ia_uid) || -                            (is_permission_different (&local->stbuf.ia_prot, -                                                      &stbuf->ia_prot)))) { -                                local->need_attrheal = 1; -                        } -                } +        if (dict_get(xattr, conf->mds_xattr_key)) { +            local->mds_subvol = prev; +            local->mds_stbuf.ia_gid = stbuf->ia_gid; +            local->mds_stbuf.ia_uid = stbuf->ia_uid; +            local->mds_stbuf.ia_prot = stbuf->ia_prot; +        } -                if (local->inode == NULL) -                        local->inode = inode_ref (inode); +        if (local->stbuf.ia_type != IA_INVAL) { +            if (!__is_root_gfid(stbuf->ia_gfid) && +                ((local->stbuf.ia_gid != stbuf->ia_gid) || +                 (local->stbuf.ia_uid != stbuf->ia_uid) || +                 (is_permission_different(&local->stbuf.ia_prot, +                                          &stbuf->ia_prot)))) { +                local->need_attrheal = 1; +            } +        } -                dht_iatt_merge (this, &local->stbuf, stbuf); -                dht_iatt_merge (this, &local->postparent, postparent); +        if (local->inode == NULL) +            local->inode = inode_ref(inode); -                if (!dict_get (xattr, conf->mds_xattr_key)) { -                        gf_msg_debug (this->name, 0, -                                      "Internal xattr %s is not present " -                                      " on path %s gfid is %s " , -                                      conf->mds_xattr_key, -                                      local->loc.path, gfid_local); -                        goto unlock; -                } else { -                        /* Save mds subvol on inode ctx */ -                        ret = dht_inode_ctx_mdsvol_set (local->inode, this, -                                                        prev); -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, 0, -                                        DHT_MSG_SET_INODE_CTX_FAILED, -                                        "Failed to set hashed subvol for %s vol is %s", -                                        local->loc.path, prev->name); -                         } -                } -                check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key, -                                                mds_xattr_val, 1, &errst); -                if ((check_mds < 0) && !errst) { -                        local->mds_xattr = dict_ref (xattr); -                        gf_msg_debug (this->name, 0, -                                      "Value of %s is not zero on hashed subvol " -                                      "so xattr needs to be heal on non hashed" -                                      " path is %s and vol name is %s " -                                      " gfid is %s" , -                                      conf->mds_xattr_key, -                                      local->loc.path, -                                      prev->name, gfid_local); -                        local->need_xattr_heal = 1; -                        local->mds_subvol  = prev; -                } +        dht_iatt_merge(this, &local->stbuf, stbuf); +        dht_iatt_merge(this, &local->postparent, postparent); +        if (!dict_get(xattr, conf->mds_xattr_key)) { +            gf_msg_debug(this->name, 0, +                         "Internal xattr %s is not present " +                         " on path %s gfid is %s ", +                         conf->mds_xattr_key, local->loc.path, gfid_local); +            goto unlock; +        } else { +            /* Save mds subvol on inode ctx */ +            ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); +            if (ret) { +                gf_msg(this->name, GF_LOG_ERROR, 0, +                       DHT_MSG_SET_INODE_CTX_FAILED, +                       "Failed to set hashed subvol for %s vol is %s", +                       local->loc.path, prev->name); +            }          } +        check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, +                                       mds_xattr_val, 1, &errst); +        if ((check_mds < 0) && !errst) { +            local->mds_xattr = dict_ref(xattr); +            gf_msg_debug(this->name, 0, +                         "Value of %s is not zero on hashed subvol " +                         "so xattr needs to be heal on non hashed" +                         " path is %s and vol name is %s " +                         " gfid is %s", +                         conf->mds_xattr_key, local->loc.path, prev->name, +                         gfid_local); +            local->need_xattr_heal = 1; +            local->mds_subvol = prev; +        } +    }  unlock: -        UNLOCK (&frame->lock); - +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); +    this_call_cnt = dht_frame_return(frame); -        if (is_last_call (this_call_cnt)) { -                /* No need to call xattr heal code if volume count is 1 -                */ -                if (conf->subvolume_cnt == 1) -                        local->need_xattr_heal = 0; +    if (is_last_call(this_call_cnt)) { +        /* No need to call xattr heal code if volume count is 1 +         */ +        if (conf->subvolume_cnt == 1) +            local->need_xattr_heal = 0; -                /* Code to update all extended attributed from hashed subvol -                   to local->xattr -                */ -                if (local->need_xattr_heal && (local->mds_xattr)) { -                        dht_dir_set_heal_xattr (this, local, local->xattr, -                                                local->mds_xattr, NULL, NULL); -                        dict_unref (local->mds_xattr); -                        local->mds_xattr = NULL; -                } +        /* Code to update all extended attributed from hashed subvol +           to local->xattr +        */ +        if (local->need_xattr_heal && (local->mds_xattr)) { +            dht_dir_set_heal_xattr(this, local, local->xattr, local->mds_xattr, +                                   NULL, NULL); +            dict_unref(local->mds_xattr); +            local->mds_xattr = NULL; +        } -                if (local->need_selfheal) { -                        local->need_selfheal = 0; -                        dht_lookup_everywhere (frame, this, &local->loc); -                        return 0; -                } +        if (local->need_selfheal) { +            local->need_selfheal = 0; +            dht_lookup_everywhere(frame, this, &local->loc); +            return 0; +        } -                if (local->op_ret == 0) { -                        ret = dht_layout_normalize (this, &local->loc, layout); +        if (local->op_ret == 0) { +            ret = dht_layout_normalize(this, &local->loc, layout); -                        if (ret != 0) { -                                gf_msg_debug (this->name, 0, -                                              "fixing assignment on %s", -                                              local->loc.path); -                                goto selfheal; -                        } +            if (ret != 0) { +                gf_msg_debug(this->name, 0, "fixing assignment on %s", +                             local->loc.path); +                goto selfheal; +            } -                        dht_layout_set (this, local->inode, layout); -                        if (!dict_get (local->xattr, conf->mds_xattr_key) || -                            local->need_xattr_heal) -                                goto selfheal; -                } +            dht_layout_set(this, local->inode, layout); +            if (!dict_get(local->xattr, conf->mds_xattr_key) || +                local->need_xattr_heal) +                goto selfheal; +        } -                if (local->inode) { -                        dht_inode_ctx_time_update (local->inode, this, -                                                   &local->stbuf, 1); -                } +        if (local->inode) { +            dht_inode_ctx_time_update(local->inode, this, &local->stbuf, 1); +        } -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1); +        } -                if (local->need_attrheal) { -                        local->need_attrheal = 0; -                        if (!__is_root_gfid (inode->gfid)) { -                                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; -                                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; -                                local->stbuf.ia_prot = local->mds_stbuf.ia_prot; -                        } -                        copy = create_frame (this, this->ctx->pool); -                        if (copy) { -                                copy_local = dht_local_init (copy, &local->loc, -                                                             NULL, 0); -                                if (!copy_local) { -                                        DHT_STACK_DESTROY (copy); -                                        goto skip_attr_heal; -                                } -                                copy_local->stbuf = local->stbuf; -                                gf_uuid_copy (copy_local->loc.gfid, -                                              local->stbuf.ia_gfid); -                                copy_local->mds_stbuf = local->mds_stbuf; -                                copy_local->mds_subvol = local->mds_subvol; -                                copy->local = copy_local; -                                FRAME_SU_DO (copy, dht_local_t); -                                ret = synctask_new (this->ctx->env, -                                                    dht_dir_attr_heal, -                                                    dht_dir_attr_heal_done, -                                                    copy, copy); -                                if (ret) { -                                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                                DHT_MSG_DIR_ATTR_HEAL_FAILED, -                                                "Synctask creation failed to heal attr " -                                                "for path %s gfid %s ", -                                                local->loc.path, local->gfid); -                                        DHT_STACK_DESTROY (copy); -                                } -                        } +        if (local->need_attrheal) { +            local->need_attrheal = 0; +            if (!__is_root_gfid(inode->gfid)) { +                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; +                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; +                local->stbuf.ia_prot = local->mds_stbuf.ia_prot; +            } +            copy = create_frame(this, this->ctx->pool); +            if (copy) { +                copy_local = dht_local_init(copy, &local->loc, NULL, 0); +                if (!copy_local) { +                    DHT_STACK_DESTROY(copy); +                    goto skip_attr_heal; +                } +                copy_local->stbuf = local->stbuf; +                gf_uuid_copy(copy_local->loc.gfid, local->stbuf.ia_gfid); +                copy_local->mds_stbuf = local->mds_stbuf; +                copy_local->mds_subvol = local->mds_subvol; +                copy->local = copy_local; +                FRAME_SU_DO(copy, dht_local_t); +                ret = synctask_new(this->ctx->env, dht_dir_attr_heal, +                                   dht_dir_attr_heal_done, copy, copy); +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, +                           DHT_MSG_DIR_ATTR_HEAL_FAILED, +                           "Synctask creation failed to heal attr " +                           "for path %s gfid %s ", +                           local->loc.path, local->gfid); +                    DHT_STACK_DESTROY(copy);                  } - -skip_attr_heal: -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                dht_set_fixed_dir_stat (&local->postparent); -                /* Delete mds xattr at the time of STACK UNWIND */ -                if (local->xattr) -                        GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr); -                DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, -                                  local->inode, &local->stbuf, local->xattr, -                                  &local->postparent); +            }          } -        return 0; +    skip_attr_heal: +        DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +        dht_set_fixed_dir_stat(&local->postparent); +        /* Delete mds xattr at the time of STACK UNWIND */ +        if (local->xattr) +            GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); +        DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                         local->inode, &local->stbuf, local->xattr, +                         &local->postparent); +    } + +    return 0;  selfheal: -        FRAME_SU_DO (frame, dht_local_t); -        ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk, -                                      &local->loc, layout); +    FRAME_SU_DO(frame, dht_local_t); +    ret = dht_selfheal_directory(frame, dht_lookup_selfheal_cbk, &local->loc, +                                 layout);  out: -        return ret; -} +    return ret; +} + +int +is_permission_different(ia_prot_t *prot1, ia_prot_t *prot2) +{ +    if ((prot1->owner.read != prot2->owner.read) || +        (prot1->owner.write != prot2->owner.write) || +        (prot1->owner.exec != prot2->owner.exec) || +        (prot1->group.read != prot2->group.read) || +        (prot1->group.write != prot2->group.write) || +        (prot1->group.exec != prot2->group.exec) || +        (prot1->other.read != prot2->other.read) || +        (prot1->other.write != prot2->other.write) || +        (prot1->other.exec != prot2->other.exec) || +        (prot1->suid != prot2->suid) || (prot1->sgid != prot2->sgid) || +        (prot1->sticky != prot2->sticky)) { +        return 1; +    } else { +        return 0; +    } +} + +int +dht_revalidate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                   int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, +                   dict_t *xattr, struct iatt *postparent) +{ +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    dht_layout_t *layout = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    int is_dir = 0; +    int is_linkfile = 0; +    int follow_link = 0; +    call_frame_t *copy = NULL; +    dht_local_t *copy_local = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    uint32_t vol_commit_hash = 0; +    xlator_t *subvol = NULL; +    int32_t check_mds = 0; +    int errst = 0; +    int32_t mds_xattr_val[1] = {0}; + +    GF_VALIDATE_OR_GOTO("dht", frame, err); +    GF_VALIDATE_OR_GOTO("dht", this, err); +    GF_VALIDATE_OR_GOTO("dht", frame->local, err); +    GF_VALIDATE_OR_GOTO("dht", cookie, err); + +    local = frame->local; +    prev = cookie; +    conf = this->private; +    if (!conf) +        goto out; -int -is_permission_different (ia_prot_t *prot1, ia_prot_t *prot2) -{ -        if ((prot1->owner.read != prot2->owner.read) || -            (prot1->owner.write != prot2->owner.write) || -            (prot1->owner.exec != prot2->owner.exec) || -            (prot1->group.read != prot2->group.read) || -            (prot1->group.write != prot2->group.write) || -            (prot1->group.exec != prot2->group.exec) || -            (prot1->other.read != prot2->other.read) || -            (prot1->other.write != prot2->other.write) || -            (prot1->other.exec != prot2->other.exec) || -            (prot1->suid != prot2->suid) || -            (prot1->sgid != prot2->sgid) || -            (prot1->sticky != prot2->sticky)) { -                return 1; -        } else { -                return 0; +    if (!conf->vch_forced) { +        ret = dict_get_uint32(xattr, conf->commithash_xattr_name, +                              &vol_commit_hash); +        if (ret == 0) { +            conf->vol_commit_hash = vol_commit_hash;          } -} - -int -dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                    int op_ret, int op_errno, -                    inode_t *inode, struct iatt *stbuf, dict_t *xattr, -                    struct iatt *postparent) -{ -        dht_local_t  *local         = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev          = NULL; -        dht_layout_t *layout        = NULL; -        dht_conf_t   *conf          = NULL; -        int           ret  = -1; -        int           is_dir = 0; -        int           is_linkfile = 0; -        int           follow_link = 0; -        call_frame_t *copy          = NULL; -        dht_local_t  *copy_local    = NULL; -        char gfid[GF_UUID_BUF_SIZE] = {0}; -        uint32_t      vol_commit_hash = 0; -        xlator_t      *subvol = NULL; -        int32_t       check_mds       = 0; -        int           errst           = 0; -        int32_t       mds_xattr_val[1] = {0}; - -        GF_VALIDATE_OR_GOTO ("dht", frame, err); -        GF_VALIDATE_OR_GOTO ("dht", this, err); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, err); -        GF_VALIDATE_OR_GOTO ("dht", cookie, err); +    } -        local = frame->local; -        prev  = cookie; -        conf = this->private; -        if (!conf) -                goto out; +    gf_uuid_unparse(local->loc.gfid, gfid); -        if (!conf->vch_forced) { -                ret = dict_get_uint32 (xattr, conf->commithash_xattr_name, -                                       &vol_commit_hash); -                if (ret == 0) { -                        conf->vol_commit_hash = vol_commit_hash; -                } +    LOCK(&frame->lock); +    { +        if (gf_uuid_is_null(local->gfid)) { +            memcpy(local->gfid, local->loc.gfid, 16);          } -        gf_uuid_unparse (local->loc.gfid, gfid); +        gf_msg_debug(this->name, op_errno, +                     "revalidate lookup of %s " +                     "returned with op_ret %d", +                     local->loc.path, op_ret); -        LOCK (&frame->lock); -        { -                if (gf_uuid_is_null (local->gfid)) { -                        memcpy (local->gfid, local->loc.gfid, 16); -                } +        if (op_ret == -1) { +            local->op_errno = op_errno; + +            if ((op_errno != ENOTCONN) && (op_errno != ENOENT) && +                (op_errno != ESTALE)) { +                gf_msg(this->name, GF_LOG_INFO, op_errno, +                       DHT_MSG_REVALIDATE_CBK_INFO, +                       "Revalidate: subvolume %s for %s " +                       "(gfid = %s) returned -1", +                       prev->name, local->loc.path, gfid); +            } +            if (op_errno == ESTALE) { +                /* propagate the ESTALE to parent. +                 * setting local->return_estale would send +                 * ESTALE to parent. */ +                local->return_estale = 1; +            } + +            /* if it is ENOENT, we may have to do a +             * 'lookup_everywhere()' to make sure +             * the file is not migrated */ +            if (op_errno == ENOENT) { +                if (IA_ISREG(local->loc.inode->ia_type)) { +                    gf_msg_debug(this->name, 0, +                                 "found ENOENT for %s. " +                                 "Setting " +                                 "need_lookup_everywhere" +                                 " flag to 1", +                                 local->loc.path); -                gf_msg_debug (this->name, op_errno, -                              "revalidate lookup of %s " -                              "returned with op_ret %d", -                              local->loc.path, op_ret); - -                if (op_ret == -1) { -                        local->op_errno = op_errno; - -                        if ((op_errno != ENOTCONN) -                            && (op_errno != ENOENT) -                            && (op_errno != ESTALE)) { -                                gf_msg (this->name, GF_LOG_INFO, op_errno, -                                        DHT_MSG_REVALIDATE_CBK_INFO, -                                        "Revalidate: subvolume %s for %s " -                                        "(gfid = %s) returned -1", -                                        prev->name, local->loc.path, -                                        gfid); -                        } -                        if (op_errno == ESTALE) { -                                /* propagate the ESTALE to parent. -                                 * setting local->return_estale would send -                                 * ESTALE to parent. */ -                                local->return_estale = 1; -                        } - -                        /* if it is ENOENT, we may have to do a -                         * 'lookup_everywhere()' to make sure -                         * the file is not migrated */ -                        if (op_errno == ENOENT) { -                                if (IA_ISREG (local->loc.inode->ia_type)) { - -                                        gf_msg_debug (this->name, 0, -                                                      "found ENOENT for %s. " -                                                      "Setting " -                                                      "need_lookup_everywhere" -                                                      " flag to 1", -                                                      local->loc.path); - -                                        local->need_lookup_everywhere = 1; -                                } -                        } -                        goto unlock; +                    local->need_lookup_everywhere = 1;                  } +            } +            goto unlock; +        } + +        if ((!IA_ISINVAL(local->inode->ia_type)) && +            stbuf->ia_type != local->inode->ia_type) { +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_FILE_TYPE_MISMATCH, +                   "mismatching filetypes 0%o v/s 0%o for %s," +                   " gfid = %s", +                   (stbuf->ia_type), (local->inode->ia_type), local->loc.path, +                   gfid); -                if ((!IA_ISINVAL(local->inode->ia_type)) && -                    stbuf->ia_type != local->inode->ia_type) { -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_FILE_TYPE_MISMATCH, -                                "mismatching filetypes 0%o v/s 0%o for %s," -                                " gfid = %s", -                                (stbuf->ia_type), (local->inode->ia_type), -                                local->loc.path, gfid); +            local->op_ret = -1; +            local->op_errno = EINVAL; -                        local->op_ret = -1; -                        local->op_errno = EINVAL; +            goto unlock; +        } + +        layout = local->layout; -                        goto unlock; +        is_dir = check_is_dir(inode, stbuf, xattr); +        is_linkfile = check_is_linkfile(inode, stbuf, xattr, +                                        conf->link_xattr_name); +        if (is_linkfile) { +            follow_link = 1; +            goto unlock; +        } +        if (is_dir) { +            ret = dht_dir_has_layout(xattr, conf->xattr_name); +            if (ret >= 0) { +                if (is_greater_time(local->stbuf.ia_ctime, +                                    local->stbuf.ia_ctime_nsec, stbuf->ia_ctime, +                                    stbuf->ia_ctime_nsec)) { +                    /* Choose source */ +                    local->prebuf.ia_gid = stbuf->ia_gid; +                    local->prebuf.ia_uid = stbuf->ia_uid; + +                    if (__is_root_gfid(stbuf->ia_gfid)) +                        local->prebuf.ia_prot = stbuf->ia_prot; +                } +            } +            if (local->stbuf.ia_type != IA_INVAL) { +                if ((local->stbuf.ia_gid != stbuf->ia_gid) || +                    (local->stbuf.ia_uid != stbuf->ia_uid) || +                    is_permission_different(&local->stbuf.ia_prot, +                                            &stbuf->ia_prot)) { +                    local->need_selfheal = 1;                  } +            } -                layout = local->layout; +            if (!dict_get(xattr, conf->mds_xattr_key)) { +                gf_msg_debug(this->name, 0, +                             "internal xattr %s is not present" +                             " on path %s gfid is %s ", +                             conf->mds_xattr_key, local->loc.path, gfid); +            } else { +                check_mds = dht_dict_get_array(xattr, conf->mds_xattr_key, +                                               mds_xattr_val, 1, &errst); +                local->mds_subvol = prev; +                local->mds_stbuf.ia_gid = stbuf->ia_gid; +                local->mds_stbuf.ia_uid = stbuf->ia_uid; +                local->mds_stbuf.ia_prot = stbuf->ia_prot; -                is_dir = check_is_dir (inode, stbuf, xattr); -                is_linkfile = check_is_linkfile (inode, stbuf, xattr, -                                                 conf->link_xattr_name); -                if (is_linkfile) { -                        follow_link = 1; -                        goto unlock; +                /* save mds subvol on inode ctx */ +                ret = dht_inode_ctx_mdsvol_set(local->inode, this, prev); +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, 0, +                           DHT_MSG_SET_INODE_CTX_FAILED, +                           "Failed to set MDS subvol for %s vol is %s", +                           local->loc.path, prev->name);                  } -                if (is_dir) { -                        ret = dht_dir_has_layout (xattr, conf->xattr_name); -                        if (ret >= 0) { -                                if (is_greater_time(local->stbuf.ia_ctime, -                                                    local->stbuf.ia_ctime_nsec, -                                                    stbuf->ia_ctime, -                                                    stbuf->ia_ctime_nsec)) { -                                        /* Choose source */ -                                        local->prebuf.ia_gid = stbuf->ia_gid; -                                        local->prebuf.ia_uid = stbuf->ia_uid; - -                                        if (__is_root_gfid (stbuf->ia_gfid)) -                                                local->prebuf.ia_prot = stbuf->ia_prot; -                                } -                        } - -                        if (local->stbuf.ia_type != IA_INVAL) -                        { -                                if ((local->stbuf.ia_gid != stbuf->ia_gid) || -                                    (local->stbuf.ia_uid != stbuf->ia_uid) || -                                     is_permission_different (&local->stbuf.ia_prot, -                                                              &stbuf->ia_prot)) { -                                        local->need_selfheal = 1; -                                } -                        } - -                        if (!dict_get (xattr, conf->mds_xattr_key)) { -                                gf_msg_debug (this->name, 0, -                                              "internal xattr %s is not present" -                                              " on path %s gfid is %s " , -                                              conf->mds_xattr_key, -                                              local->loc.path, gfid); -                        } else { -                                check_mds = dht_dict_get_array (xattr, conf->mds_xattr_key, -                                                                mds_xattr_val, 1, &errst); -                                local->mds_subvol  = prev; -                                local->mds_stbuf.ia_gid = stbuf->ia_gid; -                                local->mds_stbuf.ia_uid = stbuf->ia_uid; -                                local->mds_stbuf.ia_prot = stbuf->ia_prot; - -                                /* save mds subvol on inode ctx */ -                                ret = dht_inode_ctx_mdsvol_set (local->inode, this, -                                                                prev); -                                if (ret) { -                                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                                DHT_MSG_SET_INODE_CTX_FAILED, -                                                "Failed to set MDS subvol for %s vol is %s", -                                                local->loc.path, prev->name); -                                } -                                if ((check_mds < 0) && !errst) { -                                        local->mds_xattr = dict_ref (xattr); -                                        gf_msg_debug (this->name, 0, -                                                      "Value of %s is not zero on " -                                                      "hashed subvol so xattr needs to" -                                                      " be healed on non hashed" -                                                      " path is %s and vol name is %s " -                                                      " gfid is %s" , -                                                      conf->mds_xattr_key, -                                                      local->loc.path, -                                                      prev->name, gfid); -                                        local->need_xattr_heal = 1; -                                } -                        } -                        ret = dht_layout_dir_mismatch (this, layout, -                                                       prev, &local->loc, -                                                       xattr); -                        if (ret != 0) { -                                gf_msg (this->name, GF_LOG_INFO, 0, -                                        DHT_MSG_LAYOUT_MISMATCH, -                                        "Mismatching layouts for %s, gfid = %s", -                                        local->loc.path, gfid); - -                                local->layout_mismatch = 1; - -                                goto unlock; -                        } +                if ((check_mds < 0) && !errst) { +                    local->mds_xattr = dict_ref(xattr); +                    gf_msg_debug(this->name, 0, +                                 "Value of %s is not zero on " +                                 "hashed subvol so xattr needs to" +                                 " be healed on non hashed" +                                 " path is %s and vol name is %s " +                                 " gfid is %s", +                                 conf->mds_xattr_key, local->loc.path, +                                 prev->name, gfid); +                    local->need_xattr_heal = 1;                  } +            } +            ret = dht_layout_dir_mismatch(this, layout, prev, &local->loc, +                                          xattr); +            if (ret != 0) { +                gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_MISMATCH, +                       "Mismatching layouts for %s, gfid = %s", local->loc.path, +                       gfid); +                local->layout_mismatch = 1; -                /* Update stbuf from the servers where layout is present. This -                 * is an indication that the server is not a newly added brick. -                 * Merging stbuf from newly added brick may result in the added -                 * brick being the source of heal for uid/gid */ -                if (!is_dir || (is_dir && -                    dht_dir_has_layout (xattr, conf->xattr_name) >= 0) -                    || conf->subvolume_cnt == 1) { +                goto unlock; +            } +        } -                        dht_iatt_merge (this, &local->stbuf, stbuf); -                        dht_iatt_merge (this, &local->postparent, postparent); -                } else { -                        /* copy the gfid anyway */ -                        gf_uuid_copy (local->stbuf.ia_gfid, stbuf->ia_gfid); -                } +        /* Update stbuf from the servers where layout is present. This +         * is an indication that the server is not a newly added brick. +         * Merging stbuf from newly added brick may result in the added +         * brick being the source of heal for uid/gid */ +        if (!is_dir || +            (is_dir && dht_dir_has_layout(xattr, conf->xattr_name) >= 0) || +            conf->subvolume_cnt == 1) { +            dht_iatt_merge(this, &local->stbuf, stbuf); +            dht_iatt_merge(this, &local->postparent, postparent); +        } else { +            /* copy the gfid anyway */ +            gf_uuid_copy(local->stbuf.ia_gfid, stbuf->ia_gfid); +        } -                local->op_ret = 0; +        local->op_ret = 0; -                if (!local->xattr) { -                        local->xattr = dict_ref (xattr); -                } else if (is_dir) { -                        dht_aggregate_xattr (local->xattr, xattr); -                } +        if (!local->xattr) { +            local->xattr = dict_ref(xattr); +        } else if (is_dir) { +            dht_aggregate_xattr(local->xattr, xattr);          } +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        if (follow_link) { -                gf_uuid_copy (local->gfid, stbuf->ia_gfid); +    if (follow_link) { +        gf_uuid_copy(local->gfid, stbuf->ia_gfid); -                subvol = dht_linkfile_subvol (this, inode, stbuf, xattr); -                if (!subvol) { -                        op_errno = ESTALE; -                        local->op_ret = -1; -                } else { - -                        STACK_WIND_COOKIE (frame, dht_lookup_linkfile_cbk, -                                           subvol, subvol, subvol->fops->lookup, -                                           &local->loc, local->xattr_req); -                        return 0; -                } +        subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); +        if (!subvol) { +            op_errno = ESTALE; +            local->op_ret = -1; +        } else { +            STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, +                              subvol->fops->lookup, &local->loc, +                              local->xattr_req); +            return 0;          } +    }  out: -        this_call_cnt = dht_frame_return (frame); - -        if (is_last_call (this_call_cnt)) { -                if (!IA_ISDIR (local->stbuf.ia_type) -                    && (local->hashed_subvol != local->cached_subvol) -                    && (local->stbuf.ia_nlink == 1) -                    && (conf && conf->unhashed_sticky_bit)) { -                        local->stbuf.ia_prot.sticky = 1; -                } -                /* No need to call heal code if volume count is 1 +    this_call_cnt = dht_frame_return(frame); + +    if (is_last_call(this_call_cnt)) { +        if (!IA_ISDIR(local->stbuf.ia_type) && +            (local->hashed_subvol != local->cached_subvol) && +            (local->stbuf.ia_nlink == 1) && +            (conf && conf->unhashed_sticky_bit)) { +            local->stbuf.ia_prot.sticky = 1; +        } +        /* No need to call heal code if volume count is 1 +         */ +        if (conf->subvolume_cnt == 1) +            local->need_xattr_heal = 0; + +        if (IA_ISDIR(local->stbuf.ia_type)) { +            /* Code to update all extended attributed from hashed +               subvol to local->xattr and call heal code to heal +               custom xattr from hashed subvol to non-hashed subvol +            */ +            if (local->need_xattr_heal && (local->mds_xattr)) { +                dht_dir_set_heal_xattr(this, local, local->xattr, +                                       local->mds_xattr, NULL, NULL); +                dict_unref(local->mds_xattr); +                local->mds_xattr = NULL; +                local->need_xattr_heal = 0; +                ret = dht_dir_xattr_heal(this, local); +                if (ret) +                    gf_msg(this->name, GF_LOG_ERROR, ret, +                           DHT_MSG_DIR_XATTR_HEAL_FAILED, +                           "xattr heal failed for directory %s " +                           " gfid %s ", +                           local->loc.path, gfid); +            } else { +                /* Call function to save hashed subvol on inode +                   ctx if internal mds xattr is not present and +                   all subvols are up                  */ -                if (conf->subvolume_cnt == 1) -                        local->need_xattr_heal = 0; - -                if (IA_ISDIR (local->stbuf.ia_type)) { -                        /* Code to update all extended attributed from hashed -                           subvol to local->xattr and call heal code to heal -                           custom xattr from hashed subvol to non-hashed subvol -                        */ -                        if (local->need_xattr_heal && (local->mds_xattr)) { -                                dht_dir_set_heal_xattr (this, local, -                                                        local->xattr, -                                                        local->mds_xattr, NULL, -                                                        NULL); -                                dict_unref (local->mds_xattr); -                                local->mds_xattr = NULL; -                                local->need_xattr_heal = 0; -                                ret =  dht_dir_xattr_heal (this, local); -                                if (ret) -                                        gf_msg (this->name, GF_LOG_ERROR, -                                                ret, DHT_MSG_DIR_XATTR_HEAL_FAILED, -                                                "xattr heal failed for directory %s " -                                                " gfid %s ", local->loc.path, -                                                gfid); -                        } else { -                                /* Call function to save hashed subvol on inode -                                   ctx if internal mds xattr is not present and -                                   all subvols are up -                                */ -                                if (inode && !__is_root_gfid (inode->gfid) && -                                    (!local->op_ret)) -                                        (void) dht_common_mark_mdsxattr (frame, NULL, 1); -                        } -                } -                if (local->need_selfheal) { -                        local->need_selfheal = 0; -                        if (!__is_root_gfid (inode->gfid)) { -                                gf_uuid_copy (local->gfid, local->mds_stbuf.ia_gfid); -                                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; -                                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; -                                local->stbuf.ia_prot = local->mds_stbuf.ia_prot; -                        } else { -                                gf_uuid_copy (local->gfid, local->stbuf.ia_gfid); -                                local->stbuf.ia_gid = local->prebuf.ia_gid; -                                local->stbuf.ia_uid = local->prebuf.ia_uid; -                                local->stbuf.ia_prot = local->prebuf.ia_prot; -                        } - -                        copy = create_frame (this, this->ctx->pool); -                        if (copy) { -                                copy_local = dht_local_init (copy, &local->loc, -                                                             NULL, 0); -                                if (!copy_local) { -                                        DHT_STACK_DESTROY (copy); -                                        goto cont; -                                } -                                copy_local->stbuf = local->stbuf; -                                copy_local->mds_stbuf = local->mds_stbuf; -                                copy_local->mds_subvol = local->mds_subvol; -                                copy->local = copy_local; -                                FRAME_SU_DO (copy, dht_local_t); -                                ret = synctask_new (this->ctx->env, -                                                    dht_dir_attr_heal, -                                                    dht_dir_attr_heal_done, -                                                    copy, copy); -                                if (ret) { -                                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                                DHT_MSG_DIR_ATTR_HEAL_FAILED, -                                                "Synctask creation failed to heal attr " -                                                "for path %s gfid %s ", -                                                local->loc.path, local->gfid); -                                        DHT_STACK_DESTROY (copy); -                                } -                        } -                } -cont: -                if (local->layout_mismatch) { -                        /* Found layout mismatch in the directory, need to -                           fix this in the inode context */ -                        dht_layout_unref (this, local->layout); -                        local->layout = NULL; -                        dht_lookup_directory (frame, this, &local->loc); -                        return 0; -                } +                if (inode && !__is_root_gfid(inode->gfid) && (!local->op_ret)) +                    (void)dht_common_mark_mdsxattr(frame, NULL, 1); +            } +        } +        if (local->need_selfheal) { +            local->need_selfheal = 0; +            if (!__is_root_gfid(inode->gfid)) { +                gf_uuid_copy(local->gfid, local->mds_stbuf.ia_gfid); +                local->stbuf.ia_gid = local->mds_stbuf.ia_gid; +                local->stbuf.ia_uid = local->mds_stbuf.ia_uid; +                local->stbuf.ia_prot = local->mds_stbuf.ia_prot; +            } else { +                gf_uuid_copy(local->gfid, local->stbuf.ia_gfid); +                local->stbuf.ia_gid = local->prebuf.ia_gid; +                local->stbuf.ia_uid = local->prebuf.ia_uid; +                local->stbuf.ia_prot = local->prebuf.ia_prot; +            } -                if (local->need_lookup_everywhere) { -                        /* As the current layout gave ENOENT error, we would -                           need a new layout */ -                        dht_layout_unref (this, local->layout); -                        local->layout = NULL; - -                        /* We know that current cached subvol is no more -                           valid, get the new one */ -                        local->cached_subvol = NULL; -                        dht_lookup_everywhere (frame, this, &local->loc); -                        return 0; -                } -                if (local->return_estale) { -                        local->op_ret = -1; -                        local->op_errno = ESTALE; +            copy = create_frame(this, this->ctx->pool); +            if (copy) { +                copy_local = dht_local_init(copy, &local->loc, NULL, 0); +                if (!copy_local) { +                    DHT_STACK_DESTROY(copy); +                    goto cont; +                } +                copy_local->stbuf = local->stbuf; +                copy_local->mds_stbuf = local->mds_stbuf; +                copy_local->mds_subvol = local->mds_subvol; +                copy->local = copy_local; +                FRAME_SU_DO(copy, dht_local_t); +                ret = synctask_new(this->ctx->env, dht_dir_attr_heal, +                                   dht_dir_attr_heal_done, copy, copy); +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, +                           DHT_MSG_DIR_ATTR_HEAL_FAILED, +                           "Synctask creation failed to heal attr " +                           "for path %s gfid %s ", +                           local->loc.path, local->gfid); +                    DHT_STACK_DESTROY(copy);                  } +            } +        } +    cont: +        if (local->layout_mismatch) { +            /* Found layout mismatch in the directory, need to +               fix this in the inode context */ +            dht_layout_unref(this, local->layout); +            local->layout = NULL; +            dht_lookup_directory(frame, this, &local->loc); +            return 0; +        } -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } +        if (local->need_lookup_everywhere) { +            /* As the current layout gave ENOENT error, we would +               need a new layout */ +            dht_layout_unref(this, local->layout); +            local->layout = NULL; -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                dht_set_fixed_dir_stat (&local->postparent); - -                /* local->stbuf is updated only from subvols which have a layout -                 * The reason is to avoid choosing attr heal source from newly -                 * added bricks. In case e.g we have only one subvol and for -                 * some reason layout is not present on it, then local->stbuf -                 * will be EINVAL. This is an indication that the subvols -                 * active in the cluster do not have layouts on disk. -                 * Unwind with ESTALE to trigger a fresh lookup */ -                if (is_dir && local->stbuf.ia_type == IA_INVAL) { -                        local->op_ret = -1; -                        local->op_errno = ESTALE; -                } -                /* Delete mds xattr at the time of STACK UNWIND */ -                if (local->xattr) -                        GF_REMOVE_INTERNAL_XATTR (conf->mds_xattr_key, local->xattr); +            /* We know that current cached subvol is no more +               valid, get the new one */ +            local->cached_subvol = NULL; +            dht_lookup_everywhere(frame, this, &local->loc); +            return 0; +        } +        if (local->return_estale) { +            local->op_ret = -1; +            local->op_errno = ESTALE; +        } -                DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, -                                  local->inode, &local->stbuf, local->xattr, -                                  &local->postparent); +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1);          } +        DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +        dht_set_fixed_dir_stat(&local->postparent); + +        /* local->stbuf is updated only from subvols which have a layout +         * The reason is to avoid choosing attr heal source from newly +         * added bricks. In case e.g we have only one subvol and for +         * some reason layout is not present on it, then local->stbuf +         * will be EINVAL. This is an indication that the subvols +         * active in the cluster do not have layouts on disk. +         * Unwind with ESTALE to trigger a fresh lookup */ +        if (is_dir && local->stbuf.ia_type == IA_INVAL) { +            local->op_ret = -1; +            local->op_errno = ESTALE; +        } +        /* Delete mds xattr at the time of STACK UNWIND */ +        if (local->xattr) +            GF_REMOVE_INTERNAL_XATTR(conf->mds_xattr_key, local->xattr); + +        DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                         local->inode, &local->stbuf, local->xattr, +                         &local->postparent); +    } +  err: -        return ret; +    return ret;  } -  int -dht_lookup_linkfile_create_cbk (call_frame_t *frame, void *cookie, -                                xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *stbuf, -                                struct iatt *preparent, struct iatt *postparent, -                                dict_t *xdata) +dht_lookup_linkfile_create_cbk(call_frame_t *frame, void *cookie, +                               xlator_t *this, int32_t op_ret, int32_t op_errno, +                               inode_t *inode, struct iatt *stbuf, +                               struct iatt *preparent, struct iatt *postparent, +                               dict_t *xdata)  { -        dht_local_t  *local = NULL; -        xlator_t     *cached_subvol = NULL; -        dht_conf_t   *conf = NULL; -        int           ret = -1; -        char          gfid[GF_UUID_BUF_SIZE] = {0}; +    dht_local_t *local = NULL; +    xlator_t *cached_subvol = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); - -        local = frame->local; -        cached_subvol = local->cached_subvol; -        conf = this->private; +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); -        gf_uuid_unparse(local->loc.gfid, gfid); +    local = frame->local; +    cached_subvol = local->cached_subvol; +    conf = this->private; -        if (local->locked) -                dht_unlock_namespace (frame, &local->lock[0]); +    gf_uuid_unparse(local->loc.gfid, gfid); -        ret = dht_layout_preset (this, local->cached_subvol, local->loc.inode); -        if (ret < 0) { -                gf_msg_debug (this->name, EINVAL, -                              "Failed to set layout for subvolume %s, " -                              "(gfid = %s)", -                              cached_subvol ? cached_subvol->name : "<nil>", -                              gfid); -                local->op_ret = -1; -                local->op_errno = EINVAL; -                goto unwind; -        } +    if (local->locked) +        dht_unlock_namespace(frame, &local->lock[0]); -        local->op_ret = 0; -        if ((local->stbuf.ia_nlink == 1) -            && (conf && conf->unhashed_sticky_bit)) { -                local->stbuf.ia_prot.sticky = 1; -        } +    ret = dht_layout_preset(this, local->cached_subvol, local->loc.inode); +    if (ret < 0) { +        gf_msg_debug(this->name, EINVAL, +                     "Failed to set layout for subvolume %s, " +                     "(gfid = %s)", +                     cached_subvol ? cached_subvol->name : "<nil>", gfid); +        local->op_ret = -1; +        local->op_errno = EINVAL; +        goto unwind; +    } -        if (local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } +    local->op_ret = 0; +    if ((local->stbuf.ia_nlink == 1) && (conf && conf->unhashed_sticky_bit)) { +        local->stbuf.ia_prot.sticky = 1; +    } +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    }  unwind: -        gf_msg_debug (this->name, 0, -                      "creation of linkto on hashed subvol:%s, " -                      "returned with op_ret %d and op_errno %d: %s", -                      local->hashed_subvol->name, -                      op_ret, op_errno, uuid_utoa (local->loc.gfid)); +    gf_msg_debug(this->name, 0, +                 "creation of linkto on hashed subvol:%s, " +                 "returned with op_ret %d and op_errno %d: %s", +                 local->hashed_subvol->name, op_ret, op_errno, +                 uuid_utoa(local->loc.gfid)); -        if (local->linked == _gf_true) -                dht_linkfile_attr_heal (frame, this); +    if (local->linked == _gf_true) +        dht_linkfile_attr_heal(frame, this); +    dht_set_fixed_dir_stat(&local->postparent); -        dht_set_fixed_dir_stat (&local->postparent); - -        DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -        DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, -                          local->inode, &local->stbuf, local->xattr, -                          &local->postparent); +    DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +    DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                     local->inode, &local->stbuf, local->xattr, +                     &local->postparent);  out: -        return ret; +    return ret;  }  int -dht_lookup_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, -                       struct iatt *preparent, struct iatt *postparent, -                       dict_t *xdata) +dht_lookup_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int op_ret, int op_errno, struct iatt *preparent, +                      struct iatt *postparent, dict_t *xdata)  { -        int             this_call_cnt = 0; -        dht_local_t     *local = NULL; -        const char      *path =  NULL; +    int this_call_cnt = 0; +    dht_local_t *local = NULL; +    const char *path = NULL; -        local =  (dht_local_t*)frame->local; -        path = local->loc.path; -        FRAME_SU_UNDO (frame, dht_local_t); +    local = (dht_local_t *)frame->local; +    path = local->loc.path; +    FRAME_SU_UNDO(frame, dht_local_t); -        gf_msg (this->name, GF_LOG_INFO, 0, -                DHT_MSG_UNLINK_LOOKUP_INFO, "lookup_unlink returned with " -                "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno, -                ((path == NULL)? "null" : path )); +    gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, +           "lookup_unlink returned with " +           "op_ret -> %d and op-errno -> %d for %s", +           op_ret, op_errno, ((path == NULL) ? "null" : path)); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                dht_lookup_everywhere_done (frame, this); -        } +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        dht_lookup_everywhere_done(frame, this); +    } -        return 0; +    return 0;  }  int -dht_lookup_unlink_of_false_linkto_cbk (call_frame_t *frame, void *cookie, -                                       xlator_t *this, int op_ret, int op_errno, -                                       struct iatt *preparent, -                                       struct iatt *postparent, dict_t *xdata) +dht_lookup_unlink_of_false_linkto_cbk(call_frame_t *frame, void *cookie, +                                      xlator_t *this, int op_ret, int op_errno, +                                      struct iatt *preparent, +                                      struct iatt *postparent, dict_t *xdata)  { -        int             this_call_cnt = 0; -        dht_local_t     *local = NULL; -        const char      *path =  NULL; +    int this_call_cnt = 0; +    dht_local_t *local = NULL; +    const char *path = NULL; -        local =  (dht_local_t*)frame->local; -        path = local->loc.path; - -        FRAME_SU_UNDO (frame, dht_local_t); +    local = (dht_local_t *)frame->local; +    path = local->loc.path; -        gf_msg (this->name, GF_LOG_INFO, 0, -                DHT_MSG_UNLINK_LOOKUP_INFO, "lookup_unlink returned with " -                "op_ret -> %d and op-errno -> %d for %s", op_ret, op_errno, -                ((path == NULL)? "null" : path )); +    FRAME_SU_UNDO(frame, dht_local_t); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { +    gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, +           "lookup_unlink returned with " +           "op_ret -> %d and op-errno -> %d for %s", +           op_ret, op_errno, ((path == NULL) ? "null" : path)); -                if (op_ret == 0) { -                        dht_lookup_everywhere_done (frame, this); -                } else { -                       /*When dht_lookup_everywhere is performed, one cached -                         *and one hashed file was found and hashed file does -                         *not point to the above mentioned cached node. So it -                         *was considered as stale and an unlink was performed. -                         *But unlink fails. So may be rebalance is in progress. -                        *now ideally we have two data-files. One obtained during -                         *lookup_everywhere and one where unlink-failed. So -                         *at this point in time we cannot decide which one to -                         *choose because there are chances of first cached -                         *file is truncated after rebalance and if it is chosen -                        *as cached node, application will fail. So return EIO.*/ - -                        if (op_errno == EBUSY) { - -                                gf_msg (this->name, GF_LOG_ERROR, op_errno, -                                        DHT_MSG_UNLINK_FAILED, -                                        "Could not unlink the linkto file as " -                                        "either fd is open and/or linkto xattr " -                                        "is set for %s", -                                        ((path == NULL)? "null":path)); - -                        } -                        DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, -                                          NULL, NULL); - -                } +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        if (op_ret == 0) { +            dht_lookup_everywhere_done(frame, this); +        } else { +            /*When dht_lookup_everywhere is performed, one cached +             *and one hashed file was found and hashed file does +             *not point to the above mentioned cached node. So it +             *was considered as stale and an unlink was performed. +             *But unlink fails. So may be rebalance is in progress. +             *now ideally we have two data-files. One obtained during +             *lookup_everywhere and one where unlink-failed. So +             *at this point in time we cannot decide which one to +             *choose because there are chances of first cached +             *file is truncated after rebalance and if it is chosen +             *as cached node, application will fail. So return EIO.*/ + +            if (op_errno == EBUSY) { +                gf_msg(this->name, GF_LOG_ERROR, op_errno, +                       DHT_MSG_UNLINK_FAILED, +                       "Could not unlink the linkto file as " +                       "either fd is open and/or linkto xattr " +                       "is set for %s", +                       ((path == NULL) ? "null" : path)); +            } +            DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL);          } +    } -        return 0; +    return 0;  }  int -dht_lookup_unlink_stale_linkto_cbk (call_frame_t *frame, void *cookie, -                                    xlator_t *this, int op_ret, int op_errno, -                                    struct iatt *preparent, -                                    struct iatt *postparent, dict_t *xdata) +dht_lookup_unlink_stale_linkto_cbk(call_frame_t *frame, void *cookie, +                                   xlator_t *this, int op_ret, int op_errno, +                                   struct iatt *preparent, +                                   struct iatt *postparent, dict_t *xdata)  { +    dht_local_t *local = NULL; +    const char *path = NULL; -        dht_local_t     *local = NULL; -        const char      *path  = NULL; - -        /* NOTE: -         * If stale file unlink fails either there is an open-fd or is not an -         * dht-linkto-file then posix_unlink returns EBUSY, which is overwritten -         *  to ENOENT -         */ +    /* NOTE: +     * If stale file unlink fails either there is an open-fd or is not an +     * dht-linkto-file then posix_unlink returns EBUSY, which is overwritten +     *  to ENOENT +     */ -        local = frame->local; +    local = frame->local; -        if (local && local->loc.path) -                path = local->loc.path; +    if (local && local->loc.path) +        path = local->loc.path; -        gf_msg (this->name, GF_LOG_INFO, 0, -                DHT_MSG_UNLINK_LOOKUP_INFO, -                "Returned with op_ret %d and " -                "op_errno %d for %s", op_ret, op_errno, -                ((path==NULL)?"null":path)); +    gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_UNLINK_LOOKUP_INFO, +           "Returned with op_ret %d and " +           "op_errno %d for %s", +           op_ret, op_errno, ((path == NULL) ? "null" : path)); -        FRAME_SU_UNDO (frame, dht_local_t); -        DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL, -                          NULL); +    FRAME_SU_UNDO(frame, dht_local_t); +    DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  }  int -dht_fill_dict_to_avoid_unlink_of_migrating_file (dict_t *dict) { - -        int                      ret = 0; -        xlator_t                *this           = NULL; -        char                    *linktoskip_key = NULL; - -        this    = THIS; -        GF_VALIDATE_OR_GOTO ("dht", this, err); +dht_fill_dict_to_avoid_unlink_of_migrating_file(dict_t *dict) +{ +    int ret = 0; +    xlator_t *this = NULL; +    char *linktoskip_key = NULL; -        if (dht_is_tier_xlator (this)) -                linktoskip_key = TIER_SKIP_NON_LINKTO_UNLINK; -        else -                linktoskip_key = DHT_SKIP_NON_LINKTO_UNLINK; +    this = THIS; +    GF_VALIDATE_OR_GOTO("dht", this, err); -        ret = dict_set_int32 (dict, linktoskip_key, 1); +    if (dht_is_tier_xlator(this)) +        linktoskip_key = TIER_SKIP_NON_LINKTO_UNLINK; +    else +        linktoskip_key = DHT_SKIP_NON_LINKTO_UNLINK; -        if (ret) -                goto err; +    ret = dict_set_int32(dict, linktoskip_key, 1); -        ret =  dict_set_int32 (dict, DHT_SKIP_OPEN_FD_UNLINK, 1); +    if (ret) +        goto err; -        if (ret) -                goto err; +    ret = dict_set_int32(dict, DHT_SKIP_OPEN_FD_UNLINK, 1); +    if (ret) +        goto err; -        return 0; +    return 0;  err: -        return -1; - +    return -1;  }  int32_t -dht_linkfile_create_lookup_cbk (call_frame_t *frame, void *cookie, -                                xlator_t *this, int32_t op_ret, -                                int32_t op_errno, inode_t *inode, -                                struct iatt *buf, dict_t *xdata, -                                struct iatt *postparent) -{ -        dht_local_t *local                      = NULL; -        int          call_cnt                   = 0, ret = 0; -        xlator_t    *subvol                     = NULL; -        uuid_t       gfid                       = {0, }; -        char         gfid_str[GF_UUID_BUF_SIZE] = {0}; - -        subvol = cookie; -        local = frame->local; +dht_linkfile_create_lookup_cbk(call_frame_t *frame, void *cookie, +                               xlator_t *this, int32_t op_ret, int32_t op_errno, +                               inode_t *inode, struct iatt *buf, dict_t *xdata, +                               struct iatt *postparent) +{ +    dht_local_t *local = NULL; +    int call_cnt = 0, ret = 0; +    xlator_t *subvol = NULL; +    uuid_t gfid = { +        0, +    }; +    char gfid_str[GF_UUID_BUF_SIZE] = {0}; + +    subvol = cookie; +    local = frame->local; + +    if (subvol == local->hashed_subvol) { +        if ((op_ret == 0) || (op_errno != ENOENT)) +            local->dont_create_linkto = _gf_true; +    } else { +        if (gf_uuid_is_null(local->gfid)) +            gf_uuid_copy(gfid, local->loc.gfid); +        else +            gf_uuid_copy(gfid, local->gfid); + +        if ((op_ret == 0) && gf_uuid_compare(gfid, buf->ia_gfid)) { +            gf_uuid_unparse(gfid, gfid_str); +            gf_msg_debug(this->name, 0, +                         "gfid (%s) different on cached subvol " +                         "(%s) and looked up inode (%s), not " +                         "creating linkto", +                         uuid_utoa(buf->ia_gfid), subvol->name, gfid_str); +            local->dont_create_linkto = _gf_true; +        } else if (op_ret == -1) { +            local->dont_create_linkto = _gf_true; +        } +    } + +    call_cnt = dht_frame_return(frame); +    if (is_last_call(call_cnt)) { +        if (local->dont_create_linkto) +            goto no_linkto; +        else { +            gf_msg_debug(this->name, 0, +                         "Creating linkto file on %s(hash) to " +                         "%s on %s (gfid = %s)", +                         local->hashed_subvol->name, local->loc.path, +                         local->cached_subvol->name, gfid); -        if (subvol == local->hashed_subvol) { -                if ((op_ret == 0) || (op_errno != ENOENT)) -                        local->dont_create_linkto = _gf_true; -        } else { -                if (gf_uuid_is_null (local->gfid)) -                        gf_uuid_copy (gfid, local->loc.gfid); -                else -                        gf_uuid_copy (gfid, local->gfid); - -                if ((op_ret == 0) && gf_uuid_compare (gfid, buf->ia_gfid)) { -                        gf_uuid_unparse (gfid, gfid_str); -                        gf_msg_debug (this->name, 0, -                                      "gfid (%s) different on cached subvol " -                                      "(%s) and looked up inode (%s), not " -                                      "creating linkto", -                                      uuid_utoa (buf->ia_gfid), subvol->name, -                                      gfid_str); -                        local->dont_create_linkto = _gf_true; -                } else if (op_ret == -1) { -                        local->dont_create_linkto = _gf_true; -                } -        } +            ret = dht_linkfile_create(frame, dht_lookup_linkfile_create_cbk, +                                      this, local->cached_subvol, +                                      local->hashed_subvol, &local->loc); -        call_cnt = dht_frame_return (frame); -        if (is_last_call (call_cnt)) { -                if (local->dont_create_linkto) -                        goto no_linkto; -                else { -                        gf_msg_debug (this->name, 0, -                                      "Creating linkto file on %s(hash) to " -                                      "%s on %s (gfid = %s)", -                                      local->hashed_subvol->name, -                                      local->loc.path, -                                      local->cached_subvol->name, gfid); - -                        ret = dht_linkfile_create -                                (frame, dht_lookup_linkfile_create_cbk, -                                 this, local->cached_subvol, -                                 local->hashed_subvol, &local->loc); - -                        if (ret < 0) -                                goto no_linkto; -                } +            if (ret < 0) +                goto no_linkto;          } +    } -        return 0; +    return 0;  no_linkto: -        gf_msg_debug (this->name, 0, -                      "skipped linkto creation (path:%s) (gfid:%s) " -                      "(hashed-subvol:%s) (cached-subvol:%s)", -                      local->loc.path, gfid_str, local->hashed_subvol->name, -                      local->cached_subvol->name); - -        dht_lookup_linkfile_create_cbk (frame, NULL, this, 0, 0, -                                        local->loc.inode, &local->stbuf, -                                        &local->preparent, &local->postparent, -                                        local->xattr); -        return 0; -} +    gf_msg_debug(this->name, 0, +                 "skipped linkto creation (path:%s) (gfid:%s) " +                 "(hashed-subvol:%s) (cached-subvol:%s)", +                 local->loc.path, gfid_str, local->hashed_subvol->name, +                 local->cached_subvol->name); +    dht_lookup_linkfile_create_cbk(frame, NULL, this, 0, 0, local->loc.inode, +                                   &local->stbuf, &local->preparent, +                                   &local->postparent, local->xattr); +    return 0; +}  int32_t -dht_call_lookup_linkfile_create (call_frame_t *frame, void *cookie, -                                 xlator_t *this, int32_t op_ret, -                                 int32_t op_errno, dict_t *xdata) +dht_call_lookup_linkfile_create(call_frame_t *frame, void *cookie, +                                xlator_t *this, int32_t op_ret, +                                int32_t op_errno, dict_t *xdata)  { -        dht_local_t *local          = NULL; -        char gfid[GF_UUID_BUF_SIZE] = {0}; -        int          i              = 0; -        xlator_t    *subvol         = NULL; - -        local = frame->local; -        if (gf_uuid_is_null (local->gfid)) -                gf_uuid_unparse (local->loc.gfid, gfid); -        else -                gf_uuid_unparse (local->gfid, gfid); +    dht_local_t *local = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    int i = 0; +    xlator_t *subvol = NULL; -        if (op_ret < 0) { -                gf_log (this->name, GF_LOG_WARNING, -                        "protecting namespace failed, skipping linkto " -                        "creation (path:%s)(gfid:%s)(hashed-subvol:%s)" -                        "(cached-subvol:%s)", local->loc.path, gfid, -                        local->hashed_subvol->name, local->cached_subvol->name); -                goto err; -        } +    local = frame->local; +    if (gf_uuid_is_null(local->gfid)) +        gf_uuid_unparse(local->loc.gfid, gfid); +    else +        gf_uuid_unparse(local->gfid, gfid); -        local->locked = _gf_true; +    if (op_ret < 0) { +        gf_log(this->name, GF_LOG_WARNING, +               "protecting namespace failed, skipping linkto " +               "creation (path:%s)(gfid:%s)(hashed-subvol:%s)" +               "(cached-subvol:%s)", +               local->loc.path, gfid, local->hashed_subvol->name, +               local->cached_subvol->name); +        goto err; +    } +    local->locked = _gf_true; -        local->call_cnt = 2; +    local->call_cnt = 2; -        for (i = 0; i < 2; i++) { -                subvol = (subvol == NULL) ? local->hashed_subvol -                        : local->cached_subvol; +    for (i = 0; i < 2; i++) { +        subvol = (subvol == NULL) ? local->hashed_subvol : local->cached_subvol; -                STACK_WIND_COOKIE (frame, dht_linkfile_create_lookup_cbk, -                                   subvol, subvol, subvol->fops->lookup, -                                   &local->loc, NULL); -        } +        STACK_WIND_COOKIE(frame, dht_linkfile_create_lookup_cbk, subvol, subvol, +                          subvol->fops->lookup, &local->loc, NULL); +    } -        return 0; +    return 0;  err: -        dht_lookup_linkfile_create_cbk (frame, NULL, this, 0, 0, -                                        local->loc.inode, -                                        &local->stbuf, &local->preparent, -                                        &local->postparent, local->xattr); -        return 0; +    dht_lookup_linkfile_create_cbk(frame, NULL, this, 0, 0, local->loc.inode, +                                   &local->stbuf, &local->preparent, +                                   &local->postparent, local->xattr); +    return 0;  }  /* Rebalance is performed from cached_node to hashed_node. Initial cached_node @@ -2387,760 +2235,693 @@ err:   */  int -dht_lookup_everywhere_done (call_frame_t *frame, xlator_t *this) -{ -        int           ret                        = 0; -        dht_local_t  *local                      = NULL; -        xlator_t     *hashed_subvol              = NULL; -        xlator_t     *cached_subvol              = NULL; -        dht_layout_t *layout                     = NULL; -        char gfid[GF_UUID_BUF_SIZE]              = {0}; -        gf_boolean_t  found_non_linkto_on_hashed = _gf_false; - -        local = frame->local; -        hashed_subvol = local->hashed_subvol; -        cached_subvol = local->cached_subvol; +dht_lookup_everywhere_done(call_frame_t *frame, xlator_t *this) +{ +    int ret = 0; +    dht_local_t *local = NULL; +    xlator_t *hashed_subvol = NULL; +    xlator_t *cached_subvol = NULL; +    dht_layout_t *layout = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    gf_boolean_t found_non_linkto_on_hashed = _gf_false; + +    local = frame->local; +    hashed_subvol = local->hashed_subvol; +    cached_subvol = local->cached_subvol; + +    gf_uuid_unparse(local->loc.gfid, gfid); + +    if (local->file_count && local->dir_count) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_FILE_TYPE_MISMATCH, +               "path %s (gfid = %s)exists as a file on one " +               "subvolume and directory on another. " +               "Please fix it manually", +               local->loc.path, gfid); +        DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL); +        return 0; +    } + +    if (local->dir_count) { +        dht_lookup_directory(frame, this, &local->loc); +        return 0; +    } + +    gf_msg_debug(this->name, 0, +                 "STATUS: hashed_subvol %s " +                 "cached_subvol %s", +                 (hashed_subvol == NULL) ? "null" : hashed_subvol->name, +                 (cached_subvol == NULL) ? "null" : cached_subvol->name); + +    if (!cached_subvol) { +        if (local->skip_unlink.handle_valid_link && hashed_subvol) { +            /*Purpose of "DHT_SKIP_NON_LINKTO_UNLINK": +             * If this lookup is performed by rebalance and this +             * rebalance process detected hashed file and by +             * the time it sends the lookup request to cached node, +             * file got migrated and now at initial hashed_node, +             * final migrated file is present. With current logic, +             * because this process fails to find the cached_node, +             * it will unlink the file at initial hashed_node. +             * +             * So we avoid this by setting key, and checking at the +             * posix_unlink that unlink the file only if file is a +             * linkto file and not a migrated_file. +             */ + +            ret = dht_fill_dict_to_avoid_unlink_of_migrating_file( +                local->xattr_req); + +            if (ret) { +                /* If for some reason, setting key in the dict +                 * fails, return with ENOENT, as with respect to +                 * this process, it detected only a stale link +                 * file. +                 * +                 * Next lookup will delete it. +                 * +                 * Performing deletion of stale link file when +                 * setting key in dict fails, may cause the data +                 * loss because of the above mentioned race. +                 */ -        gf_uuid_unparse (local->loc.gfid, gfid); - -        if (local->file_count && local->dir_count) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_FILE_TYPE_MISMATCH, -                        "path %s (gfid = %s)exists as a file on one " -                        "subvolume and directory on another. " -                        "Please fix it manually", -                        local->loc.path, gfid); -                DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL, -                                  NULL); -                return 0; -        } +                DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, +                                 NULL); +            } else { +                local->skip_unlink.handle_valid_link = _gf_false; -        if (local->dir_count) { -                dht_lookup_directory (frame, this, &local->loc); -                return 0; -        } - -        gf_msg_debug (this->name, 0, "STATUS: hashed_subvol %s " -                      "cached_subvol %s", -                      (hashed_subvol == NULL)?"null":hashed_subvol->name, -                      (cached_subvol == NULL)?"null":cached_subvol->name); +                gf_msg_debug(this->name, 0, +                             "No Cached was found and " +                             "unlink on hashed was skipped" +                             " so performing now: %s", +                             local->loc.path); +                FRAME_SU_DO(frame, dht_local_t); +                STACK_WIND(frame, dht_lookup_unlink_stale_linkto_cbk, +                           hashed_subvol, hashed_subvol->fops->unlink, +                           &local->loc, 0, local->xattr_req); +            } -        if (!cached_subvol) { +        } else { +            gf_msg_debug(this->name, 0, +                         "There was no cached file and  " +                         "unlink on hashed is not skipped %s", +                         local->loc.path); -                if (local->skip_unlink.handle_valid_link && hashed_subvol) { - -                        /*Purpose of "DHT_SKIP_NON_LINKTO_UNLINK": -                         * If this lookup is performed by rebalance and this -                         * rebalance process detected hashed file and by -                         * the time it sends the lookup request to cached node, -                         * file got migrated and now at initial hashed_node, -                         * final migrated file is present. With current logic, -                         * because this process fails to find the cached_node, -                         * it will unlink the file at initial hashed_node. -                         * -                         * So we avoid this by setting key, and checking at the -                         * posix_unlink that unlink the file only if file is a -                         * linkto file and not a migrated_file. -                         */ - - -                        ret = dht_fill_dict_to_avoid_unlink_of_migrating_file -                              (local->xattr_req); - -                        if (ret) { -                                /* If for some reason, setting key in the dict -                                 * fails, return with ENOENT, as with respect to -                                 * this process, it detected only a stale link -                                 * file. -                                 * -                                 * Next lookup will delete it. -                                 * -                                 * Performing deletion of stale link file when -                                 * setting key in dict fails, may cause the data -                                 * loss because of the above mentioned race. -                                 */ - - -                                DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, -                                                  NULL, NULL, NULL, NULL); -                        } else { -                                local->skip_unlink.handle_valid_link = _gf_false; - -                                gf_msg_debug (this->name, 0, -                                              "No Cached was found and " -                                              "unlink on hashed was skipped" -                                              " so performing now: %s", -                                              local->loc.path); -                                FRAME_SU_DO (frame, dht_local_t); -                                STACK_WIND (frame, -                                            dht_lookup_unlink_stale_linkto_cbk, -                                            hashed_subvol, -                                            hashed_subvol->fops->unlink, -                                            &local->loc, 0, local->xattr_req); -                        } - -                } else  { - -                        gf_msg_debug (this->name, 0, -                                      "There was no cached file and  " -                                      "unlink on hashed is not skipped %s", -                                      local->loc.path); - -                        DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, -                                          NULL, NULL, NULL, NULL); -                } -                return 0; +            DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, NULL);          } +        return 0; +    } -        /* At the time of dht_lookup, no file was found on hashed and that is -         * why dht_lookup_everywhere is called, but by the time -         * dht_lookup_everywhere -         * reached to server, file might have already migrated. In that case we -         * will find a migrated file at the hashed_node. In this case store the -         * layout in context and return successfully. -         */ - -        if (hashed_subvol || local->need_lookup_everywhere) { - -                if (local->need_lookup_everywhere) { - -                        found_non_linkto_on_hashed = _gf_true; - -                } else if ((local->file_count == 1) && -                            (hashed_subvol == cached_subvol)) { - -                        gf_msg_debug (this->name, 0, -                                      "found cached file on hashed subvolume " -                                      "so store in context and return for %s", -                                      local->loc.path); +    /* At the time of dht_lookup, no file was found on hashed and that is +     * why dht_lookup_everywhere is called, but by the time +     * dht_lookup_everywhere +     * reached to server, file might have already migrated. In that case we +     * will find a migrated file at the hashed_node. In this case store the +     * layout in context and return successfully. +     */ -                        found_non_linkto_on_hashed = _gf_true; -                } +    if (hashed_subvol || local->need_lookup_everywhere) { +        if (local->need_lookup_everywhere) { +            found_non_linkto_on_hashed = _gf_true; -                if (found_non_linkto_on_hashed) -                        goto preset_layout; +        } else if ((local->file_count == 1) && +                   (hashed_subvol == cached_subvol)) { +            gf_msg_debug(this->name, 0, +                         "found cached file on hashed subvolume " +                         "so store in context and return for %s", +                         local->loc.path); +            found_non_linkto_on_hashed = _gf_true;          } +        if (found_non_linkto_on_hashed) +            goto preset_layout; +    } -        if (hashed_subvol) { -                if (local->skip_unlink.handle_valid_link == _gf_true) { -                        if (cached_subvol == local->skip_unlink.hash_links_to) { - -                             if (gf_uuid_compare (local->skip_unlink.cached_gfid, -                                               local->skip_unlink.hashed_gfid)){ - -                                        /*GFID different, return error*/ -                                        DHT_STACK_UNWIND (lookup, frame, -1, -                                                          ESTALE, NULL, NULL, -                                                          NULL, NULL); - -                                        return 0; -                                } - -                                ret = dht_layout_preset (this, cached_subvol, -                                                         local->loc.inode); -                                if (ret) { -                                        gf_msg (this->name, GF_LOG_INFO, 0, -                                                DHT_MSG_LAYOUT_PRESET_FAILED, -                                                "Could not set pre-set layout " -                                                "for subvolume %s", -                                                cached_subvol->name); -                                } - -                                local->op_ret = (ret == 0) ? ret : -1; -                                local->op_errno = (ret == 0) ? ret : EINVAL; - -                                /* Presence of local->cached_subvol validates -                                 * that lookup from cached node is successful -                                 */ - -                                if (!local->op_ret && local->loc.parent) { -                                        dht_inode_ctx_time_update -                                                (local->loc.parent, this, -                                                 &local->postparent, 1); -                                } - -                                gf_msg_debug (this->name, 0, -                                              "Skipped unlinking linkto file " -                                              "on the hashed subvolume. " -                                              "Returning success as it is a " -                                              "valid linkto file. Path:%s" -                                              ,local->loc.path); +    if (hashed_subvol) { +        if (local->skip_unlink.handle_valid_link == _gf_true) { +            if (cached_subvol == local->skip_unlink.hash_links_to) { +                if (gf_uuid_compare(local->skip_unlink.cached_gfid, +                                    local->skip_unlink.hashed_gfid)) { +                    /*GFID different, return error*/ +                    DHT_STACK_UNWIND(lookup, frame, -1, ESTALE, NULL, NULL, +                                     NULL, NULL); -                                goto unwind_hashed_and_cached; -                        } else { - -                               local->skip_unlink.handle_valid_link = _gf_false; - -                               gf_msg_debug (this->name, 0, -                                             "Linkto file found on hashed " -                                             "subvol " -                                             "and data file found on cached " -                                             "subvolume. But linkto points to " -                                             "different cached subvolume (%s) " -                                             "path %s", -                                            (local->skip_unlink.hash_links_to ? -                                        local->skip_unlink.hash_links_to->name : -                                             " <nil>"), local->loc.path); - -                               if (local->skip_unlink.opend_fd_count == 0) { +                    return 0; +                } +                ret = dht_layout_preset(this, cached_subvol, local->loc.inode); +                if (ret) { +                    gf_msg(this->name, GF_LOG_INFO, 0, +                           DHT_MSG_LAYOUT_PRESET_FAILED, +                           "Could not set pre-set layout " +                           "for subvolume %s", +                           cached_subvol->name); +                } -                          ret = dht_fill_dict_to_avoid_unlink_of_migrating_file -                                  (local->xattr_req); +                local->op_ret = (ret == 0) ? ret : -1; +                local->op_errno = (ret == 0) ? ret : EINVAL; +                /* Presence of local->cached_subvol validates +                 * that lookup from cached node is successful +                 */ -                                        if (ret) { -                                          DHT_STACK_UNWIND (lookup, frame, -1, -                                                            EIO, NULL, NULL, -                                                            NULL, NULL); -                                        } else { -                                                local->call_cnt = 1; -                                                FRAME_SU_DO (frame, dht_local_t); -                                                STACK_WIND (frame, -                                          dht_lookup_unlink_of_false_linkto_cbk, -                                                    hashed_subvol, -                                                    hashed_subvol->fops->unlink, -                                                    &local->loc, 0, -                                                    local->xattr_req); -                                        } +                if (!local->op_ret && local->loc.parent) { +                    dht_inode_ctx_time_update(local->loc.parent, this, +                                              &local->postparent, 1); +                } -                                        return 0; +                gf_msg_debug(this->name, 0, +                             "Skipped unlinking linkto file " +                             "on the hashed subvolume. " +                             "Returning success as it is a " +                             "valid linkto file. Path:%s", +                             local->loc.path); -                                } -                        } +                goto unwind_hashed_and_cached; +            } else { +                local->skip_unlink.handle_valid_link = _gf_false; +                gf_msg_debug(this->name, 0, +                             "Linkto file found on hashed " +                             "subvol " +                             "and data file found on cached " +                             "subvolume. But linkto points to " +                             "different cached subvolume (%s) " +                             "path %s", +                             (local->skip_unlink.hash_links_to +                                  ? local->skip_unlink.hash_links_to->name +                                  : " <nil>"), +                             local->loc.path); + +                if (local->skip_unlink.opend_fd_count == 0) { +                    ret = dht_fill_dict_to_avoid_unlink_of_migrating_file( +                        local->xattr_req); + +                    if (ret) { +                        DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, +                                         NULL, NULL); +                    } else { +                        local->call_cnt = 1; +                        FRAME_SU_DO(frame, dht_local_t); +                        STACK_WIND(frame, dht_lookup_unlink_of_false_linkto_cbk, +                                   hashed_subvol, hashed_subvol->fops->unlink, +                                   &local->loc, 0, local->xattr_req); +                    } + +                    return 0;                  } +            }          } - +    }  preset_layout: -        if (found_non_linkto_on_hashed) { - -                if (local->need_lookup_everywhere) { -                        if (gf_uuid_compare (local->gfid, local->inode->gfid)) { -                                /* GFID different, return error */ -                                DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, -                                                  NULL, NULL, NULL, NULL); -                                return 0; -                        } -                } - -                local->op_ret = 0; -                local->op_errno = 0; -                layout = dht_layout_for_subvol (this, cached_subvol); -                if (!layout) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_SUBVOL_INFO, -                                "%s: no pre-set layout for subvolume %s," -                                " gfid = %s", -                                local->loc.path, (cached_subvol ? -                                                  cached_subvol->name : -                                                  "<nil>"), gfid); -                } - -                ret = dht_layout_set (this, local->inode, layout); -                if (ret < 0) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_SUBVOL_INFO, -                                "%s: failed to set layout for subvol %s, " -                                "gfid = %s", -                                local->loc.path, (cached_subvol ? -                                                  cached_subvol->name : -                                                  "<nil>"), gfid); -                } - -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } - -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                dht_set_fixed_dir_stat (&local->postparent); -                DHT_STACK_UNWIND (lookup, frame, local->op_ret, -                                  local->op_errno, local->inode, -                                  &local->stbuf, local->xattr, -                                  &local->postparent); +    if (found_non_linkto_on_hashed) { +        if (local->need_lookup_everywhere) { +            if (gf_uuid_compare(local->gfid, local->inode->gfid)) { +                /* GFID different, return error */ +                DHT_STACK_UNWIND(lookup, frame, -1, ENOENT, NULL, NULL, NULL, +                                 NULL);                  return 0; +            }          } -        if (!hashed_subvol) { - -                gf_msg_debug (this->name, 0, -                              "Cannot create linkfile for %s on %s: " -                              "hashed subvolume cannot be found, gfid = %s.", -                              local->loc.path, cached_subvol->name, gfid); +        local->op_ret = 0; +        local->op_errno = 0; +        layout = dht_layout_for_subvol(this, cached_subvol); +        if (!layout) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, +                   "%s: no pre-set layout for subvolume %s," +                   " gfid = %s", +                   local->loc.path, +                   (cached_subvol ? cached_subvol->name : "<nil>"), gfid); +        } -                local->op_ret = 0; -                local->op_errno = 0; +        ret = dht_layout_set(this, local->inode, layout); +        if (ret < 0) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, +                   "%s: failed to set layout for subvol %s, " +                   "gfid = %s", +                   local->loc.path, +                   (cached_subvol ? cached_subvol->name : "<nil>"), gfid); +        } -                ret = dht_layout_preset (frame->this, cached_subvol, -                                         local->inode); -                if (ret < 0) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_LAYOUT_PRESET_FAILED, -                                "Failed to set layout for subvol %s" -                                ", gfid = %s", -                                cached_subvol ? cached_subvol->name : -                                "<nil>", gfid); -                        local->op_ret = -1; -                        local->op_errno = EINVAL; -                } +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1); +        } -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } +        DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +        dht_set_fixed_dir_stat(&local->postparent); +        DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                         local->inode, &local->stbuf, local->xattr, +                         &local->postparent); +        return 0; +    } -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                dht_set_fixed_dir_stat (&local->postparent); -                DHT_STACK_UNWIND (lookup, frame, local->op_ret, -                                  local->op_errno, local->inode, -                                  &local->stbuf, local->xattr, -                                  &local->postparent); -                return 0; -        } +    if (!hashed_subvol) { +        gf_msg_debug(this->name, 0, +                     "Cannot create linkfile for %s on %s: " +                     "hashed subvolume cannot be found, gfid = %s.", +                     local->loc.path, cached_subvol->name, gfid); -        if (frame->root->op != GF_FOP_RENAME) { -                local->current = &local->lock[0]; -                ret = dht_protect_namespace (frame, &local->loc, hashed_subvol, -                                             &local->current->ns, -                                             dht_call_lookup_linkfile_create); -        } else { -                gf_msg_debug (this->name, 0, -                              "Creating linkto file on %s(hash) to %s on %s " -                              "(gfid = %s)", -                              hashed_subvol->name, local->loc.path, -                              cached_subvol->name, gfid); +        local->op_ret = 0; +        local->op_errno = 0; -                ret = dht_linkfile_create (frame, -                                           dht_lookup_linkfile_create_cbk, this, -                                           cached_subvol, hashed_subvol, -                                           &local->loc); +        ret = dht_layout_preset(frame->this, cached_subvol, local->inode); +        if (ret < 0) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, +                   "Failed to set layout for subvol %s" +                   ", gfid = %s", +                   cached_subvol ? cached_subvol->name : "<nil>", gfid); +            local->op_ret = -1; +            local->op_errno = EINVAL;          } -        return ret; +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1); +        } -unwind_hashed_and_cached: -        DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -        dht_set_fixed_dir_stat (&local->postparent); -        DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, -                          local->inode, &local->stbuf, local->xattr, -                          &local->postparent); +        DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +        dht_set_fixed_dir_stat(&local->postparent); +        DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                         local->inode, &local->stbuf, local->xattr, +                         &local->postparent);          return 0; -} - -int -dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int32_t op_ret, int32_t op_errno, -                           inode_t *inode, struct iatt *buf, dict_t *xattr, -                           struct iatt *postparent) -{ -        dht_local_t  *local         = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev          = NULL; -        int           is_linkfile   = 0; -        int           is_dir        = 0; -        loc_t        *loc           = NULL; -        xlator_t     *link_subvol   = NULL; -        int           ret           = -1; -        int32_t       fd_count      = 0; -        dht_conf_t   *conf          = NULL; -        char         gfid[GF_UUID_BUF_SIZE] = {0}; -        dict_t       *dict_req      = {0}; - -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", cookie, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); - -        local  = frame->local; -        loc    = &local->loc; -        conf   = this->private; - -        prev   = cookie; - -        gf_msg_debug (this->name, 0, -                      "returned with op_ret %d and op_errno %d (%s) " -                      "from subvol %s", op_ret, op_errno, loc->path, -                      prev->name); - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        if (op_errno != ENOENT) -                                local->op_errno = op_errno; -                        goto unlock; -                } - -                if (gf_uuid_is_null (local->gfid)) -                        gf_uuid_copy (local->gfid, buf->ia_gfid); +    } -                gf_uuid_unparse(local->gfid, gfid); +    if (frame->root->op != GF_FOP_RENAME) { +        local->current = &local->lock[0]; +        ret = dht_protect_namespace(frame, &local->loc, hashed_subvol, +                                    &local->current->ns, +                                    dht_call_lookup_linkfile_create); +    } else { +        gf_msg_debug(this->name, 0, +                     "Creating linkto file on %s(hash) to %s on %s " +                     "(gfid = %s)", +                     hashed_subvol->name, local->loc.path, cached_subvol->name, +                     gfid); + +        ret = dht_linkfile_create(frame, dht_lookup_linkfile_create_cbk, this, +                                  cached_subvol, hashed_subvol, &local->loc); +    } + +    return ret; -                if (gf_uuid_compare (local->gfid, buf->ia_gfid)) { -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_GFID_MISMATCH, -                                "%s: gfid differs on subvolume %s," -                                " gfid local = %s, gfid node = %s", -                                loc->path, prev->name, gfid, -                                uuid_utoa(buf->ia_gfid)); -                } +unwind_hashed_and_cached: +    DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +    dht_set_fixed_dir_stat(&local->postparent); +    DHT_STACK_UNWIND(lookup, frame, local->op_ret, local->op_errno, +                     local->inode, &local->stbuf, local->xattr, +                     &local->postparent); +    return 0; +} + +int +dht_lookup_everywhere_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int32_t op_ret, int32_t op_errno, inode_t *inode, +                          struct iatt *buf, dict_t *xattr, +                          struct iatt *postparent) +{ +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    int is_linkfile = 0; +    int is_dir = 0; +    loc_t *loc = NULL; +    xlator_t *link_subvol = NULL; +    int ret = -1; +    int32_t fd_count = 0; +    dht_conf_t *conf = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    dict_t *dict_req = {0}; + +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", cookie, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); + +    local = frame->local; +    loc = &local->loc; +    conf = this->private; + +    prev = cookie; + +    gf_msg_debug(this->name, 0, +                 "returned with op_ret %d and op_errno %d (%s) " +                 "from subvol %s", +                 op_ret, op_errno, loc->path, prev->name); + +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            if (op_errno != ENOENT) +                local->op_errno = op_errno; +            goto unlock; +        } -                is_linkfile = check_is_linkfile (inode, buf, xattr, -                                                 conf->link_xattr_name); - -                if (is_linkfile) { -                        link_subvol = dht_linkfile_subvol (this, inode, buf, -                                                           xattr); -                        gf_msg_debug (this->name, 0, -                                      "found on %s linkfile %s (-> %s)", -                                      prev->name, loc->path, -                                      link_subvol ? link_subvol->name : "''"); -                        goto unlock; -                } +        if (gf_uuid_is_null(local->gfid)) +            gf_uuid_copy(local->gfid, buf->ia_gfid); -                is_dir = check_is_dir (inode, buf, xattr); +        gf_uuid_unparse(local->gfid, gfid); -                /* non linkfile GFID takes precedence but don't overwrite -                 gfid if we have already found a cached file*/ -                if (!local->cached_subvol) -                        gf_uuid_copy (local->gfid, buf->ia_gfid); +        if (gf_uuid_compare(local->gfid, buf->ia_gfid)) { +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, +                   "%s: gfid differs on subvolume %s," +                   " gfid local = %s, gfid node = %s", +                   loc->path, prev->name, gfid, uuid_utoa(buf->ia_gfid)); +        } -                if (is_dir) { -                        local->dir_count++; +        is_linkfile = check_is_linkfile(inode, buf, xattr, +                                        conf->link_xattr_name); -                        gf_msg_debug (this->name, 0, -                                      "found on %s directory %s", -                                      prev->name, loc->path); -                } else { -                        local->file_count++; - -                        gf_msg_debug (this->name, 0, -                                      "found cached file on %s for %s", -                                      prev->name, loc->path); - -                        if (!local->cached_subvol) { -                                /* found one file */ -                                dht_iatt_merge (this, &local->stbuf, buf); - -                                local->xattr = dict_ref (xattr); -                                local->cached_subvol = prev; - -                                gf_msg_debug (this->name, 0, -                                              "storing cached on %s file" -                                              " %s", prev->name, loc->path); - -                                dht_iatt_merge (this, &local->postparent, -                                                postparent); - -                                gf_uuid_copy (local->skip_unlink.cached_gfid, -                                           buf->ia_gfid); -                        } else { -                                /* This is where we need 'rename' both entries logic */ -                                gf_msg (this->name, GF_LOG_WARNING, 0, -                                        DHT_MSG_FILE_ON_MULT_SUBVOL, -                                        "multiple subvolumes (%s and %s) have " -                                        "file %s (preferably rename the file " -                                        "in the backend,and do a fresh lookup)", -                                        local->cached_subvol->name, -                                        prev->name, local->loc.path); -                        } -                } +        if (is_linkfile) { +            link_subvol = dht_linkfile_subvol(this, inode, buf, xattr); +            gf_msg_debug(this->name, 0, "found on %s linkfile %s (-> %s)", +                         prev->name, loc->path, +                         link_subvol ? link_subvol->name : "''"); +            goto unlock;          } -unlock: -        UNLOCK (&frame->lock); -        if (is_linkfile) { -                ret = dict_get_int32 (xattr, GLUSTERFS_OPEN_FD_COUNT, &fd_count); +        is_dir = check_is_dir(inode, buf, xattr); -                /*  Any linkto file found on the non-hashed subvolume should -                 *  be unlinked (performed in the "else if" block below) -                 * -                 *  But if a linkto file is found on hashed subvolume, it may be -                 *  pointing to valid cached node. So unlinking of linkto -                 *  file on hashed subvolume is skipped and inside -                 *  dht_lookup_everywhere_done, checks are performed. If this -                 *  linkto file is found as stale linkto file, it is deleted -                 *  otherwise unlink is skipped. -                 */ +        /* non linkfile GFID takes precedence but don't overwrite +         gfid if we have already found a cached file*/ +        if (!local->cached_subvol) +            gf_uuid_copy(local->gfid, buf->ia_gfid); -                if (local->hashed_subvol && local->hashed_subvol == prev) { - -                        local->skip_unlink.handle_valid_link = _gf_true; -                        local->skip_unlink.opend_fd_count = fd_count; -                        local->skip_unlink.hash_links_to = link_subvol; -                        gf_uuid_copy (local->skip_unlink.hashed_gfid, -                                   buf->ia_gfid); - -                        gf_msg_debug (this->name, 0, "Found" -                                      " one linkto file on hashed subvol %s " -                                      "for %s: Skipping unlinking till " -                                      "everywhere_done", prev->name, -                                      loc->path); - -                } else if (!ret && (fd_count == 0)) { - -                        dict_req = dict_new (); - -                        ret = dht_fill_dict_to_avoid_unlink_of_migrating_file -                              (dict_req); - -                        if (ret) { - -                                /* Skip unlinking for dict_failure -                                 *File is found as a linkto file on non-hashed, -                                 *subvolume. In the current implementation, -                                 *finding a linkto-file on non-hashed does not -                                 *always implies that it is stale. So deletion -                                 *of file should be done only when both fd is -                                 *closed and linkto-xattr is set. In case of -                                 *dict_set failure, avoid skipping of file. -                                 *NOTE: dht_frame_return should get called for -                                 *      this block. -                                 */ - -                                dict_unref (dict_req); - -                        } else { -                                gf_msg (this->name, GF_LOG_INFO, 0, -                                        DHT_MSG_SUBVOL_INFO, -                                        "attempting deletion of stale linkfile " -                                        "%s on %s (hashed subvol is %s)", -                                        loc->path, prev->name, -                                        (local->hashed_subvol? -                                        local->hashed_subvol->name : "<null>")); -                                /* * -                                 * These stale files may be created using root -                                 * user. Hence deletion will work only with -                                 * root. -                                 */ -                                FRAME_SU_DO (frame, dht_local_t); -                                STACK_WIND (frame, dht_lookup_unlink_cbk, -                                            prev, prev->fops->unlink, loc, -                                            0, dict_req); - -                                dict_unref (dict_req); - -                                return 0; -                        } -                } -        } +        if (is_dir) { +            local->dir_count++; -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                dht_lookup_everywhere_done (frame, this); -        } +            gf_msg_debug(this->name, 0, "found on %s directory %s", prev->name, +                         loc->path); +        } else { +            local->file_count++; -out: -        return ret; -} +            gf_msg_debug(this->name, 0, "found cached file on %s for %s", +                         prev->name, loc->path); +            if (!local->cached_subvol) { +                /* found one file */ +                dht_iatt_merge(this, &local->stbuf, buf); -int -dht_lookup_everywhere (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ -        dht_conf_t     *conf = NULL; -        dht_local_t    *local = NULL; -        int             i = 0; -        int             call_cnt = 0; +                local->xattr = dict_ref(xattr); +                local->cached_subvol = prev; + +                gf_msg_debug(this->name, 0, +                             "storing cached on %s file" +                             " %s", +                             prev->name, loc->path); + +                dht_iatt_merge(this, &local->postparent, postparent); + +                gf_uuid_copy(local->skip_unlink.cached_gfid, buf->ia_gfid); +            } else { +                /* This is where we need 'rename' both entries logic */ +                gf_msg(this->name, GF_LOG_WARNING, 0, +                       DHT_MSG_FILE_ON_MULT_SUBVOL, +                       "multiple subvolumes (%s and %s) have " +                       "file %s (preferably rename the file " +                       "in the backend,and do a fresh lookup)", +                       local->cached_subvol->name, prev->name, local->loc.path); +            } +        } +    } +unlock: +    UNLOCK(&frame->lock); -        GF_VALIDATE_OR_GOTO ("dht", frame, err); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); -        GF_VALIDATE_OR_GOTO ("dht", loc, out); +    if (is_linkfile) { +        ret = dict_get_int32(xattr, GLUSTERFS_OPEN_FD_COUNT, &fd_count); -        conf = this->private; -        local = frame->local; +        /*  Any linkto file found on the non-hashed subvolume should +         *  be unlinked (performed in the "else if" block below) +         * +         *  But if a linkto file is found on hashed subvolume, it may be +         *  pointing to valid cached node. So unlinking of linkto +         *  file on hashed subvolume is skipped and inside +         *  dht_lookup_everywhere_done, checks are performed. If this +         *  linkto file is found as stale linkto file, it is deleted +         *  otherwise unlink is skipped. +         */ -        call_cnt = conf->subvolume_cnt; -        local->call_cnt = call_cnt; +        if (local->hashed_subvol && local->hashed_subvol == prev) { +            local->skip_unlink.handle_valid_link = _gf_true; +            local->skip_unlink.opend_fd_count = fd_count; +            local->skip_unlink.hash_links_to = link_subvol; +            gf_uuid_copy(local->skip_unlink.hashed_gfid, buf->ia_gfid); + +            gf_msg_debug(this->name, 0, +                         "Found" +                         " one linkto file on hashed subvol %s " +                         "for %s: Skipping unlinking till " +                         "everywhere_done", +                         prev->name, loc->path); + +        } else if (!ret && (fd_count == 0)) { +            dict_req = dict_new(); + +            ret = dht_fill_dict_to_avoid_unlink_of_migrating_file(dict_req); + +            if (ret) { +                /* Skip unlinking for dict_failure +                 *File is found as a linkto file on non-hashed, +                 *subvolume. In the current implementation, +                 *finding a linkto-file on non-hashed does not +                 *always implies that it is stale. So deletion +                 *of file should be done only when both fd is +                 *closed and linkto-xattr is set. In case of +                 *dict_set failure, avoid skipping of file. +                 *NOTE: dht_frame_return should get called for +                 *      this block. +                 */ -        if (!local->inode) -                local->inode = inode_ref (loc->inode); +                dict_unref(dict_req); + +            } else { +                gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, +                       "attempting deletion of stale linkfile " +                       "%s on %s (hashed subvol is %s)", +                       loc->path, prev->name, +                       (local->hashed_subvol ? local->hashed_subvol->name +                                             : "<null>")); +                /* * +                 * These stale files may be created using root +                 * user. Hence deletion will work only with +                 * root. +                 */ +                FRAME_SU_DO(frame, dht_local_t); +                STACK_WIND(frame, dht_lookup_unlink_cbk, prev, +                           prev->fops->unlink, loc, 0, dict_req); -        gf_msg_debug (this->name, 0, -                      "winding lookup call to %d subvols", call_cnt); +                dict_unref(dict_req); -        for (i = 0; i < call_cnt; i++) { -                STACK_WIND_COOKIE (frame, dht_lookup_everywhere_cbk, -                                   conf->subvolumes[i], conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->lookup, -                                   loc, local->xattr_req); +                return 0; +            }          } +    } + +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        dht_lookup_everywhere_done(frame, this); +    } -        return 0;  out: -        DHT_STACK_UNWIND (lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL); -err: -        return -1; +    return ret;  } -  int -dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie, -                         xlator_t *this, int op_ret, int op_errno, -                         inode_t *inode, struct iatt *stbuf, dict_t *xattr, -                         struct iatt *postparent) +dht_lookup_everywhere(call_frame_t *frame, xlator_t *this, loc_t *loc)  { -        xlator_t     *prev          = NULL; -        dht_local_t  *local         = NULL; -        xlator_t     *subvol        = NULL; -        loc_t        *loc           = NULL; -        dht_conf_t   *conf          = NULL; -        int           ret           = 0; -        char          gfid[GF_UUID_BUF_SIZE]     = {0}; - -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, unwind); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, unwind); -        GF_VALIDATE_OR_GOTO ("dht", this->private, unwind); -        GF_VALIDATE_OR_GOTO ("dht", cookie, unwind); +    dht_conf_t *conf = NULL; +    dht_local_t *local = NULL; +    int i = 0; +    int call_cnt = 0; -        prev   = cookie; -        subvol = prev; -        conf   = this->private; -        local  = frame->local; -        loc    = &local->loc; - -        gf_uuid_unparse(loc->gfid, gfid); - -        if (op_ret == -1) { -                gf_msg (this->name, GF_LOG_INFO, op_errno, -                        DHT_MSG_LINK_FILE_LOOKUP_INFO, -                        "Lookup of %s on %s (following linkfile) failed " -                        ",gfid = %s", local->loc.path, subvol->name, gfid); - -                /* If cached subvol returned ENOTCONN, do not do -                lookup_everywhere. We need to make sure linkfile does not get -                removed, which can take away the namespace, and subvol is -                anyways down. */ - -                local->cached_subvol = NULL; -                if (op_errno != ENOTCONN) -                        goto err; -                else -                        goto unwind; -        } +    GF_VALIDATE_OR_GOTO("dht", frame, err); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); +    GF_VALIDATE_OR_GOTO("dht", loc, out); -        if (check_is_dir (inode, stbuf, xattr)) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_LINK_FILE_LOOKUP_INFO, -                        "Lookup of %s on %s (following linkfile) reached dir," -                        " gfid = %s", local->loc.path, subvol->name, gfid); -                goto err; -        } +    conf = this->private; +    local = frame->local; -        if (check_is_linkfile (inode, stbuf, xattr, conf->link_xattr_name)) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_LINK_FILE_LOOKUP_INFO, -                        "lookup of %s on %s (following linkfile) reached link," -                        "gfid = %s", local->loc.path, subvol->name, gfid); -                goto err; -        } +    call_cnt = conf->subvolume_cnt; +    local->call_cnt = call_cnt; -        if (gf_uuid_compare (local->gfid, stbuf->ia_gfid)) { -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_GFID_MISMATCH, -                        "%s: gfid different on data file on %s," -                        " gfid local = %s, gfid node = %s ", -                        local->loc.path, subvol->name, gfid, -                        uuid_utoa(stbuf->ia_gfid)); -                goto err; -        } +    if (!local->inode) +        local->inode = inode_ref(loc->inode); -        if ((stbuf->ia_nlink == 1) -            && (conf && conf->unhashed_sticky_bit)) { -                stbuf->ia_prot.sticky = 1; -        } +    gf_msg_debug(this->name, 0, "winding lookup call to %d subvols", call_cnt); -        ret = dht_layout_preset (this, prev, inode); -        if (ret < 0) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_LAYOUT_PRESET_FAILED, -                        "Failed to set layout for subvolume %s," -                        "gfid = %s", prev->name, gfid); -                op_ret   = -1; -                op_errno = EINVAL; -        } +    for (i = 0; i < call_cnt; i++) { +        STACK_WIND_COOKIE(frame, dht_lookup_everywhere_cbk, conf->subvolumes[i], +                          conf->subvolumes[i], +                          conf->subvolumes[i]->fops->lookup, loc, +                          local->xattr_req); +    } -        if (local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } +    return 0; +out: +    DHT_STACK_UNWIND(lookup, frame, -1, EINVAL, NULL, NULL, NULL, NULL); +err: +    return -1; +} + +int +dht_lookup_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, inode_t *inode, +                        struct iatt *stbuf, dict_t *xattr, +                        struct iatt *postparent) +{ +    xlator_t *prev = NULL; +    dht_local_t *local = NULL; +    xlator_t *subvol = NULL; +    loc_t *loc = NULL; +    dht_conf_t *conf = NULL; +    int ret = 0; +    char gfid[GF_UUID_BUF_SIZE] = {0}; + +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, unwind); +    GF_VALIDATE_OR_GOTO("dht", frame->local, unwind); +    GF_VALIDATE_OR_GOTO("dht", this->private, unwind); +    GF_VALIDATE_OR_GOTO("dht", cookie, unwind); + +    prev = cookie; +    subvol = prev; +    conf = this->private; +    local = frame->local; +    loc = &local->loc; + +    gf_uuid_unparse(loc->gfid, gfid); + +    if (op_ret == -1) { +        gf_msg(this->name, GF_LOG_INFO, op_errno, DHT_MSG_LINK_FILE_LOOKUP_INFO, +               "Lookup of %s on %s (following linkfile) failed " +               ",gfid = %s", +               local->loc.path, subvol->name, gfid); + +        /* If cached subvol returned ENOTCONN, do not do +        lookup_everywhere. We need to make sure linkfile does not get +        removed, which can take away the namespace, and subvol is +        anyways down. */ + +        local->cached_subvol = NULL; +        if (op_errno != ENOTCONN) +            goto err; +        else +            goto unwind; +    } + +    if (check_is_dir(inode, stbuf, xattr)) { +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LINK_FILE_LOOKUP_INFO, +               "Lookup of %s on %s (following linkfile) reached dir," +               " gfid = %s", +               local->loc.path, subvol->name, gfid); +        goto err; +    } + +    if (check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name)) { +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LINK_FILE_LOOKUP_INFO, +               "lookup of %s on %s (following linkfile) reached link," +               "gfid = %s", +               local->loc.path, subvol->name, gfid); +        goto err; +    } + +    if (gf_uuid_compare(local->gfid, stbuf->ia_gfid)) { +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GFID_MISMATCH, +               "%s: gfid different on data file on %s," +               " gfid local = %s, gfid node = %s ", +               local->loc.path, subvol->name, gfid, uuid_utoa(stbuf->ia_gfid)); +        goto err; +    } + +    if ((stbuf->ia_nlink == 1) && (conf && conf->unhashed_sticky_bit)) { +        stbuf->ia_prot.sticky = 1; +    } + +    ret = dht_layout_preset(this, prev, inode); +    if (ret < 0) { +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, +               "Failed to set layout for subvolume %s," +               "gfid = %s", +               prev->name, gfid); +        op_ret = -1; +        op_errno = EINVAL; +    } + +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    }  unwind: -        DHT_STRIP_PHASE1_FLAGS (stbuf); -        dht_set_fixed_dir_stat (postparent); -        DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr, -                          postparent); +    DHT_STRIP_PHASE1_FLAGS(stbuf); +    dht_set_fixed_dir_stat(postparent); +    DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, +                     postparent); -        return 0; +    return 0;  err: -        dht_lookup_everywhere (frame, this, loc); +    dht_lookup_everywhere(frame, this, loc);  out: -        return 0; +    return 0;  } -  int -dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc) +dht_lookup_directory(call_frame_t *frame, xlator_t *this, loc_t *loc)  { -        int           call_cnt = 0; -        int           i = 0; -        dht_conf_t   *conf = NULL; -        dht_local_t  *local = NULL; -        int           ret = 0; +    int call_cnt = 0; +    int i = 0; +    dht_conf_t *conf = NULL; +    dht_local_t *local = NULL; +    int ret = 0; -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, unwind); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, unwind); -        GF_VALIDATE_OR_GOTO ("dht", this->private, unwind); -        GF_VALIDATE_OR_GOTO ("dht", loc, unwind); +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, unwind); +    GF_VALIDATE_OR_GOTO("dht", frame->local, unwind); +    GF_VALIDATE_OR_GOTO("dht", this->private, unwind); +    GF_VALIDATE_OR_GOTO("dht", loc, unwind); -        conf = this->private; -        local = frame->local; - -        call_cnt        = conf->subvolume_cnt; -        local->call_cnt = call_cnt; +    conf = this->private; +    local = frame->local; -        local->layout = dht_layout_new (this, conf->subvolume_cnt); -        if (!local->layout) { -                goto unwind; -        } +    call_cnt = conf->subvolume_cnt; +    local->call_cnt = call_cnt; -        if (local->xattr != NULL) { -                dict_unref (local->xattr); -                local->xattr = NULL; -        } +    local->layout = dht_layout_new(this, conf->subvolume_cnt); +    if (!local->layout) { +        goto unwind; +    } -        if (!gf_uuid_is_null (local->gfid)) { -                ret = dict_set_gfuuid (local->xattr_req, "gfid-req", -                                       local->gfid, true); -                if (ret) -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_DICT_SET_FAILED, -                                "%s: Failed to set dictionary value:" -                                " key = gfid-req", local->loc.path); -        } +    if (local->xattr != NULL) { +        dict_unref(local->xattr); +        local->xattr = NULL; +    } -        for (i = 0; i < call_cnt; i++) { -                STACK_WIND_COOKIE (frame, dht_lookup_dir_cbk, -                                   conf->subvolumes[i], conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->lookup, -                                   &local->loc, local->xattr_req); -        } -        return 0; +    if (!gf_uuid_is_null(local->gfid)) { +        ret = dict_set_gfuuid(local->xattr_req, "gfid-req", local->gfid, true); +        if (ret) +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +                   "%s: Failed to set dictionary value:" +                   " key = gfid-req", +                   local->loc.path); +    } + +    for (i = 0; i < call_cnt; i++) { +        STACK_WIND_COOKIE( +            frame, dht_lookup_dir_cbk, conf->subvolumes[i], conf->subvolumes[i], +            conf->subvolumes[i]->fops->lookup, &local->loc, local->xattr_req); +    } +    return 0;  unwind: -        DHT_STACK_UNWIND (lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL); +    DHT_STACK_UNWIND(lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);  out: -        return 0; - +    return 0;  }  /* Code to get hashed subvol based on inode and loc @@ -3149,246 +2930,230 @@ out:  */  xlator_t * -dht_inode_get_hashed_subvol (inode_t *inode, xlator_t *this, loc_t *loc) -{ -        char                    *path           = NULL; -        loc_t                    populate_loc   = {0, }; -        char                    *name           = NULL; -        xlator_t                *hash_subvol    = NULL; - -        if (!inode) -                return hash_subvol; - -        if (loc && loc->parent && loc->path) { -                if (!loc->name) { -                        name = strrchr (loc->path, '/'); -                        if (name) { -                                loc->name = name + 1; -                        } else { -                                goto out; -                        } -                } -                hash_subvol = dht_subvol_get_hashed (this, loc); +dht_inode_get_hashed_subvol(inode_t *inode, xlator_t *this, loc_t *loc) +{ +    char *path = NULL; +    loc_t populate_loc = { +        0, +    }; +    char *name = NULL; +    xlator_t *hash_subvol = NULL; + +    if (!inode) +        return hash_subvol; + +    if (loc && loc->parent && loc->path) { +        if (!loc->name) { +            name = strrchr(loc->path, '/'); +            if (name) { +                loc->name = name + 1; +            } else {                  goto out; +            }          } +        hash_subvol = dht_subvol_get_hashed(this, loc); +        goto out; +    } -        if (!gf_uuid_is_null (inode->gfid)) { -                populate_loc.inode = inode_ref (inode); -                populate_loc.parent = inode_parent (populate_loc.inode, -                                                    NULL, NULL); -                inode_path (populate_loc.inode, NULL, &path); +    if (!gf_uuid_is_null(inode->gfid)) { +        populate_loc.inode = inode_ref(inode); +        populate_loc.parent = inode_parent(populate_loc.inode, NULL, NULL); +        inode_path(populate_loc.inode, NULL, &path); -                if (!path) -                        goto out; +        if (!path) +            goto out; -                populate_loc.path = path; -                if (!populate_loc.name && populate_loc.path) { -                        name = strrchr (populate_loc.path, '/'); -                        if (name) { -                                populate_loc.name = name + 1; +        populate_loc.path = path; +        if (!populate_loc.name && populate_loc.path) { +            name = strrchr(populate_loc.path, '/'); +            if (name) { +                populate_loc.name = name + 1; -                        } else { -                                goto out; -                        } -                } -                hash_subvol = dht_subvol_get_hashed (this, &populate_loc); +            } else { +                goto out; +            }          } +        hash_subvol = dht_subvol_get_hashed(this, &populate_loc); +    }  out: -        if (populate_loc.inode) -                loc_wipe (&populate_loc); -        return hash_subvol; -} - - -int -dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                int op_ret, int op_errno, -                inode_t *inode, struct iatt *stbuf, dict_t *xattr, -                struct iatt *postparent) -{ -        char          is_linkfile   = 0; -        char          is_dir        = 0; -        xlator_t     *subvol        = NULL; -        dht_conf_t   *conf          = NULL; -        dht_local_t  *local         = NULL; -        loc_t        *loc           = NULL; -        xlator_t     *prev          = NULL; -        int           ret           = 0; -        dht_layout_t *parent_layout = NULL; -        uint32_t      vol_commit_hash = 0; - -        GF_VALIDATE_OR_GOTO ("dht", frame, err); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); -        GF_VALIDATE_OR_GOTO ("dht", cookie, out); -        GF_VALIDATE_OR_GOTO ("dht", this->private, out); - -        conf  = this->private; - -        prev  = cookie; -        local = frame->local; -        loc   = &local->loc; +    if (populate_loc.inode) +        loc_wipe(&populate_loc); +    return hash_subvol; +} + +int +dht_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +               int op_errno, inode_t *inode, struct iatt *stbuf, dict_t *xattr, +               struct iatt *postparent) +{ +    char is_linkfile = 0; +    char is_dir = 0; +    xlator_t *subvol = NULL; +    dht_conf_t *conf = NULL; +    dht_local_t *local = NULL; +    loc_t *loc = NULL; +    xlator_t *prev = NULL; +    int ret = 0; +    dht_layout_t *parent_layout = NULL; +    uint32_t vol_commit_hash = 0; + +    GF_VALIDATE_OR_GOTO("dht", frame, err); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", cookie, out); +    GF_VALIDATE_OR_GOTO("dht", this->private, out); + +    conf = this->private; + +    prev = cookie; +    local = frame->local; +    loc = &local->loc; + +    /* This is required for handling stale linkfile deletion, +     * or any more call which happens from this 'loc'. +     */ +    if (!op_ret && gf_uuid_is_null(local->gfid)) +        memcpy(local->gfid, stbuf->ia_gfid, 16); + +    gf_msg_debug(this->name, op_errno, +                 "fresh_lookup returned for %s with op_ret %d", loc->path, +                 op_ret); + +    if (!conf->vch_forced) { +        ret = dict_get_uint32(xattr, conf->commithash_xattr_name, +                              &vol_commit_hash); +        if (ret == 0) { +            conf->vol_commit_hash = vol_commit_hash; +        } +    } -        /* This is required for handling stale linkfile deletion, -         * or any more call which happens from this 'loc'. -         */ -        if (!op_ret && gf_uuid_is_null (local->gfid)) -                memcpy (local->gfid, stbuf->ia_gfid, 16); - -        gf_msg_debug (this->name, op_errno, -                      "fresh_lookup returned for %s with op_ret %d", -                      loc->path, op_ret); - -        if (!conf->vch_forced) { -                ret = dict_get_uint32 (xattr, conf->commithash_xattr_name, -                                       &vol_commit_hash); -                if (ret == 0) { -                        conf->vol_commit_hash = vol_commit_hash; -                } +    if (ENTRY_MISSING(op_ret, op_errno)) { +        if (1 == conf->subvolume_cnt) { +            /* No need to lookup again */ +            goto out;          } -        if (ENTRY_MISSING (op_ret, op_errno)) { +        gf_msg_debug(this->name, 0, "Entry %s missing on subvol %s", loc->path, +                     prev->name); -                if (1 == conf->subvolume_cnt) { -                        /* No need to lookup again */ -                        goto out; -                } +        /* lookup-optimize supersedes lookup-unhashed settings, +         *   - so if it is set, do not process search_unhashed +         *   - except, in the case of rebalance daemon, we want to +         *     force the lookup_everywhere behavior */ +        if (!conf->defrag && conf->lookup_optimize && loc->parent) { +            ret = dht_inode_ctx_layout_get(loc->parent, this, &parent_layout); +            if (ret || !parent_layout || +                (parent_layout->commit_hash != conf->vol_commit_hash)) { +                gf_msg_debug(this->name, 0, +                             "hashes don't match (ret - %d," +                             " parent_layout - %p, parent_hash - %x," +                             " vol_hash - %x), do global lookup", +                             ret, parent_layout, +                             (parent_layout ? parent_layout->commit_hash : -1), +                             conf->vol_commit_hash); +                local->op_errno = ENOENT; +                dht_lookup_everywhere(frame, this, loc); +                return 0; +            } +        } else { +            if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_ON) { +                local->op_errno = ENOENT; +                dht_lookup_everywhere(frame, this, loc); +                return 0; +            } -                gf_msg_debug (this->name, 0, -                              "Entry %s missing on subvol %s", -                              loc->path, prev->name); - -                /* lookup-optimize supersedes lookup-unhashed settings, -                 *   - so if it is set, do not process search_unhashed -                 *   - except, in the case of rebalance daemon, we want to -                 *     force the lookup_everywhere behavior */ -                if (!conf->defrag && conf->lookup_optimize && loc->parent) { -                        ret = dht_inode_ctx_layout_get (loc->parent, this, -                                                        &parent_layout); -                        if (ret || !parent_layout || -                            (parent_layout->commit_hash != -                             conf->vol_commit_hash)) { -                                gf_msg_debug (this->name, 0, -                                              "hashes don't match (ret - %d," -                                              " parent_layout - %p, parent_hash - %x," -                                              " vol_hash - %x), do global lookup", -                                              ret, parent_layout, -                                              (parent_layout ? -                                              parent_layout->commit_hash : -1), -                                              conf->vol_commit_hash); -                                local->op_errno = ENOENT; -                                dht_lookup_everywhere (frame, this, loc); -                                return 0; -                        } -                } else { -                        if (conf->search_unhashed == -                            GF_DHT_LOOKUP_UNHASHED_ON) { -                                local->op_errno = ENOENT; -                                dht_lookup_everywhere (frame, this, loc); -                                return 0; -                        } - -                        if ((conf->search_unhashed == -                            GF_DHT_LOOKUP_UNHASHED_AUTO) && -                            (loc->parent)) { -                                ret = dht_inode_ctx_layout_get (loc->parent, -                                                                this, -                                                                &parent_layout); -                                if (ret || !parent_layout) -                                        goto out; -                                if (parent_layout->search_unhashed) { -                                        local->op_errno = ENOENT; -                                        dht_lookup_everywhere (frame, this, -                                                               loc); -                                        return 0; -                                } -                        } +            if ((conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) && +                (loc->parent)) { +                ret = dht_inode_ctx_layout_get(loc->parent, this, +                                               &parent_layout); +                if (ret || !parent_layout) +                    goto out; +                if (parent_layout->search_unhashed) { +                    local->op_errno = ENOENT; +                    dht_lookup_everywhere(frame, this, loc); +                    return 0;                  } +            }          } +    } -        if (op_ret == 0) { -                is_dir      = check_is_dir (inode, stbuf, xattr); -                if (is_dir) { -                        local->inode = inode_ref (inode); -                        local->xattr = dict_ref (xattr); -                } +    if (op_ret == 0) { +        is_dir = check_is_dir(inode, stbuf, xattr); +        if (is_dir) { +            local->inode = inode_ref(inode); +            local->xattr = dict_ref(xattr);          } +    } -        if (is_dir || (op_ret == -1 && op_errno == ENOTCONN)) { -                dht_lookup_directory (frame, this, &local->loc); -                return 0; -        } +    if (is_dir || (op_ret == -1 && op_errno == ENOTCONN)) { +        dht_lookup_directory(frame, this, &local->loc); +        return 0; +    } -        if (op_ret == -1) { -                gf_msg_debug (this->name, op_errno, -                              "Lookup of %s for subvolume" -                              " %s failed", loc->path, -                              prev->name); -                goto out; -        } +    if (op_ret == -1) { +        gf_msg_debug(this->name, op_errno, +                     "Lookup of %s for subvolume" +                     " %s failed", +                     loc->path, prev->name); +        goto out; +    } -        is_linkfile = check_is_linkfile (inode, stbuf, xattr, -                                         conf->link_xattr_name); +    is_linkfile = check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name); -        if (!is_linkfile) { -                /* non-directory and not a linkfile */ +    if (!is_linkfile) { +        /* non-directory and not a linkfile */ -                ret = dht_layout_preset (this, prev, inode); -                if (ret < 0) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_LAYOUT_PRESET_FAILED, -                                "could not set pre-set layout for subvolume %s", -                                prev->name); -                        op_ret   = -1; -                        op_errno = EINVAL; -                        goto out; -                } -                goto out; +        ret = dht_layout_preset(this, prev, inode); +        if (ret < 0) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_LAYOUT_PRESET_FAILED, +                   "could not set pre-set layout for subvolume %s", prev->name); +            op_ret = -1; +            op_errno = EINVAL; +            goto out;          } +        goto out; +    } -        subvol = dht_linkfile_subvol (this, inode, stbuf, xattr); -        if (!subvol) { - -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_SUBVOL_INFO, "linkfile not having link " -                        "subvol for %s", loc->path); +    subvol = dht_linkfile_subvol(this, inode, stbuf, xattr); +    if (!subvol) { +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, +               "linkfile not having link " +               "subvol for %s", +               loc->path); -                gf_msg_debug (this->name, 0, -                              "linkfile not having link subvolume. path=%s", -                              loc->path); -                dht_lookup_everywhere (frame, this, loc); -                return 0; -        } +        gf_msg_debug(this->name, 0, +                     "linkfile not having link subvolume. path=%s", loc->path); +        dht_lookup_everywhere(frame, this, loc); +        return 0; +    } -        gf_msg_debug (this->name, 0, -                      "Calling lookup on linkto target %s for path %s", -                      subvol->name, loc->path); +    gf_msg_debug(this->name, 0, +                 "Calling lookup on linkto target %s for path %s", subvol->name, +                 loc->path); -        STACK_WIND_COOKIE (frame, dht_lookup_linkfile_cbk, subvol, -                           subvol, subvol->fops->lookup, -                           &local->loc, local->xattr_req); +    STACK_WIND_COOKIE(frame, dht_lookup_linkfile_cbk, subvol, subvol, +                      subvol->fops->lookup, &local->loc, local->xattr_req); -        return 0; +    return 0;  out: -        /* -         * FIXME: postparent->ia_size and postparent->st_blocks do not have -         * correct values. since, postparent corresponds to a directory these -         * two members should have values equal to sum of corresponding values -         * from each of the subvolume. See dht_iatt_merge for reference. -         */ - -        if (!op_ret && local && local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } - -        DHT_STRIP_PHASE1_FLAGS (stbuf); -        dht_set_fixed_dir_stat (postparent); -        DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr, -                          postparent); +    /* +     * FIXME: postparent->ia_size and postparent->st_blocks do not have +     * correct values. since, postparent corresponds to a directory these +     * two members should have values equal to sum of corresponding values +     * from each of the subvolume. See dht_iatt_merge for reference. +     */ + +    if (!op_ret && local && local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    } + +    DHT_STRIP_PHASE1_FLAGS(stbuf); +    dht_set_fixed_dir_stat(postparent); +    DHT_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, stbuf, xattr, +                     postparent);  err: -        return 0; +    return 0;  }  /* For directories, check if acl xattrs have been requested (by the acl xlator), @@ -3396,3537 +3161,3339 @@ err:   * perform proper self-healing of dirs   */  void -dht_check_and_set_acl_xattr_req (xlator_t *this, dict_t *xattr_req) +dht_check_and_set_acl_xattr_req(xlator_t *this, dict_t *xattr_req)  { -        int     ret = 0; +    int ret = 0; -        GF_ASSERT (xattr_req); +    GF_ASSERT(xattr_req); -        if (!dict_get (xattr_req, POSIX_ACL_ACCESS_XATTR)) { -                ret = dict_set_int8 (xattr_req, POSIX_ACL_ACCESS_XATTR, 0); -                if (ret) -                        gf_msg (this->name, GF_LOG_WARNING, -ret, -                                DHT_MSG_DICT_SET_FAILED, -                                "Failed to set dictionary value:key = %s", -                                POSIX_ACL_ACCESS_XATTR); -        } +    if (!dict_get(xattr_req, POSIX_ACL_ACCESS_XATTR)) { +        ret = dict_set_int8(xattr_req, POSIX_ACL_ACCESS_XATTR, 0); +        if (ret) +            gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_DICT_SET_FAILED, +                   "Failed to set dictionary value:key = %s", +                   POSIX_ACL_ACCESS_XATTR); +    } -        if (!dict_get (xattr_req, POSIX_ACL_DEFAULT_XATTR)) { -                ret = dict_set_int8 (xattr_req, POSIX_ACL_DEFAULT_XATTR, 0); -                if (ret) -                        gf_msg (this->name, GF_LOG_WARNING, -ret, -                                DHT_MSG_DICT_SET_FAILED, -                                "Failed to set dictionary value:key = %s", -                                POSIX_ACL_DEFAULT_XATTR); -        } +    if (!dict_get(xattr_req, POSIX_ACL_DEFAULT_XATTR)) { +        ret = dict_set_int8(xattr_req, POSIX_ACL_DEFAULT_XATTR, 0); +        if (ret) +            gf_msg(this->name, GF_LOG_WARNING, -ret, DHT_MSG_DICT_SET_FAILED, +                   "Failed to set dictionary value:key = %s", +                   POSIX_ACL_DEFAULT_XATTR); +    } -        return; +    return;  } -  /* for directories, we need the following info:   * the layout : trusted.glusterfs.dht   * the mds information : trusted.glusterfs.dht.mds   * the acl info: See above   */  int -dht_set_dir_xattr_req (xlator_t *this, loc_t *loc, dict_t *xattr_req) -{ -        int ret   = -EINVAL; -        dht_conf_t *conf = NULL; - -        conf = this->private; -        if (!conf) { -                goto err; +dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req) +{ +    int ret = -EINVAL; +    dht_conf_t *conf = NULL; + +    conf = this->private; +    if (!conf) { +        goto err; +    } + +    if (!xattr_req) { +        goto err; +    } + +    /* Xattr to get the layout for a directory +     */ +    ret = dict_set_uint32(xattr_req, conf->xattr_name, 4 * 4); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value:key = %s for " +               "path %s", +               conf->xattr_name, loc->path); +        goto err; +    } + +    /*Non-fatal failure */ +    ret = dict_set_uint32(xattr_req, conf->mds_xattr_key, 4); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value:key = %s for " +               "path %s", +               conf->mds_xattr_key, loc->path); +    } + +    dht_check_and_set_acl_xattr_req(this, xattr_req); +    ret = 0; +err: +    return ret; +} + +int +dht_set_file_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req) +{ +    int ret = -EINVAL; +    dht_conf_t *conf = NULL; + +    conf = this->private; +    if (!conf) { +        goto err; +    } + +    if (!xattr_req) { +        goto err; +    } + +    /* Used to check whether this is a linkto file. +     */ +    ret = dict_set_uint32(xattr_req, conf->link_xattr_name, 256); +    if (ret < 0) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value:key = %s for " +               "path %s", +               conf->link_xattr_name, loc->path); +        goto err; +    } + +    /* This is used to make sure we don't unlink linkto files +     * which are the target of an ongoing file migration. +     */ +    ret = dict_set_uint32(xattr_req, GLUSTERFS_OPEN_FD_COUNT, 4); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value:key = %s for " +               "path %s", +               GLUSTERFS_OPEN_FD_COUNT, loc->path); +        goto err; +    } + +    ret = 0; +err: +    return ret; +} + +int +dht_do_revalidate(call_frame_t *frame, xlator_t *this, loc_t *loc) +{ +    xlator_t *subvol = NULL; +    xlator_t *mds_subvol = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    int op_errno = -1; +    dht_layout_t *layout = NULL; +    int i = 0; +    int call_cnt = 0; +    int gen = 0; + +    conf = this->private; +    if (!conf) { +        op_errno = EINVAL; +        goto err; +    } + +    local = frame->local; +    if (!local) { +        op_errno = EINVAL; +        goto err; +    } + +    layout = local->layout; +    if (!layout) { +        gf_msg_debug(this->name, 0, +                     "path = %s. No layout found in the inode ctx.", loc->path); +        op_errno = EINVAL; +        goto err; +    } + +    /* Generation number has changed. This layout may be stale. */ +    if (layout->gen && (layout->gen < conf->gen)) { +        gen = layout->gen; +        dht_layout_unref(this, local->layout); +        local->layout = NULL; +        local->cached_subvol = NULL; + +        gf_msg_debug(this->name, 0, +                     "path = %s. In memory layout may be stale." +                     "(layout->gen (%d) is less than " +                     "conf->gen (%d)). Calling fresh lookup.", +                     loc->path, gen, conf->gen); + +        dht_do_fresh_lookup(frame, this, loc); +        return 0; +    } + +    local->inode = inode_ref(loc->inode); + +    /* Since we don't know whether this has changed, +     * request all xattrs*/ +    ret = dht_set_file_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        op_errno = -ret; +        goto err; +    } + +    ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        op_errno = -ret; +        goto err; +    } + +    if (IA_ISDIR(local->inode->ia_type)) { +        ret = dht_inode_ctx_mdsvol_get(local->inode, this, &mds_subvol); +        if (ret || !mds_subvol) { +            gf_msg_debug(this->name, 0, "path = %s. No mds subvol in inode ctx", +                         local->loc.path);          } +        local->mds_subvol = mds_subvol; +        local->call_cnt = conf->subvolume_cnt; +        call_cnt = local->call_cnt; -        if (!xattr_req) { -                goto err; +        for (i = 0; i < call_cnt; i++) { +            STACK_WIND_COOKIE(frame, dht_revalidate_cbk, conf->subvolumes[i], +                              conf->subvolumes[i], +                              conf->subvolumes[i]->fops->lookup, loc, +                              local->xattr_req);          } +        return 0; +    } -        /* Xattr to get the layout for a directory -         */ -        ret = dict_set_uint32 (xattr_req, conf->xattr_name, 4 * 4); -        if (ret) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value:key = %s for " -                        "path %s", conf->xattr_name, loc->path); -                goto err; -         } +    /* If not a dir, this should be 1 */ +    local->call_cnt = layout->cnt; +    call_cnt = local->call_cnt; -        /*Non-fatal failure */ -        ret = dict_set_uint32 (xattr_req, conf->mds_xattr_key, 4); -        if (ret) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value:key = %s for " -                        "path %s", conf->mds_xattr_key, loc->path); -        } +    for (i = 0; i < call_cnt; i++) { +        subvol = layout->list[i].xlator; -        dht_check_and_set_acl_xattr_req (this, xattr_req); -        ret = 0; -err: -        return ret; -} +        gf_msg_debug(this->name, 0, +                     "path = %s. Calling " +                     "revalidate lookup on %s", +                     loc->path, subvol->name); +        STACK_WIND_COOKIE(frame, dht_revalidate_cbk, subvol, subvol, +                          subvol->fops->lookup, &local->loc, local->xattr_req); +    } +    return 0; +err: +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); +    return 0; +} + +int +dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc) +{ +    int ret = -1; +    dht_conf_t *conf = NULL; +    xlator_t *hashed_subvol = NULL; +    dht_local_t *local = NULL; +    int op_errno = -1; +    int call_cnt = 0; +    int i = 0; + +    conf = this->private; +    if (!conf) { +        op_errno = EINVAL; +        goto err; +    } + +    local = frame->local; +    if (!local) { +        op_errno = EINVAL; +        goto err; +    } + +    /* Since we don't know whether this is a file or a directory, +     * request all xattrs*/ +    ret = dht_set_file_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        op_errno = -ret; +        goto err; +    } + +    ret = dht_set_dir_xattr_req(this, loc, local->xattr_req); +    if (ret) { +        op_errno = -ret; +        goto err; +    } + +    /* This should have been set in dht_lookup */ +    hashed_subvol = local->hashed_subvol; + +    if (!hashed_subvol) { +        gf_msg_debug(this->name, 0, +                     "%s: no subvolume in layout for path, " +                     "checking on all the subvols to see if " +                     "it is a directory", +                     loc->path); -int dht_set_file_xattr_req (xlator_t *this, loc_t *loc, dict_t *xattr_req) -{ -        int ret   = -EINVAL; -        dht_conf_t *conf = NULL; +        call_cnt = conf->subvolume_cnt; +        local->call_cnt = call_cnt; -        conf = this->private; -        if (!conf) { -                goto err; +        local->layout = dht_layout_new(this, conf->subvolume_cnt); +        if (!local->layout) { +            op_errno = ENOMEM; +            goto err;          } -        if (!xattr_req) { -                goto err; -        } +        gf_msg_debug(this->name, 0, +                     "%s: Found null hashed subvol. Calling lookup" +                     " on all nodes.", +                     loc->path); -        /* Used to check whether this is a linkto file. -         */ -        ret = dict_set_uint32 (xattr_req, -                               conf->link_xattr_name, 256); -        if (ret < 0) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value:key = %s for " -                        "path %s", conf->link_xattr_name, loc->path); -                goto err; +        for (i = 0; i < call_cnt; i++) { +            STACK_WIND_COOKIE(frame, dht_lookup_dir_cbk, conf->subvolumes[i], +                              conf->subvolumes[i], +                              conf->subvolumes[i]->fops->lookup, &local->loc, +                              local->xattr_req);          } +        return 0; +    } -        /* This is used to make sure we don't unlink linkto files -         * which are the target of an ongoing file migration. -         */ -        ret = dict_set_uint32 (xattr_req, -                               GLUSTERFS_OPEN_FD_COUNT, 4); -        if (ret) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value:key = %s for " -                        "path %s", GLUSTERFS_OPEN_FD_COUNT, loc->path); -                goto err; -        } +    /* if we have the hashed_subvol, send the lookup there first so +     * as to see whether we have a file or a directory */ +    gf_msg_debug(this->name, 0, +                 "Calling fresh lookup for %s on" +                 " %s", +                 loc->path, hashed_subvol->name); -        ret = 0; +    STACK_WIND_COOKIE(frame, dht_lookup_cbk, hashed_subvol, hashed_subvol, +                      hashed_subvol->fops->lookup, loc, local->xattr_req); +    return 0;  err: -        return ret; +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); +    return 0;  } - -  int -dht_do_revalidate (call_frame_t *frame, xlator_t *this, loc_t *loc) +dht_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)  { -        xlator_t     *subvol = NULL; -        xlator_t     *mds_subvol = NULL; -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           ret    = -1; -        int           op_errno = -1; -        dht_layout_t *layout = NULL; -        int           i = 0; -        int           call_cnt = 0; -        int           gen = 0; +    xlator_t *hashed_subvol = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    int op_errno = -1; +    loc_t new_loc = { +        0, +    }; -        conf = this->private; -        if (!conf) { -                op_errno = EINVAL; -                goto err; -        } +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); -        local = frame->local; -        if (!local) { -                op_errno = EINVAL; -                goto err; -        } +    conf = this->private; +    if (!conf) +        goto err; -        layout = local->layout; -        if (!layout) { -                gf_msg_debug (this->name, 0, -                              "path = %s. No layout found in the inode ctx.", -                              loc->path); -                op_errno = EINVAL; -                goto err; -        } - -        /* Generation number has changed. This layout may be stale. */ -        if (layout->gen && (layout->gen < conf->gen)) { -                gen = layout->gen; -                dht_layout_unref (this, local->layout); -                local->layout = NULL; -                local->cached_subvol = NULL; - -                gf_msg_debug(this->name, 0, -                             "path = %s. In memory layout may be stale." -                             "(layout->gen (%d) is less than " -                             "conf->gen (%d)). Calling fresh lookup.", -                             loc->path, gen, conf->gen); +    local = dht_local_init(frame, loc, NULL, GF_FOP_LOOKUP); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -                dht_do_fresh_lookup (frame, this, loc); -                return 0; -        } +    ret = dht_filter_loc_subvol_key(this, loc, &new_loc, &hashed_subvol); +    if (ret) { +        loc_wipe(&local->loc); +        ret = loc_dup(&new_loc, &local->loc); -        local->inode = inode_ref (loc->inode); +        /* we no longer need 'new_loc' entries */ +        loc_wipe(&new_loc); -        /* Since we don't know whether this has changed, -         * request all xattrs*/ -        ret = dht_set_file_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                op_errno = -ret; -                goto err; +        /* check if loc_dup() is successful */ +        if (ret == -1) { +            op_errno = errno; +            gf_msg_debug(this->name, errno, +                         "copying location failed for path=%s", loc->path); +            goto err;          } +    } -        ret = dht_set_dir_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                op_errno = -ret; -                goto err; -        } +    if (xattr_req) { +        local->xattr_req = dict_ref(xattr_req); +    } else { +        local->xattr_req = dict_new(); +    } -        if (IA_ISDIR (local->inode->ia_type)) { -                ret = dht_inode_ctx_mdsvol_get (local->inode, this, -                                                &mds_subvol); -                if (ret || !mds_subvol) { -                        gf_msg_debug (this->name, 0, -                                      "path = %s. No mds subvol in inode ctx", -                                      local->loc.path); -                } -                local->mds_subvol = mds_subvol; -                local->call_cnt = conf->subvolume_cnt; -                call_cnt = local->call_cnt; - -                for (i = 0; i < call_cnt; i++) { -                        STACK_WIND_COOKIE (frame, dht_revalidate_cbk, -                                           conf->subvolumes[i], -                                           conf->subvolumes[i], -                                           conf->subvolumes[i]->fops->lookup, -                                           loc, local->xattr_req); -                } -                return 0; -        } +    /* Nameless lookup */ -        /* If not a dir, this should be 1 */ -        local->call_cnt = layout->cnt; -        call_cnt = local->call_cnt; +    if (gf_uuid_is_null(loc->pargfid) && !gf_uuid_is_null(loc->gfid) && +        !__is_root_gfid(loc->inode->gfid)) { +        local->cached_subvol = NULL; +        dht_do_discover(frame, this, loc); +        return 0; +    } -        for (i = 0; i < call_cnt; i++) { -                subvol = layout->list[i].xlator; +    if (loc_is_root(loc)) { +        ret = dict_set_uint32(local->xattr_req, conf->commithash_xattr_name, +                              sizeof(uint32_t)); +    } -                gf_msg_debug (this->name, 0, "path = %s. Calling " -                              "revalidate lookup on %s", -                              loc->path, subvol->name); +    if (!hashed_subvol) +        hashed_subvol = dht_subvol_get_hashed(this, loc); +    local->hashed_subvol = hashed_subvol; -                STACK_WIND_COOKIE (frame, dht_revalidate_cbk, subvol, -                                   subvol, subvol->fops->lookup, -                                   &local->loc, local->xattr_req); -        } +    /* The entry has been looked up before and has an inode_ctx set +     */ +    if (is_revalidate(loc)) { +        dht_do_revalidate(frame, this, loc);          return 0; -err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL); +    } else { +        dht_do_fresh_lookup(frame, this, loc);          return 0; -} - -int -dht_do_fresh_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ -        int           ret    = -1; -        dht_conf_t   *conf  = NULL; -        xlator_t     *hashed_subvol = NULL; -        dht_local_t  *local  = NULL; -        int           op_errno = -1; -        int           call_cnt = 0; -        int           i        = 0; - -        conf = this->private; -        if (!conf) { -                op_errno = EINVAL; -                goto err; -        } - -        local = frame->local; -        if (!local) { -                op_errno = EINVAL; -                goto err; -        } - -        /* Since we don't know whether this is a file or a directory, -         * request all xattrs*/ -        ret = dht_set_file_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                op_errno = -ret; -                goto err; -        } - -        ret = dht_set_dir_xattr_req (this, loc, local->xattr_req); -        if (ret) { -                op_errno = -ret; -                goto err; -        } - -        /* This should have been set in dht_lookup */ -        hashed_subvol = local->hashed_subvol; - -        if (!hashed_subvol) { -                gf_msg_debug (this->name, 0, -                              "%s: no subvolume in layout for path, " -                              "checking on all the subvols to see if " -                              "it is a directory", loc->path); - -                call_cnt   = conf->subvolume_cnt; -                local->call_cnt = call_cnt; - -                local->layout = dht_layout_new (this, -                                                conf->subvolume_cnt); -                if (!local->layout) { -                        op_errno = ENOMEM; -                        goto err; -                } - -                gf_msg_debug (this->name, 0, -                              "%s: Found null hashed subvol. Calling lookup" -                              " on all nodes.", loc->path); +    } -                for (i = 0; i < call_cnt; i++) { -                        STACK_WIND_COOKIE (frame, dht_lookup_dir_cbk, -                                           conf->subvolumes[i], -                                           conf->subvolumes[i], -                                           conf->subvolumes[i]->fops->lookup, -                                           &local->loc, local->xattr_req); -                } -                return 0; -        } - -        /* if we have the hashed_subvol, send the lookup there first so -         * as to see whether we have a file or a directory */ -        gf_msg_debug (this->name, 0, "Calling fresh lookup for %s on" -                      " %s", loc->path, hashed_subvol->name); - -        STACK_WIND_COOKIE (frame, dht_lookup_cbk, hashed_subvol, -                           hashed_subvol, hashed_subvol->fops->lookup, -                           loc, local->xattr_req); -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL); -        return 0; +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL); +    return 0;  } -  int -dht_lookup (call_frame_t *frame, xlator_t *this, -            loc_t *loc, dict_t *xattr_req) +dht_unlink_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                        int op_ret, int op_errno, struct iatt *preparent, +                        struct iatt *postparent, dict_t *xdata)  { -        xlator_t     *hashed_subvol = NULL; -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           ret    = -1; -        int           op_errno = -1; -        loc_t         new_loc = {0,}; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); - -        conf = this->private; -        if (!conf) -                goto err; - -        local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        ret = dht_filter_loc_subvol_key (this, loc, &new_loc, -                                         &hashed_subvol); -        if (ret) { -                loc_wipe (&local->loc); -                ret = loc_dup (&new_loc, &local->loc); - -                /* we no longer need 'new_loc' entries */ -                loc_wipe (&new_loc); - -                /* check if loc_dup() is successful */ -                if (ret == -1) { -                        op_errno = errno; -                        gf_msg_debug (this->name, errno, -                                      "copying location failed for path=%s", -                                      loc->path); -                        goto err; -                } -        } - -        if (xattr_req) { -                local->xattr_req = dict_ref (xattr_req); -        } else { -                local->xattr_req = dict_new (); -        } +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; -        /* Nameless lookup */ +    local = frame->local; +    prev = cookie; -        if (gf_uuid_is_null (loc->pargfid) && !gf_uuid_is_null (loc->gfid) && -            !__is_root_gfid (loc->inode->gfid)) { -                local->cached_subvol = NULL; -                dht_do_discover (frame, this, loc); -                return 0; -        } - -        if (loc_is_root (loc)) { -                ret = dict_set_uint32 (local->xattr_req, -                                       conf->commithash_xattr_name, -                                       sizeof(uint32_t)); +    LOCK(&frame->lock); +    { +        if ((op_ret == -1) && +            !((op_errno == ENOENT) || (op_errno == ENOTCONN))) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, +                         "Unlink link: subvolume %s" +                         " returned -1", +                         prev->name); +            goto unlock;          } -        if (!hashed_subvol) -                hashed_subvol = dht_subvol_get_hashed (this, loc); -        local->hashed_subvol = hashed_subvol; - +        local->op_ret = 0; +    } +unlock: +    UNLOCK(&frame->lock); -        /* The entry has been looked up before and has an inode_ctx set -         */ -        if (is_revalidate (loc)) { -                dht_do_revalidate (frame, this, loc); -                return 0; -        } else  { -                dht_do_fresh_lookup (frame, this, loc); -                return 0; -        } +    dht_set_fixed_dir_stat(&local->preparent); +    dht_set_fixed_dir_stat(&local->postparent); +    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, +                     &local->preparent, &local->postparent, xdata); -        return 0; -err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL); -        return 0; +    return 0;  }  int -dht_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int op_ret, int op_errno, struct iatt *preparent, -                         struct iatt *postparent, dict_t *xdata) +dht_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +               int op_errno, struct iatt *preparent, struct iatt *postparent, +               dict_t *xdata)  { -        dht_local_t     *local          = NULL; -        xlator_t        *prev           = NULL; +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    xlator_t *hashed_subvol = NULL; -        local = frame->local; -        prev  = cookie; - -        LOCK (&frame->lock); -        { -                if ((op_ret == -1) && !((op_errno == ENOENT) || -                                        (op_errno == ENOTCONN))) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "Unlink link: subvolume %s" -                                      " returned -1", -                                      prev->name); -                        goto unlock; -                } +    local = frame->local; +    prev = cookie; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            if (op_errno != ENOENT) { +                local->op_ret = -1; +                local->op_errno = op_errno; +            } else {                  local->op_ret = 0; +            } +            gf_msg_debug(this->name, op_errno, +                         "Unlink: subvolume %s returned -1", prev->name); +            goto unlock;          } -unlock: -        UNLOCK (&frame->lock); - -        dht_set_fixed_dir_stat (&local->preparent); -        dht_set_fixed_dir_stat (&local->postparent); -        DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, -                          &local->preparent, &local->postparent, xdata); -        return 0; -} - -int -dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                int op_ret, int op_errno, struct iatt *preparent, -                struct iatt *postparent, dict_t *xdata) -{ -        dht_local_t     *local          = NULL; -        xlator_t        *prev           = NULL; -        xlator_t        *hashed_subvol  = NULL; - -        local = frame->local; -        prev  = cookie; - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        if (op_errno != ENOENT) { -                                local->op_ret   = -1; -                                local->op_errno = op_errno; -                        } else { -                                local->op_ret = 0; -                        } -                        gf_msg_debug (this->name, op_errno, -                                      "Unlink: subvolume %s returned -1", -                                       prev->name); -                        goto unlock; -                } - -                local->op_ret = 0; +        local->op_ret = 0; -                local->postparent = *postparent; -                local->preparent = *preparent; +        local->postparent = *postparent; +        local->preparent = *preparent; -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->preparent, 0); -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->preparent, 0); +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1);          } +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        if (!local->op_ret) { -                hashed_subvol = dht_subvol_get_hashed (this, &local->loc); -                if (hashed_subvol && hashed_subvol != local->cached_subvol) { -                        /* -                         * If hashed and cached are different, then we need -                         * to unlink linkfile from hashed subvol if data -                         * file is deleted successfully -                         */ -                         STACK_WIND_COOKIE (frame, dht_unlink_linkfile_cbk, -                                            hashed_subvol, hashed_subvol, -                                            hashed_subvol->fops->unlink, -                                            &local->loc, local->flags, xdata); -                         return 0; -                } +    if (!local->op_ret) { +        hashed_subvol = dht_subvol_get_hashed(this, &local->loc); +        if (hashed_subvol && hashed_subvol != local->cached_subvol) { +            /* +             * If hashed and cached are different, then we need +             * to unlink linkfile from hashed subvol if data +             * file is deleted successfully +             */ +            STACK_WIND_COOKIE(frame, dht_unlink_linkfile_cbk, hashed_subvol, +                              hashed_subvol, hashed_subvol->fops->unlink, +                              &local->loc, local->flags, xdata); +            return 0;          } +    } -        dht_set_fixed_dir_stat (&local->preparent); -        dht_set_fixed_dir_stat (&local->postparent); -        DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno, -                          &local->preparent, &local->postparent, xdata); +    dht_set_fixed_dir_stat(&local->preparent); +    dht_set_fixed_dir_stat(&local->postparent); +    DHT_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno, +                     &local->preparent, &local->postparent, xdata); -        return 0; +    return 0;  }  static int -dht_common_setxattr_cbk (call_frame_t *frame, void *cookie, -                         xlator_t *this, int32_t op_ret, int32_t op_errno, -                         dict_t *xdata) +dht_common_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -         DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); -         return 0; +    DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); +    return 0;  } - -  static int -dht_fix_layout_setxattr_cbk (call_frame_t *frame, void *cookie, -                             xlator_t *this, int32_t op_ret, int32_t op_errno, -                             dict_t *xdata) +dht_fix_layout_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                            int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t   *local   = NULL; -        dht_layout_t  *layout  = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; -        if (op_ret == 0) { +    if (op_ret == 0) { +        /* update the layout in the inode ctx */ +        local = frame->local; +        layout = local->selfheal.layout; -                /* update the layout in the inode ctx */ -                local = frame->local; -                layout = local->selfheal.layout; +        dht_layout_set(this, local->loc.inode, layout); +    } -                dht_layout_set (this, local->loc.inode, layout); -        } - -         DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); -         return 0; +    DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); +    return 0;  } -  int -dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -             int op_ret, int op_errno, dict_t *xdata) +dht_err_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +            int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev = NULL; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; -        local = frame->local; -        prev = cookie; - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "subvolume %s returned -1", -                                      prev->name); -                        goto unlock; -                } +    local = frame->local; +    prev = cookie; -                local->op_ret = 0; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                         prev->name); +            goto unlock;          } + +        local->op_ret = 0; +    }  unlock: -        UNLOCK (&frame->lock); - -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                if ((local->fop == GF_FOP_SETXATTR) || -                    (local->fop == GF_FOP_FSETXATTR)) { -                        DHT_STACK_UNWIND (setxattr, frame, local->op_ret, -                                          local->op_errno, NULL); -                } -                if ((local->fop == GF_FOP_REMOVEXATTR) || -                    (local->fop == GF_FOP_FREMOVEXATTR)) { -                        DHT_STACK_UNWIND (removexattr, frame, local->op_ret, -                                          local->op_errno, NULL); -                } +    UNLOCK(&frame->lock); + +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        if ((local->fop == GF_FOP_SETXATTR) || +            (local->fop == GF_FOP_FSETXATTR)) { +            DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, +                             NULL); +        } +        if ((local->fop == GF_FOP_REMOVEXATTR) || +            (local->fop == GF_FOP_FREMOVEXATTR)) { +            DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, +                             NULL);          } +    } -        return 0; +    return 0;  }  /* Set the value[] of key into dict after convert from     host byte order to network byte order  */ -int32_t dht_dict_set_array (dict_t *dict, char *key, int32_t value[], -                            int32_t size) +int32_t +dht_dict_set_array(dict_t *dict, char *key, int32_t value[], int32_t size)  { -        int         ret = -1; -        int32_t   *ptr = NULL; -        int32_t     vindex; +    int ret = -1; +    int32_t *ptr = NULL; +    int32_t vindex; -        if (value == NULL) { -                return -EINVAL; -        } +    if (value == NULL) { +        return -EINVAL; +    } -        ptr = GF_MALLOC(sizeof(int32_t) * size, gf_common_mt_char); -        if (ptr == NULL) { -                return -ENOMEM; -        } -        for (vindex = 0; vindex < size; vindex++) { -                ptr[vindex] = hton32(value[vindex]); -        } -        ret = dict_set_bin(dict, key, ptr, sizeof(int32_t) * size); -        if (ret) -                GF_FREE (ptr); -        return ret; +    ptr = GF_MALLOC(sizeof(int32_t) * size, gf_common_mt_char); +    if (ptr == NULL) { +        return -ENOMEM; +    } +    for (vindex = 0; vindex < size; vindex++) { +        ptr[vindex] = hton32(value[vindex]); +    } +    ret = dict_set_bin(dict, key, ptr, sizeof(int32_t) * size); +    if (ret) +        GF_FREE(ptr); +    return ret;  }  int -dht_common_mds_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                            int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) +dht_common_mds_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                           int32_t op_ret, int32_t op_errno, dict_t *dict, +                           dict_t *xdata)  { -        dht_local_t *local = NULL; -        call_frame_t  *prev  = cookie; +    dht_local_t *local = NULL; +    call_frame_t *prev = cookie; -        local = frame->local; +    local = frame->local; -        if (op_ret) -                gf_msg_debug (this->name, op_errno, -                              "subvolume %s returned -1", -                              prev->this->name); +    if (op_ret) +        gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                     prev->this->name); -         if (local->fop == GF_FOP_SETXATTR) { -                DHT_STACK_UNWIND (setxattr, frame, 0, op_errno, local->xdata); -         } +    if (local->fop == GF_FOP_SETXATTR) { +        DHT_STACK_UNWIND(setxattr, frame, 0, op_errno, local->xdata); +    } -         if (local->fop == GF_FOP_FSETXATTR) { -                DHT_STACK_UNWIND (fsetxattr, frame, 0, op_errno, local->xdata); -         } +    if (local->fop == GF_FOP_FSETXATTR) { +        DHT_STACK_UNWIND(fsetxattr, frame, 0, op_errno, local->xdata); +    } -         if (local->fop == GF_FOP_REMOVEXATTR) { -                DHT_STACK_UNWIND (removexattr, frame, 0, op_errno, NULL); -         } +    if (local->fop == GF_FOP_REMOVEXATTR) { +        DHT_STACK_UNWIND(removexattr, frame, 0, op_errno, NULL); +    } -         if (local->fop == GF_FOP_FREMOVEXATTR) { -                DHT_STACK_UNWIND (fremovexattr, frame, 0, op_errno, NULL); -         } +    if (local->fop == GF_FOP_FREMOVEXATTR) { +        DHT_STACK_UNWIND(fremovexattr, frame, 0, op_errno, NULL); +    } -        return 0; +    return 0;  }  /* Code to wind a xattrop call to add 1 on current mds internal xattr     value  */  int -dht_setxattr_non_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                          int op_ret, int op_errno, dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        int           ret           = 0; -        dict_t        *xattrop      = NULL; -        int32_t       addone[1]     = {1}; -        call_frame_t  *prev         = NULL; -        dht_conf_t    *conf         = NULL; - -        local = frame->local; -        prev = cookie; -        conf = this->private; - -        LOCK (&frame->lock); -        { -             if (op_ret && !local->op_ret) { -                        local->op_ret = op_ret; -                        local->op_errno = op_errno; -                         gf_msg_debug (this->name, op_errno, -                                       "subvolume %s returned -1", -                                       prev->this->name); -             } -        } -        UNLOCK (&frame->lock); -        this_call_cnt = dht_frame_return (frame); - -        if (is_last_call (this_call_cnt)) { -                if (!local->op_ret) { -                        xattrop = dict_new (); -                        if (!xattrop) { -                                gf_msg (this->name, GF_LOG_ERROR, -                                        DHT_MSG_NO_MEMORY, 0, -                                        "dictionary creation failed"); -                                ret = -1; -                                goto out; -                        } -                        ret = dht_dict_set_array (xattrop, -                                                  conf->mds_xattr_key, -                                                  addone, 1); -                        if (ret != 0) { -                                gf_msg (this->name, GF_LOG_ERROR, 0, -                                        DHT_MSG_DICT_SET_FAILED, -                                        "dictionary set array failed "); -                                ret = -1; -                                goto out; -                        } -                        if ((local->fop == GF_FOP_SETXATTR) || -                            (local->fop == GF_FOP_REMOVEXATTR)) { -                                STACK_WIND (frame, dht_common_mds_xattrop_cbk, -                                            local->mds_subvol, -                                            local->mds_subvol->fops->xattrop, -                                            &local->loc, GF_XATTROP_ADD_ARRAY, -                                            xattrop, NULL); -                        } else { -                                STACK_WIND (frame, dht_common_mds_xattrop_cbk, -                                            local->mds_subvol, -                                            local->mds_subvol->fops->fxattrop, -                                            local->fd, GF_XATTROP_ADD_ARRAY, -                                            xattrop, NULL); -                        } -                } else  { -                        if (local->fop == GF_FOP_SETXATTR) { -                                DHT_STACK_UNWIND (setxattr, frame, 0, 0, local->xdata); -                        } - -                        if (local->fop == GF_FOP_FSETXATTR) { -                                DHT_STACK_UNWIND (fsetxattr, frame, 0, 0, local->xdata); -                        } - -                        if (local->fop == GF_FOP_REMOVEXATTR) { -                                DHT_STACK_UNWIND (removexattr, frame, 0, 0, NULL); -                        } - -                        if (local->fop == GF_FOP_FREMOVEXATTR) { -                                DHT_STACK_UNWIND (fremovexattr, frame, 0, 0, NULL); -                        } -                } -        } -out: -        if (xattrop) -                dict_unref (xattrop); -        if (ret) { -                if (local->fop == GF_FOP_SETXATTR) { -                        DHT_STACK_UNWIND (setxattr, frame, 0, 0, local->xdata); -                } - -                if (local->fop == GF_FOP_FSETXATTR) { -                        DHT_STACK_UNWIND (fsetxattr, frame, 0, 0, local->xdata); -                } - -                if (local->fop == GF_FOP_REMOVEXATTR) { -                        DHT_STACK_UNWIND (removexattr, frame, 0, 0, NULL); -                } - -                if (local->fop == GF_FOP_FREMOVEXATTR) { -                        DHT_STACK_UNWIND (fremovexattr, frame, 0, 0, NULL); -                } -        } -        return 0; -} - - -int -dht_setxattr_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                      int op_ret, int op_errno, dict_t *xdata) +dht_setxattr_non_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                         int op_ret, int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        dht_conf_t   *conf  = NULL; -        call_frame_t *prev = NULL; -        xlator_t     *mds_subvol = NULL; -        int i = 0; - -        local = frame->local; -        prev = cookie; -        conf = this->private; -        mds_subvol = local->mds_subvol; - -        if (op_ret == -1) { -                local->op_ret  = op_ret; -                local->op_errno = op_errno; -                gf_msg_debug (this->name, op_errno, -                              "subvolume %s returned -1", -                              prev->this->name); +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    int ret = 0; +    dict_t *xattrop = NULL; +    int32_t addone[1] = {1}; +    call_frame_t *prev = NULL; +    dht_conf_t *conf = NULL; + +    local = frame->local; +    prev = cookie; +    conf = this->private; + +    LOCK(&frame->lock); +    { +        if (op_ret && !local->op_ret) { +            local->op_ret = op_ret; +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                         prev->this->name); +        } +    } +    UNLOCK(&frame->lock); +    this_call_cnt = dht_frame_return(frame); + +    if (is_last_call(this_call_cnt)) { +        if (!local->op_ret) { +            xattrop = dict_new(); +            if (!xattrop) { +                gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0, +                       "dictionary creation failed"); +                ret = -1;                  goto out; -        } - -        local->op_ret = 0; -        local->call_cnt = conf->subvolume_cnt - 1; -        local->xdata    = dict_ref (xdata); - -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (mds_subvol && (mds_subvol == conf->subvolumes[i])) -                        continue; -                if (local->fop == GF_FOP_SETXATTR) { -                        STACK_WIND (frame, dht_setxattr_non_mds_cbk, -                                    conf->subvolumes[i], -                                    conf->subvolumes[i]->fops->setxattr, -                                    &local->loc, local->xattr, -                                    local->flags, local->xattr_req); -                } +            } +            ret = dht_dict_set_array(xattrop, conf->mds_xattr_key, addone, 1); +            if (ret != 0) { +                gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +                       "dictionary set array failed "); +                ret = -1; +                goto out; +            } +            if ((local->fop == GF_FOP_SETXATTR) || +                (local->fop == GF_FOP_REMOVEXATTR)) { +                STACK_WIND(frame, dht_common_mds_xattrop_cbk, local->mds_subvol, +                           local->mds_subvol->fops->xattrop, &local->loc, +                           GF_XATTROP_ADD_ARRAY, xattrop, NULL); +            } else { +                STACK_WIND(frame, dht_common_mds_xattrop_cbk, local->mds_subvol, +                           local->mds_subvol->fops->fxattrop, local->fd, +                           GF_XATTROP_ADD_ARRAY, xattrop, NULL); +            } +        } else { +            if (local->fop == GF_FOP_SETXATTR) { +                DHT_STACK_UNWIND(setxattr, frame, 0, 0, local->xdata); +            } -                if (local->fop == GF_FOP_FSETXATTR) { -                        STACK_WIND (frame, dht_setxattr_non_mds_cbk, -                                    conf->subvolumes[i], -                                    conf->subvolumes[i]->fops->fsetxattr, -                                    local->fd, local->xattr, -                                    local->flags, local->xattr_req); -                } +            if (local->fop == GF_FOP_FSETXATTR) { +                DHT_STACK_UNWIND(fsetxattr, frame, 0, 0, local->xdata); +            } -                if (local->fop == GF_FOP_REMOVEXATTR) { -                        STACK_WIND (frame, dht_setxattr_non_mds_cbk, -                                    conf->subvolumes[i], -                                    conf->subvolumes[i]->fops->removexattr, -                                    &local->loc, local->key, -                                    local->xattr_req); -                } +            if (local->fop == GF_FOP_REMOVEXATTR) { +                DHT_STACK_UNWIND(removexattr, frame, 0, 0, NULL); +            } -                if (local->fop == GF_FOP_FREMOVEXATTR) { -                        STACK_WIND (frame, dht_setxattr_non_mds_cbk, -                                    conf->subvolumes[i], -                                    conf->subvolumes[i]->fops->fremovexattr, -                                    local->fd, local->key, -                                    local->xattr_req); -                } +            if (local->fop == GF_FOP_FREMOVEXATTR) { +                DHT_STACK_UNWIND(fremovexattr, frame, 0, 0, NULL); +            }          } - -        return 0; +    }  out: +    if (xattrop) +        dict_unref(xattrop); +    if (ret) {          if (local->fop == GF_FOP_SETXATTR) { -                DHT_STACK_UNWIND (setxattr, frame, local->op_ret, -                                  local->op_errno, xdata); +            DHT_STACK_UNWIND(setxattr, frame, 0, 0, local->xdata);          }          if (local->fop == GF_FOP_FSETXATTR) { -                DHT_STACK_UNWIND (fsetxattr, frame, local->op_ret, -                                  local->op_errno, xdata); +            DHT_STACK_UNWIND(fsetxattr, frame, 0, 0, local->xdata);          }          if (local->fop == GF_FOP_REMOVEXATTR) { -                DHT_STACK_UNWIND (removexattr, frame, local->op_ret, -                                  local->op_errno, NULL); +            DHT_STACK_UNWIND(removexattr, frame, 0, 0, NULL);          }          if (local->fop == GF_FOP_FREMOVEXATTR) { -                DHT_STACK_UNWIND (fremovexattr, frame, local->op_ret, -                                  local->op_errno, NULL); +            DHT_STACK_UNWIND(fremovexattr, frame, 0, 0, NULL);          } - -        return 0; +    } +    return 0;  }  int -dht_xattrop_mds_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, dict_t *dict, dict_t *xdata) +dht_setxattr_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int op_ret, int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        call_frame_t *prev = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    call_frame_t *prev = NULL; +    xlator_t *mds_subvol = NULL; +    int i = 0; -        local = frame->local; -        prev = cookie; +    local = frame->local; +    prev = cookie; +    conf = this->private; +    mds_subvol = local->mds_subvol; -        if (op_ret == -1) { -                local->op_errno = op_errno; -                local->op_ret   = op_ret; -                gf_msg_debug (this->name, op_errno, -                              "subvolume %s returned -1", -                              prev->this->name); -                goto out; -        } +    if (op_ret == -1) { +        local->op_ret = op_ret; +        local->op_errno = op_errno; +        gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                     prev->this->name); +        goto out; +    } +    local->op_ret = 0; +    local->call_cnt = conf->subvolume_cnt - 1; +    local->xdata = dict_ref(xdata); + +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (mds_subvol && (mds_subvol == conf->subvolumes[i])) +            continue;          if (local->fop == GF_FOP_SETXATTR) { -                STACK_WIND (frame, dht_setxattr_mds_cbk, -                            local->mds_subvol, -                            local->mds_subvol->fops->setxattr, -                            &local->loc, local->xattr, -                            local->flags, local->xattr_req); +            STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], +                       conf->subvolumes[i]->fops->setxattr, &local->loc, +                       local->xattr, local->flags, local->xattr_req);          }          if (local->fop == GF_FOP_FSETXATTR) { -                STACK_WIND (frame, dht_setxattr_mds_cbk, -                            local->mds_subvol, -                            local->mds_subvol->fops->fsetxattr, -                            local->fd, local->xattr, -                            local->flags, local->xattr_req); +            STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], +                       conf->subvolumes[i]->fops->fsetxattr, local->fd, +                       local->xattr, local->flags, local->xattr_req);          }          if (local->fop == GF_FOP_REMOVEXATTR) { -                STACK_WIND (frame, dht_setxattr_mds_cbk, -                            local->mds_subvol, -                            local->mds_subvol->fops->removexattr, -                            &local->loc, local->key, -                            local->xattr_req); +            STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], +                       conf->subvolumes[i]->fops->removexattr, &local->loc, +                       local->key, local->xattr_req);          }          if (local->fop == GF_FOP_FREMOVEXATTR) { -                STACK_WIND (frame, dht_setxattr_mds_cbk, -                            local->mds_subvol, -                            local->mds_subvol->fops->fremovexattr, -                            local->fd, local->key, -                            local->xattr_req); +            STACK_WIND(frame, dht_setxattr_non_mds_cbk, conf->subvolumes[i], +                       conf->subvolumes[i]->fops->fremovexattr, local->fd, +                       local->key, local->xattr_req);          } +    } +    return 0; +out: +    if (local->fop == GF_FOP_SETXATTR) { +        DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, +                         xdata); +    } -        return 0; +    if (local->fop == GF_FOP_FSETXATTR) { +        DHT_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, +                         xdata); +    } + +    if (local->fop == GF_FOP_REMOVEXATTR) { +        DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, +                         NULL); +    } + +    if (local->fop == GF_FOP_FREMOVEXATTR) { +        DHT_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, +                         NULL); +    } + +    return 0; +} + +int +dht_xattrop_mds_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                    int op_ret, int op_errno, dict_t *dict, dict_t *xdata) +{ +    dht_local_t *local = NULL; +    call_frame_t *prev = NULL; + +    local = frame->local; +    prev = cookie; + +    if (op_ret == -1) { +        local->op_errno = op_errno; +        local->op_ret = op_ret; +        gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                     prev->this->name); +        goto out; +    } + +    if (local->fop == GF_FOP_SETXATTR) { +        STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, +                   local->mds_subvol->fops->setxattr, &local->loc, local->xattr, +                   local->flags, local->xattr_req); +    } + +    if (local->fop == GF_FOP_FSETXATTR) { +        STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, +                   local->mds_subvol->fops->fsetxattr, local->fd, local->xattr, +                   local->flags, local->xattr_req); +    } + +    if (local->fop == GF_FOP_REMOVEXATTR) { +        STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, +                   local->mds_subvol->fops->removexattr, &local->loc, +                   local->key, local->xattr_req); +    } + +    if (local->fop == GF_FOP_FREMOVEXATTR) { +        STACK_WIND(frame, dht_setxattr_mds_cbk, local->mds_subvol, +                   local->mds_subvol->fops->fremovexattr, local->fd, local->key, +                   local->xattr_req); +    } + +    return 0;  out: -        if (local->fop == GF_FOP_SETXATTR) { -                DHT_STACK_UNWIND (setxattr, frame, local->op_ret, -                                  local->op_errno, xdata); -        } +    if (local->fop == GF_FOP_SETXATTR) { +        DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, +                         xdata); +    } -        if (local->fop == GF_FOP_FSETXATTR) { -                DHT_STACK_UNWIND (fsetxattr, frame, local->op_ret, -                                  local->op_errno, xdata); -        } +    if (local->fop == GF_FOP_FSETXATTR) { +        DHT_STACK_UNWIND(fsetxattr, frame, local->op_ret, local->op_errno, +                         xdata); +    } -        if (local->fop == GF_FOP_REMOVEXATTR) { -                DHT_STACK_UNWIND (removexattr, frame, local->op_ret, -                                  local->op_errno, NULL); -        } +    if (local->fop == GF_FOP_REMOVEXATTR) { +        DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, +                         NULL); +    } -        if (local->fop == GF_FOP_FREMOVEXATTR) { -                DHT_STACK_UNWIND (fremovexattr, frame, local->op_ret, -                                  local->op_errno, NULL); -        } +    if (local->fop == GF_FOP_FREMOVEXATTR) { +        DHT_STACK_UNWIND(fremovexattr, frame, local->op_ret, local->op_errno, +                         NULL); +    } -        return 0; +    return 0;  }  static void -fill_layout_info (dht_layout_t *layout, char *buf) +fill_layout_info(dht_layout_t *layout, char *buf)  { -        int i = 0; -        char tmp_buf[128] = {0,}; +    int i = 0; +    char tmp_buf[128] = { +        0, +    }; -        for (i = 0; i < layout->cnt; i++) { -                snprintf (tmp_buf, sizeof (tmp_buf), "(%s %u %u)", -                          layout->list[i].xlator->name, -                          layout->list[i].start, -                          layout->list[i].stop); -                if (i) -                        strcat (buf, " "); -                strcat (buf, tmp_buf); -        } +    for (i = 0; i < layout->cnt; i++) { +        snprintf(tmp_buf, sizeof(tmp_buf), "(%s %u %u)", +                 layout->list[i].xlator->name, layout->list[i].start, +                 layout->list[i].stop); +        if (i) +            strcat(buf, " "); +        strcat(buf, tmp_buf); +    }  }  static void -dht_fill_pathinfo_xattr (xlator_t *this, dht_local_t *local, -                         char *xattr_buf, int32_t alloc_len, -                         int flag, char *layout_buf) -{ -        if (flag) { -                if (local->xattr_val) { -                        snprintf (xattr_buf, alloc_len, -                          "((<"DHT_PATHINFO_HEADER"%s> %s) (%s-layout %s))", -                          this->name, local->xattr_val, this->name, -                          layout_buf); -                } else { -                        snprintf (xattr_buf, alloc_len, "(%s-layout %s)", -                          this->name, layout_buf); -                } -        } else if (local->xattr_val) { -                snprintf (xattr_buf, alloc_len, -                          "(<"DHT_PATHINFO_HEADER"%s> %s)", -                          this->name, local->xattr_val); +dht_fill_pathinfo_xattr(xlator_t *this, dht_local_t *local, char *xattr_buf, +                        int32_t alloc_len, int flag, char *layout_buf) +{ +    if (flag) { +        if (local->xattr_val) { +            snprintf(xattr_buf, alloc_len, +                     "((<" DHT_PATHINFO_HEADER "%s> %s) (%s-layout %s))", +                     this->name, local->xattr_val, this->name, layout_buf);          } else { -                xattr_buf[0] = '\0'; +            snprintf(xattr_buf, alloc_len, "(%s-layout %s)", this->name, +                     layout_buf);          } +    } else if (local->xattr_val) { +        snprintf(xattr_buf, alloc_len, "(<" DHT_PATHINFO_HEADER "%s> %s)", +                 this->name, local->xattr_val); +    } else { +        xattr_buf[0] = '\0'; +    }  }  int -dht_vgetxattr_alloc_and_fill (dht_local_t *local, dict_t *xattr, xlator_t *this, -                              int op_errno) +dht_vgetxattr_alloc_and_fill(dht_local_t *local, dict_t *xattr, xlator_t *this, +                             int op_errno)  { -        int      ret       = -1; -        char    *value     = NULL; +    int ret = -1; +    char *value = NULL; -        ret = dict_get_str (xattr, local->xsel, &value); -        if (ret) { -                gf_msg (this->name, GF_LOG_ERROR, op_errno, -                        DHT_MSG_GET_XATTR_FAILED, -                        "Subvolume %s returned -1", this->name); -                local->op_ret = -1; -                local->op_errno = op_errno; -                goto out; -        } +    ret = dict_get_str(xattr, local->xsel, &value); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, +               "Subvolume %s returned -1", this->name); +        local->op_ret = -1; +        local->op_errno = op_errno; +        goto out; +    } -        local->alloc_len += strlen(value); +    local->alloc_len += strlen(value); +    if (!local->xattr_val) { +        local->alloc_len += (SLEN(DHT_PATHINFO_HEADER) + 10); +        local->xattr_val = GF_MALLOC(local->alloc_len, gf_common_mt_char);          if (!local->xattr_val) { -                local->alloc_len += (SLEN (DHT_PATHINFO_HEADER) + 10); -                local->xattr_val = GF_MALLOC (local->alloc_len, -                                              gf_common_mt_char); -                if (!local->xattr_val) { -                        ret = -1; -                        goto out; -                } -                local->xattr_val[0] = '\0'; -        } - -        int plen = strlen (local->xattr_val); -        if (plen) { -                /* extra byte(s) for \0 to be safe */ -                local->alloc_len += (plen + 2); -                local->xattr_val = GF_REALLOC (local->xattr_val, -                                               local->alloc_len); -                if (!local->xattr_val) { -                        ret = -1; -                        goto out; -                } +            ret = -1; +            goto out;          } +        local->xattr_val[0] = '\0'; +    } -        (void) strcat (local->xattr_val, value); -        (void) strcat (local->xattr_val, " "); -        local->op_ret = 0; +    int plen = strlen(local->xattr_val); +    if (plen) { +        /* extra byte(s) for \0 to be safe */ +        local->alloc_len += (plen + 2); +        local->xattr_val = GF_REALLOC(local->xattr_val, local->alloc_len); +        if (!local->xattr_val) { +            ret = -1; +            goto out; +        } +    } -        ret = 0; +    (void)strcat(local->xattr_val, value); +    (void)strcat(local->xattr_val, " "); +    local->op_ret = 0; - out: -        return ret; +    ret = 0; + +out: +    return ret;  }  int -dht_vgetxattr_fill_and_set (dht_local_t *local, dict_t **dict, xlator_t *this, -                            gf_boolean_t flag) +dht_vgetxattr_fill_and_set(dht_local_t *local, dict_t **dict, xlator_t *this, +                           gf_boolean_t flag)  { -        int   ret             = -1; -        char *xattr_buf       = NULL; -        char layout_buf[8192] = {0,}; - -        if (flag) -                fill_layout_info (local->layout, layout_buf); +    int ret = -1; +    char *xattr_buf = NULL; +    char layout_buf[8192] = { +        0, +    }; -        *dict = dict_new (); -        if (!*dict) -                goto out; - -        local->xattr_val[strlen (local->xattr_val) - 1] = '\0'; +    if (flag) +        fill_layout_info(local->layout, layout_buf); -        /* we would need max this many bytes to create xattr string -         * extra 40 bytes is just an estimated amount of additional -         * space required as we include translator name and some -         * spaces, brackets etc. when forming the pathinfo string. -         * -         * For node-uuid we just don't have all the pretty formatting, -         * but since this is a generic routine for pathinfo & node-uuid -         * we don't have conditional space allocation and try to be -         * generic -         */ -        local->alloc_len += (2 * strlen (this->name)) -                + strlen (layout_buf) -                + 40; -        xattr_buf = GF_MALLOC (local->alloc_len, gf_common_mt_char); -        if (!xattr_buf) -                goto out; - -        if (XATTR_IS_PATHINFO (local->xsel)) { -                (void) dht_fill_pathinfo_xattr (this, local, xattr_buf, -                                                local->alloc_len, flag, -                                                layout_buf); -        } else if ((XATTR_IS_NODE_UUID (local->xsel)) -                   || (XATTR_IS_NODE_UUID_LIST (local->xsel))) { -                (void) snprintf (xattr_buf, local->alloc_len, "%s", -                                 local->xattr_val); -        } else { -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_GET_XATTR_FAILED, -                        "Unknown local->xsel (%s)", local->xsel); -                GF_FREE (xattr_buf); -                goto out; -        } - -        ret = dict_set_dynstr (*dict, local->xsel, xattr_buf); -        if (ret) -                GF_FREE (xattr_buf); -        GF_FREE (local->xattr_val); +    *dict = dict_new(); +    if (!*dict) +        goto out; - out: -        return ret; -} +    local->xattr_val[strlen(local->xattr_val) - 1] = '\0'; + +    /* we would need max this many bytes to create xattr string +     * extra 40 bytes is just an estimated amount of additional +     * space required as we include translator name and some +     * spaces, brackets etc. when forming the pathinfo string. +     * +     * For node-uuid we just don't have all the pretty formatting, +     * but since this is a generic routine for pathinfo & node-uuid +     * we don't have conditional space allocation and try to be +     * generic +     */ +    local->alloc_len += (2 * strlen(this->name)) + strlen(layout_buf) + 40; +    xattr_buf = GF_MALLOC(local->alloc_len, gf_common_mt_char); +    if (!xattr_buf) +        goto out; +    if (XATTR_IS_PATHINFO(local->xsel)) { +        (void)dht_fill_pathinfo_xattr(this, local, xattr_buf, local->alloc_len, +                                      flag, layout_buf); +    } else if ((XATTR_IS_NODE_UUID(local->xsel)) || +               (XATTR_IS_NODE_UUID_LIST(local->xsel))) { +        (void)snprintf(xattr_buf, local->alloc_len, "%s", local->xattr_val); +    } else { +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_GET_XATTR_FAILED, +               "Unknown local->xsel (%s)", local->xsel); +        GF_FREE(xattr_buf); +        goto out; +    } -int -dht_find_local_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int op_ret, int op_errno, dict_t *xattr, -                           dict_t *xdata) -{ -        dht_local_t  *local         = NULL; -        dht_conf_t   *conf          = NULL; -        xlator_t     *prev          = NULL; -        int           this_call_cnt = 0; -        int           ret           = 0; -        char         *uuid_str      = NULL; -        char         *uuid_list     = NULL; -        char         *next_uuid_str = NULL; -        char         *saveptr       = NULL; -        uuid_t        node_uuid     = {0,}; -        char         *uuid_list_copy = NULL; -        int           count          = 0; -        int           i              = 0; -        int           index          = 0; -        int           found          = 0; -        nodeuuid_info_t *tmp_ptr     = NULL; - -        VALIDATE_OR_GOTO (frame, out); -        VALIDATE_OR_GOTO (frame->local, out); +    ret = dict_set_dynstr(*dict, local->xsel, xattr_buf); +    if (ret) +        GF_FREE(xattr_buf); +    GF_FREE(local->xattr_val); -        local = frame->local; -        prev = cookie; -        conf = this->private; - -        VALIDATE_OR_GOTO (conf->defrag, out); - -        gf_msg_debug (this->name, 0, "subvol %s returned", prev->name); - -        LOCK (&frame->lock); -        { -                this_call_cnt = --local->call_cnt; -                if (op_ret < 0) { -                        gf_msg (this->name, GF_LOG_ERROR, op_errno, -                                DHT_MSG_GET_XATTR_FAILED, -                                "getxattr err for dir"); -                        local->op_ret = -1; -                        local->op_errno = op_errno; -                        goto unlock; -                } +out: +    return ret; +} + +int +dht_find_local_subvol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int op_ret, int op_errno, dict_t *xattr, +                          dict_t *xdata) +{ +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    xlator_t *prev = NULL; +    int this_call_cnt = 0; +    int ret = 0; +    char *uuid_str = NULL; +    char *uuid_list = NULL; +    char *next_uuid_str = NULL; +    char *saveptr = NULL; +    uuid_t node_uuid = { +        0, +    }; +    char *uuid_list_copy = NULL; +    int count = 0; +    int i = 0; +    int index = 0; +    int found = 0; +    nodeuuid_info_t *tmp_ptr = NULL; + +    VALIDATE_OR_GOTO(frame, out); +    VALIDATE_OR_GOTO(frame->local, out); + +    local = frame->local; +    prev = cookie; +    conf = this->private; + +    VALIDATE_OR_GOTO(conf->defrag, out); + +    gf_msg_debug(this->name, 0, "subvol %s returned", prev->name); + +    LOCK(&frame->lock); +    { +        this_call_cnt = --local->call_cnt; +        if (op_ret < 0) { +            gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, +                   "getxattr err for dir"); +            local->op_ret = -1; +            local->op_errno = op_errno; +            goto unlock; +        } -                ret = dict_get_str (xattr, local->xsel, &uuid_list); +        ret = dict_get_str(xattr, local->xsel, &uuid_list); -                if (ret < 0) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_DICT_GET_FAILED, -                                "Failed to get %s", local->xsel); -                        local->op_ret = -1; -                        local->op_errno = EINVAL; -                        goto unlock; -                } +        if (ret < 0) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_GET_FAILED, +                   "Failed to get %s", local->xsel); +            local->op_ret = -1; +            local->op_errno = EINVAL; +            goto unlock; +        } -                /* As DHT will not know details of its child xlators -                 * we need to parse this twice to get the count first -                 * and allocate memory later. -                 */ -                count = 0; -                index = conf->local_subvols_cnt; - -                uuid_list_copy = gf_strdup (uuid_list); - -                for (uuid_str = strtok_r (uuid_list, " ", &saveptr); -                     uuid_str; -                     uuid_str = next_uuid_str) { - -                        next_uuid_str = strtok_r (NULL, " ", &saveptr); -                        if (gf_uuid_parse (uuid_str, node_uuid)) { -                                gf_msg (this->name, GF_LOG_ERROR, 0, -                                        DHT_MSG_UUID_PARSE_ERROR, -                                        "Failed to parse uuid" -                                        " for %s", prev->name); -                                local->op_ret = -1; -                                local->op_errno = EINVAL; -                                goto unlock; -                        } - -                        count++; -                        if (gf_uuid_compare (node_uuid, conf->defrag->node_uuid)) { -                                gf_msg_debug (this->name, 0, "subvol %s does not" -                                              "belong to this node", -                                              prev->name); -                        } else { - -                                /* handle multiple bricks of the same replica -                                 * on the same node */ -                                if (found) -                                        continue; -                                conf->local_subvols[(conf->local_subvols_cnt)++] -                                                = prev; -                                found = 1; -                                gf_msg_debug (this->name, 0, "subvol %s belongs to" -                                              " this node", prev->name); -                        } -                } +        /* As DHT will not know details of its child xlators +         * we need to parse this twice to get the count first +         * and allocate memory later. +         */ +        count = 0; +        index = conf->local_subvols_cnt; + +        uuid_list_copy = gf_strdup(uuid_list); + +        for (uuid_str = strtok_r(uuid_list, " ", &saveptr); uuid_str; +             uuid_str = next_uuid_str) { +            next_uuid_str = strtok_r(NULL, " ", &saveptr); +            if (gf_uuid_parse(uuid_str, node_uuid)) { +                gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_UUID_PARSE_ERROR, +                       "Failed to parse uuid" +                       " for %s", +                       prev->name); +                local->op_ret = -1; +                local->op_errno = EINVAL; +                goto unlock; +            } -                if (!found) { -                        local->op_ret = 0; -                        goto unlock; -                } +            count++; +            if (gf_uuid_compare(node_uuid, conf->defrag->node_uuid)) { +                gf_msg_debug(this->name, 0, +                             "subvol %s does not" +                             "belong to this node", +                             prev->name); +            } else { +                /* handle multiple bricks of the same replica +                 * on the same node */ +                if (found) +                    continue; +                conf->local_subvols[(conf->local_subvols_cnt)++] = prev; +                found = 1; +                gf_msg_debug(this->name, 0, +                             "subvol %s belongs to" +                             " this node", +                             prev->name); +            } +        } -                conf->local_nodeuuids[index].count = count; -                conf->local_nodeuuids[index].elements -                               = GF_CALLOC (count, sizeof (nodeuuid_info_t), 1); +        if (!found) { +            local->op_ret = 0; +            goto unlock; +        } -                /* The node-uuids are guaranteed to be returned in the same -                 * order as the bricks -                 * A null node-uuid is returned for a brick that is down. -                 */ +        conf->local_nodeuuids[index].count = count; +        conf->local_nodeuuids[index].elements = GF_CALLOC( +            count, sizeof(nodeuuid_info_t), 1); -                saveptr = NULL; -                i = 0; +        /* The node-uuids are guaranteed to be returned in the same +         * order as the bricks +         * A null node-uuid is returned for a brick that is down. +         */ -                for (uuid_str = strtok_r (uuid_list_copy, " ", &saveptr); -                     uuid_str; -                     uuid_str = next_uuid_str) { +        saveptr = NULL; +        i = 0; -                        next_uuid_str = strtok_r (NULL, " ", &saveptr); -                        tmp_ptr = &(conf->local_nodeuuids[index].elements[i]); -                        gf_uuid_parse (uuid_str, tmp_ptr->uuid); +        for (uuid_str = strtok_r(uuid_list_copy, " ", &saveptr); uuid_str; +             uuid_str = next_uuid_str) { +            next_uuid_str = strtok_r(NULL, " ", &saveptr); +            tmp_ptr = &(conf->local_nodeuuids[index].elements[i]); +            gf_uuid_parse(uuid_str, tmp_ptr->uuid); -                        if (!gf_uuid_compare (tmp_ptr->uuid, -                                              conf->defrag->node_uuid)) { -                                tmp_ptr->info = REBAL_NODEUUID_MINE; -                        } -                        i++; -                        tmp_ptr = NULL; -                } +            if (!gf_uuid_compare(tmp_ptr->uuid, conf->defrag->node_uuid)) { +                tmp_ptr->info = REBAL_NODEUUID_MINE; +            } +            i++; +            tmp_ptr = NULL;          } +    } -        local->op_ret = 0; - unlock: -        UNLOCK (&frame->lock); +    local->op_ret = 0; +unlock: +    UNLOCK(&frame->lock); -        if (!is_last_call (this_call_cnt)) -                goto out; +    if (!is_last_call(this_call_cnt)) +        goto out; -        if (local->op_ret == -1) { -                goto unwind; -        } +    if (local->op_ret == -1) { +        goto unwind; +    } -        DHT_STACK_UNWIND (getxattr, frame, 0, 0, xattr, xdata); -        goto out; +    DHT_STACK_UNWIND(getxattr, frame, 0, 0, xattr, xdata); +    goto out; - unwind: +unwind: -        GF_FREE (conf->local_nodeuuids[index].elements); -        conf->local_nodeuuids[index].elements = NULL; +    GF_FREE(conf->local_nodeuuids[index].elements); +    conf->local_nodeuuids[index].elements = NULL; -        DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno, NULL, xdata); - out: -        GF_FREE (uuid_list_copy); -        return 0; +    DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, xdata); +out: +    GF_FREE(uuid_list_copy); +    return 0;  }  int -dht_vgetxattr_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) +dht_vgetxattr_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)  { -        int          ret           = 0; -        dht_local_t *local         = NULL; -        int          this_call_cnt = 0; -        dict_t      *dict          = NULL; +    int ret = 0; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    dict_t *dict = NULL; -        VALIDATE_OR_GOTO (frame, out); -        VALIDATE_OR_GOTO (frame->local, out); +    VALIDATE_OR_GOTO(frame, out); +    VALIDATE_OR_GOTO(frame->local, out); -        local = frame->local; +    local = frame->local; -        LOCK (&frame->lock); -        { -                this_call_cnt = --local->call_cnt; -                if (op_ret < 0) { -                        if (op_errno != ENOTCONN) { -                                gf_msg (this->name, GF_LOG_ERROR, op_errno, -                                        DHT_MSG_GET_XATTR_FAILED, -                                        "getxattr err for dir"); -                                local->op_ret = -1; -                                local->op_errno = op_errno; -                        } - -                        goto unlock; -                } +    LOCK(&frame->lock); +    { +        this_call_cnt = --local->call_cnt; +        if (op_ret < 0) { +            if (op_errno != ENOTCONN) { +                gf_msg(this->name, GF_LOG_ERROR, op_errno, +                       DHT_MSG_GET_XATTR_FAILED, "getxattr err for dir"); +                local->op_ret = -1; +                local->op_errno = op_errno; +            } -                ret = dht_vgetxattr_alloc_and_fill (local, xattr, this, -                                                    op_errno); -                if (ret) -                        gf_msg (this->name, GF_LOG_ERROR, op_errno, -                                DHT_MSG_DICT_SET_FAILED, -                                "alloc or fill failure"); +            goto unlock;          } - unlock: -        UNLOCK (&frame->lock); -        if (!is_last_call (this_call_cnt)) -                goto out; +        ret = dht_vgetxattr_alloc_and_fill(local, xattr, this, op_errno); +        if (ret) +            gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_DICT_SET_FAILED, +                   "alloc or fill failure"); +    } +unlock: +    UNLOCK(&frame->lock); -        /* -- last call: do patch ups -- */ +    if (!is_last_call(this_call_cnt)) +        goto out; -        if (local->op_ret == -1) { -                goto unwind; -        } +    /* -- last call: do patch ups -- */ -        ret = dht_vgetxattr_fill_and_set (local, &dict, this, _gf_true); -        if (ret) -                goto unwind; +    if (local->op_ret == -1) { +        goto unwind; +    } -        DHT_STACK_UNWIND (getxattr, frame, 0, 0, dict, xdata); -        goto cleanup; +    ret = dht_vgetxattr_fill_and_set(local, &dict, this, _gf_true); +    if (ret) +        goto unwind; - unwind: -        DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno, NULL, NULL); - cleanup: -        if (dict) -                dict_unref (dict); - out: -        return 0; +    DHT_STACK_UNWIND(getxattr, frame, 0, 0, dict, xdata); +    goto cleanup; + +unwind: +    DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, NULL); +cleanup: +    if (dict) +        dict_unref(dict); +out: +    return 0;  }  int -dht_vgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                   int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) +dht_vgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                  int op_errno, dict_t *xattr, dict_t *xdata)  { -        dht_local_t  *local         = NULL; -        int           ret           = 0; -        dict_t       *dict          = NULL; -        xlator_t     *prev          = NULL; -        gf_boolean_t  flag          = _gf_true; +    dht_local_t *local = NULL; +    int ret = 0; +    dict_t *dict = NULL; +    xlator_t *prev = NULL; +    gf_boolean_t flag = _gf_true; -        local = frame->local; -        prev = cookie; +    local = frame->local; +    prev = cookie; -        if (op_ret < 0) { -                local->op_ret = -1; -                local->op_errno = op_errno; -                gf_msg (this->name, GF_LOG_ERROR, op_errno, -                        DHT_MSG_GET_XATTR_FAILED, -                        "vgetxattr: Subvolume %s returned -1", -                         prev->name); -                goto unwind; -        } +    if (op_ret < 0) { +        local->op_ret = -1; +        local->op_errno = op_errno; +        gf_msg(this->name, GF_LOG_ERROR, op_errno, DHT_MSG_GET_XATTR_FAILED, +               "vgetxattr: Subvolume %s returned -1", prev->name); +        goto unwind; +    } -        ret = dht_vgetxattr_alloc_and_fill (local, xattr, this, -                                            op_errno); -        if (ret) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_NO_MEMORY, -                        "Allocation or fill failure"); -                goto unwind; -        } +    ret = dht_vgetxattr_alloc_and_fill(local, xattr, this, op_errno); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, +               "Allocation or fill failure"); +        goto unwind; +    } -        flag = (local->layout->cnt > 1) ? _gf_true : _gf_false; +    flag = (local->layout->cnt > 1) ? _gf_true : _gf_false; -        ret = dht_vgetxattr_fill_and_set (local, &dict, this, flag); -        if (ret) -                goto unwind; +    ret = dht_vgetxattr_fill_and_set(local, &dict, this, flag); +    if (ret) +        goto unwind; -        DHT_STACK_UNWIND (getxattr, frame, 0, 0, dict, xdata); -        goto cleanup; +    DHT_STACK_UNWIND(getxattr, frame, 0, 0, dict, xdata); +    goto cleanup; - unwind: -        DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno, -                          NULL, NULL); - cleanup: -        if (dict) -                dict_unref (dict); +unwind: +    DHT_STACK_UNWIND(getxattr, frame, -1, local->op_errno, NULL, NULL); +cleanup: +    if (dict) +        dict_unref(dict); -        return 0; +    return 0;  }  int -dht_linkinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int op_ret, int op_errno, dict_t *xattr, -                           dict_t *xdata) +dht_linkinfo_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int op_ret, int op_errno, dict_t *xattr, +                          dict_t *xdata)  { -        int   ret   = 0; -        char *value = NULL; +    int ret = 0; +    char *value = NULL; -        if (op_ret != -1) { -                ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value); -                if (!ret) { -                        ret = dict_set_str (xattr, GF_XATTR_LINKINFO_KEY, value); -                        if (!ret) -                                gf_msg_trace (this->name, 0, -                                              "failed to set linkinfo"); -                } +    if (op_ret != -1) { +        ret = dict_get_str(xattr, GF_XATTR_PATHINFO_KEY, &value); +        if (!ret) { +            ret = dict_set_str(xattr, GF_XATTR_LINKINFO_KEY, value); +            if (!ret) +                gf_msg_trace(this->name, 0, "failed to set linkinfo");          } +    } -        DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata); +    DHT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, xattr, xdata); -        return 0; +    return 0;  } -  int -dht_mds_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                      int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) +dht_mds_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)  { -        dht_local_t     *local = NULL; -        dht_conf_t      *conf = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; -        VALIDATE_OR_GOTO (frame, out); -        VALIDATE_OR_GOTO (frame->local, out); -        VALIDATE_OR_GOTO (this->private, out); +    VALIDATE_OR_GOTO(frame, out); +    VALIDATE_OR_GOTO(frame->local, out); +    VALIDATE_OR_GOTO(this->private, out); -        conf = this->private; -        local = frame->local; +    conf = this->private; +    local = frame->local; -        if (!xattr || (op_ret == -1)) { -                local->op_ret = op_ret; -                goto out; -        } -        if (dict_get (xattr, conf->xattr_name)) { -                dict_del (xattr, conf->xattr_name); -        } -        local->op_ret = 0; +    if (!xattr || (op_ret == -1)) { +        local->op_ret = op_ret; +        goto out; +    } +    if (dict_get(xattr, conf->xattr_name)) { +        dict_del(xattr, conf->xattr_name); +    } +    local->op_ret = 0; -        if (!local->xattr) { -                local->xattr = dict_copy_with_ref (xattr, NULL); -        } +    if (!local->xattr) { +        local->xattr = dict_copy_with_ref(xattr, NULL); +    }  out: -        DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, -                          local->xattr, xdata); -        return 0; +    DHT_STACK_UNWIND(getxattr, frame, local->op_ret, op_errno, local->xattr, +                     xdata); +    return 0;  } -  int -dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                  int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) +dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                 int op_errno, dict_t *xattr, dict_t *xdata)  { -        int             this_call_cnt = 0; -        dht_local_t     *local = NULL; -        dht_conf_t      *conf = NULL; - -        VALIDATE_OR_GOTO (frame, out); -        VALIDATE_OR_GOTO (frame->local, out); -        VALIDATE_OR_GOTO (this->private, out); +    int this_call_cnt = 0; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; -        conf = this->private; -        local = frame->local; +    VALIDATE_OR_GOTO(frame, out); +    VALIDATE_OR_GOTO(frame->local, out); +    VALIDATE_OR_GOTO(this->private, out); -        LOCK (&frame->lock); -        { -                if (!xattr || (op_ret == -1)) { -                        local->op_ret = op_ret; -                        goto unlock; -                } +    conf = this->private; +    local = frame->local; -                if (dict_get (xattr, conf->xattr_name)) { -                        dict_del (xattr, conf->xattr_name); -                } +    LOCK(&frame->lock); +    { +        if (!xattr || (op_ret == -1)) { +            local->op_ret = op_ret; +            goto unlock; +        } -                if (dict_get (xattr,  conf->mds_xattr_key)) { -                        dict_del (xattr, conf->mds_xattr_key); -                } +        if (dict_get(xattr, conf->xattr_name)) { +            dict_del(xattr, conf->xattr_name); +        } -                /* filter out following two xattrs that need not -                 * be visible on the mount point for geo-rep - -                 * trusted.tier.fix.layout.complete and -                 * trusted.tier.tier-dht.commithash -                 */ +        if (dict_get(xattr, conf->mds_xattr_key)) { +            dict_del(xattr, conf->mds_xattr_key); +        } -                if (dict_get (xattr, conf->commithash_xattr_name)) { -                        dict_del (xattr, conf->commithash_xattr_name); -                } +        /* filter out following two xattrs that need not +         * be visible on the mount point for geo-rep - +         * trusted.tier.fix.layout.complete and +         * trusted.tier.tier-dht.commithash +         */ -                if (frame->root->pid >= 0 && dht_is_tier_xlator (this)) { -                        dict_del(xattr, GF_XATTR_TIER_LAYOUT_FIXED_KEY); -                } +        if (dict_get(xattr, conf->commithash_xattr_name)) { +            dict_del(xattr, conf->commithash_xattr_name); +        } -                if (frame->root->pid >= 0) { -                        GF_REMOVE_INTERNAL_XATTR -                                ("trusted.glusterfs.quota*", xattr); -                        GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); -                } +        if (frame->root->pid >= 0 && dht_is_tier_xlator(this)) { +            dict_del(xattr, GF_XATTR_TIER_LAYOUT_FIXED_KEY); +        } -                local->op_ret = 0; +        if (frame->root->pid >= 0) { +            GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); +            GF_REMOVE_INTERNAL_XATTR("trusted.pgfid*", xattr); +        } -                if (!local->xattr) { -                        local->xattr = dict_copy_with_ref (xattr, NULL); -                } else { -                        dht_aggregate_xattr (local->xattr, xattr); -                } +        local->op_ret = 0; +        if (!local->xattr) { +            local->xattr = dict_copy_with_ref(xattr, NULL); +        } else { +            dht_aggregate_xattr(local->xattr, xattr);          } +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); +    this_call_cnt = dht_frame_return(frame);  out: -        if (is_last_call (this_call_cnt)) { - -                /* If we have a valid xattr received from any one of the -                 * subvolume, let's return it */ -                if (local->xattr) { -                        local->op_ret = 0; -                } - -                DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, -                                  local->xattr, NULL); +    if (is_last_call(this_call_cnt)) { +        /* If we have a valid xattr received from any one of the +         * subvolume, let's return it */ +        if (local->xattr) { +            local->op_ret = 0;          } -        return 0; + +        DHT_STACK_UNWIND(getxattr, frame, local->op_ret, op_errno, local->xattr, +                         NULL); +    } +    return 0;  }  int32_t -dht_getxattr_unwind (call_frame_t *frame, -                     int op_ret, int op_errno, dict_t *dict, dict_t *xdata) +dht_getxattr_unwind(call_frame_t *frame, int op_ret, int op_errno, dict_t *dict, +                    dict_t *xdata)  { -        DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata); -        return 0; +    DHT_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); +    return 0;  } -  int -dht_getxattr_get_real_filename_cbk (call_frame_t *frame, void *cookie, -                                    xlator_t *this, int op_ret, int op_errno, -                                    dict_t *xattr, dict_t *xdata) +dht_getxattr_get_real_filename_cbk(call_frame_t *frame, void *cookie, +                                   xlator_t *this, int op_ret, int op_errno, +                                   dict_t *xattr, dict_t *xdata)  { -        int             this_call_cnt = 0; -        dht_local_t     *local = NULL; +    int this_call_cnt = 0; +    dht_local_t *local = NULL; +    local = frame->local; -        local = frame->local; +    LOCK(&frame->lock); +    { +        if (local->op_errno == ENODATA || local->op_errno == EOPNOTSUPP) { +            /* Nothing to do here, we have already found +             * a subvol which does not have the get_real_filename +             * optimization. If condition is for simple logic. +             */ +            goto unlock; +        } -        LOCK (&frame->lock); -        { -                if (local->op_errno == ENODATA || -                    local->op_errno == EOPNOTSUPP) { -                        /* Nothing to do here, we have already found -                         * a subvol which does not have the get_real_filename -                         * optimization. If condition is for simple logic. -                         */ -                        goto unlock; -                } +        if (op_ret == -1) { +            if (op_errno == ENODATA || op_errno == EOPNOTSUPP) { +                /* This subvol does not have the optimization. +                 * Better let the user know we don't support it. +                 * Remove previous results if any. +                 */ -                if (op_ret == -1) { - -                        if (op_errno == ENODATA || op_errno == EOPNOTSUPP) { -                                /* This subvol does not have the optimization. -                                 * Better let the user know we don't support it. -                                 * Remove previous results if any. -                                 */ - -                                if (local->xattr) { -                                        dict_unref (local->xattr); -                                        local->xattr = NULL; -                                } - -                                if (local->xattr_req) { -                                        dict_unref (local->xattr_req); -                                        local->xattr_req = NULL; -                                } - -                                local->op_ret = op_ret; -                                local->op_errno = op_errno; -                                gf_msg (this->name, GF_LOG_WARNING, op_errno, -                                        DHT_MSG_UPGRADE_BRICKS, "At least " -                                        "one of the bricks does not support " -                                        "this operation. Please upgrade all " -                                        "bricks."); -                                goto unlock; -                        } - -                        if (op_errno == ENOENT) { -                                /* Do nothing, our defaults are set to this. -                                 */ -                                goto unlock; -                        } - -                        /* This is a place holder for every other error -                         * case. I am not sure of how to interpret -                         * ENOTCONN etc. As of now, choosing to ignore -                         * down subvol and return a good result(if any) -                         * from other subvol. -                         */ -                        gf_msg (this->name, GF_LOG_WARNING, op_errno, -                                DHT_MSG_GET_XATTR_FAILED, -                                "Failed to get real filename."); -                        goto unlock; +                if (local->xattr) { +                    dict_unref(local->xattr); +                    local->xattr = NULL; +                } +                if (local->xattr_req) { +                    dict_unref(local->xattr_req); +                    local->xattr_req = NULL;                  } +                local->op_ret = op_ret; +                local->op_errno = op_errno; +                gf_msg(this->name, GF_LOG_WARNING, op_errno, +                       DHT_MSG_UPGRADE_BRICKS, +                       "At least " +                       "one of the bricks does not support " +                       "this operation. Please upgrade all " +                       "bricks."); +                goto unlock; +            } -                /* This subvol has the required file. -                 * There could be other subvols which have returned -                 * success already, choosing to return the latest good -                 * result. +            if (op_errno == ENOENT) { +                /* Do nothing, our defaults are set to this.                   */ -                if (local->xattr) -                        dict_unref (local->xattr); -                local->xattr = dict_ref (xattr); +                goto unlock; +            } -                if (local->xattr_req) { -                        dict_unref (local->xattr_req); -                        local->xattr_req = NULL; -                } -                if (xdata) -                        local->xattr_req = dict_ref (xdata); +            /* This is a place holder for every other error +             * case. I am not sure of how to interpret +             * ENOTCONN etc. As of now, choosing to ignore +             * down subvol and return a good result(if any) +             * from other subvol. +             */ +            gf_msg(this->name, GF_LOG_WARNING, op_errno, +                   DHT_MSG_GET_XATTR_FAILED, "Failed to get real filename."); +            goto unlock; +        } + +        /* This subvol has the required file. +         * There could be other subvols which have returned +         * success already, choosing to return the latest good +         * result. +         */ +        if (local->xattr) +            dict_unref(local->xattr); +        local->xattr = dict_ref(xattr); -                local->op_ret = op_ret; -                local->op_errno = 0; -                gf_msg_debug (this->name, 0, "Found a matching " -                              "file."); +        if (local->xattr_req) { +            dict_unref(local->xattr_req); +            local->xattr_req = NULL;          } -unlock: -        UNLOCK (&frame->lock); +        if (xdata) +            local->xattr_req = dict_ref(xdata); +        local->op_ret = op_ret; +        local->op_errno = 0; +        gf_msg_debug(this->name, 0, +                     "Found a matching " +                     "file."); +    } +unlock: +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                DHT_STACK_UNWIND (getxattr, frame, local->op_ret, -                                  local->op_errno, local->xattr, -                                  local->xattr_req); -        } +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        DHT_STACK_UNWIND(getxattr, frame, local->op_ret, local->op_errno, +                         local->xattr, local->xattr_req); +    } -        return 0; +    return 0;  } -  int -dht_getxattr_get_real_filename (call_frame_t *frame, xlator_t *this, -                                loc_t *loc, const char *key, dict_t *xdata) +dht_getxattr_get_real_filename(call_frame_t *frame, xlator_t *this, loc_t *loc, +                               const char *key, dict_t *xdata)  { -        dht_local_t     *local = NULL; -        int              i = 0; -        dht_layout_t    *layout = NULL; -        int              cnt = 0; -        xlator_t        *subvol = NULL; +    dht_local_t *local = NULL; +    int i = 0; +    dht_layout_t *layout = NULL; +    int cnt = 0; +    xlator_t *subvol = NULL; +    local = frame->local; +    layout = local->layout; -        local = frame->local; -        layout = local->layout; +    cnt = local->call_cnt = layout->cnt; -        cnt = local->call_cnt = layout->cnt; +    local->op_ret = -1; +    local->op_errno = ENOENT; -        local->op_ret = -1; -        local->op_errno = ENOENT; - -        for (i = 0; i < cnt; i++) { -                subvol = layout->list[i].xlator; -                STACK_WIND (frame, dht_getxattr_get_real_filename_cbk, -                            subvol, subvol->fops->getxattr, -                            loc, key, xdata); -        } +    for (i = 0; i < cnt; i++) { +        subvol = layout->list[i].xlator; +        STACK_WIND(frame, dht_getxattr_get_real_filename_cbk, subvol, +                   subvol->fops->getxattr, loc, key, xdata); +    } -        return 0; +    return 0;  }  int -dht_marker_populate_args (call_frame_t *frame, int type, int *gauge, -                          xlator_t **subvols) +dht_marker_populate_args(call_frame_t *frame, int type, int *gauge, +                         xlator_t **subvols)  { -        dht_local_t *local = NULL; -        int         i = 0; -        dht_layout_t *layout = NULL; +    dht_local_t *local = NULL; +    int i = 0; +    dht_layout_t *layout = NULL; -        local  = frame->local; -        layout = local->layout; +    local = frame->local; +    layout = local->layout; -        for (i = 0; i < layout->cnt; i++) -                subvols[i] = layout->list[i].xlator; +    for (i = 0; i < layout->cnt; i++) +        subvols[i] = layout->list[i].xlator; -        return layout->cnt; +    return layout->cnt;  } -  int -dht_is_debug_xattr_key (char **array, char *key) +dht_is_debug_xattr_key(char **array, char *key)  { -        int     i = 0; +    int i = 0; -        for (i = 0; array[i]; i++) { -                if (fnmatch (array[i], key, FNM_NOESCAPE) == 0) -                        return i; -        } +    for (i = 0; array[i]; i++) { +        if (fnmatch(array[i], key, FNM_NOESCAPE) == 0) +            return i; +    } -        return -1; +    return -1;  } -  /* Note we already have frame->local initialised here*/  int -dht_handle_debug_getxattr (call_frame_t *frame, xlator_t *this, -                           loc_t *loc, const char *key) +dht_handle_debug_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, +                          const char *key)  { -        dht_local_t  *local         = NULL; -        int           ret           = -1; -        int           op_errno      = ENODATA; -        char         *value         = NULL; -        loc_t         file_loc      = {0}; -        const char    *name         = NULL; - -        local = frame->local; -        if (!key) { -                op_errno = EINVAL; -                goto out; -        } +    dht_local_t *local = NULL; +    int ret = -1; +    int op_errno = ENODATA; +    char *value = NULL; +    loc_t file_loc = {0}; +    const char *name = NULL; -        if (dht_is_debug_xattr_key (dht_dbg_vxattrs, (char *)key) == -1) { -                goto out; -        } +    local = frame->local; +    if (!key) { +        op_errno = EINVAL; +        goto out; +    } -        local->xattr = dict_new (); -        if (!local->xattr) { -                op_errno = ENOMEM; -                goto out; -        } +    if (dht_is_debug_xattr_key(dht_dbg_vxattrs, (char *)key) == -1) { +        goto out; +    } -        if (strncmp (key, DHT_DBG_HASHED_SUBVOL_KEY, -                     SLEN (DHT_DBG_HASHED_SUBVOL_KEY)) == 0) { +    local->xattr = dict_new(); +    if (!local->xattr) { +        op_errno = ENOMEM; +        goto out; +    } -                name = key + strlen(DHT_DBG_HASHED_SUBVOL_KEY); -                if (strlen(name) == 0) { -                        op_errno = EINVAL; -                        goto out; -                } +    if (strncmp(key, DHT_DBG_HASHED_SUBVOL_KEY, +                SLEN(DHT_DBG_HASHED_SUBVOL_KEY)) == 0) { +        name = key + strlen(DHT_DBG_HASHED_SUBVOL_KEY); +        if (strlen(name) == 0) { +            op_errno = EINVAL; +            goto out; +        } -                ret = dht_build_child_loc (this, &file_loc, loc, (char *)name); -                if (ret) { -                        op_errno = ENOMEM; -                        goto out; -                } +        ret = dht_build_child_loc(this, &file_loc, loc, (char *)name); +        if (ret) { +            op_errno = ENOMEM; +            goto out; +        } -                local->hashed_subvol = dht_subvol_get_hashed (this, &file_loc); -                if (local->hashed_subvol == NULL) { -                        op_errno = ENODATA; -                        goto out; -                } +        local->hashed_subvol = dht_subvol_get_hashed(this, &file_loc); +        if (local->hashed_subvol == NULL) { +            op_errno = ENODATA; +            goto out; +        } -                value = gf_strdup (local->hashed_subvol->name); -                if (!value) { -                        op_errno = ENOMEM; -                        goto out; -                } +        value = gf_strdup(local->hashed_subvol->name); +        if (!value) { +            op_errno = ENOMEM; +            goto out; +        } -                ret = dict_set_dynstr (local->xattr,  (char *)key, value); -                if (ret < 0) { -                        op_errno = -ret; -                        ret = -1; -                        goto out; -                } -                ret = 0; -                goto out; +        ret = dict_set_dynstr(local->xattr, (char *)key, value); +        if (ret < 0) { +            op_errno = -ret; +            ret = -1; +            goto out;          } +        ret = 0; +        goto out; +    }  out: -	loc_wipe (&file_loc); -        DHT_STACK_UNWIND (getxattr, frame, ret, op_errno, local->xattr, NULL); -        return 0; +    loc_wipe(&file_loc); +    DHT_STACK_UNWIND(getxattr, frame, ret, op_errno, local->xattr, NULL); +    return 0;  } -  int -dht_getxattr (call_frame_t *frame, xlator_t *this, -              loc_t *loc, const char *key, dict_t *xdata) -#define DHT_IS_DIR(layout)  (layout->cnt > 1) -{ - -        xlator_t     *subvol        = NULL; -        xlator_t     *hashed_subvol = NULL; -        xlator_t     *mds_subvol    = NULL; -        xlator_t     *cached_subvol = NULL; -        dht_conf_t   *conf          = NULL; -        dht_local_t  *local         = NULL; -        dht_layout_t *layout        = NULL; -        int           op_errno      = -1; -        int           i             = 0; -        int           cnt           = 0; -        char         *node_uuid_key = NULL; -        int           ret           = -1; - -        GF_CHECK_XATTR_KEY_AND_GOTO (key, IO_THREADS_QUEUE_SIZE_KEY, -                                     op_errno, err); -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf   = this->private; - -        local = dht_local_init (frame, loc, NULL, GF_FOP_GETXATTR); -        if (!local) { -                op_errno = ENOMEM; - -                goto err; -        } - -        layout = local->layout; -        if (!layout) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_LAYOUT_NULL, -                        "Layout is NULL"); -                op_errno = ENOENT; -                goto err; +dht_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key, +             dict_t *xdata) +#define DHT_IS_DIR(layout) (layout->cnt > 1) +{ +    xlator_t *subvol = NULL; +    xlator_t *hashed_subvol = NULL; +    xlator_t *mds_subvol = NULL; +    xlator_t *cached_subvol = NULL; +    dht_conf_t *conf = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; +    int op_errno = -1; +    int i = 0; +    int cnt = 0; +    char *node_uuid_key = NULL; +    int ret = -1; + +    GF_CHECK_XATTR_KEY_AND_GOTO(key, IO_THREADS_QUEUE_SIZE_KEY, op_errno, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    local = dht_local_init(frame, loc, NULL, GF_FOP_GETXATTR); +    if (!local) { +        op_errno = ENOMEM; + +        goto err; +    } + +    layout = local->layout; +    if (!layout) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LAYOUT_NULL, +               "Layout is NULL"); +        op_errno = ENOENT; +        goto err; +    } + +    /* skip over code which is irrelevant without a valid key */ +    if (!key) +        goto no_key; + +    local->key = gf_strdup(key); +    if (!local->key) { +        op_errno = ENOMEM; +        goto err; +    } + +    if (strncmp(key, conf->mds_xattr_key, strlen(key)) == 0) { +        op_errno = ENOTSUP; +        goto err; +    } + +    /* skip over code which is irrelevant if !DHT_IS_DIR(layout) */ +    if (!DHT_IS_DIR(layout)) +        goto no_dht_is_dir; + +    if ((strncmp(key, GF_XATTR_GET_REAL_FILENAME_KEY, +                 SLEN(GF_XATTR_GET_REAL_FILENAME_KEY)) == 0) && +        DHT_IS_DIR(layout)) { +        dht_getxattr_get_real_filename(frame, this, loc, key, xdata); +        return 0; +    } + +    if (!strcmp(key, GF_REBAL_FIND_LOCAL_SUBVOL)) { +        ret = gf_asprintf(&node_uuid_key, "%s", GF_XATTR_LIST_NODE_UUIDS_KEY); +        if (ret == -1 || !node_uuid_key) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, +                   "Failed to copy node uuid key"); +            op_errno = ENOMEM; +            goto err; +        } +        (void)snprintf(local->xsel, sizeof(local->xsel), "%s", node_uuid_key); +        cnt = local->call_cnt = conf->subvolume_cnt; +        for (i = 0; i < cnt; i++) { +            STACK_WIND_COOKIE(frame, dht_find_local_subvol_cbk, +                              conf->subvolumes[i], conf->subvolumes[i], +                              conf->subvolumes[i]->fops->getxattr, loc, +                              node_uuid_key, xdata);          } +        if (node_uuid_key) +            GF_FREE(node_uuid_key); +        return 0; +    } -        /* skip over code which is irrelevant without a valid key */ -        if (!key) -                goto no_key; - -        local->key = gf_strdup (key); -        if (!local->key) { -                op_errno = ENOMEM; -                goto err; +    if (!strcmp(key, GF_REBAL_OLD_FIND_LOCAL_SUBVOL)) { +        ret = gf_asprintf(&node_uuid_key, "%s", GF_XATTR_NODE_UUID_KEY); +        if (ret == -1 || !node_uuid_key) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_NO_MEMORY, +                   "Failed to copy node uuid key"); +            op_errno = ENOMEM; +            goto err;          } - -        if (strncmp (key, conf->mds_xattr_key, strlen(key)) == 0) { -                op_errno = ENOTSUP; -                goto err; +        (void)snprintf(local->xsel, sizeof(local->xsel), "%s", node_uuid_key); +        cnt = local->call_cnt = conf->subvolume_cnt; +        for (i = 0; i < cnt; i++) { +            STACK_WIND_COOKIE(frame, dht_find_local_subvol_cbk, +                              conf->subvolumes[i], conf->subvolumes[i], +                              conf->subvolumes[i]->fops->getxattr, loc, +                              node_uuid_key, xdata); +        } +        if (node_uuid_key) +            GF_FREE(node_uuid_key); +        return 0; +    } + +    /* for file use cached subvolume (obviously!): see if {} +     * below +     * for directory: +     *  wind to all subvolumes and exclude subvolumes which +     *  return ENOTCONN (in callback) +     * +     * NOTE: Don't trust inode here, as that may not be valid +     *       (until inode_link() happens) +     */ + +    if (XATTR_IS_PATHINFO(key) || (strcmp(key, GF_XATTR_NODE_UUID_KEY) == 0) || +        (strcmp(key, GF_XATTR_LIST_NODE_UUIDS_KEY) == 0)) { +        (void)snprintf(local->xsel, sizeof(local->xsel), "%s", key); +        cnt = local->call_cnt = layout->cnt; +        for (i = 0; i < cnt; i++) { +            subvol = layout->list[i].xlator; +            STACK_WIND(frame, dht_vgetxattr_dir_cbk, subvol, +                       subvol->fops->getxattr, loc, key, xdata);          } +        return 0; +    } -        /* skip over code which is irrelevant if !DHT_IS_DIR(layout) */ -        if (!DHT_IS_DIR(layout)) -                goto no_dht_is_dir; - -        if ((strncmp (key, GF_XATTR_GET_REAL_FILENAME_KEY, -                      SLEN (GF_XATTR_GET_REAL_FILENAME_KEY)) == 0) -            && DHT_IS_DIR(layout)) { -                dht_getxattr_get_real_filename (frame, this, loc, key, xdata); -                return 0; -        } +no_dht_is_dir: +    /* node-uuid or pathinfo for files */ +    if (XATTR_IS_PATHINFO(key) || (strcmp(key, GF_XATTR_NODE_UUID_KEY) == 0)) { +        cached_subvol = local->cached_subvol; +        (void)snprintf(local->xsel, sizeof(local->xsel), "%s", key); +        local->call_cnt = 1; +        STACK_WIND_COOKIE(frame, dht_vgetxattr_cbk, cached_subvol, +                          cached_subvol, cached_subvol->fops->getxattr, loc, +                          key, xdata); -        if (!strcmp (key, GF_REBAL_FIND_LOCAL_SUBVOL)) { -                ret = gf_asprintf (&node_uuid_key, "%s", -                                   GF_XATTR_LIST_NODE_UUIDS_KEY); -                if (ret == -1 || !node_uuid_key) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_NO_MEMORY, -                                "Failed to copy node uuid key"); -                        op_errno = ENOMEM; -                        goto err; -                } -                (void) snprintf (local->xsel, sizeof (local->xsel), "%s", -                                 node_uuid_key); -                cnt = local->call_cnt = conf->subvolume_cnt; -                for (i = 0; i < cnt; i++) { -                        STACK_WIND_COOKIE (frame, dht_find_local_subvol_cbk, -                                           conf->subvolumes[i], -                                           conf->subvolumes[i], -                                           conf->subvolumes[i]->fops->getxattr, -                                           loc, node_uuid_key, xdata); -                } -                if (node_uuid_key) -                        GF_FREE (node_uuid_key); -                return 0; -        } +        return 0; +    } -        if (!strcmp (key, GF_REBAL_OLD_FIND_LOCAL_SUBVOL)) { -                ret = gf_asprintf (&node_uuid_key, "%s", -                                   GF_XATTR_NODE_UUID_KEY); -                if (ret == -1 || !node_uuid_key) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_NO_MEMORY, -                                "Failed to copy node uuid key"); -                        op_errno = ENOMEM; -                        goto err; -                } -                (void) snprintf (local->xsel, sizeof (local->xsel), "%s", -                                 node_uuid_key); -                cnt = local->call_cnt = conf->subvolume_cnt; -                for (i = 0; i < cnt; i++) { -                        STACK_WIND_COOKIE (frame, dht_find_local_subvol_cbk, -                                           conf->subvolumes[i], -                                           conf->subvolumes[i], -                                           conf->subvolumes[i]->fops->getxattr, -                                           loc, node_uuid_key, xdata); -                } -                if (node_uuid_key) -                        GF_FREE (node_uuid_key); -                return 0; +    if (strcmp(key, GF_XATTR_LINKINFO_KEY) == 0) { +        hashed_subvol = dht_subvol_get_hashed(this, loc); +        if (!hashed_subvol) { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Failed to get hashed subvol for %s", loc->path); +            op_errno = EINVAL; +            goto err;          } -        /* for file use cached subvolume (obviously!): see if {} -         * below -         * for directory: -         *  wind to all subvolumes and exclude subvolumes which -         *  return ENOTCONN (in callback) -         * -         * NOTE: Don't trust inode here, as that may not be valid -         *       (until inode_link() happens) -         */ - -        if (XATTR_IS_PATHINFO (key) -            || (strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0) -            || (strcmp (key, GF_XATTR_LIST_NODE_UUIDS_KEY) == 0)) { -                (void) snprintf (local->xsel, sizeof (local->xsel), "%s", key); -                cnt = local->call_cnt = layout->cnt; -                for (i = 0; i < cnt; i++) { -                        subvol = layout->list[i].xlator; -                        STACK_WIND (frame, dht_vgetxattr_dir_cbk, -                                    subvol, subvol->fops->getxattr, -                                    loc, key, xdata); -                } -                return 0; +        cached_subvol = dht_subvol_get_cached(this, loc->inode); +        if (!cached_subvol) { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_CACHED_SUBVOL_GET_FAILED, +                   "Failed to get cached subvol for %s", loc->path); +            op_errno = EINVAL; +            goto err;          } -no_dht_is_dir: -        /* node-uuid or pathinfo for files */ -        if (XATTR_IS_PATHINFO (key) -            || (strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0)) { -                cached_subvol = local->cached_subvol; -                (void) snprintf (local->xsel, sizeof (local->xsel), "%s", key); -                local->call_cnt = 1; -                STACK_WIND_COOKIE (frame, dht_vgetxattr_cbk, cached_subvol, -                                   cached_subvol, cached_subvol->fops->getxattr, -                                   loc, key, xdata); - -                return 0; +        if (hashed_subvol == cached_subvol) { +            op_errno = ENODATA; +            goto err;          } -        if (strcmp (key, GF_XATTR_LINKINFO_KEY) == 0) { - -                hashed_subvol = dht_subvol_get_hashed (this, loc); -                if (!hashed_subvol) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Failed to get hashed subvol for %s", -                                loc->path); -                        op_errno = EINVAL; -                        goto err; -                } - -                cached_subvol = dht_subvol_get_cached (this, loc->inode); -                if (!cached_subvol) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_CACHED_SUBVOL_GET_FAILED, -                                "Failed to get cached subvol for %s", -                                loc->path); -                        op_errno = EINVAL; -                        goto err; -                } - -                if (hashed_subvol == cached_subvol) { -                        op_errno = ENODATA; -                        goto err; -                } - -                STACK_WIND (frame, dht_linkinfo_getxattr_cbk, hashed_subvol, -                            hashed_subvol->fops->getxattr, loc, -                            GF_XATTR_PATHINFO_KEY, xdata); -                return 0; -        } +        STACK_WIND(frame, dht_linkinfo_getxattr_cbk, hashed_subvol, +                   hashed_subvol->fops->getxattr, loc, GF_XATTR_PATHINFO_KEY, +                   xdata); +        return 0; +    } -	if (dht_is_debug_xattr_key (dht_dbg_vxattrs, (char *)key) >= 0) { -                dht_handle_debug_getxattr (frame, this, loc, key); -                return 0; -        } +    if (dht_is_debug_xattr_key(dht_dbg_vxattrs, (char *)key) >= 0) { +        dht_handle_debug_getxattr(frame, this, loc, key); +        return 0; +    }  no_key: -        if (cluster_handle_marker_getxattr (frame, loc, key, conf->vol_uuid, -                                            dht_getxattr_unwind, -                                            dht_marker_populate_args) == 0) -                return 0; +    if (cluster_handle_marker_getxattr(frame, loc, key, conf->vol_uuid, +                                       dht_getxattr_unwind, +                                       dht_marker_populate_args) == 0) +        return 0; -        if (DHT_IS_DIR(layout)) { -                local->call_cnt = conf->subvolume_cnt; -                cnt = conf->subvolume_cnt; -                ret = dht_inode_ctx_mdsvol_get (loc->inode, this, &mds_subvol); -                if (!mds_subvol) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Cannot determine MDS, fetching xattr %s randomly" -                                " from a subvol for path %s ", key, loc->path); -                } else { -                        /* TODO need to handle it, As of now we are -                           choosing availability instead of chossing -                           consistencty, in case of mds_subvol is -                           down winding a getxattr call on other subvol -                           and return xattr -                        */ -                        local->mds_subvol = mds_subvol; -                        for (i = 0; i < cnt; i++) { -                                if (conf->subvolumes[i] == mds_subvol) { -                                        if (!conf->subvolume_status[i]) { -                                                gf_msg (this->name, -                                                        GF_LOG_INFO, 0, -                                                        DHT_MSG_HASHED_SUBVOL_DOWN, -                                                        "MDS %s is down for path" -                                                        " path %s so fetching xattr " -                                                        "%s randomly from a subvol ", -                                                        local->mds_subvol->name, -                                                        loc->path, key); -                                                ret = 1; -                                        } -                                } -                        } +    if (DHT_IS_DIR(layout)) { +        local->call_cnt = conf->subvolume_cnt; +        cnt = conf->subvolume_cnt; +        ret = dht_inode_ctx_mdsvol_get(loc->inode, this, &mds_subvol); +        if (!mds_subvol) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Cannot determine MDS, fetching xattr %s randomly" +                   " from a subvol for path %s ", +                   key, loc->path); +        } else { +            /* TODO need to handle it, As of now we are +               choosing availability instead of chossing +               consistencty, in case of mds_subvol is +               down winding a getxattr call on other subvol +               and return xattr +            */ +            local->mds_subvol = mds_subvol; +            for (i = 0; i < cnt; i++) { +                if (conf->subvolumes[i] == mds_subvol) { +                    if (!conf->subvolume_status[i]) { +                        gf_msg(this->name, GF_LOG_INFO, 0, +                               DHT_MSG_HASHED_SUBVOL_DOWN, +                               "MDS %s is down for path" +                               " path %s so fetching xattr " +                               "%s randomly from a subvol ", +                               local->mds_subvol->name, loc->path, key); +                        ret = 1; +                    }                  } +            } +        } -                if (!ret && key && local->mds_subvol && dht_match_xattr (key)) { -                        STACK_WIND (frame, dht_mds_getxattr_cbk, -                                    local->mds_subvol, -                                    local->mds_subvol->fops->getxattr, -                                    loc, key, xdata); +        if (!ret && key && local->mds_subvol && dht_match_xattr(key)) { +            STACK_WIND(frame, dht_mds_getxattr_cbk, local->mds_subvol, +                       local->mds_subvol->fops->getxattr, loc, key, xdata); -                        return 0; -                } -        } else { -                cnt = local->call_cnt  = 1; +            return 0;          } +    } else { +        cnt = local->call_cnt = 1; +    } -        for (i = 0; i < cnt; i++) { -                subvol = layout->list[i].xlator; -                STACK_WIND (frame, dht_getxattr_cbk, -                            subvol, subvol->fops->getxattr, -                            loc, key, xdata); -        } -        return 0; +    for (i = 0; i < cnt; i++) { +        subvol = layout->list[i].xlator; +        STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->getxattr, loc, +                   key, xdata); +    } +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(getxattr, frame, -1, op_errno, NULL, NULL); -        return 0; +    return 0;  }  #undef DHT_IS_DIR  int -dht_fgetxattr (call_frame_t *frame, xlator_t *this, -               fd_t *fd, const char *key, dict_t *xdata) -{ -        xlator_t     *subvol        = NULL; -        dht_local_t  *local         = NULL; -        dht_layout_t *layout        = NULL; -        int           op_errno      = -1; -        int           i             = 0; -        int           cnt           = 0; -        xlator_t      *mds_subvol = NULL; -        int           ret           = -1; -        dht_conf_t    *conf         = NULL; -        char           gfid[GF_UUID_BUF_SIZE] = {0}; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO (fd->inode, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf = this->private; - -        local = dht_local_init (frame, NULL, fd, GF_FOP_FGETXATTR); -        if (!local) { -                op_errno = ENOMEM; - -                goto err; +dht_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, +              dict_t *xdata) +{ +    xlator_t *subvol = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; +    int op_errno = -1; +    int i = 0; +    int cnt = 0; +    xlator_t *mds_subvol = NULL; +    int ret = -1; +    dht_conf_t *conf = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(fd->inode, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    local = dht_local_init(frame, NULL, fd, GF_FOP_FGETXATTR); +    if (!local) { +        op_errno = ENOMEM; + +        goto err; +    } + +    layout = local->layout; +    if (!layout) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_LAYOUT_NULL, +               "Layout is NULL"); +        op_errno = ENOENT; +        goto err; +    } + +    if (key) { +        local->key = gf_strdup(key); +        if (!local->key) { +            op_errno = ENOMEM; +            goto err;          } +    } -        layout = local->layout; -        if (!layout) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_LAYOUT_NULL, -                        "Layout is NULL"); -                op_errno = ENOENT; -                goto err; -        } +    if (fd->inode) +        gf_uuid_unparse(fd->inode->gfid, gfid); -        if (key) { -                local->key = gf_strdup (key); -                if (!local->key) { -                        op_errno = ENOMEM; -                        goto err; +    if ((fd->inode->ia_type == IA_IFDIR) && key && +        (strncmp(key, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY)) != +         0)) { +        local->call_cnt = conf->subvolume_cnt; +        cnt = conf->subvolume_cnt; +        ret = dht_inode_ctx_mdsvol_get(fd->inode, this, &mds_subvol); + +        if (!mds_subvol) { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "cannot determine MDS, fetching xattr %s " +                   " randomly from a subvol for gfid %s ", +                   key, gfid); +        } else { +            /* TODO need to handle it, As of now we are +               choosing availability instead of chossing +               consistencty, in case of hashed_subvol is +               down winding a getxattr call on other subvol +               and return xattr +            */ +            local->mds_subvol = mds_subvol; +            for (i = 0; i < cnt; i++) { +                if (conf->subvolumes[i] == mds_subvol) { +                    if (!conf->subvolume_status[i]) { +                        gf_msg(this->name, GF_LOG_WARNING, 0, +                               DHT_MSG_HASHED_SUBVOL_DOWN, +                               "MDS subvolume %s is down" +                               " for gfid %s so fetching xattr " +                               " %s randomly from a subvol ", +                               local->mds_subvol->name, gfid, key); +                        ret = 1; +                    }                  } +            }          } -        if (fd->inode) -                gf_uuid_unparse(fd->inode->gfid, gfid); - -        if ((fd->inode->ia_type == IA_IFDIR) -            && key -            && (strncmp (key, GF_XATTR_LOCKINFO_KEY, -                         SLEN (GF_XATTR_LOCKINFO_KEY)) != 0)) { -                local->call_cnt = conf->subvolume_cnt; -                cnt             = conf->subvolume_cnt; -                ret = dht_inode_ctx_mdsvol_get (fd->inode, this, &mds_subvol); - -                if (!mds_subvol) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "cannot determine MDS, fetching xattr %s " -                                " randomly from a subvol for gfid %s ", -                                key, gfid); -                } else { -                        /* TODO need to handle it, As of now we are -                           choosing availability instead of chossing -                           consistencty, in case of hashed_subvol is -                           down winding a getxattr call on other subvol -                           and return xattr -                        */ -                        local->mds_subvol = mds_subvol; -                        for (i = 0; i < cnt; i++) { -                                if (conf->subvolumes[i] == mds_subvol) { -                                        if (!conf->subvolume_status[i]) { -                                                gf_msg (this->name, -                                                        GF_LOG_WARNING, 0, -                                                        DHT_MSG_HASHED_SUBVOL_DOWN, -                                                        "MDS subvolume %s is down" -                                                        " for gfid %s so fetching xattr " -                                                        " %s randomly from a subvol ", -                                                        local->mds_subvol->name, -                                                        gfid, key); -                                                ret = 1; -                                        } -                                } -                        } -                } - -                if (!ret && key && local->mds_subvol && -                    dht_match_xattr (key)) { -                        STACK_WIND (frame, dht_mds_getxattr_cbk, -                                    local->mds_subvol, -                                    local->mds_subvol->fops->fgetxattr, -                                    fd, key, NULL); +        if (!ret && key && local->mds_subvol && dht_match_xattr(key)) { +            STACK_WIND(frame, dht_mds_getxattr_cbk, local->mds_subvol, +                       local->mds_subvol->fops->fgetxattr, fd, key, NULL); -                        return 0; -                } - -        } else { -                cnt = local->call_cnt  = 1; +            return 0;          } +    } else { +        cnt = local->call_cnt = 1; +    } -        for (i = 0; i < cnt; i++) { -                subvol = layout->list[i].xlator; -                STACK_WIND (frame, dht_getxattr_cbk, -                            subvol, subvol->fops->fgetxattr, -                            fd, key, NULL); -        } -        return 0; +    for (i = 0; i < cnt; i++) { +        subvol = layout->list[i].xlator; +        STACK_WIND(frame, dht_getxattr_cbk, subvol, subvol->fops->fgetxattr, fd, +                   key, NULL); +    } +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(fgetxattr, frame, -1, op_errno, NULL, NULL); -        return 0; +    return 0;  }  int -dht_file_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, dict_t *xdata) +dht_file_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int op_ret, int op_errno, dict_t *xdata)  { -        int           ret     = -1; -        dht_local_t  *local   = NULL; -        xlator_t     *prev    = NULL; -        struct iatt  *stbuf   = NULL; -        inode_t      *inode   = NULL; -        xlator_t     *subvol1 = NULL, *subvol2 = NULL; - -        local = frame->local; -        prev = cookie; +    int ret = -1; +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    struct iatt *stbuf = NULL; +    inode_t *inode = NULL; +    xlator_t *subvol1 = NULL, *subvol2 = NULL; -        local->op_errno = op_errno; +    local = frame->local; +    prev = cookie; -        if ((local->fop == GF_FOP_FSETXATTR) && -            op_ret == -1 && (op_errno == EBADF) && !(local->fd_checked)) { -                ret = dht_check_and_open_fd_on_subvol (this, frame); -                if (ret) -                        goto out; -                return 0; -        } +    local->op_errno = op_errno; -        if ((op_ret == -1) && !dht_inode_missing (op_errno)) { -                gf_msg_debug (this->name, op_errno, -                              "subvolume %s returned -1.", -                              prev->name); -                goto out; -        } +    if ((local->fop == GF_FOP_FSETXATTR) && op_ret == -1 && +        (op_errno == EBADF) && !(local->fd_checked)) { +        ret = dht_check_and_open_fd_on_subvol(this, frame); +        if (ret) +            goto out; +        return 0; +    } -        if (local->call_cnt != 1) -                goto out; +    if ((op_ret == -1) && !dht_inode_missing(op_errno)) { +        gf_msg_debug(this->name, op_errno, "subvolume %s returned -1.", +                     prev->name); +        goto out; +    } -        ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf); +    if (local->call_cnt != 1) +        goto out; -        if ((!op_ret) && !stbuf) { -                goto out; -        } +    ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); -        local->op_ret = op_ret; -        local->rebalance.target_op_fn = dht_setxattr2; -        if (xdata) -                local->rebalance.xdata = dict_ref (xdata); +    if ((!op_ret) && !stbuf) { +        goto out; +    } -        /* Phase 2 of migration */ -        if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) { -                ret = dht_rebalance_complete_check (this, frame); -                if (!ret) -                        return 0; -        } +    local->op_ret = op_ret; +    local->rebalance.target_op_fn = dht_setxattr2; +    if (xdata) +        local->rebalance.xdata = dict_ref(xdata); -        /* Phase 1 of migration */ -        if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { -                inode = (local->fd) ? local->fd->inode : local->loc.inode; +    /* Phase 2 of migration */ +    if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { +        ret = dht_rebalance_complete_check(this, frame); +        if (!ret) +            return 0; +    } -                ret = dht_inode_ctx_get_mig_info (this, inode, -                                                  &subvol1, &subvol2); -                if (!dht_mig_info_is_invalid (local->cached_subvol, -                                              subvol1, subvol2)) { -                        dht_setxattr2 (this, subvol2, frame, 0); -                        return 0; -                } +    /* Phase 1 of migration */ +    if (IS_DHT_MIGRATION_PHASE1(stbuf)) { +        inode = (local->fd) ? local->fd->inode : local->loc.inode; -                ret = dht_rebalance_in_progress_check (this, frame); -                if (!ret) -                        return 0; +        ret = dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2); +        if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { +            dht_setxattr2(this, subvol2, frame, 0); +            return 0;          } +        ret = dht_rebalance_in_progress_check(this, frame); +        if (!ret) +            return 0; +    } +  out: -        if (local->fop == GF_FOP_SETXATTR) { -                DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); -        } else { -                DHT_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); -        } +    if (local->fop == GF_FOP_SETXATTR) { +        DHT_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); +    } else { +        DHT_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); +    } -        return 0; +    return 0;  }  /* Function is call by dict_foreach_fnmatch if key is match with     user.* and set boolean flag to true  */  static int -dht_is_user_xattr (dict_t *this, char *key, data_t *value, void *data) +dht_is_user_xattr(dict_t *this, char *key, data_t *value, void *data)  { -        gf_boolean_t *user_xattr_found = data; -        *user_xattr_found = _gf_true; -        return 0; +    gf_boolean_t *user_xattr_found = data; +    *user_xattr_found = _gf_true; +    return 0;  } -  /* Common code to wind a (f)(set|remove)xattr call to set xattr on directory -*/ + */  int -dht_dir_common_set_remove_xattr (call_frame_t *frame, xlator_t *this, loc_t *loc, -                                 fd_t *fd, dict_t *xattr, int flags, dict_t *xdata, -                                 int *op_errno) - -{ -        dict_t       *xattrop             = NULL; -        int32_t       subone[1]            = {-1}; -        gf_boolean_t  uxattr_key_found     = _gf_false; -        xlator_t     *mds_subvol          = NULL; -        xlator_t     *travvol              = NULL; -        dht_conf_t   *conf                = NULL; -        int           ret                  = -1; -        int           i                    = 0; -        int           call_cnt             = 0; -        dht_local_t  *local                = NULL; -        char          gfid_local[GF_UUID_BUF_SIZE] = {0}; - -        conf = this->private; -        local    = frame->local; -        call_cnt = conf->subvolume_cnt; -        local->flags = flags; - -        if (!gf_uuid_is_null (local->gfid)) { -                gf_uuid_unparse(local->gfid, gfid_local); -        } - -        if ((local->fop == GF_FOP_SETXATTR) || -            (local->fop == GF_FOP_FSETXATTR)) { -                /* Check if any user xattr present in xattr -                */ -                dict_foreach_fnmatch (xattr, "user*", dht_is_user_xattr, -                                      &uxattr_key_found); - -                /* Check if any custom key xattr present in dict xattr -                   and start index from 1 because user xattr already -                   checked in previous line -                */ -                for (i = 1; xattrs_to_heal[i]; i++) -                        if (dict_get (xattr, xattrs_to_heal[i])) -                                uxattr_key_found = _gf_true; -        } +dht_dir_common_set_remove_xattr(call_frame_t *frame, xlator_t *this, loc_t *loc, +                                fd_t *fd, dict_t *xattr, int flags, +                                dict_t *xdata, int *op_errno) + +{ +    dict_t *xattrop = NULL; +    int32_t subone[1] = {-1}; +    gf_boolean_t uxattr_key_found = _gf_false; +    xlator_t *mds_subvol = NULL; +    xlator_t *travvol = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    int i = 0; +    int call_cnt = 0; +    dht_local_t *local = NULL; +    char gfid_local[GF_UUID_BUF_SIZE] = {0}; + +    conf = this->private; +    local = frame->local; +    call_cnt = conf->subvolume_cnt; +    local->flags = flags; + +    if (!gf_uuid_is_null(local->gfid)) { +        gf_uuid_unparse(local->gfid, gfid_local); +    } -        if ((local->fop == GF_FOP_REMOVEXATTR) || -            (local->fop == GF_FOP_FREMOVEXATTR)) { -                /* Check if any custom key xattr present in local->key -                */ -                for (i = 0; xattrs_to_heal[i]; i++) -                        if (strstr (local->key, xattrs_to_heal[i])) -                                uxattr_key_found = _gf_true; -        } +    if ((local->fop == GF_FOP_SETXATTR) || (local->fop == GF_FOP_FSETXATTR)) { +        /* Check if any user xattr present in xattr +         */ +        dict_foreach_fnmatch(xattr, "user*", dht_is_user_xattr, +                             &uxattr_key_found); -        /* If there is no custom key xattr present or gfid is root -           or call_cnt is 1 then wind a (f)setxattr call on all subvols +        /* Check if any custom key xattr present in dict xattr +           and start index from 1 because user xattr already +           checked in previous line          */ -        if (!uxattr_key_found || __is_root_gfid (local->gfid) || call_cnt == 1) { -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        travvol = conf->subvolumes[i]; -                        if ((local->fop == GF_FOP_SETXATTR) || -                            (local->fop == GF_FOP_FSETXATTR)) { -                                if (fd) { -                                        STACK_WIND_COOKIE (frame, dht_err_cbk, -                                                           travvol, travvol, -                                                           travvol->fops->fsetxattr, -                                                           fd, xattr, flags, xdata); -                                } else { -                                        STACK_WIND_COOKIE (frame, dht_err_cbk, -                                                           travvol, travvol, -                                                           travvol->fops->setxattr, -                                                           loc, xattr, flags, xdata); -                                } -                        } - -                        if ((local->fop == GF_FOP_REMOVEXATTR) || -                            (local->fop == GF_FOP_FREMOVEXATTR)) { -                                if (fd) { -                                        STACK_WIND_COOKIE (frame, dht_err_cbk, -                                                           travvol, travvol, -                                                           travvol->fops->fremovexattr, -                                                           fd, local->key, local->xattr_req); -                                } else { -                                        STACK_WIND_COOKIE (frame, dht_err_cbk, -                                                           travvol, travvol, -                                                           travvol->fops->removexattr, -                                                           loc, local->key, local->xattr_req); -                                } -                        } -                } - -                return 0; -        } - -        /* Calculate hash subvol based on inode and parent inode +        for (i = 1; xattrs_to_heal[i]; i++) +            if (dict_get(xattr, xattrs_to_heal[i])) +                uxattr_key_found = _gf_true; +    } + +    if ((local->fop == GF_FOP_REMOVEXATTR) || +        (local->fop == GF_FOP_FREMOVEXATTR)) { +        /* Check if any custom key xattr present in local->key           */ -        if (fd) { -                ret = dht_inode_ctx_mdsvol_get (fd->inode, this, &mds_subvol); -        } else { -                ret = dht_inode_ctx_mdsvol_get (loc->inode, this, &mds_subvol); -        } -        if (ret || !mds_subvol) { +        for (i = 0; xattrs_to_heal[i]; i++) +            if (strstr(local->key, xattrs_to_heal[i])) +                uxattr_key_found = _gf_true; +    } + +    /* If there is no custom key xattr present or gfid is root +       or call_cnt is 1 then wind a (f)setxattr call on all subvols +    */ +    if (!uxattr_key_found || __is_root_gfid(local->gfid) || call_cnt == 1) { +        for (i = 0; i < conf->subvolume_cnt; i++) { +            travvol = conf->subvolumes[i]; +            if ((local->fop == GF_FOP_SETXATTR) || +                (local->fop == GF_FOP_FSETXATTR)) {                  if (fd) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Failed to get mds subvol for fd %p" -                                "gfid is %s ", fd, gfid_local); +                    STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, +                                      travvol->fops->fsetxattr, fd, xattr, +                                      flags, xdata);                  } else { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Failed to get mds subvol for path %s" -                                "gfid is %s ", loc->path, gfid_local); +                    STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, +                                      travvol->fops->setxattr, loc, xattr, +                                      flags, xdata);                  } -                (*op_errno) = ENOENT; -                goto err; -        } - -        local->mds_subvol = mds_subvol; - -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (conf->subvolumes[i] ==  mds_subvol) { -                        if (!conf->subvolume_status[i]) { -                                gf_msg (this->name, GF_LOG_WARNING, -                                        0, DHT_MSG_HASHED_SUBVOL_DOWN, -                                        "MDS subvol is down for path " -                                        " %s gfid is %s Unable to set xattr " , -                                        local->loc.path, gfid_local); -                                (*op_errno) = ENOTCONN; -                                goto err; -                        } -                } -        } +            } -        if (uxattr_key_found) { -                xattrop = dict_new (); -                if (!xattrop) { -                        gf_msg (this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, -                                0, "dictionary creation failed for path %s " -                                "for gfid is %s ", local->loc.path, gfid_local); -                        (*op_errno) = ENOMEM; -                        goto err; -                } -                local->xattr = dict_ref (xattr); -                /* Subtract current MDS xattr value to -1 , value of MDS -                   xattr represents no. of times xattr modification failed -                   on non MDS subvols. -                */ -                ret = dht_dict_set_array (xattrop, conf->mds_xattr_key, subone, 1); -                if (ret != 0) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, -                                "dictionary set array failed for path %s " -                                "for gfid is %s ", local->loc.path, gfid_local); -                        if (xattrop) -                                dict_unref (xattrop); -                        (*op_errno) = ret; -                        goto err; -                } -                /* Wind a xattrop call to use ref counting approach -                   update mds xattr to -1 before update xattr on -                   hashed subvol and update mds xattr to +1 after update -                   xattr on all non hashed subvol -                */ +            if ((local->fop == GF_FOP_REMOVEXATTR) || +                (local->fop == GF_FOP_FREMOVEXATTR)) {                  if (fd) { -                        STACK_WIND (frame, dht_xattrop_mds_cbk, -                                    local->mds_subvol, -                                    local->mds_subvol->fops->fxattrop, -                                     fd, GF_XATTROP_ADD_ARRAY, xattrop, NULL); +                    STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, +                                      travvol->fops->fremovexattr, fd, +                                      local->key, local->xattr_req);                  } else { -                        STACK_WIND (frame, dht_xattrop_mds_cbk, -                                    local->mds_subvol, -                                    local->mds_subvol->fops->xattrop, -                                    loc, GF_XATTROP_ADD_ARRAY, -                                    xattrop, NULL); +                    STACK_WIND_COOKIE(frame, dht_err_cbk, travvol, travvol, +                                      travvol->fops->removexattr, loc, +                                      local->key, local->xattr_req);                  } -                if (xattrop) -                        dict_unref (xattrop); +            }          }          return 0; -err: -        return -1; -} - - -int -dht_fsetxattr (call_frame_t *frame, xlator_t *this, -               fd_t *fd, dict_t *xattr, int flags, dict_t *xdata) -{ -        xlator_t     *subvol   = NULL; -        dht_local_t  *local    = NULL; -        int           op_errno = EINVAL; -        dht_conf_t   *conf     = NULL; -        dht_layout_t *layout   = NULL; -        int           ret      = -1; -        int           call_cnt = 0; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO (fd->inode, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf = this->private; - -        if (!conf->defrag) -                GF_IF_INTERNAL_XATTR_GOTO (conf->wild_xattr_name, xattr, -                                           op_errno, err); - -        local = dht_local_init (frame, NULL, fd, GF_FOP_FSETXATTR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        subvol = local->cached_subvol; -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for fd=%p", fd); -                op_errno = EINVAL; -                goto err; -        } +    } -        layout = local->layout; -        if (!layout) { -                gf_msg_debug (this->name, 0, -                              "no layout for fd=%p", fd); -                op_errno = EINVAL; +    /* Calculate hash subvol based on inode and parent inode +     */ +    if (fd) { +        ret = dht_inode_ctx_mdsvol_get(fd->inode, this, &mds_subvol); +    } else { +        ret = dht_inode_ctx_mdsvol_get(loc->inode, this, &mds_subvol); +    } +    if (ret || !mds_subvol) { +        if (fd) { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Failed to get mds subvol for fd %p" +                   "gfid is %s ", +                   fd, gfid_local); +        } else { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Failed to get mds subvol for path %s" +                   "gfid is %s ", +                   loc->path, gfid_local); +        } +        (*op_errno) = ENOENT; +        goto err; +    } + +    local->mds_subvol = mds_subvol; + +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (conf->subvolumes[i] == mds_subvol) { +            if (!conf->subvolume_status[i]) { +                gf_msg(this->name, GF_LOG_WARNING, 0, +                       DHT_MSG_HASHED_SUBVOL_DOWN, +                       "MDS subvol is down for path " +                       " %s gfid is %s Unable to set xattr ", +                       local->loc.path, gfid_local); +                (*op_errno) = ENOTCONN;                  goto err; +            }          } - -        local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); -        local->call_cnt = call_cnt = layout->cnt; - -        if (IA_ISDIR (fd->inode->ia_type)) { -                local->hashed_subvol = NULL; -                ret = dht_dir_common_set_remove_xattr (frame, this, NULL, fd, -                                                       xattr, flags, xdata, &op_errno); -                if (ret) -                        goto err; +    } + +    if (uxattr_key_found) { +        xattrop = dict_new(); +        if (!xattrop) { +            gf_msg(this->name, GF_LOG_ERROR, DHT_MSG_NO_MEMORY, 0, +                   "dictionary creation failed for path %s " +                   "for gfid is %s ", +                   local->loc.path, gfid_local); +            (*op_errno) = ENOMEM; +            goto err; +        } +        local->xattr = dict_ref(xattr); +        /* Subtract current MDS xattr value to -1 , value of MDS +           xattr represents no. of times xattr modification failed +           on non MDS subvols. +        */ +        ret = dht_dict_set_array(xattrop, conf->mds_xattr_key, subone, 1); +        if (ret != 0) { +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +                   "dictionary set array failed for path %s " +                   "for gfid is %s ", +                   local->loc.path, gfid_local); +            if (xattrop) +                dict_unref(xattrop); +            (*op_errno) = ret; +            goto err; +        } +        /* Wind a xattrop call to use ref counting approach +           update mds xattr to -1 before update xattr on +           hashed subvol and update mds xattr to +1 after update +           xattr on all non hashed subvol +        */ +        if (fd) { +            STACK_WIND(frame, dht_xattrop_mds_cbk, local->mds_subvol, +                       local->mds_subvol->fops->fxattrop, fd, +                       GF_XATTROP_ADD_ARRAY, xattrop, NULL);          } else { +            STACK_WIND(frame, dht_xattrop_mds_cbk, local->mds_subvol, +                       local->mds_subvol->fops->xattrop, loc, +                       GF_XATTROP_ADD_ARRAY, xattrop, NULL); +        } +        if (xattrop) +            dict_unref(xattrop); +    } -                local->call_cnt = 1; -                local->rebalance.xattr = dict_ref (xattr); -                local->rebalance.flags = flags; - -                ret = dict_set_int8 (local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); -                if (ret) { -                        gf_msg_debug (this->name, 0, -                                      "Failed to set dictionary key %s for fd=%p", -                                      DHT_IATT_IN_XDATA_KEY, fd); -                } +    return 0; +err: +    return -1; +} + +int +dht_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xattr, +              int flags, dict_t *xdata) +{ +    xlator_t *subvol = NULL; +    dht_local_t *local = NULL; +    int op_errno = EINVAL; +    dht_conf_t *conf = NULL; +    dht_layout_t *layout = NULL; +    int ret = -1; +    int call_cnt = 0; + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(fd->inode, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    if (!conf->defrag) +        GF_IF_INTERNAL_XATTR_GOTO(conf->wild_xattr_name, xattr, op_errno, err); + +    local = dht_local_init(frame, NULL, fd, GF_FOP_FSETXATTR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } + +    subvol = local->cached_subvol; +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for fd=%p", fd); +        op_errno = EINVAL; +        goto err; +    } + +    layout = local->layout; +    if (!layout) { +        gf_msg_debug(this->name, 0, "no layout for fd=%p", fd); +        op_errno = EINVAL; +        goto err; +    } + +    local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); +    local->call_cnt = call_cnt = layout->cnt; + +    if (IA_ISDIR(fd->inode->ia_type)) { +        local->hashed_subvol = NULL; +        ret = dht_dir_common_set_remove_xattr(frame, this, NULL, fd, xattr, +                                              flags, xdata, &op_errno); +        if (ret) +            goto err; +    } else { +        local->call_cnt = 1; +        local->rebalance.xattr = dict_ref(xattr); +        local->rebalance.flags = flags; -                STACK_WIND_COOKIE (frame, dht_file_setxattr_cbk, subvol, -                                   subvol, subvol->fops->fsetxattr, fd, xattr, -                                   flags, local->xattr_req); +        ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); +        if (ret) { +            gf_msg_debug(this->name, 0, +                         "Failed to set dictionary key %s for fd=%p", +                         DHT_IATT_IN_XDATA_KEY, fd);          } -        return 0; + +        STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, +                          subvol->fops->fsetxattr, fd, xattr, flags, +                          local->xattr_req); +    } +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(fsetxattr, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } -  int -dht_checking_pathinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                           int op_ret, int op_errno, dict_t *xattr, -                           dict_t *xdata) +dht_checking_pathinfo_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                          int op_ret, int op_errno, dict_t *xattr, +                          dict_t *xdata)  { -        int           i     = -1; -        int           ret   = -1; -        char         *value = NULL; -        dht_local_t  *local = NULL; -        dht_conf_t   *conf  = NULL; -        xlator_t     *prev  = NULL; -        int           this_call_cnt = 0; - -        local = frame->local; -        prev = cookie; -        conf = this->private; +    int i = -1; +    int ret = -1; +    char *value = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    xlator_t *prev = NULL; +    int this_call_cnt = 0; -        if (op_ret == -1) -                goto out; +    local = frame->local; +    prev = cookie; +    conf = this->private; +    if (op_ret == -1) +        goto out; -        ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value); -        if (ret) -                goto out; +    ret = dict_get_str(xattr, GF_XATTR_PATHINFO_KEY, &value); +    if (ret) +        goto out; -        if (!strcmp (value, local->key)) { -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (conf->subvolumes[i] == prev) -                                conf->decommissioned_bricks[i] = prev; -                } +    if (!strcmp(value, local->key)) { +        for (i = 0; i < conf->subvolume_cnt; i++) { +            if (conf->subvolumes[i] == prev) +                conf->decommissioned_bricks[i] = prev;          } +    }  out: -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                DHT_STACK_UNWIND (setxattr, frame, local->op_ret, ENOTSUP, NULL); -        } -        return 0; - +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        DHT_STACK_UNWIND(setxattr, frame, local->op_ret, ENOTSUP, NULL); +    } +    return 0;  } -  int -dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) +dht_setxattr2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)  { -        dht_local_t  *local  = NULL; -        int          op_errno = EINVAL; +    dht_local_t *local = NULL; +    int op_errno = EINVAL; -        if (!frame || !frame->local) -                goto err; +    if (!frame || !frame->local) +        goto err; -        local = frame->local; -        op_errno = local->op_errno; - -        if (we_are_not_migrating (ret)) { -                /* This dht xlator is not migrating the file. Unwind and -                 * pass on the original mode bits so the higher DHT layer -                 * can handle this. -                 */ -                DHT_STACK_UNWIND (setxattr, frame, local->op_ret, -                                  local->op_errno, local->rebalance.xdata); -                return 0; -        } +    local = frame->local; +    op_errno = local->op_errno; -        if (subvol == NULL) -                goto err; +    if (we_are_not_migrating(ret)) { +        /* This dht xlator is not migrating the file. Unwind and +         * pass on the original mode bits so the higher DHT layer +         * can handle this. +         */ +        DHT_STACK_UNWIND(setxattr, frame, local->op_ret, local->op_errno, +                         local->rebalance.xdata); +        return 0; +    } +    if (subvol == NULL) +        goto err; -        local->call_cnt = 2; /* This is the second attempt */ +    local->call_cnt = 2; /* This is the second attempt */ -        if (local->fop == GF_FOP_SETXATTR) { -                STACK_WIND_COOKIE (frame, dht_file_setxattr_cbk, subvol, -                                   subvol, subvol->fops->setxattr, &local->loc, -                                   local->rebalance.xattr, -                                   local->rebalance.flags, local->xattr_req); -        } else { -                STACK_WIND_COOKIE (frame, dht_file_setxattr_cbk, subvol, -                                   subvol, subvol->fops->fsetxattr, local->fd, -                                   local->rebalance.xattr, -                                   local->rebalance.flags, local->xattr_req); -        } +    if (local->fop == GF_FOP_SETXATTR) { +        STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, +                          subvol->fops->setxattr, &local->loc, +                          local->rebalance.xattr, local->rebalance.flags, +                          local->xattr_req); +    } else { +        STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, +                          subvol->fops->fsetxattr, local->fd, +                          local->rebalance.xattr, local->rebalance.flags, +                          local->xattr_req); +    } -        return 0; +    return 0;  err: -        DHT_STACK_UNWIND (setxattr, frame, (local ? local->op_ret : -1), -                          op_errno, NULL); -        return 0; +    DHT_STACK_UNWIND(setxattr, frame, (local ? local->op_ret : -1), op_errno, +                     NULL); +    return 0;  }  int -dht_nuke_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                  int32_t op_ret, int32_t op_errno, struct iatt *preparent, -                  struct iatt *postparent, dict_t *xdata) +dht_nuke_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, struct iatt *preparent, +                 struct iatt *postparent, dict_t *xdata)  { -        STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL); +    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, NULL); +    return 0; +} + +int +dht_nuke_dir(call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *tmp) +{ +    if (!IA_ISDIR(loc->inode->ia_type)) { +        DHT_STACK_UNWIND(setxattr, frame, -1, ENOTSUP, NULL);          return 0; -} - -int -dht_nuke_dir (call_frame_t *frame, xlator_t *this, loc_t *loc, data_t *tmp) -{ -        if (!IA_ISDIR(loc->inode->ia_type)) { -                DHT_STACK_UNWIND (setxattr, frame, -1, ENOTSUP, NULL); -                return 0; +    } + +    /* Setxattr didn't need the parent, but rmdir does. */ +    loc->parent = inode_parent(loc->inode, NULL, NULL); +    if (!loc->parent) { +        DHT_STACK_UNWIND(setxattr, frame, -1, ENOENT, NULL); +        return 0; +    } +    gf_uuid_copy(loc->pargfid, loc->parent->gfid); + +    if (!loc->name && loc->path) { +        loc->name = strrchr(loc->path, '/'); +        if (loc->name) { +            ++(loc->name);          } +    } -        /* Setxattr didn't need the parent, but rmdir does. */ -        loc->parent = inode_parent (loc->inode, NULL, NULL); -        if (!loc->parent) { -                DHT_STACK_UNWIND (setxattr, frame, -1, ENOENT, NULL); -                return 0; -        } -        gf_uuid_copy (loc->pargfid, loc->parent->gfid); +    /* +     * We do this instead of calling dht_rmdir_do directly for two reasons. +     * The first is that we want to reuse all of the initialization that +     * dht_rmdir does, so if it ever changes we'll just follow along.  The +     * second (i.e. why we don't use STACK_WIND_TAIL) is so that we don't +     * obscure the fact that we came in via this path instead of a genuine +     * rmdir.  That makes debugging just a tiny bit easier. +     */ +    STACK_WIND(frame, dht_nuke_dir_cbk, this, this->fops->rmdir, loc, 1, NULL); -        if (!loc->name && loc->path) { -                loc->name = strrchr (loc->path, '/'); -                if (loc->name) { -                        ++(loc->name); -                } -        } - -        /* -         * We do this instead of calling dht_rmdir_do directly for two reasons. -         * The first is that we want to reuse all of the initialization that -         * dht_rmdir does, so if it ever changes we'll just follow along.  The -         * second (i.e. why we don't use STACK_WIND_TAIL) is so that we don't -         * obscure the fact that we came in via this path instead of a genuine -         * rmdir.  That makes debugging just a tiny bit easier. -         */ -        STACK_WIND (frame, dht_nuke_dir_cbk, this, this->fops->rmdir, -                    loc, 1, NULL); - -        return 0; +    return 0;  } -  int -dht_setxattr (call_frame_t *frame, xlator_t *this, -              loc_t *loc, dict_t *xattr, int flags, dict_t *xdata) +dht_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr, +             int flags, dict_t *xdata)  { -        xlator_t     *subvol   = NULL; -        dht_local_t  *local    = NULL; -        dht_conf_t   *conf     = NULL; -        dht_methods_t *methods = NULL; -        dht_layout_t *layout   = NULL; -        int           i        = 0; -        int           op_errno = EINVAL; -        int           ret      = -1; -        data_t       *tmp      = NULL; -        uint32_t      dir_spread = 0; -        char          value[4096] = {0,}; -        gf_dht_migrate_data_type_t forced_rebalance = GF_DHT_MIGRATE_DATA; -        int           call_cnt = 0; -        uint32_t      new_hash = 0; +    xlator_t *subvol = NULL; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    dht_methods_t *methods = NULL; +    dht_layout_t *layout = NULL; +    int i = 0; +    int op_errno = EINVAL; +    int ret = -1; +    data_t *tmp = NULL; +    uint32_t dir_spread = 0; +    char value[4096] = { +        0, +    }; +    gf_dht_migrate_data_type_t forced_rebalance = GF_DHT_MIGRATE_DATA; +    int call_cnt = 0; +    uint32_t new_hash = 0; +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); +    conf = this->private; +    GF_VALIDATE_OR_GOTO(this->name, conf, err); -        conf   = this->private; -        GF_VALIDATE_OR_GOTO (this->name, conf, err); - -        methods = &(conf->methods); - -        /* Rebalance daemon is allowed to set internal keys */ -        if (!conf->defrag) -                GF_IF_INTERNAL_XATTR_GOTO (conf->wild_xattr_name, xattr, -                                           op_errno, err); +    methods = &(conf->methods); + +    /* Rebalance daemon is allowed to set internal keys */ +    if (!conf->defrag) +        GF_IF_INTERNAL_XATTR_GOTO(conf->wild_xattr_name, xattr, op_errno, err); + +    local = dht_local_init(frame, loc, NULL, GF_FOP_SETXATTR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } + +    subvol = local->cached_subvol; +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", +                     loc->path); +        op_errno = EINVAL; +        goto err; +    } + +    layout = local->layout; +    if (!layout) { +        gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); +        op_errno = EINVAL; +        goto err; +    } + +    local->call_cnt = call_cnt = layout->cnt; +    tmp = dict_get(xattr, conf->mds_xattr_key); +    if (tmp) { +        op_errno = ENOTSUP; +        goto err; +    } + +    tmp = dict_get(xattr, GF_XATTR_FILE_MIGRATE_KEY); +    if (tmp) { +        if (IA_ISDIR(loc->inode->ia_type)) { +            op_errno = ENOTSUP; +            goto err; +        } + +        /* TODO: need to interpret the 'value' for more meaning +           (ie, 'target' subvolume given there, etc) */ +        memcpy(value, tmp->data, tmp->len); +        if (strcmp(value, "force") == 0) +            forced_rebalance = GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS; + +        if (conf->decommission_in_progress) +            forced_rebalance = GF_DHT_MIGRATE_HARDLINK; + +        if (!loc->path) { +            op_errno = EINVAL; +            goto err; +        } + +        if (!local->loc.name) +            local->loc.name = strrchr(local->loc.path, '/') + 1; + +        if (!local->loc.parent) +            local->loc.parent = inode_parent(local->loc.inode, NULL, NULL); + +        if ((!local->loc.name) || (!local->loc.parent)) { +            op_errno = EINVAL; +            goto err; +        } + +        if (gf_uuid_is_null(local->loc.pargfid)) +            gf_uuid_copy(local->loc.pargfid, local->loc.parent->gfid); + +        methods->migration_get_dst_subvol(this, local); + +        if (!local->rebalance.target_node) { +            gf_msg(this->name, GF_LOG_ERROR, 0, +                   DHT_MSG_HASHED_SUBVOL_GET_FAILED, +                   "Failed to get hashed subvol for %s", loc->path); +            op_errno = EINVAL; +            goto err; +        } + +        local->rebalance.from_subvol = local->cached_subvol; + +        if (local->rebalance.target_node == local->rebalance.from_subvol) { +            op_errno = EEXIST; +            goto err; +        } +        if (local->rebalance.target_node) { +            local->flags = forced_rebalance; + +            /* Flag to suggest its a tiering migration +             * The reason for this dic key-value is that +             * promotions and demotions are multithreaded +             * so the original frame from gf_defrag_start() +             * is not carried. A new frame will be created when +             * we do syncop_setxattr(). This does not have the +             * frame->root->pid of the original frame. So we pass +             * this dic key-value when we do syncop_setxattr() to do +             * data migration and set the frame->root->pid to +             * GF_CLIENT_PID_TIER_DEFRAG in dht_setxattr() just before +             * calling dht_start_rebalance_task() */ +            tmp = dict_get(xattr, TIERING_MIGRATION_KEY); +            if (tmp) +                frame->root->pid = GF_CLIENT_PID_TIER_DEFRAG; +            else +                frame->root->pid = GF_CLIENT_PID_DEFRAG; + +            ret = dht_start_rebalance_task(this, frame); +            if (!ret) +                return 0; -        local = dht_local_init (frame, loc, NULL, GF_FOP_SETXATTR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; +            gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_REBALANCE_START_FAILED, +                   "%s: failed to create a new rebalance synctask", loc->path);          } +        op_errno = EINVAL; +        goto err; +    } -        subvol = local->cached_subvol; -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for path=%s", -                              loc->path); -                op_errno = EINVAL; -                goto err; +    tmp = dict_get(xattr, "decommission-brick"); +    if (tmp) { +        /* This operation should happen only on '/' */ +        if (!__is_root_gfid(loc->inode->gfid)) { +            op_errno = ENOTSUP; +            goto err;          } -        layout = local->layout; -        if (!layout) { -                gf_msg_debug (this->name, 0, -                              "no layout for path=%s", loc->path); -                op_errno = EINVAL; -                goto err; -        } +        memcpy(value, tmp->data, min(tmp->len, 4095)); +        local->key = gf_strdup(value); +        local->call_cnt = conf->subvolume_cnt; -        local->call_cnt = call_cnt = layout->cnt; -        tmp = dict_get (xattr, conf->mds_xattr_key); -        if (tmp) { -                op_errno = ENOTSUP; -                goto err; +        for (i = 0; i < conf->subvolume_cnt; i++) { +            /* Get the pathinfo, and then compare */ +            STACK_WIND_COOKIE(frame, dht_checking_pathinfo_cbk, +                              conf->subvolumes[i], conf->subvolumes[i], +                              conf->subvolumes[i]->fops->getxattr, loc, +                              GF_XATTR_PATHINFO_KEY, NULL);          } +        return 0; +    } -        tmp = dict_get (xattr, GF_XATTR_FILE_MIGRATE_KEY); -        if (tmp) { - -                if (IA_ISDIR (loc->inode->ia_type)) { -                        op_errno = ENOTSUP; -                        goto err; -                } - -                /* TODO: need to interpret the 'value' for more meaning -                   (ie, 'target' subvolume given there, etc) */ -                memcpy (value, tmp->data, tmp->len); -                if (strcmp (value, "force") == 0) -                       forced_rebalance = -                                GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS; - -                if (conf->decommission_in_progress) -                        forced_rebalance = GF_DHT_MIGRATE_HARDLINK; - -                if (!loc->path) { -                        op_errno = EINVAL; -                        goto err; -                } - -                if (!local->loc.name) -                        local->loc.name = strrchr (local->loc.path, '/')+1; - -                if (!local->loc.parent) -                        local->loc.parent = -                                inode_parent(local->loc.inode, NULL, NULL); - -                if ((!local->loc.name) || (!local->loc.parent)) { -                        op_errno = EINVAL; -                        goto err; -                } - -                if (gf_uuid_is_null (local->loc.pargfid)) -                        gf_uuid_copy (local->loc.pargfid, local->loc.parent->gfid); - -                methods->migration_get_dst_subvol(this, local); - -                if (!local->rebalance.target_node) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                                "Failed to get hashed subvol for %s", -                                loc->path); -                        op_errno = EINVAL; -                        goto err; -                } - -                local->rebalance.from_subvol = local->cached_subvol; +    tmp = dict_get(xattr, GF_XATTR_FIX_LAYOUT_KEY); +    if (tmp) { +        ret = dict_get_uint32(xattr, "new-commit-hash", &new_hash); +        if (ret == 0) { +            gf_msg_debug(this->name, 0, +                         "updating commit hash for %s from %u to %u", +                         uuid_utoa(loc->gfid), layout->commit_hash, new_hash); +            layout->commit_hash = new_hash; -                if (local->rebalance.target_node == local->rebalance.from_subvol) { -                        op_errno = EEXIST; -                        goto err; -                } -                if (local->rebalance.target_node) { -                        local->flags = forced_rebalance; - -                        /* Flag to suggest its a tiering migration -                         * The reason for this dic key-value is that -                         * promotions and demotions are multithreaded -                         * so the original frame from gf_defrag_start() -                         * is not carried. A new frame will be created when -                         * we do syncop_setxattr(). This does not have the -                         * frame->root->pid of the original frame. So we pass -                         * this dic key-value when we do syncop_setxattr() to do -                         * data migration and set the frame->root->pid to -                         * GF_CLIENT_PID_TIER_DEFRAG in dht_setxattr() just before -                         * calling dht_start_rebalance_task() */ -                        tmp = dict_get (xattr, TIERING_MIGRATION_KEY); -                        if (tmp) -                                frame->root->pid = GF_CLIENT_PID_TIER_DEFRAG; -                        else -                                frame->root->pid = GF_CLIENT_PID_DEFRAG; - -                        ret = dht_start_rebalance_task (this, frame); -                        if (!ret) -                                return 0; - -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                DHT_MSG_REBALANCE_START_FAILED, -                                "%s: failed to create a new rebalance synctask", -                                loc->path); -                } -                op_errno = EINVAL; +            ret = dht_update_commit_hash_for_layout(frame); +            if (ret) { +                op_errno = ENOTCONN;                  goto err; - +            } +            return ret;          } -        tmp = dict_get (xattr, "decommission-brick"); -        if (tmp) { -                /* This operation should happen only on '/' */ -                if (!__is_root_gfid (loc->inode->gfid)) { -                        op_errno = ENOTSUP; -                        goto err; -                } +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_FIX_LAYOUT_INFO, +               "fixing the layout of %s", loc->path); -                memcpy (value, tmp->data, min (tmp->len, 4095)); -                local->key = gf_strdup (value); -                local->call_cnt = conf->subvolume_cnt; - -                for (i = 0 ; i < conf->subvolume_cnt; i++) { -                        /* Get the pathinfo, and then compare */ -                        STACK_WIND_COOKIE (frame, dht_checking_pathinfo_cbk, -                                           conf->subvolumes[i], conf->subvolumes[i], -                                           conf->subvolumes[i]->fops->getxattr, -                                           loc, GF_XATTR_PATHINFO_KEY, NULL); -                } -                return 0; +        ret = dht_fix_directory_layout(frame, dht_fix_layout_setxattr_cbk, +                                       layout); +        if (ret) { +            op_errno = ENOTCONN; +            goto err;          } +        return ret; +    } -        tmp = dict_get (xattr, GF_XATTR_FIX_LAYOUT_KEY); -        if (tmp) { -                ret = dict_get_uint32(xattr, "new-commit-hash", &new_hash); -                if (ret == 0) { -                        gf_msg_debug (this->name, 0, -                                      "updating commit hash for %s from %u to %u", -                                      uuid_utoa(loc->gfid), -                                      layout->commit_hash, new_hash); -                        layout->commit_hash = new_hash; - -                        ret = dht_update_commit_hash_for_layout (frame); -                        if (ret) { -                                op_errno = ENOTCONN; -                                goto err; -                        } -                        return ret; -                } - -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_FIX_LAYOUT_INFO, -                        "fixing the layout of %s", loc->path); - -                ret = dht_fix_directory_layout (frame, -                                                dht_fix_layout_setxattr_cbk, -                                                layout); -                if (ret) { -                        op_errno = ENOTCONN; -                        goto err; -                } -                return ret; -        } +    tmp = dict_get(xattr, "distribute.directory-spread-count"); +    if (tmp) { +        /* Setxattr value is packed as 'binary', not string */ +        memcpy(value, tmp->data, min(tmp->len, 4095)); +        ret = gf_string2uint32(value, &dir_spread); +        if (!ret && ((dir_spread <= conf->subvolume_cnt) && (dir_spread > 0))) { +            layout->spread_cnt = dir_spread; -        tmp = dict_get (xattr, "distribute.directory-spread-count"); -        if (tmp) { -                /* Setxattr value is packed as 'binary', not string */ -                memcpy (value, tmp->data, min (tmp->len, 4095)); -                ret = gf_string2uint32 (value, &dir_spread); -                if (!ret && ((dir_spread <= conf->subvolume_cnt) && -                             (dir_spread > 0))) { -                        layout->spread_cnt = dir_spread; - -                        ret = dht_fix_directory_layout (frame, -                                                        dht_common_setxattr_cbk, -                                                        layout); -                        if (ret) { -                                op_errno = ENOTCONN; -                                goto err; -                        } -                        return ret; -                } -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_OPERATION_NOT_SUP, -                        "wrong 'directory-spread-count' value (%s)", value); -                op_errno = ENOTSUP; +            ret = dht_fix_directory_layout(frame, dht_common_setxattr_cbk, +                                           layout); +            if (ret) { +                op_errno = ENOTCONN;                  goto err; -        } - -        tmp = dict_get (xattr, "glusterfs.dht.nuke"); -        if (tmp) { -                return dht_nuke_dir (frame, this, loc, tmp); -        } -        local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); - -        if (IA_ISDIR (loc->inode->ia_type)) { -                local->hashed_subvol = NULL; -                ret = dht_dir_common_set_remove_xattr (frame, this, loc, NULL, -                                                       xattr, flags, xdata, &op_errno); -                if (ret) -                        goto err; -        } else { +            } +            return ret; +        } +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_OPERATION_NOT_SUP, +               "wrong 'directory-spread-count' value (%s)", value); +        op_errno = ENOTSUP; +        goto err; +    } + +    tmp = dict_get(xattr, "glusterfs.dht.nuke"); +    if (tmp) { +        return dht_nuke_dir(frame, this, loc, tmp); +    } +    local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); + +    if (IA_ISDIR(loc->inode->ia_type)) { +        local->hashed_subvol = NULL; +        ret = dht_dir_common_set_remove_xattr(frame, this, loc, NULL, xattr, +                                              flags, xdata, &op_errno); +        if (ret) +            goto err; +    } else { +        local->rebalance.xattr = dict_ref(xattr); +        local->rebalance.flags = flags; +        local->call_cnt = 1; -                local->rebalance.xattr = dict_ref (xattr); -                local->rebalance.flags = flags; -                local->call_cnt = 1; +        ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); -                ret = dict_set_int8 (local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); +        STACK_WIND_COOKIE(frame, dht_file_setxattr_cbk, subvol, subvol, +                          subvol->fops->setxattr, loc, xattr, flags, +                          local->xattr_req); +    } -                STACK_WIND_COOKIE (frame, dht_file_setxattr_cbk, subvol, -                                   subvol, subvol->fops->setxattr, loc, xattr, -                                   flags, local->xattr_req); -        } - -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(setxattr, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } - - -  int -dht_file_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                          int op_ret, int op_errno, dict_t *xdata) +dht_file_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                         int op_ret, int op_errno, dict_t *xdata)  { -        int           ret     = -1; -        dht_local_t  *local   = NULL; -        xlator_t     *prev    = NULL; -        struct iatt  *stbuf   = NULL; -        inode_t      *inode   = NULL; -        xlator_t     *subvol1 = NULL, *subvol2 = NULL; +    int ret = -1; +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    struct iatt *stbuf = NULL; +    inode_t *inode = NULL; +    xlator_t *subvol1 = NULL, *subvol2 = NULL; -        local = frame->local; -        prev = cookie; +    local = frame->local; +    prev = cookie; -        local->op_errno = op_errno; - -        if ((local->fop == GF_FOP_FREMOVEXATTR) && -            (op_ret == -1) && (op_errno == EBADF) && !(local->fd_checked)) { -                ret = dht_check_and_open_fd_on_subvol (this, frame); -                if (ret) -                        goto out; -                return 0; -        } +    local->op_errno = op_errno; -        if ((op_ret == -1) && !dht_inode_missing (op_errno)) { -                gf_msg_debug (this->name, op_errno, -                              "subvolume %s returned -1", -                              prev->name); -                goto out; -        } +    if ((local->fop == GF_FOP_FREMOVEXATTR) && (op_ret == -1) && +        (op_errno == EBADF) && !(local->fd_checked)) { +        ret = dht_check_and_open_fd_on_subvol(this, frame); +        if (ret) +            goto out; +        return 0; +    } -        if (local->call_cnt != 1) -                goto out; +    if ((op_ret == -1) && !dht_inode_missing(op_errno)) { +        gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                     prev->name); +        goto out; +    } -        ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **) &stbuf); +    if (local->call_cnt != 1) +        goto out; -        if ((!op_ret) && !stbuf) { -                goto out; -        } +    ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&stbuf); -        local->op_ret = 0; +    if ((!op_ret) && !stbuf) { +        goto out; +    } -        local->rebalance.target_op_fn = dht_removexattr2; -        if (xdata) -                local->rebalance.xdata = dict_ref (xdata); +    local->op_ret = 0; -        /* Phase 2 of migration */ -        if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) { -                ret = dht_rebalance_complete_check (this, frame); -                if (!ret) -                        return 0; -        } +    local->rebalance.target_op_fn = dht_removexattr2; +    if (xdata) +        local->rebalance.xdata = dict_ref(xdata); -        /* Phase 1 of migration */ -        if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { -                inode = (local->fd) ? local->fd->inode : local->loc.inode; +    /* Phase 2 of migration */ +    if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2(stbuf)) { +        ret = dht_rebalance_complete_check(this, frame); +        if (!ret) +            return 0; +    } -                ret = dht_inode_ctx_get_mig_info (this, inode, -                                                  &subvol1, &subvol2); -                if (!dht_mig_info_is_invalid (local->cached_subvol, -                                              subvol1, subvol2)) { -                        dht_removexattr2 (this, subvol2, frame, 0); -                        return 0; -                } +    /* Phase 1 of migration */ +    if (IS_DHT_MIGRATION_PHASE1(stbuf)) { +        inode = (local->fd) ? local->fd->inode : local->loc.inode; -                ret = dht_rebalance_in_progress_check (this, frame); -                if (!ret) -                        return 0; +        ret = dht_inode_ctx_get_mig_info(this, inode, &subvol1, &subvol2); +        if (!dht_mig_info_is_invalid(local->cached_subvol, subvol1, subvol2)) { +            dht_removexattr2(this, subvol2, frame, 0); +            return 0;          } -out: -        if (local->fop == GF_FOP_REMOVEXATTR) { -                DHT_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata); -        } else { -                DHT_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata); -        } -        return 0; +        ret = dht_rebalance_in_progress_check(this, frame); +        if (!ret) +            return 0; +    } +out: +    if (local->fop == GF_FOP_REMOVEXATTR) { +        DHT_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); +    } else { +        DHT_STACK_UNWIND(fremovexattr, frame, op_ret, op_errno, xdata); +    } +    return 0;  }  int -dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, -                  int ret) +dht_removexattr2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)  { -        dht_local_t *local    = NULL; -        int          op_errno = EINVAL; - -        if (!frame || !frame->local) -                goto err; - -        local = frame->local; -        op_errno = local->op_errno; +    dht_local_t *local = NULL; +    int op_errno = EINVAL; -        local->call_cnt = 2; /* This is the second attempt */ +    if (!frame || !frame->local) +        goto err; -        if (we_are_not_migrating (ret)) { +    local = frame->local; +    op_errno = local->op_errno; -                /* This dht xlator is not migrating the file. Unwind and -                 * pass on the original mode bits so the higher DHT layer -                 * can handle this. -                 */ -                DHT_STACK_UNWIND (removexattr, frame, local->op_ret, -                                  local->op_errno, local->rebalance.xdata); -                return 0; -        } +    local->call_cnt = 2; /* This is the second attempt */ -        if (subvol == NULL) -                goto err; - -        if (local->fop == GF_FOP_REMOVEXATTR) { -                STACK_WIND_COOKIE (frame, dht_file_removexattr_cbk, subvol, -                                   subvol, subvol->fops->removexattr, -                                   &local->loc, local->key, local->xattr_req); -        } else { -                STACK_WIND_COOKIE (frame, dht_file_removexattr_cbk, subvol, -                                   subvol, subvol->fops->fremovexattr, -                                   local->fd, local->key, local->xattr_req); -        } - -        return 0; - -err: -        DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); +    if (we_are_not_migrating(ret)) { +        /* This dht xlator is not migrating the file. Unwind and +         * pass on the original mode bits so the higher DHT layer +         * can handle this. +         */ +        DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, +                         local->rebalance.xdata);          return 0; -} - - -int -dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                     int op_ret, int op_errno, dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev = NULL; +    } -        local = frame->local; -        prev = cookie; - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "subvolume %s returned -1", -                                      prev->name); -                        goto unlock; -                } +    if (subvol == NULL) +        goto err; -                local->op_ret = 0; -        } -unlock: -        UNLOCK (&frame->lock); +    if (local->fop == GF_FOP_REMOVEXATTR) { +        STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, +                          subvol->fops->removexattr, &local->loc, local->key, +                          local->xattr_req); +    } else { +        STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, +                          subvol->fops->fremovexattr, local->fd, local->key, +                          local->xattr_req); +    } -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                DHT_STACK_UNWIND (removexattr, frame, local->op_ret, -                                  local->op_errno, NULL); -        } +    return 0; -        return 0; +err: +    DHT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); +    return 0;  } -  int -dht_removexattr (call_frame_t *frame, xlator_t *this, -                 loc_t *loc, const char *key, dict_t *xdata) +dht_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                    int op_ret, int op_errno, dict_t *xdata)  { -        xlator_t     *subvol = NULL; -        int           op_errno = -1; -        dht_local_t  *local = NULL; -        dht_layout_t *layout = NULL; -        int           call_cnt = 0; -        dht_conf_t   *conf = NULL; -        int           ret = 0; - -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (this->private, err); +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; -        conf = this->private; +    local = frame->local; +    prev = cookie; -        GF_IF_NATIVE_XATTR_GOTO (conf->wild_xattr_name, key, op_errno, err); - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); - -        local = dht_local_init (frame, loc, NULL, GF_FOP_REMOVEXATTR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        subvol = local->cached_subvol; -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for path=%s", loc->path); -                op_errno = EINVAL; -                goto err; -        } - -        layout = local->layout; -        if (!local->layout) { -                gf_msg_debug (this->name, 0, -                              "no layout for path=%s", loc->path); -                op_errno = EINVAL; -                goto err; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                         prev->name); +            goto unlock;          } -        local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); -        local->call_cnt = call_cnt = layout->cnt; -        local->key = gf_strdup (key); +        local->op_ret = 0; +    } +unlock: +    UNLOCK(&frame->lock); + +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        DHT_STACK_UNWIND(removexattr, frame, local->op_ret, local->op_errno, +                         NULL); +    } + +    return 0; +} + +int +dht_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, +                const char *key, dict_t *xdata) +{ +    xlator_t *subvol = NULL; +    int op_errno = -1; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; +    int call_cnt = 0; +    dht_conf_t *conf = NULL; +    int ret = 0; + +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    GF_IF_NATIVE_XATTR_GOTO(conf->wild_xattr_name, key, op_errno, err); + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); + +    local = dht_local_init(frame, loc, NULL, GF_FOP_REMOVEXATTR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } + +    subvol = local->cached_subvol; +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", +                     loc->path); +        op_errno = EINVAL; +        goto err; +    } + +    layout = local->layout; +    if (!local->layout) { +        gf_msg_debug(this->name, 0, "no layout for path=%s", loc->path); +        op_errno = EINVAL; +        goto err; +    } +    local->xattr_req = (xdata) ? dict_ref(xdata) : dict_new(); + +    local->call_cnt = call_cnt = layout->cnt; +    local->key = gf_strdup(key); + +    if (key && (strncmp(key, conf->mds_xattr_key, strlen(key)) == 0)) { +        op_errno = ENOTSUP; +        goto err; +    } + +    if (IA_ISDIR(loc->inode->ia_type)) { +        local->hashed_subvol = NULL; +        ret = dht_dir_common_set_remove_xattr(frame, this, loc, NULL, NULL, 0, +                                              local->xattr_req, &op_errno); +        if (ret) +            goto err; -        if (key && -            (strncmp (key, conf->mds_xattr_key, strlen(key)) == 0)) { -                op_errno = ENOTSUP; -                goto err; +    } else { +        local->call_cnt = 1; +        ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); +        if (ret) { +            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, +                   "Failed to " +                   "set dictionary key %s for %s", +                   DHT_IATT_IN_XDATA_KEY, loc->path);          } -        if (IA_ISDIR (loc->inode->ia_type)) { -                local->hashed_subvol = NULL; -                ret = dht_dir_common_set_remove_xattr (frame, this, loc, NULL, -                                                       NULL, 0, local->xattr_req, &op_errno); -                if (ret) -                        goto err; +        STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, +                          subvol->fops->removexattr, loc, key, +                          local->xattr_req); +    } -        } else { - -                local->call_cnt = 1; -                ret = dict_set_int8 (local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); -                if (ret) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                DHT_MSG_DICT_SET_FAILED, "Failed to " -                                "set dictionary key %s for %s", -                                DHT_IATT_IN_XDATA_KEY, loc->path); -                } - -                STACK_WIND_COOKIE (frame, dht_file_removexattr_cbk, subvol, -                                   subvol, subvol->fops->removexattr, loc, key, -                                   local->xattr_req); -        } - -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(removexattr, frame, -1, op_errno, NULL); -        return 0; +    return 0;  }  int -dht_fremovexattr (call_frame_t *frame, xlator_t *this, -                  fd_t *fd, const char *key, dict_t *xdata) +dht_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key, +                 dict_t *xdata)  { -        xlator_t     *subvol = NULL; -        int           op_errno = -1; -        dht_local_t  *local = NULL; -        dht_layout_t *layout = NULL; -        int           call_cnt = 0; -        dht_conf_t   *conf = 0; -        int           ret = 0; - - -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf = this->private; - -        GF_IF_NATIVE_XATTR_GOTO (conf->wild_xattr_name, key, op_errno, err); - -        VALIDATE_OR_GOTO (frame, err); - -        local = dht_local_init (frame, NULL, fd, GF_FOP_FREMOVEXATTR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        subvol = local->cached_subvol; -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for inode=%s", -                              uuid_utoa (fd->inode->gfid)); -                op_errno = EINVAL; -                goto err; -        } +    xlator_t *subvol = NULL; +    int op_errno = -1; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; +    int call_cnt = 0; +    dht_conf_t *conf = 0; +    int ret = 0; + +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    GF_IF_NATIVE_XATTR_GOTO(conf->wild_xattr_name, key, op_errno, err); + +    VALIDATE_OR_GOTO(frame, err); + +    local = dht_local_init(frame, NULL, fd, GF_FOP_FREMOVEXATTR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } + +    subvol = local->cached_subvol; +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for inode=%s", +                     uuid_utoa(fd->inode->gfid)); +        op_errno = EINVAL; +        goto err; +    } + +    layout = local->layout; +    if (!local->layout) { +        gf_msg_debug(this->name, 0, "no layout for inode=%s", +                     uuid_utoa(fd->inode->gfid)); +        op_errno = EINVAL; +        goto err; +    } +    local->xattr_req = xdata ? dict_ref(xdata) : dict_new(); + +    local->call_cnt = call_cnt = layout->cnt; +    local->key = gf_strdup(key); + +    if (IA_ISDIR(fd->inode->ia_type)) { +        local->hashed_subvol = NULL; +        ret = dht_dir_common_set_remove_xattr(frame, this, NULL, fd, NULL, 0, +                                              local->xattr_req, &op_errno); +        if (ret) +            goto err; -        layout = local->layout; -        if (!local->layout) { -                gf_msg_debug (this->name, 0, -                              "no layout for inode=%s", -                              uuid_utoa (fd->inode->gfid)); -                op_errno = EINVAL; -                goto err; +    } else { +        local->call_cnt = 1; +        ret = dict_set_int8(local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); +        if (ret) { +            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, +                   "Failed to " +                   "set dictionary key %s for fd=%p", +                   DHT_IATT_IN_XDATA_KEY, fd);          } -        local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); - -        local->call_cnt = call_cnt = layout->cnt; -        local->key = gf_strdup (key); - -        if (IA_ISDIR (fd->inode->ia_type)) { -                local->hashed_subvol = NULL; -                ret = dht_dir_common_set_remove_xattr (frame, this, NULL, fd, -                                                       NULL, 0, local->xattr_req, &op_errno); -                if (ret) -                        goto err; - -        } else { - -                local->call_cnt = 1; -                ret = dict_set_int8 (local->xattr_req, DHT_IATT_IN_XDATA_KEY, 1); -                if (ret) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                DHT_MSG_DICT_SET_FAILED, "Failed to " -                                "set dictionary key %s for fd=%p", -                                DHT_IATT_IN_XDATA_KEY, fd); -                } -                STACK_WIND_COOKIE (frame, dht_file_removexattr_cbk, subvol, -                                   subvol, subvol->fops->fremovexattr, fd, key, -                                   local->xattr_req); -        } +        STACK_WIND_COOKIE(frame, dht_file_removexattr_cbk, subvol, subvol, +                          subvol->fops->fremovexattr, fd, key, +                          local->xattr_req); +    } -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(fremovexattr, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } -  int -dht_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -            int op_ret, int op_errno, fd_t *fd, dict_t *xdata) +dht_fd_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +           int op_errno, fd_t *fd, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev = NULL; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; -        local = frame->local; -        prev = cookie; - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        gf_msg_debug (this->name, op_errno, -                                      "subvolume %s returned -1", -                                      prev->name); -                        goto unlock; -                } +    local = frame->local; +    prev = cookie; -                local->op_ret = 0; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            local->op_errno = op_errno; +            gf_msg_debug(this->name, op_errno, "subvolume %s returned -1", +                         prev->name); +            goto unlock;          } + +        local->op_ret = 0; +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) -                DHT_STACK_UNWIND (open, frame, local->op_ret, local->op_errno, -                                  local->fd, NULL); +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) +        DHT_STACK_UNWIND(open, frame, local->op_ret, local->op_errno, local->fd, +                         NULL); -        return 0; +    return 0;  }  /*   * dht_normalize_stats -   */  void -dht_normalize_stats (struct statvfs *buf, unsigned long bsize, -                     unsigned long frsize) +dht_normalize_stats(struct statvfs *buf, unsigned long bsize, +                    unsigned long frsize)  { -        double factor = 0; +    double factor = 0; -        if (buf->f_bsize != bsize) { -                buf->f_bsize = bsize; -        } - -        if (buf->f_frsize != frsize) { -                factor = ((double) buf->f_frsize) / frsize; -                buf->f_frsize = frsize; -                buf->f_blocks = (fsblkcnt_t) (factor * buf->f_blocks); -                buf->f_bfree  = (fsblkcnt_t) (factor * buf->f_bfree); -                buf->f_bavail = (fsblkcnt_t) (factor * buf->f_bavail); +    if (buf->f_bsize != bsize) { +        buf->f_bsize = bsize; +    } -        } +    if (buf->f_frsize != frsize) { +        factor = ((double)buf->f_frsize) / frsize; +        buf->f_frsize = frsize; +        buf->f_blocks = (fsblkcnt_t)(factor * buf->f_blocks); +        buf->f_bfree = (fsblkcnt_t)(factor * buf->f_bfree); +        buf->f_bavail = (fsblkcnt_t)(factor * buf->f_bavail); +    }  }  int -dht_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                int op_ret, int op_errno, struct statvfs *statvfs, -                dict_t *xdata) +dht_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +               int op_errno, struct statvfs *statvfs, dict_t *xdata)  { +    gf_boolean_t event = _gf_false; +    qdstatfs_action_t action = qdstatfs_action_OFF; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    int bsize = 0; +    int frsize = 0; +    GF_UNUSED int ret = 0; +    unsigned long new_usage = 0; +    unsigned long cur_usage = 0; -        gf_boolean_t            event              = _gf_false; -        qdstatfs_action_t       action             = qdstatfs_action_OFF; -        dht_local_t *           local              = NULL; -        int                     this_call_cnt      = 0; -        int                     bsize              = 0; -        int                     frsize             = 0; -        GF_UNUSED int           ret                = 0; -        unsigned long           new_usage          = 0; -        unsigned long           cur_usage          = 0; +    local = frame->local; +    GF_ASSERT(local); -        local = frame->local; -        GF_ASSERT (local); +    if (xdata) +        ret = dict_get_int8(xdata, "quota-deem-statfs", (int8_t *)&event); -        if (xdata) -                ret = dict_get_int8 (xdata, "quota-deem-statfs", -                                     (int8_t *)&event); - -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        goto unlock; -                } -                if (!statvfs) { -                        op_errno = EINVAL; -                        local->op_ret = -1; -                        goto unlock; -                } -                local->op_ret = 0; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            local->op_errno = op_errno; +            goto unlock; +        } +        if (!statvfs) { +            op_errno = EINVAL; +            local->op_ret = -1; +            goto unlock; +        } +        local->op_ret = 0; -                if (local->quota_deem_statfs) { -                        if (event == _gf_true) { -                                action = qdstatfs_action_COMPARE; -                        } else { -                                action = qdstatfs_action_NEGLECT; -                        } -                } else { -                        if (event == _gf_true) { -                                action = qdstatfs_action_REPLACE; -                                local->quota_deem_statfs = _gf_true; -                        } -                } +        if (local->quota_deem_statfs) { +            if (event == _gf_true) { +                action = qdstatfs_action_COMPARE; +            } else { +                action = qdstatfs_action_NEGLECT; +            } +        } else { +            if (event == _gf_true) { +                action = qdstatfs_action_REPLACE; +                local->quota_deem_statfs = _gf_true; +            } +        } -                if (local->quota_deem_statfs) { -                        switch (action) { -                        case qdstatfs_action_NEGLECT: -                                goto unlock; - -                        case qdstatfs_action_REPLACE: -                                local->statvfs = *statvfs; -                                goto unlock; - -                        case qdstatfs_action_COMPARE: -                                new_usage = statvfs->f_blocks - -                                             statvfs->f_bfree; -                                cur_usage = local->statvfs.f_blocks - -                                             local->statvfs.f_bfree; - -                                /* Take the max of the usage from subvols */ -                                if (new_usage >= cur_usage) -                                        local->statvfs = *statvfs; -                                goto unlock; - -                        default: -                                break; -                        } -                } +        if (local->quota_deem_statfs) { +            switch (action) { +                case qdstatfs_action_NEGLECT: +                    goto unlock; -                if (local->statvfs.f_bsize != 0) { -                        bsize = max(local->statvfs.f_bsize, statvfs->f_bsize); -                        frsize = max(local->statvfs.f_frsize, statvfs->f_frsize); -                        dht_normalize_stats(&local->statvfs, bsize, frsize); -                        dht_normalize_stats(statvfs, bsize, frsize); -                } else { -                        local->statvfs.f_bsize    = statvfs->f_bsize; -                        local->statvfs.f_frsize   = statvfs->f_frsize; -                } +                case qdstatfs_action_REPLACE: +                    local->statvfs = *statvfs; +                    goto unlock; -                local->statvfs.f_blocks  += statvfs->f_blocks; -                local->statvfs.f_bfree   += statvfs->f_bfree; -                local->statvfs.f_bavail  += statvfs->f_bavail; -                local->statvfs.f_files   += statvfs->f_files; -                local->statvfs.f_ffree   += statvfs->f_ffree; -                local->statvfs.f_favail  += statvfs->f_favail; -                local->statvfs.f_fsid     = statvfs->f_fsid; -                local->statvfs.f_flag     = statvfs->f_flag; -                local->statvfs.f_namemax  = statvfs->f_namemax; +                case qdstatfs_action_COMPARE: +                    new_usage = statvfs->f_blocks - statvfs->f_bfree; +                    cur_usage = local->statvfs.f_blocks - +                                local->statvfs.f_bfree; +                    /* Take the max of the usage from subvols */ +                    if (new_usage >= cur_usage) +                        local->statvfs = *statvfs; +                    goto unlock; +                default: +                    break; +            }          } -unlock: -        UNLOCK (&frame->lock); +        if (local->statvfs.f_bsize != 0) { +            bsize = max(local->statvfs.f_bsize, statvfs->f_bsize); +            frsize = max(local->statvfs.f_frsize, statvfs->f_frsize); +            dht_normalize_stats(&local->statvfs, bsize, frsize); +            dht_normalize_stats(statvfs, bsize, frsize); +        } else { +            local->statvfs.f_bsize = statvfs->f_bsize; +            local->statvfs.f_frsize = statvfs->f_frsize; +        } + +        local->statvfs.f_blocks += statvfs->f_blocks; +        local->statvfs.f_bfree += statvfs->f_bfree; +        local->statvfs.f_bavail += statvfs->f_bavail; +        local->statvfs.f_files += statvfs->f_files; +        local->statvfs.f_ffree += statvfs->f_ffree; +        local->statvfs.f_favail += statvfs->f_favail; +        local->statvfs.f_fsid = statvfs->f_fsid; +        local->statvfs.f_flag = statvfs->f_flag; +        local->statvfs.f_namemax = statvfs->f_namemax; +    } +unlock: +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) -                DHT_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno, -                                  &local->statvfs, xdata); +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) +        DHT_STACK_UNWIND(statfs, frame, local->op_ret, local->op_errno, +                         &local->statvfs, xdata); -        return 0; +    return 0;  } -  int -dht_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +dht_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)  { -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           op_errno = -1; -        int           i = -1; -        inode_t          *inode         = NULL; -        inode_table_t    *itable        = NULL; -        uuid_t            root_gfid     = {0, }; -        loc_t         newloc = {0, }; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = -1; +    int i = -1; +    inode_t *inode = NULL; +    inode_table_t *itable = NULL; +    uuid_t root_gfid = { +        0, +    }; +    loc_t newloc = { +        0, +    }; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (this->private, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(this->private, err); -        conf = this->private; +    conf = this->private; -        local = dht_local_init (frame, NULL, NULL, GF_FOP_STATFS); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        if (loc->inode && !IA_ISDIR (loc->inode->ia_type)) { -                itable = loc->inode->table; -                if (!itable) { -                        op_errno = EINVAL; -                        goto err; -                } +    local = dht_local_init(frame, NULL, NULL, GF_FOP_STATFS); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -                loc = &local->loc2; -                root_gfid[15] = 1; +    if (loc->inode && !IA_ISDIR(loc->inode->ia_type)) { +        itable = loc->inode->table; +        if (!itable) { +            op_errno = EINVAL; +            goto err; +        } -                inode = inode_find (itable, root_gfid); -                if (!inode) { -                        op_errno = EINVAL; -                        goto err; -                } +        loc = &local->loc2; +        root_gfid[15] = 1; -                dht_build_root_loc (inode, &newloc); -                loc = &newloc; +        inode = inode_find(itable, root_gfid); +        if (!inode) { +            op_errno = EINVAL; +            goto err;          } -        local->call_cnt = conf->subvolume_cnt; +        dht_build_root_loc(inode, &newloc); +        loc = &newloc; +    } -        for (i = 0; i < conf->subvolume_cnt; i++) { -                STACK_WIND (frame, dht_statfs_cbk, -                            conf->subvolumes[i], -                            conf->subvolumes[i]->fops->statfs, loc, -                            xdata); -        } -        return 0; +    local->call_cnt = conf->subvolume_cnt; + +    for (i = 0; i < conf->subvolume_cnt; i++) { +        STACK_WIND(frame, dht_statfs_cbk, conf->subvolumes[i], +                   conf->subvolumes[i]->fops->statfs, loc, xdata); +    } +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(statfs, frame, -1, op_errno, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, -             dict_t *xdata) +dht_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, +            dict_t *xdata)  { -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           op_errno = -1; -        int           i = -1; -        int           ret = 0; -        gf_boolean_t  new_xdata = _gf_false; -        xlator_t    **subvolumes = NULL; -        int           call_count = 0; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf = this->private; - -        local = dht_local_init (frame, loc, fd, GF_FOP_OPENDIR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } -        local->first_up_subvol = dht_first_up_subvol (this); - +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = -1; +    int i = -1; +    int ret = 0; +    gf_boolean_t new_xdata = _gf_false; +    xlator_t **subvolumes = NULL; +    int call_count = 0; + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(this->private, err); + +    conf = this->private; + +    local = dht_local_init(frame, loc, fd, GF_FOP_OPENDIR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } +    local->first_up_subvol = dht_first_up_subvol(this); + +    if (!xdata) { +        xdata = dict_new();          if (!xdata) { -                xdata = dict_new (); -                if (!xdata) { -                        op_errno = ENOMEM; -                        goto err; -                } -                new_xdata = _gf_true; +            op_errno = ENOMEM; +            goto err; +        } +        new_xdata = _gf_true; +    } + +    ret = dict_set_uint32(xdata, conf->link_xattr_name, 256); +    if (ret) +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value : key = %s", +               conf->link_xattr_name); + +    /* dht_readdirp will wind to all subvols so open has to be sent to +     * all subvols whether or not conf->local_subvols is set */ + +    call_count = local->call_cnt = conf->subvolume_cnt; +    subvolumes = conf->subvolumes; + +    /* In case of parallel-readdir, the readdir-ahead will be loaded +     * below dht, in this case, if we want to enable or disable SKIP_DIRs +     * it has to be done in opendir, so that prefetching logic in +     * readdir-ahead, honors it */ +    for (i = 0; i < call_count; i++) { +        if (conf->readdir_optimize == _gf_true) { +            if (subvolumes[i] != local->first_up_subvol) { +                ret = dict_set_int32(xdata, GF_READDIR_SKIP_DIRS, 1); +                if (ret) +                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +                           "Failed to set dictionary" +                           " value :key = %s, ret:%d", +                           GF_READDIR_SKIP_DIRS, ret); +            }          } -        ret = dict_set_uint32 (xdata, conf->link_xattr_name, 256); -        if (ret) -                gf_msg (this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value : key = %s", -                        conf->link_xattr_name); - -        /* dht_readdirp will wind to all subvols so open has to be sent to -         * all subvols whether or not conf->local_subvols is set */ - -        call_count = local->call_cnt = conf->subvolume_cnt; -        subvolumes = conf->subvolumes; - -        /* In case of parallel-readdir, the readdir-ahead will be loaded -         * below dht, in this case, if we want to enable or disable SKIP_DIRs -         * it has to be done in opendir, so that prefetching logic in -         * readdir-ahead, honors it */ -        for (i = 0; i < call_count; i++) { -                if (conf->readdir_optimize == _gf_true) { -                        if (subvolumes[i] != local->first_up_subvol) { -                                ret = dict_set_int32 (xdata, -                                                      GF_READDIR_SKIP_DIRS, 1); -                                if (ret) -                                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                                DHT_MSG_DICT_SET_FAILED, -                                                "Failed to set dictionary" -                                                " value :key = %s, ret:%d", -                                                GF_READDIR_SKIP_DIRS, ret); -                                } -                } +        STACK_WIND_COOKIE(frame, dht_fd_cbk, subvolumes[i], subvolumes[i], +                          subvolumes[i]->fops->opendir, loc, fd, xdata); +        dict_del(xdata, GF_READDIR_SKIP_DIRS); +    } -                STACK_WIND_COOKIE (frame, dht_fd_cbk, -                                   subvolumes[i], -                                   subvolumes[i], -                                   subvolumes[i]->fops->opendir, -                                   loc, fd, xdata); -                dict_del (xdata, GF_READDIR_SKIP_DIRS); -        } +    if (new_xdata) +        dict_unref(xdata); -        if (new_xdata) -                dict_unref (xdata); - -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(opendir, frame, -1, op_errno, NULL, NULL); -        return 0; +    return 0;  } -  /* dht_readdirp_cbk creates a new dentry and dentry->inode is not assigned.     This functions assigns an inode if all of the following conditions are true: @@ -6937,3807 +6504,3589 @@ err:  */  void -dht_populate_inode_for_dentry (xlator_t *this, xlator_t *subvol, -                               gf_dirent_t *entry, gf_dirent_t *orig_entry) +dht_populate_inode_for_dentry(xlator_t *this, xlator_t *subvol, +                              gf_dirent_t *entry, gf_dirent_t *orig_entry)  { -        dht_layout_t *layout = NULL; -        int           ret    = 0; -        loc_t         loc    = {0, }; - -        if (gf_uuid_is_null (orig_entry->d_stat.ia_gfid)) { -                /* this skips the '..' entry for the root of the volume */ -                return; -        } +    dht_layout_t *layout = NULL; +    int ret = 0; +    loc_t loc = { +        0, +    }; -        gf_uuid_copy (loc.gfid, orig_entry->d_stat.ia_gfid); -        loc.inode = inode_ref (orig_entry->inode); +    if (gf_uuid_is_null(orig_entry->d_stat.ia_gfid)) { +        /* this skips the '..' entry for the root of the volume */ +        return; +    } -        if (is_revalidate (&loc)) { -                goto out; -        } +    gf_uuid_copy(loc.gfid, orig_entry->d_stat.ia_gfid); +    loc.inode = inode_ref(orig_entry->inode); -        layout = dht_layout_new (this, 1); -        if (!layout) -                goto out; +    if (is_revalidate(&loc)) { +        goto out; +    } -        ret = dht_layout_merge (this, layout, subvol, 0, 0, orig_entry->dict); -        if (!ret) { -                ret = dht_layout_normalize (this, &loc, layout); -                if (ret == 0) { -                        dht_layout_set (this, orig_entry->inode, layout); -                        entry->inode = inode_ref (orig_entry->inode); -                        layout = NULL; -                } +    layout = dht_layout_new(this, 1); +    if (!layout) +        goto out; +    ret = dht_layout_merge(this, layout, subvol, 0, 0, orig_entry->dict); +    if (!ret) { +        ret = dht_layout_normalize(this, &loc, layout); +        if (ret == 0) { +            dht_layout_set(this, orig_entry->inode, layout); +            entry->inode = inode_ref(orig_entry->inode); +            layout = NULL;          } +    } -        if (layout) -                dht_layout_unref (this, layout); +    if (layout) +        dht_layout_unref(this, layout);  out: -        loc_wipe (&loc); -        return; +    loc_wipe(&loc); +    return;  } -  /* Posix returns op_errno = ENOENT to indicate that there are no more entries   */  int -dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, -                  int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) -{ -        dht_local_t             *local = NULL; -        gf_dirent_t              entries; -        gf_dirent_t             *orig_entry = NULL; -        gf_dirent_t             *entry = NULL; -        xlator_t                *prev = NULL; -        xlator_t                *next_subvol = NULL; -        off_t                    next_offset = 0; -        int                      count = 0; -        dht_layout_t            *layout = NULL; -        dht_conf_t              *conf   = NULL; -        dht_methods_t           *methods = NULL; -        xlator_t                *subvol = 0; -        xlator_t                *hashed_subvol = 0; -        int                      ret    = 0; -        int                      readdir_optimize = 0; -        inode_table_t           *itable = NULL; -        inode_t                 *inode = NULL; -        gf_boolean_t             skip_hashed_check = _gf_false; - -        INIT_LIST_HEAD (&entries.list); - -        prev = cookie; -        local = frame->local; -        itable = local->fd ? local->fd->inode->table : NULL; +dht_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                 int op_errno, gf_dirent_t *orig_entries, dict_t *xdata) +{ +    dht_local_t *local = NULL; +    gf_dirent_t entries; +    gf_dirent_t *orig_entry = NULL; +    gf_dirent_t *entry = NULL; +    xlator_t *prev = NULL; +    xlator_t *next_subvol = NULL; +    off_t next_offset = 0; +    int count = 0; +    dht_layout_t *layout = NULL; +    dht_conf_t *conf = NULL; +    dht_methods_t *methods = NULL; +    xlator_t *subvol = 0; +    xlator_t *hashed_subvol = 0; +    int ret = 0; +    int readdir_optimize = 0; +    inode_table_t *itable = NULL; +    inode_t *inode = NULL; +    gf_boolean_t skip_hashed_check = _gf_false; + +    INIT_LIST_HEAD(&entries.list); + +    prev = cookie; +    local = frame->local; +    itable = local->fd ? local->fd->inode->table : NULL; + +    conf = this->private; +    GF_VALIDATE_OR_GOTO(this->name, conf, unwind); + +    methods = &(conf->methods); + +    if (op_ret <= 0) { +        goto done; +    } + +    /* Why aren't we skipping DHT entirely in case of a single subvol? +     * Because if this was a larger volume earlier and all but one subvol +     * was removed, there might be stale linkto files on the subvol. +     */ +    if (conf->subvolume_cnt == 1) { +        /* return all directory and file entries except +         * linkto files for a single child DHT +         */ +        skip_hashed_check = _gf_true; +    } -        conf  = this->private; -        GF_VALIDATE_OR_GOTO(this->name, conf, unwind); +    if (!local->layout) +        local->layout = dht_layout_get(this, local->fd->inode); -        methods = &(conf->methods); +    layout = local->layout; -        if (op_ret <= 0) { -                goto done; -        } +    /* We have seen crashes in while running "rm -rf" on tier volumes +       when the layout was NULL on the hot tier. This will skip the +       entries on the subvol without a layout, hence preventing the crash +       but rmdir might fail with "directory not empty" errors*/ -        /* Why aren't we skipping DHT entirely in case of a single subvol? -         * Because if this was a larger volume earlier and all but one subvol -         * was removed, there might be stale linkto files on the subvol. -         */ -        if (conf->subvolume_cnt == 1) { -                /* return all directory and file entries except -                 * linkto files for a single child DHT -                 */ -                skip_hashed_check = _gf_true; -        } - -        if (!local->layout) -                local->layout = dht_layout_get (this, local->fd->inode); +    if (layout == NULL) +        goto done; -        layout = local->layout; +    if (conf->readdir_optimize == _gf_true) +        readdir_optimize = 1; -        /* We have seen crashes in while running "rm -rf" on tier volumes -           when the layout was NULL on the hot tier. This will skip the -           entries on the subvol without a layout, hence preventing the crash -           but rmdir might fail with "directory not empty" errors*/ - -        if (layout == NULL) -                goto done; +    gf_msg_debug(this->name, 0, "Processing entries from %s", prev->name); -        if (conf->readdir_optimize == _gf_true) -                readdir_optimize = 1; +    list_for_each_entry(orig_entry, (&orig_entries->list), list) +    { +        next_offset = orig_entry->d_off; -        gf_msg_debug (this->name, 0, "Processing entries from %s", -                      prev->name); +        gf_msg_debug(this->name, 0, "%s: entry = %s, type = %d", prev->name, +                     orig_entry->d_name, orig_entry->d_type); -        list_for_each_entry (orig_entry, (&orig_entries->list), list) { -                next_offset = orig_entry->d_off; +        if (IA_ISINVAL(orig_entry->d_stat.ia_type)) { +            /*stat failed somewhere- ignore this entry*/ +            gf_msg_debug(this->name, EINVAL, +                         "Invalid stat, ignoring entry " +                         "%s gfid %s", +                         orig_entry->d_name, +                         uuid_utoa(orig_entry->d_stat.ia_gfid)); +            continue; +        } -                gf_msg_debug (this->name, 0, "%s: entry = %s, type = %d", -                              prev->name, orig_entry->d_name, -                              orig_entry->d_type); +        if (check_is_linkfile(NULL, (&orig_entry->d_stat), orig_entry->dict, +                              conf->link_xattr_name)) { +            gf_msg_debug(this->name, 0, "%s: %s is a linkto file", prev->name, +                         orig_entry->d_name); +            continue; +        } -                if (IA_ISINVAL(orig_entry->d_stat.ia_type)) { -                        /*stat failed somewhere- ignore this entry*/ -                        gf_msg_debug (this->name, EINVAL, -                                      "Invalid stat, ignoring entry " -                                      "%s gfid %s", orig_entry->d_name, -                                      uuid_utoa (orig_entry->d_stat.ia_gfid)); -                        continue; -                } +        if (skip_hashed_check) { +            goto list; +        } -                if (check_is_linkfile (NULL, (&orig_entry->d_stat), -                                       orig_entry->dict, -                                       conf->link_xattr_name)) { -                        gf_msg_debug (this->name, 0, "%s: %s is a linkto file", -                                      prev->name, orig_entry->d_name); -                        continue; -                } +        if (check_is_dir(NULL, (&orig_entry->d_stat), NULL)) { +            /*Directory entries filtering : +             * a) If rebalance is running, pick from first_up_subvol +             * b) (rebalance not running)hashed subvolume is NULL or +             * down then filter in first_up_subvolume. Other wise the +             * corresponding hashed subvolume will take care of the +             * directory entry. +             */ +            if (readdir_optimize) { +                if (prev == local->first_up_subvol) +                    goto list; +                else +                    continue; +            } -                if (skip_hashed_check) { -                        goto list; -                } +            hashed_subvol = methods->layout_search(this, layout, +                                                   orig_entry->d_name); -                if (check_is_dir (NULL, (&orig_entry->d_stat), NULL)) { +            if (prev == hashed_subvol) +                goto list; +            if ((hashed_subvol && dht_subvol_status(conf, hashed_subvol)) || +                (prev != local->first_up_subvol)) +                continue; -                /*Directory entries filtering : -                 * a) If rebalance is running, pick from first_up_subvol -                 * b) (rebalance not running)hashed subvolume is NULL or -                 * down then filter in first_up_subvolume. Other wise the -                 * corresponding hashed subvolume will take care of the -                 * directory entry. -                 */ -                        if (readdir_optimize) { -                                if (prev == local->first_up_subvol) -                                        goto list; -                                else -                                        continue; +            goto list; +        } -                        } +    list: +        entry = gf_dirent_for_name(orig_entry->d_name); +        if (!entry) { +            goto unwind; +        } -                        hashed_subvol = methods->layout_search (this, layout, -                                                         orig_entry->d_name); +        /* Do this if conf->search_unhashed is set to "auto" */ +        if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) { +            subvol = methods->layout_search(this, layout, orig_entry->d_name); +            if (!subvol || (subvol != prev)) { +                /* TODO: Count the number of entries which need +                   linkfile to prove its existence in fs */ +                layout->search_unhashed++; +            } +        } -                        if (prev == hashed_subvol) -                                goto list; -                        if ((hashed_subvol -                             && dht_subvol_status (conf, hashed_subvol)) -                            || (prev != local->first_up_subvol)) -                                continue; +        entry->d_off = orig_entry->d_off; +        entry->d_stat = orig_entry->d_stat; +        entry->d_ino = orig_entry->d_ino; +        entry->d_type = orig_entry->d_type; +        entry->d_len = orig_entry->d_len; -                        goto list; -                } +        if (orig_entry->dict) +            entry->dict = dict_ref(orig_entry->dict); -list: -                entry = gf_dirent_for_name (orig_entry->d_name); -                if (!entry) { -                        goto unwind; -                } +        /* making sure we set the inode ctx right with layout, +           currently possible only for non-directories, so for +           directories don't set entry inodes */ +        if (IA_ISDIR(entry->d_stat.ia_type)) { +            entry->d_stat.ia_blocks = DHT_DIR_STAT_BLOCKS; +            entry->d_stat.ia_size = DHT_DIR_STAT_SIZE; +            if (orig_entry->inode) { +                dht_inode_ctx_time_update(orig_entry->inode, this, +                                          &entry->d_stat, 1); -                /* Do this if conf->search_unhashed is set to "auto" */ -                if (conf->search_unhashed == GF_DHT_LOOKUP_UNHASHED_AUTO) { -                        subvol = methods->layout_search (this, layout, -                                                         orig_entry->d_name); -                        if (!subvol || (subvol != prev)) { -                                /* TODO: Count the number of entries which need -                                   linkfile to prove its existence in fs */ -                                layout->search_unhashed++; -                        } +                if (conf->subvolume_cnt == 1) { +                    dht_populate_inode_for_dentry(this, prev, entry, +                                                  orig_entry);                  } - -                entry->d_off  = orig_entry->d_off; -                entry->d_stat = orig_entry->d_stat; -                entry->d_ino  = orig_entry->d_ino; -                entry->d_type = orig_entry->d_type; -                entry->d_len  = orig_entry->d_len; - -                if (orig_entry->dict) -                        entry->dict = dict_ref (orig_entry->dict); - -                /* making sure we set the inode ctx right with layout, -                   currently possible only for non-directories, so for -                   directories don't set entry inodes */ -                if (IA_ISDIR(entry->d_stat.ia_type)) { -                        entry->d_stat.ia_blocks = DHT_DIR_STAT_BLOCKS; -                        entry->d_stat.ia_size = DHT_DIR_STAT_SIZE; -                        if (orig_entry->inode) { -                                dht_inode_ctx_time_update (orig_entry->inode, -                                                           this, &entry->d_stat, -                                                           1); - -                                if (conf->subvolume_cnt == 1) { -                                        dht_populate_inode_for_dentry (this, -                                                                       prev, -                                                                       entry, -                                                                       orig_entry); -                                } - -                        } -                } else { -                        if (orig_entry->inode) { -                                ret = dht_layout_preset (this, prev, -                                                         orig_entry->inode); -                                if (ret) -                                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                                DHT_MSG_LAYOUT_SET_FAILED, -                                                "failed to link the layout " -                                                "in inode for %s", -                                                orig_entry->d_name); - -                                entry->inode = inode_ref (orig_entry->inode); -                        } else if (itable) { -                                /* -                                 * orig_entry->inode might be null if any upper -                                 * layer xlators below client set to null, to -                                 * force a lookup on the inode even if the inode -                                 * is present in the inode table. In that case -                                 * we just update the ctx to make sure we didn't -                                 * missed anything. -                                 */ -                                inode = inode_find (itable, -                                                    orig_entry->d_stat.ia_gfid); -                                if (inode) { -                                        ret = dht_layout_preset -                                                            (this, prev, -                                                             inode); -                                        if (ret) -                                                gf_msg (this->name, -                                                     GF_LOG_WARNING, 0, -                                                     DHT_MSG_LAYOUT_SET_FAILED, -                                                     "failed to link the layout" -                                                     " in inode for %s", -                                                     orig_entry->d_name); -                                        inode_unref (inode); -                                        inode = NULL; -                                } -                        } +            } +        } else { +            if (orig_entry->inode) { +                ret = dht_layout_preset(this, prev, orig_entry->inode); +                if (ret) +                    gf_msg(this->name, GF_LOG_WARNING, 0, +                           DHT_MSG_LAYOUT_SET_FAILED, +                           "failed to link the layout " +                           "in inode for %s", +                           orig_entry->d_name); + +                entry->inode = inode_ref(orig_entry->inode); +            } else if (itable) { +                /* +                 * orig_entry->inode might be null if any upper +                 * layer xlators below client set to null, to +                 * force a lookup on the inode even if the inode +                 * is present in the inode table. In that case +                 * we just update the ctx to make sure we didn't +                 * missed anything. +                 */ +                inode = inode_find(itable, orig_entry->d_stat.ia_gfid); +                if (inode) { +                    ret = dht_layout_preset(this, prev, inode); +                    if (ret) +                        gf_msg(this->name, GF_LOG_WARNING, 0, +                               DHT_MSG_LAYOUT_SET_FAILED, +                               "failed to link the layout" +                               " in inode for %s", +                               orig_entry->d_name); +                    inode_unref(inode); +                    inode = NULL;                  } +            } +        } -                gf_msg_debug (this->name, 0, "%s: Adding entry = %s", -                              prev->name, entry->d_name); +        gf_msg_debug(this->name, 0, "%s: Adding entry = %s", prev->name, +                     entry->d_name); -                list_add_tail (&entry->list, &entries.list); -                count++; -        } +        list_add_tail(&entry->list, &entries.list); +        count++; +    }  done: -        /* We need to ensure that only the last subvolume's end-of-directory -         * notification is respected so that directory reading does not stop -         * before all subvolumes have been read. That could happen because the -         * posix for each subvolume sends a ENOENT on end-of-directory but in -         * distribute we're not concerned only with a posix's view of the -         * directory but the aggregated namespace' view of the directory. -         * Possible values: -         * op_ret == 0 and op_errno != 0 -         *   if op_errno != ENOENT : Error.Unwind. -         *   if op_errno == ENOENT : There are no more entries on this subvol. -         *                           Move to the next one. -         * op_ret > 0 and count == 0 : -         *    The subvol returned entries to dht but all were stripped out. -         *    For example, if they were linkto files or dirs where -         *    hashed_subvol != prev. Try to get some entries by winding -         *    to the next subvol. This can be dangerous if parallel readdir -         *    is enabled as it grows the stack. -         * -         * op_ret > 0 and count > 0: -         *   We found some entries. Unwind even if the buffer is not full. -         * +    /* We need to ensure that only the last subvolume's end-of-directory +     * notification is respected so that directory reading does not stop +     * before all subvolumes have been read. That could happen because the +     * posix for each subvolume sends a ENOENT on end-of-directory but in +     * distribute we're not concerned only with a posix's view of the +     * directory but the aggregated namespace' view of the directory. +     * Possible values: +     * op_ret == 0 and op_errno != 0 +     *   if op_errno != ENOENT : Error.Unwind. +     *   if op_errno == ENOENT : There are no more entries on this subvol. +     *                           Move to the next one. +     * op_ret > 0 and count == 0 : +     *    The subvol returned entries to dht but all were stripped out. +     *    For example, if they were linkto files or dirs where +     *    hashed_subvol != prev. Try to get some entries by winding +     *    to the next subvol. This can be dangerous if parallel readdir +     *    is enabled as it grows the stack. +     * +     * op_ret > 0 and count > 0: +     *   We found some entries. Unwind even if the buffer is not full. +     * +     */ + +    op_ret = count; +    if (count == 0) { +        /* non-zero next_offset means that +         * EOF is not yet hit on the current subvol           */ +        if ((next_offset == 0) || (op_errno == ENOENT)) { +            next_offset = 0; +            next_subvol = dht_subvol_next(this, prev); +        } else { +            next_subvol = prev; +        } -        op_ret = count; -        if (count == 0) { -                /* non-zero next_offset means that -                 * EOF is not yet hit on the current subvol -                 */ -                if ((next_offset == 0) || (op_errno == ENOENT)) { -                        next_offset = 0; -                        next_subvol = dht_subvol_next (this, prev); -                } else { -                        next_subvol = prev; -                } - -                if (!next_subvol) { -                        goto unwind; -                } - -                if (conf->readdir_optimize == _gf_true) { -                        if (next_subvol != local->first_up_subvol) { -                                ret = dict_set_int32 (local->xattr, -                                                      GF_READDIR_SKIP_DIRS, 1); -                                if (ret) -                                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                                DHT_MSG_DICT_SET_FAILED, -                                                "Failed to set dictionary value" -                                                ":key = %s", -                                                GF_READDIR_SKIP_DIRS ); -                        } else { -                                 dict_del (local->xattr, -                                           GF_READDIR_SKIP_DIRS); -                        } -                } +        if (!next_subvol) { +            goto unwind; +        } -                STACK_WIND_COOKIE (frame, dht_readdirp_cbk, next_subvol, -                                   next_subvol, next_subvol->fops->readdirp, -                                   local->fd, local->size, -                                   next_offset, local->xattr); -                return 0; +        if (conf->readdir_optimize == _gf_true) { +            if (next_subvol != local->first_up_subvol) { +                ret = dict_set_int32(local->xattr, GF_READDIR_SKIP_DIRS, 1); +                if (ret) +                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +                           "Failed to set dictionary value" +                           ":key = %s", +                           GF_READDIR_SKIP_DIRS); +            } else { +                dict_del(local->xattr, GF_READDIR_SKIP_DIRS); +            }          } +        STACK_WIND_COOKIE(frame, dht_readdirp_cbk, next_subvol, next_subvol, +                          next_subvol->fops->readdirp, local->fd, local->size, +                          next_offset, local->xattr); +        return 0; +    } +  unwind: -        /* We need to ensure that only the last subvolume's end-of-directory -         * notification is respected so that directory reading does not stop -         * before all subvolumes have been read. That could happen because the -         * posix for each subvolume sends a ENOENT on end-of-directory but in -         * distribute we're not concerned only with a posix's view of the -         * directory but the aggregated namespace' view of the directory. -         */ -        if (op_ret < 0) -                op_ret = 0; +    /* We need to ensure that only the last subvolume's end-of-directory +     * notification is respected so that directory reading does not stop +     * before all subvolumes have been read. That could happen because the +     * posix for each subvolume sends a ENOENT on end-of-directory but in +     * distribute we're not concerned only with a posix's view of the +     * directory but the aggregated namespace' view of the directory. +     */ +    if (op_ret < 0) +        op_ret = 0; -        if (prev != dht_last_up_subvol (this)) -                op_errno = 0; +    if (prev != dht_last_up_subvol(this)) +        op_errno = 0; -        DHT_STACK_UNWIND (readdirp, frame, op_ret, op_errno, -                          &entries, NULL); +    DHT_STACK_UNWIND(readdirp, frame, op_ret, op_errno, &entries, NULL); -        gf_dirent_free (&entries); -        return 0; +    gf_dirent_free(&entries); +    return 0;  } -  int -dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                 int op_ret, int op_errno, gf_dirent_t *orig_entries, -                 dict_t *xdata) +dht_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                int op_errno, gf_dirent_t *orig_entries, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        gf_dirent_t   entries; -        gf_dirent_t  *orig_entry = NULL; -        gf_dirent_t  *entry = NULL; -        xlator_t     *prev = NULL; -        xlator_t     *next_subvol = NULL; -        off_t         next_offset = 0; -        int           count = 0; -        dht_layout_t *layout = 0; -        xlator_t     *subvol = 0; -        dht_conf_t   *conf = NULL; -        dht_methods_t *methods = NULL; -        gf_boolean_t   skip_hashed_check = _gf_false; - -        INIT_LIST_HEAD (&entries.list); - -        prev = cookie; -        local = frame->local; +    dht_local_t *local = NULL; +    gf_dirent_t entries; +    gf_dirent_t *orig_entry = NULL; +    gf_dirent_t *entry = NULL; +    xlator_t *prev = NULL; +    xlator_t *next_subvol = NULL; +    off_t next_offset = 0; +    int count = 0; +    dht_layout_t *layout = 0; +    xlator_t *subvol = 0; +    dht_conf_t *conf = NULL; +    dht_methods_t *methods = NULL; +    gf_boolean_t skip_hashed_check = _gf_false; -        conf = this->private; -        GF_VALIDATE_OR_GOTO (this->name, conf, done); +    INIT_LIST_HEAD(&entries.list); -        methods = &(conf->methods); +    prev = cookie; +    local = frame->local; -        if (op_ret <= 0) -                goto done; +    conf = this->private; +    GF_VALIDATE_OR_GOTO(this->name, conf, done); -        if (!local->layout) -                local->layout = dht_layout_get (this, local->fd->inode); +    methods = &(conf->methods); -        layout = local->layout; +    if (op_ret <= 0) +        goto done; -        gf_msg_debug (this->name, 0, "Processing entries from %s", -                      prev->name); +    if (!local->layout) +        local->layout = dht_layout_get(this, local->fd->inode); -        if (conf->subvolume_cnt == 1) { -                /*return everything*/ -                skip_hashed_check = _gf_true; -                count = op_ret; -                goto done; -        } +    layout = local->layout; + +    gf_msg_debug(this->name, 0, "Processing entries from %s", prev->name); -        list_for_each_entry (orig_entry, (&orig_entries->list), list) { -                next_offset = orig_entry->d_off; +    if (conf->subvolume_cnt == 1) { +        /*return everything*/ +        skip_hashed_check = _gf_true; +        count = op_ret; +        goto done; +    } -                gf_msg_debug (this->name, 0, "%s: entry = %s, type = %d", -                              prev->name, orig_entry->d_name, -                              orig_entry->d_type); +    list_for_each_entry(orig_entry, (&orig_entries->list), list) +    { +        next_offset = orig_entry->d_off; -                subvol = methods->layout_search (this, layout, -                                                 orig_entry->d_name); +        gf_msg_debug(this->name, 0, "%s: entry = %s, type = %d", prev->name, +                     orig_entry->d_name, orig_entry->d_type); -                if (!subvol || (subvol == prev)) { -                        entry = gf_dirent_for_name (orig_entry->d_name); -                        if (!entry) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_NO_MEMORY, -                                        "Memory allocation failed "); -                                goto unwind; -                        } +        subvol = methods->layout_search(this, layout, orig_entry->d_name); -                        entry->d_off  = orig_entry->d_off; -                        entry->d_ino  = orig_entry->d_ino; -                        entry->d_type = orig_entry->d_type; -                        entry->d_len  = orig_entry->d_len; +        if (!subvol || (subvol == prev)) { +            entry = gf_dirent_for_name(orig_entry->d_name); +            if (!entry) { +                gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +                       "Memory allocation failed "); +                goto unwind; +            } -                        gf_msg_debug (this->name, 0, "%s: Adding = entry %s", -                                      prev->name, entry->d_name); +            entry->d_off = orig_entry->d_off; +            entry->d_ino = orig_entry->d_ino; +            entry->d_type = orig_entry->d_type; +            entry->d_len = orig_entry->d_len; -                        list_add_tail (&entry->list, &entries.list); -                        count++; -                } +            gf_msg_debug(this->name, 0, "%s: Adding = entry %s", prev->name, +                         entry->d_name); + +            list_add_tail(&entry->list, &entries.list); +            count++;          } +    }  done: -        op_ret = count; -        /* We need to ensure that only the last subvolume's end-of-directory -         * notification is respected so that directory reading does not stop -         * before all subvolumes have been read. That could happen because the -         * posix for each subvolume sends a ENOENT on end-of-directory but in -         * distribute we're not concerned only with a posix's view of the -         * directory but the aggregated namespace' view of the directory. -         */ -        if (count == 0) { -                if ((next_offset == 0) || (op_errno == ENOENT)) { -                        next_offset = 0; -                        next_subvol = dht_subvol_next (this, prev); -                } else { -                        next_subvol = prev; -                } - -                if (!next_subvol) { -                        goto unwind; -                } +    op_ret = count; +    /* We need to ensure that only the last subvolume's end-of-directory +     * notification is respected so that directory reading does not stop +     * before all subvolumes have been read. That could happen because the +     * posix for each subvolume sends a ENOENT on end-of-directory but in +     * distribute we're not concerned only with a posix's view of the +     * directory but the aggregated namespace' view of the directory. +     */ +    if (count == 0) { +        if ((next_offset == 0) || (op_errno == ENOENT)) { +            next_offset = 0; +            next_subvol = dht_subvol_next(this, prev); +        } else { +            next_subvol = prev; +        } -                STACK_WIND_COOKIE (frame, dht_readdir_cbk, next_subvol, -                                   next_subvol, next_subvol->fops->readdir, -                                   local->fd, local->size, -                                   next_offset, NULL); -                return 0; +        if (!next_subvol) { +            goto unwind;          } +        STACK_WIND_COOKIE(frame, dht_readdir_cbk, next_subvol, next_subvol, +                          next_subvol->fops->readdir, local->fd, local->size, +                          next_offset, NULL); +        return 0; +    } +  unwind: -        /* We need to ensure that only the last subvolume's end-of-directory -         * notification is respected so that directory reading does not stop -         * before all subvolumes have been read. That could happen because the -         * posix for each subvolume sends a ENOENT on end-of-directory but in -         * distribute we're not concerned only with a posix's view of the -         * directory but the aggregated namespace' view of the directory. -         */ +    /* We need to ensure that only the last subvolume's end-of-directory +     * notification is respected so that directory reading does not stop +     * before all subvolumes have been read. That could happen because the +     * posix for each subvolume sends a ENOENT on end-of-directory but in +     * distribute we're not concerned only with a posix's view of the +     * directory but the aggregated namespace' view of the directory. +     */ -        if (prev != dht_last_up_subvol (this)) -                op_errno = 0; +    if (prev != dht_last_up_subvol(this)) +        op_errno = 0; -        if (!skip_hashed_check) { -                DHT_STACK_UNWIND (readdir, frame, op_ret, op_errno, -                                  &entries, NULL); -                gf_dirent_free (&entries); +    if (!skip_hashed_check) { +        DHT_STACK_UNWIND(readdir, frame, op_ret, op_errno, &entries, NULL); +        gf_dirent_free(&entries); -        } else { -                DHT_STACK_UNWIND (readdir, frame, op_ret, op_errno, -                                  orig_entries, NULL); -        } -        return 0; +    } else { +        DHT_STACK_UNWIND(readdir, frame, op_ret, op_errno, orig_entries, NULL); +    } +    return 0;  } -  int -dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -                off_t yoff, int whichop, dict_t *dict) +dht_do_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +               off_t yoff, int whichop, dict_t *dict)  { -        dht_local_t  *local  = NULL; -        int           op_errno = -1; -        xlator_t     *xvol = NULL; -        int           ret = 0; -        dht_conf_t   *conf = NULL; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO (this->private, err); - -        conf = this->private; - -        local = dht_local_init (frame, NULL, NULL, whichop); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } - -        local->fd = fd_ref (fd); -        local->size = size; -        local->xattr_req = (dict)? dict_ref (dict) : NULL; -        local->first_up_subvol = dht_first_up_subvol (this); -        local->op_ret = -1; +    dht_local_t *local = NULL; +    int op_errno = -1; +    xlator_t *xvol = NULL; +    int ret = 0; +    dht_conf_t *conf = NULL; -        dht_deitransform (this, yoff, &xvol); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(this->private, err); -        /* TODO: do proper readdir */ -        if (whichop == GF_FOP_READDIRP) { -                if (dict) -                        local->xattr = dict_ref (dict); -                else -                        local->xattr = dict_new (); +    conf = this->private; -                if (local->xattr) { -                        ret = dict_set_uint32 (local->xattr, -                                               conf->link_xattr_name, 256); -                        if (ret) -                                gf_msg (this->name, GF_LOG_WARNING, 0, -                                        DHT_MSG_DICT_SET_FAILED, -                                        "Failed to set dictionary value" -                                        " : key = %s", -                                        conf->link_xattr_name); +    local = dht_local_init(frame, NULL, NULL, whichop); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -                        if (conf->readdir_optimize == _gf_true) { -                                if (xvol != local->first_up_subvol) { -                                        ret = dict_set_int32 (local->xattr, -                                                       GF_READDIR_SKIP_DIRS, 1); -                                        if (ret) -                                                gf_msg (this->name, -                                                        GF_LOG_ERROR, 0, -                                                        DHT_MSG_DICT_SET_FAILED, -                                                        "Failed to set " -                                                        "dictionary value: " -                                                        "key = %s", -                                                        GF_READDIR_SKIP_DIRS); -                                } else { -                                        dict_del (local->xattr, -                                                  GF_READDIR_SKIP_DIRS); -                                } -                        } - -                        if (conf->subvolume_cnt == 1) { -                                ret = dict_set_uint32 (local->xattr, -                                                       conf->xattr_name, 4 * 4); -                                if (ret) { -                                        gf_msg (this->name, GF_LOG_WARNING, -                                                ENOMEM, -                                                DHT_MSG_DICT_SET_FAILED, -                                                "Failed to set dictionary " -                                                "value:key = %s ", -                                                conf->xattr_name); -                                } -                        } +    local->fd = fd_ref(fd); +    local->size = size; +    local->xattr_req = (dict) ? dict_ref(dict) : NULL; +    local->first_up_subvol = dht_first_up_subvol(this); +    local->op_ret = -1; +    dht_deitransform(this, yoff, &xvol); +    /* TODO: do proper readdir */ +    if (whichop == GF_FOP_READDIRP) { +        if (dict) +            local->xattr = dict_ref(dict); +        else +            local->xattr = dict_new(); + +        if (local->xattr) { +            ret = dict_set_uint32(local->xattr, conf->link_xattr_name, 256); +            if (ret) +                gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +                       "Failed to set dictionary value" +                       " : key = %s", +                       conf->link_xattr_name); + +            if (conf->readdir_optimize == _gf_true) { +                if (xvol != local->first_up_subvol) { +                    ret = dict_set_int32(local->xattr, GF_READDIR_SKIP_DIRS, 1); +                    if (ret) +                        gf_msg(this->name, GF_LOG_ERROR, 0, +                               DHT_MSG_DICT_SET_FAILED, +                               "Failed to set " +                               "dictionary value: " +                               "key = %s", +                               GF_READDIR_SKIP_DIRS); +                } else { +                    dict_del(local->xattr, GF_READDIR_SKIP_DIRS);                  } +            } -                STACK_WIND_COOKIE (frame, dht_readdirp_cbk, xvol, xvol, -                                   xvol->fops->readdirp, fd, size, yoff, -                                   local->xattr); -        } else { -                STACK_WIND_COOKIE (frame, dht_readdir_cbk, xvol, xvol, -                                   xvol->fops->readdir, fd, size, yoff, -                                   local->xattr); +            if (conf->subvolume_cnt == 1) { +                ret = dict_set_uint32(local->xattr, conf->xattr_name, 4 * 4); +                if (ret) { +                    gf_msg(this->name, GF_LOG_WARNING, ENOMEM, +                           DHT_MSG_DICT_SET_FAILED, +                           "Failed to set dictionary " +                           "value:key = %s ", +                           conf->xattr_name); +                } +            }          } -        return 0; +        STACK_WIND_COOKIE(frame, dht_readdirp_cbk, xvol, xvol, +                          xvol->fops->readdirp, fd, size, yoff, local->xattr); +    } else { +        STACK_WIND_COOKIE(frame, dht_readdir_cbk, xvol, xvol, +                          xvol->fops->readdir, fd, size, yoff, local->xattr); +    } + +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(readdir, frame, -1, op_errno, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -             off_t yoff, dict_t *xdata) +dht_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +            off_t yoff, dict_t *xdata)  { -        int          op = GF_FOP_READDIR; -        dht_conf_t  *conf = NULL; -        int          i = 0; +    int op = GF_FOP_READDIR; +    dht_conf_t *conf = NULL; +    int i = 0; -        conf = this->private; -        if (!conf) -                goto out; +    conf = this->private; +    if (!conf) +        goto out; -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (!conf->subvolume_status[i]) { -                        op = GF_FOP_READDIRP; -                        break; -                } +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (!conf->subvolume_status[i]) { +            op = GF_FOP_READDIRP; +            break;          } +    } -        if (conf->use_readdirp) -                op = GF_FOP_READDIRP; +    if (conf->use_readdirp) +        op = GF_FOP_READDIRP;  out: -        dht_do_readdir (frame, this, fd, size, yoff, op, 0); -        return 0; +    dht_do_readdir(frame, this, fd, size, yoff, op, 0); +    return 0;  }  int -dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, -              off_t yoff, dict_t *dict) +dht_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +             off_t yoff, dict_t *dict)  { -        dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP, dict); -        return 0; +    dht_do_readdir(frame, this, fd, size, yoff, GF_FOP_READDIRP, dict); +    return 0;  } - -  int -dht_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                  int op_ret, int op_errno, dict_t *xdata) +dht_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                 int op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; - +    dht_local_t *local = NULL; +    int this_call_cnt = 0; -        local = frame->local; +    local = frame->local; -        LOCK (&frame->lock); -        { -                if (op_ret == -1) -                        local->op_errno = op_errno; +    LOCK(&frame->lock); +    { +        if (op_ret == -1) +            local->op_errno = op_errno; -                if (op_ret == 0) -                        local->op_ret = 0; -        } -        UNLOCK (&frame->lock); +        if (op_ret == 0) +            local->op_ret = 0; +    } +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) -                DHT_STACK_UNWIND (fsyncdir, frame, local->op_ret, -                                  local->op_errno, xdata); +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) +        DHT_STACK_UNWIND(fsyncdir, frame, local->op_ret, local->op_errno, +                         xdata); -        return 0; +    return 0;  } -  int -dht_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, -              int datasync, dict_t *xdata) +dht_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, +             dict_t *xdata)  { -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           op_errno = -1; -        int           i = -1; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = -1; +    int i = -1; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO (this->private, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(this->private, err); -        conf = this->private; +    conf = this->private; -        local = dht_local_init (frame, NULL, NULL, GF_FOP_FSYNCDIR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    local = dht_local_init(frame, NULL, NULL, GF_FOP_FSYNCDIR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        local->fd = fd_ref (fd); -        local->call_cnt = conf->subvolume_cnt; +    local->fd = fd_ref(fd); +    local->call_cnt = conf->subvolume_cnt; -        for (i = 0; i < conf->subvolume_cnt; i++) { -                STACK_WIND (frame, dht_fsyncdir_cbk, -                            conf->subvolumes[i], -                            conf->subvolumes[i]->fops->fsyncdir, -                            fd, datasync, xdata); -        } +    for (i = 0; i < conf->subvolume_cnt; i++) { +        STACK_WIND(frame, dht_fsyncdir_cbk, conf->subvolumes[i], +                   conf->subvolumes[i]->fops->fsyncdir, fd, datasync, xdata); +    } -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(fsyncdir, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } -  int -dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                 int op_ret, int op_errno, -                 inode_t *inode, struct iatt *stbuf, struct iatt *preparent, -                 struct iatt *postparent, dict_t *xdata) +dht_newfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +                int op_errno, inode_t *inode, struct iatt *stbuf, +                struct iatt *preparent, struct iatt *postparent, dict_t *xdata)  { -        xlator_t     *prev = NULL; -        int           ret = -1; -        dht_local_t  *local = NULL; - +    xlator_t *prev = NULL; +    int ret = -1; +    dht_local_t *local = NULL; -        if (op_ret == -1) -                goto out; - -        local = frame->local; -        if (!local) { -                op_ret = -1; -                op_errno = EINVAL; -                goto out; -        } - -        prev = cookie; - -        if (local->loc.parent) { - -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           preparent, 0); -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } +    if (op_ret == -1) +        goto out; -        ret = dht_layout_preset (this, prev, inode); -        if (ret < 0) { -                gf_msg_debug (this->name, EINVAL, -                              "could not set pre-set layout for subvolume %s", -                              prev? prev->name: NULL); -                op_ret   = -1; -                op_errno = EINVAL; -                goto out; -        } -        if (local->linked == _gf_true) -                dht_linkfile_attr_heal (frame, this); +    local = frame->local; +    if (!local) { +        op_ret = -1; +        op_errno = EINVAL; +        goto out; +    } + +    prev = cookie; + +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, preparent, 0); +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    } + +    ret = dht_layout_preset(this, prev, inode); +    if (ret < 0) { +        gf_msg_debug(this->name, EINVAL, +                     "could not set pre-set layout for subvolume %s", +                     prev ? prev->name : NULL); +        op_ret = -1; +        op_errno = EINVAL; +        goto out; +    } +    if (local->linked == _gf_true) +        dht_linkfile_attr_heal(frame, this);  out: -        /* -         * FIXME: ia_size and st_blocks of preparent and postparent do not have -         * correct values. since, preparent and postparent buffers correspond -         * to a directory these two members should have values equal to sum of -         * corresponding values from each of the subvolume. -         * See dht_iatt_merge for reference. -         */ -        DHT_STRIP_PHASE1_FLAGS (stbuf); -        dht_set_fixed_dir_stat (postparent); -        dht_set_fixed_dir_stat (preparent); - -        if (local && local->lock[0].layout.parent_layout.locks) { -                /* store op_errno for failure case*/ -                local->op_errno = op_errno; -                local->refresh_layout_unlock (frame, this, op_ret, 1); +    /* +     * FIXME: ia_size and st_blocks of preparent and postparent do not have +     * correct values. since, preparent and postparent buffers correspond +     * to a directory these two members should have values equal to sum of +     * corresponding values from each of the subvolume. +     * See dht_iatt_merge for reference. +     */ +    DHT_STRIP_PHASE1_FLAGS(stbuf); +    dht_set_fixed_dir_stat(postparent); +    dht_set_fixed_dir_stat(preparent); + +    if (local && local->lock[0].layout.parent_layout.locks) { +        /* store op_errno for failure case*/ +        local->op_errno = op_errno; +        local->refresh_layout_unlock(frame, this, op_ret, 1); -                if (op_ret == 0) { -                        DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, -                                          inode, stbuf, preparent, postparent, -                                          xdata); -                } -        } else { -                DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, -                                  stbuf, preparent, postparent, xdata); +        if (op_ret == 0) { +            DHT_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, stbuf, +                             preparent, postparent, xdata);          } +    } else { +        DHT_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, stbuf, +                         preparent, postparent, xdata); +    } -        return 0; +    return 0;  }  int -dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie, -                               xlator_t *this, -                               int32_t op_ret, int32_t op_errno, -                               inode_t *inode, struct iatt *stbuf, -                               struct iatt *preparent, struct iatt *postparent, -                               dict_t *xdata) +dht_mknod_linkfile_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                              int32_t op_ret, int32_t op_errno, inode_t *inode, +                              struct iatt *stbuf, struct iatt *preparent, +                              struct iatt *postparent, dict_t *xdata)  { -        dht_local_t     *local          = NULL; -        xlator_t        *cached_subvol  = NULL; -        dht_conf_t      *conf           = NULL; +    dht_local_t *local = NULL; +    xlator_t *cached_subvol = NULL; +    dht_conf_t *conf = NULL; -        local = frame->local; +    local = frame->local; -        if (!local || !local->cached_subvol) { -                op_errno = EINVAL; -                goto err; -        } +    if (!local || !local->cached_subvol) { +        op_errno = EINVAL; +        goto err; +    } -        if (op_ret == -1) { -                local->op_errno = op_errno; -                goto err; -        } +    if (op_ret == -1) { +        local->op_errno = op_errno; +        goto err; +    } -        conf = this->private; -        if (!conf) { -                local->op_errno =  EINVAL; -                op_errno = EINVAL; -                goto err; -        } +    conf = this->private; +    if (!conf) { +        local->op_errno = EINVAL; +        op_errno = EINVAL; +        goto err; +    } -        cached_subvol = local->cached_subvol; +    cached_subvol = local->cached_subvol; -        if (local->params) { -                 dict_del (local->params, conf->link_xattr_name); -                 dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY); -        } +    if (local->params) { +        dict_del(local->params, conf->link_xattr_name); +        dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); +    } -        STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)cached_subvol, -                           cached_subvol, cached_subvol->fops->mknod, -                           &local->loc, local->mode, local->rdev, local->umask, -                           local->params); +    STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)cached_subvol, +                      cached_subvol, cached_subvol->fops->mknod, &local->loc, +                      local->mode, local->rdev, local->umask, local->params); -        return 0; +    return 0;  err: -        if (local && local->lock[0].layout.parent_layout.locks) { -                local->refresh_layout_unlock (frame, this, -1, 1); -        } else { -                DHT_STACK_UNWIND (mknod, frame, -1, -                                  op_errno, NULL, NULL, NULL, -                                  NULL, NULL); -        } -        return 0; +    if (local && local->lock[0].layout.parent_layout.locks) { +        local->refresh_layout_unlock(frame, this, -1, 1); +    } else { +        DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, +                         NULL); +    } +    return 0;  }  int -dht_mknod_wind_to_avail_subvol (call_frame_t *frame, xlator_t *this, -                                 xlator_t *subvol, loc_t *loc, dev_t rdev, -                                 mode_t mode, mode_t umask, dict_t *params) +dht_mknod_wind_to_avail_subvol(call_frame_t *frame, xlator_t *this, +                               xlator_t *subvol, loc_t *loc, dev_t rdev, +                               mode_t mode, mode_t umask, dict_t *params)  { -        dht_local_t     *local          = NULL; -        xlator_t        *avail_subvol   = NULL; - -        local = frame->local; +    dht_local_t *local = NULL; +    xlator_t *avail_subvol = NULL; -        if (!dht_is_subvol_filled (this, subvol)) { -                gf_msg_debug (this->name, 0, -                              "creating %s on %s", loc->path, -                              subvol->name); +    local = frame->local; -                STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol, -                                   subvol, subvol->fops->mknod, loc, mode, -                                   rdev, umask, params); -        } else { -                avail_subvol = dht_free_disk_available_subvol (this, subvol, local); +    if (!dht_is_subvol_filled(this, subvol)) { +        gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, +                     subvol->name); -                if (avail_subvol != subvol) { -                        local->params = dict_ref (params); -                        local->rdev = rdev; -                        local->mode = mode; -                        local->umask = umask; -                        local->cached_subvol = avail_subvol; -                        local->hashed_subvol = subvol; +        STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, +                          subvol->fops->mknod, loc, mode, rdev, umask, params); +    } else { +        avail_subvol = dht_free_disk_available_subvol(this, subvol, local); -                        gf_msg_debug (this->name, 0, -                                      "creating %s on %s (link at %s)", loc->path, -                                      avail_subvol->name, subvol->name); +        if (avail_subvol != subvol) { +            local->params = dict_ref(params); +            local->rdev = rdev; +            local->mode = mode; +            local->umask = umask; +            local->cached_subvol = avail_subvol; +            local->hashed_subvol = subvol; -                        dht_linkfile_create (frame, -                                             dht_mknod_linkfile_create_cbk, -                                             this, avail_subvol, subvol, loc); +            gf_msg_debug(this->name, 0, "creating %s on %s (link at %s)", +                         loc->path, avail_subvol->name, subvol->name); -                        goto out; -                } +            dht_linkfile_create(frame, dht_mknod_linkfile_create_cbk, this, +                                avail_subvol, subvol, loc); -                gf_msg_debug (this->name, 0, -                              "creating %s on %s", loc->path, subvol->name); +            goto out; +        } -                STACK_WIND_COOKIE (frame, dht_newfile_cbk, -                                   (void *)subvol, subvol, -                                   subvol->fops->mknod, loc, mode, -                                   rdev, umask, params); +        gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, +                     subvol->name); -        } +        STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, +                          subvol->fops->mknod, loc, mode, rdev, umask, params); +    }  out: -        return 0; +    return 0;  }  int32_t -dht_mknod_do (call_frame_t *frame) +dht_mknod_do(call_frame_t *frame)  { -        dht_local_t     *local          = NULL; -        dht_layout_t    *refreshed      = NULL; -        xlator_t        *subvol         = NULL; -        xlator_t        *this           = NULL; -        dht_conf_t      *conf           = NULL; -        dht_methods_t   *methods        = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *refreshed = NULL; +    xlator_t *subvol = NULL; +    xlator_t *this = NULL; +    dht_conf_t *conf = NULL; +    dht_methods_t *methods = NULL; -        local = frame->local; +    local = frame->local; -        this = THIS; +    this = THIS; -        conf = this->private; +    conf = this->private; -        GF_VALIDATE_OR_GOTO (this->name, conf, err); +    GF_VALIDATE_OR_GOTO(this->name, conf, err); -        methods = &(conf->methods); +    methods = &(conf->methods); -        /* We don't need parent_loc anymore */ -        loc_wipe (&local->loc); +    /* We don't need parent_loc anymore */ +    loc_wipe(&local->loc); -        loc_copy (&local->loc, &local->loc2); +    loc_copy(&local->loc, &local->loc2); -        loc_wipe (&local->loc2); +    loc_wipe(&local->loc2); -        refreshed = local->selfheal.refreshed_layout; +    refreshed = local->selfheal.refreshed_layout; -        subvol = methods->layout_search (this, refreshed, local->loc.name); +    subvol = methods->layout_search(this, refreshed, local->loc.name); -        if (!subvol) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_HASHED_SUBVOL_GET_FAILED, "no subvolume in " -                        "layout for path=%s", local->loc.path); -                local->op_errno = ENOENT; -                goto err; -        } +    if (!subvol) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, +               "no subvolume in " +               "layout for path=%s", +               local->loc.path); +        local->op_errno = ENOENT; +        goto err; +    } -        dht_mknod_wind_to_avail_subvol (frame, this, subvol, &local->loc, -                                         local->rdev, local->mode, -                                         local->umask, local->params); -        return 0; +    dht_mknod_wind_to_avail_subvol(frame, this, subvol, &local->loc, +                                   local->rdev, local->mode, local->umask, +                                   local->params); +    return 0;  err: -        local->refresh_layout_unlock (frame, this, -1, 1); +    local->refresh_layout_unlock(frame, this, -1, 1); -        return 0; +    return 0;  } -  int32_t -dht_mknod_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_mknod_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  }  int32_t -dht_mknod_finish (call_frame_t *frame, xlator_t *this, int op_ret, -                  int invoke_cbk) -{ -        dht_local_t  *local      = NULL, *lock_local = NULL; -        call_frame_t *lock_frame = NULL; -        int           lock_count = 0; - -        local = frame->local; -        lock_count = dht_lock_count (local->lock[0].layout.parent_layout.locks, -                                     local->lock[0].layout.parent_layout.lk_count); -        if (lock_count == 0) -                goto done; - -        lock_frame = copy_frame (frame); -        if (lock_frame == NULL) { -                goto done; -        } - -        lock_local = dht_local_init (lock_frame, &local->loc, NULL, -                                     lock_frame->root->op); -        if (lock_local == NULL) { -                goto done; -        } - -        lock_local->lock[0].layout.parent_layout.locks = local->lock[0].layout.parent_layout.locks; -        lock_local->lock[0].layout.parent_layout.lk_count = local->lock[0].layout.parent_layout.lk_count; - -        local->lock[0].layout.parent_layout.locks = NULL; -        local->lock[0].layout.parent_layout.lk_count = 0; - -        dht_unlock_inodelk (lock_frame, -                            lock_local->lock[0].layout.parent_layout.locks, -                            lock_local->lock[0].layout.parent_layout.lk_count, -                            dht_mknod_unlock_cbk); -        lock_frame = NULL; +dht_mknod_finish(call_frame_t *frame, xlator_t *this, int op_ret, +                 int invoke_cbk) +{ +    dht_local_t *local = NULL, *lock_local = NULL; +    call_frame_t *lock_frame = NULL; +    int lock_count = 0; + +    local = frame->local; +    lock_count = dht_lock_count(local->lock[0].layout.parent_layout.locks, +                                local->lock[0].layout.parent_layout.lk_count); +    if (lock_count == 0) +        goto done; + +    lock_frame = copy_frame(frame); +    if (lock_frame == NULL) { +        goto done; +    } + +    lock_local = dht_local_init(lock_frame, &local->loc, NULL, +                                lock_frame->root->op); +    if (lock_local == NULL) { +        goto done; +    } + +    lock_local->lock[0] +        .layout.parent_layout.locks = local->lock[0].layout.parent_layout.locks; +    lock_local->lock[0].layout.parent_layout.lk_count = +        local->lock[0].layout.parent_layout.lk_count; + +    local->lock[0].layout.parent_layout.locks = NULL; +    local->lock[0].layout.parent_layout.lk_count = 0; + +    dht_unlock_inodelk(lock_frame, +                       lock_local->lock[0].layout.parent_layout.locks, +                       lock_local->lock[0].layout.parent_layout.lk_count, +                       dht_mknod_unlock_cbk); +    lock_frame = NULL;  done: -        if (lock_frame != NULL) { -                DHT_STACK_DESTROY (lock_frame); -        } +    if (lock_frame != NULL) { +        DHT_STACK_DESTROY(lock_frame); +    } -        if (op_ret == 0) -                return 0; - -        DHT_STACK_UNWIND (mknod, frame, op_ret, local->op_errno, NULL, NULL, -                          NULL, NULL, NULL); +    if (op_ret == 0)          return 0; + +    DHT_STACK_UNWIND(mknod, frame, op_ret, local->op_errno, NULL, NULL, NULL, +                     NULL, NULL); +    return 0;  }  int32_t -dht_mknod_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_mknod_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                   int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t     *local = NULL; +    dht_local_t *local = NULL; -        local = frame->local; +    local = frame->local; -        if (!local) { -                goto err; -        } +    if (!local) { +        goto err; +    } -        if (op_ret < 0) { -                gf_msg ("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, -                        "mknod lock failed for file: %s", local->loc2.name); +    if (op_ret < 0) { +        gf_msg("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, +               "mknod lock failed for file: %s", local->loc2.name); -                local->op_errno = op_errno; +        local->op_errno = op_errno; -                goto err; -        } +        goto err; +    } -        local->refresh_layout_unlock = dht_mknod_finish; +    local->refresh_layout_unlock = dht_mknod_finish; -        local->refresh_layout_done = dht_mknod_do; +    local->refresh_layout_done = dht_mknod_do; -        dht_refresh_layout (frame); +    dht_refresh_layout(frame); -        return 0; +    return 0;  err: -        dht_mknod_finish (frame, this, -1, 0); -        return 0; +    dht_mknod_finish(frame, this, -1, 0); +    return 0;  }  int32_t -dht_mknod_lock (call_frame_t *frame, xlator_t *subvol) +dht_mknod_lock(call_frame_t *frame, xlator_t *subvol)  { -        dht_local_t     *local          = NULL; -        int              count  = 1,    ret = -1; -        dht_lock_t     **lk_array       = NULL; +    dht_local_t *local = NULL; +    int count = 1, ret = -1; +    dht_lock_t **lk_array = NULL; -        GF_VALIDATE_OR_GOTO ("dht", frame, err); -        GF_VALIDATE_OR_GOTO (frame->this->name, frame->local, err); +    GF_VALIDATE_OR_GOTO("dht", frame, err); +    GF_VALIDATE_OR_GOTO(frame->this->name, frame->local, err); -        local = frame->local; +    local = frame->local; -        lk_array = GF_CALLOC (count, sizeof (*lk_array), gf_common_mt_pointer); +    lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); -        if (lk_array == NULL) -                goto err; +    if (lk_array == NULL) +        goto err; -        lk_array[0] = dht_lock_new (frame->this, subvol, &local->loc, F_RDLCK, -                                    DHT_LAYOUT_HEAL_DOMAIN, NULL, -                                    IGNORE_ENOENT_ESTALE); +    lk_array[0] = dht_lock_new(frame->this, subvol, &local->loc, F_RDLCK, +                               DHT_LAYOUT_HEAL_DOMAIN, NULL, +                               IGNORE_ENOENT_ESTALE); -        if (lk_array[0] == NULL) -                goto err; +    if (lk_array[0] == NULL) +        goto err; -        local->lock[0].layout.parent_layout.locks = lk_array; -        local->lock[0].layout.parent_layout.lk_count = count; +    local->lock[0].layout.parent_layout.locks = lk_array; +    local->lock[0].layout.parent_layout.lk_count = count; -        ret = dht_blocking_inodelk (frame, lk_array, count, dht_mknod_lock_cbk); +    ret = dht_blocking_inodelk(frame, lk_array, count, dht_mknod_lock_cbk); -        if (ret < 0) { -                local->lock[0].layout.parent_layout.locks = NULL; -                local->lock[0].layout.parent_layout.lk_count = 0; -                goto err; -        } +    if (ret < 0) { +        local->lock[0].layout.parent_layout.locks = NULL; +        local->lock[0].layout.parent_layout.lk_count = 0; +        goto err; +    } -        return 0; +    return 0;  err: -        if (lk_array != NULL) { -                dht_lock_array_free (lk_array, count); -                GF_FREE (lk_array); -        } +    if (lk_array != NULL) { +        dht_lock_array_free(lk_array, count); +        GF_FREE(lk_array); +    } -        return -1; +    return -1;  }  int -dht_refresh_parent_layout_resume (call_frame_t *frame, xlator_t *this, int ret, -                                  int invoke_cbk) +dht_refresh_parent_layout_resume(call_frame_t *frame, xlator_t *this, int ret, +                                 int invoke_cbk)  { -        dht_local_t  *local        = NULL, *parent_local = NULL; -        call_stub_t  *stub         = NULL; -        call_frame_t *parent_frame = NULL; +    dht_local_t *local = NULL, *parent_local = NULL; +    call_stub_t *stub = NULL; +    call_frame_t *parent_frame = NULL; -        local = frame->local; +    local = frame->local; -        stub = local->stub; -        local->stub = NULL; +    stub = local->stub; +    local->stub = NULL; -        parent_frame = stub->frame; -        parent_local = parent_frame->local; +    parent_frame = stub->frame; +    parent_local = parent_frame->local; -        if (ret < 0) { -                parent_local->op_ret = -1; -                parent_local->op_errno = local->op_errno -                        ? local->op_errno : EIO; -        } else { -                parent_local->op_ret = 0; -        } +    if (ret < 0) { +        parent_local->op_ret = -1; +        parent_local->op_errno = local->op_errno ? local->op_errno : EIO; +    } else { +        parent_local->op_ret = 0; +    } -        call_resume (stub); +    call_resume(stub); -        DHT_STACK_DESTROY (frame); +    DHT_STACK_DESTROY(frame); -        return 0; +    return 0;  } -  int -dht_refresh_parent_layout_done (call_frame_t *frame) +dht_refresh_parent_layout_done(call_frame_t *frame)  { -        dht_local_t *local = NULL; -        int          ret   = 0; +    dht_local_t *local = NULL; +    int ret = 0; -        local = frame->local; +    local = frame->local; -        if (local->op_ret < 0) { -                ret = -1; -                goto resume; -        } +    if (local->op_ret < 0) { +        ret = -1; +        goto resume; +    } -        dht_layout_set (frame->this, local->loc.inode, -                        local->selfheal.refreshed_layout); +    dht_layout_set(frame->this, local->loc.inode, +                   local->selfheal.refreshed_layout);  resume: -        dht_refresh_parent_layout_resume (frame, frame->this, ret, 1); -        return 0; +    dht_refresh_parent_layout_resume(frame, frame->this, ret, 1); +    return 0;  } -  int -dht_handle_parent_layout_change (xlator_t *this, call_stub_t *stub) +dht_handle_parent_layout_change(xlator_t *this, call_stub_t *stub)  { -        call_frame_t *refresh_frame = NULL, *frame = NULL; -        dht_local_t  *refresh_local = NULL, *local = NULL; +    call_frame_t *refresh_frame = NULL, *frame = NULL; +    dht_local_t *refresh_local = NULL, *local = NULL; -        frame = stub->frame; -        local = frame->local; +    frame = stub->frame; +    local = frame->local; -        refresh_frame = copy_frame (frame); -        refresh_local = dht_local_init (refresh_frame, NULL, NULL, -                                        stub->fop); +    refresh_frame = copy_frame(frame); +    refresh_local = dht_local_init(refresh_frame, NULL, NULL, stub->fop); -        refresh_local->loc.inode = inode_ref (local->loc.parent); -        gf_uuid_copy (refresh_local->loc.gfid, local->loc.parent->gfid); +    refresh_local->loc.inode = inode_ref(local->loc.parent); +    gf_uuid_copy(refresh_local->loc.gfid, local->loc.parent->gfid); -        refresh_local->stub = stub; +    refresh_local->stub = stub; -        refresh_local->refresh_layout_unlock = dht_refresh_parent_layout_resume; -        refresh_local->refresh_layout_done = dht_refresh_parent_layout_done; +    refresh_local->refresh_layout_unlock = dht_refresh_parent_layout_resume; +    refresh_local->refresh_layout_done = dht_refresh_parent_layout_done; -        dht_refresh_layout (refresh_frame); -        return 0; +    dht_refresh_layout(refresh_frame); +    return 0;  }  int32_t -dht_call_mkdir_stub (call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_call_mkdir_stub(call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t *local = NULL; -        call_stub_t *stub  = NULL; +    dht_local_t *local = NULL; +    call_stub_t *stub = NULL; -        local = frame->local; -        stub = local->stub; -        local->stub = NULL; +    local = frame->local; +    stub = local->stub; +    local->stub = NULL; -        if (op_ret < 0) { -                local->op_ret = -1; -                local->op_errno = op_errno; -        } else { -                local->op_ret = 0; -        } +    if (op_ret < 0) { +        local->op_ret = -1; +        local->op_errno = op_errno; +    } else { +        local->op_ret = 0; +    } -        call_resume (stub); +    call_resume(stub); -        return 0; +    return 0;  }  int32_t -dht_guard_parent_layout_and_namespace (xlator_t *subvol, call_stub_t *stub) +dht_guard_parent_layout_and_namespace(xlator_t *subvol, call_stub_t *stub)  { -        dht_local_t   *local                  = NULL; -        int            ret                    = -1; -        loc_t         *loc                    = NULL; -        xlator_t      *hashed_subvol          = NULL, *this = NULL;; -        call_frame_t  *frame                  = NULL; -        char          pgfid[GF_UUID_BUF_SIZE] = {0}; -        int32_t       *parent_disk_layout     = NULL; -        dht_layout_t  *parent_layout          = NULL; -        dht_conf_t    *conf                   = NULL; +    dht_local_t *local = NULL; +    int ret = -1; +    loc_t *loc = NULL; +    xlator_t *hashed_subvol = NULL, *this = NULL; +    ; +    call_frame_t *frame = NULL; +    char pgfid[GF_UUID_BUF_SIZE] = {0}; +    int32_t *parent_disk_layout = NULL; +    dht_layout_t *parent_layout = NULL; +    dht_conf_t *conf = NULL; -        GF_VALIDATE_OR_GOTO ("dht", stub, err); +    GF_VALIDATE_OR_GOTO("dht", stub, err); -        frame = stub->frame; -        this = frame->this; +    frame = stub->frame; +    this = frame->this; -        conf = this->private; +    conf = this->private; -        local = frame->local; +    local = frame->local; -        local->stub = stub; +    local->stub = stub; -        /* TODO: recheck whether we should lock on src or dst if we do similar -         * stale layout checks for rename. -         */ -        loc = &stub->args.loc; +    /* TODO: recheck whether we should lock on src or dst if we do similar +     * stale layout checks for rename. +     */ +    loc = &stub->args.loc; -        gf_uuid_unparse (loc->parent->gfid, pgfid); +    gf_uuid_unparse(loc->parent->gfid, pgfid); +    if (local->params == NULL) { +        local->params = dict_new();          if (local->params == NULL) { -                local->params = dict_new (); -                if (local->params == NULL) { -                        local->op_errno = ENOMEM; -                        gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                                DHT_MSG_PARENT_LAYOUT_CHANGED, -                                "%s (%s/%s) (path: %s): " -                                "dict allocation failed", -                                gf_fop_list[stub->fop], -                                pgfid, loc->name, loc->path); -                        goto err; -                } -        } - -        hashed_subvol = dht_subvol_get_hashed (this, loc); -        if (hashed_subvol == NULL) { -                local->op_errno = EINVAL; +            local->op_errno = ENOMEM; +            gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +                   DHT_MSG_PARENT_LAYOUT_CHANGED, +                   "%s (%s/%s) (path: %s): " +                   "dict allocation failed", +                   gf_fop_list[stub->fop], pgfid, loc->name, loc->path); +            goto err; +        } +    } + +    hashed_subvol = dht_subvol_get_hashed(this, loc); +    if (hashed_subvol == NULL) { +        local->op_errno = EINVAL; + +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "%s (%s/%s) (path: %s): " +               "hashed subvolume not found", +               gf_fop_list[stub->fop], pgfid, loc->name, loc->path); +        goto err; +    } + +    parent_layout = dht_layout_get(this, loc->parent); + +    ret = dht_disk_layout_extract_for_subvol(this, parent_layout, hashed_subvol, +                                             &parent_disk_layout); +    if (ret == -1) { +        local->op_errno = EINVAL; +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "%s (%s/%s) (path: %s): " +               "extracting in-memory layout of parent failed. ", +               gf_fop_list[stub->fop], pgfid, loc->name, loc->path); +        goto err; +    } + +    memcpy((void *)local->parent_disk_layout, (void *)parent_disk_layout, +           sizeof(local->parent_disk_layout)); + +    dht_layout_unref(this, parent_layout); +    parent_layout = NULL; + +    ret = dict_set_str(local->params, GF_PREOP_PARENT_KEY, conf->xattr_name); +    if (ret < 0) { +        local->op_errno = -ret; +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "%s (%s/%s) (path: %s): " +               "setting %s key in params dictionary failed. ", +               gf_fop_list[stub->fop], pgfid, loc->name, loc->path, +               GF_PREOP_PARENT_KEY); +        goto err; +    } + +    ret = dict_set_bin(local->params, conf->xattr_name, parent_disk_layout, +                       4 * 4); +    if (ret < 0) { +        local->op_errno = -ret; +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "%s (%s/%s) (path: %s): " +               "setting parent-layout in params dictionary failed. ", +               gf_fop_list[stub->fop], pgfid, loc->name, loc->path); +        goto err; +    } + +    parent_disk_layout = NULL; +    local->hashed_subvol = hashed_subvol; + +    local->current = &local->lock[0]; +    ret = dht_protect_namespace(frame, loc, hashed_subvol, &local->current->ns, +                                dht_call_mkdir_stub); +    if (ret < 0) +        goto err; + +    return 0; +err: -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "%s (%s/%s) (path: %s): " -                        "hashed subvolume not found", gf_fop_list[stub->fop], -                        pgfid, loc->name, loc->path); -                goto err; -        } +    if (parent_disk_layout != NULL) +        GF_FREE(parent_disk_layout); -        parent_layout = dht_layout_get (this, loc->parent); +    if (parent_layout != NULL) +        dht_layout_unref(this, parent_layout); -        ret = dht_disk_layout_extract_for_subvol (this, parent_layout, -                                                  hashed_subvol, -                                                  &parent_disk_layout); -        if (ret == -1) { -                local->op_errno = EINVAL; -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "%s (%s/%s) (path: %s): " -                        "extracting in-memory layout of parent failed. ", -                        gf_fop_list[stub->fop], pgfid, loc->name, loc->path); -                goto err; -        } - -        memcpy ((void *)local->parent_disk_layout, (void *)parent_disk_layout, -                sizeof (local->parent_disk_layout)); - -        dht_layout_unref (this, parent_layout); -        parent_layout = NULL; +    return -1; +} -        ret = dict_set_str (local->params, GF_PREOP_PARENT_KEY, -                            conf->xattr_name); -        if (ret < 0) { -                local->op_errno = -ret; -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "%s (%s/%s) (path: %s): " -                        "setting %s key in params dictionary failed. ", -                        gf_fop_list[stub->fop], pgfid, loc->name, loc->path, -                        GF_PREOP_PARENT_KEY); -                goto err; -        } +int +dht_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, +          dev_t rdev, mode_t umask, dict_t *params) +{ +    xlator_t *subvol = NULL; +    int op_errno = -1; +    int i = 0; +    int ret = 0; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; -        ret = dict_set_bin (local->params, conf->xattr_name, parent_disk_layout, -                            4 * 4); -        if (ret < 0) { -                local->op_errno = -ret; -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "%s (%s/%s) (path: %s): " -                        "setting parent-layout in params dictionary failed. ", -                        gf_fop_list[stub->fop], pgfid, loc->name, loc->path); -                goto err; -        } +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); -        parent_disk_layout = NULL; -        local->hashed_subvol = hashed_subvol; +    conf = this->private; -        local->current = &local->lock[0]; -        ret = dht_protect_namespace (frame, loc, hashed_subvol, -                                     &local->current->ns, dht_call_mkdir_stub); -        if (ret < 0) -                goto err; +    dht_get_du_info(frame, this, loc); -        return 0; -err: +    local = dht_local_init(frame, loc, NULL, GF_FOP_MKNOD); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        if (parent_disk_layout != NULL) -                GF_FREE (parent_disk_layout); +    subvol = dht_subvol_get_hashed(this, loc); +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", +                     loc->path); +        op_errno = EIO; +        goto err; +    } -        if (parent_layout != NULL) -                dht_layout_unref (this, parent_layout); +    /* Post remove-brick, the client layout may not be in sync with +     * disk layout because of lack of lookup. Hence,a mknod call +     * may fall on the decommissioned brick.  Hence, if the +     * hashed_subvol is part of decommissioned bricks  list, do a +     * lookup on parent dir. If a fix-layout is already done by the +     * remove-brick process, the parent directory layout will be in +     * sync with that of the disk. If fix-layout is still ending +     * on the parent directory, we can let the file get created on +     * the decommissioned brick which will be eventually migrated to +     * non-decommissioned brick based on the new layout. +     */ -        return -1; -} +    if (conf->decommission_subvols_cnt) { +        for (i = 0; i < conf->subvolume_cnt; i++) { +            if (conf->decommissioned_bricks[i] && +                conf->decommissioned_bricks[i] == subvol) { +                gf_msg_debug(this->name, 0, +                             "hashed subvol:%s is " +                             "part of decommission brick list for " +                             "file: %s", +                             subvol->name, loc->path); + +                /* dht_refresh_layout needs directory info in +                 * local->loc. Hence, storing the parent_loc in +                 * local->loc and storing the create context in +                 * local->loc2. We will restore this information +                 * in dht_creation do */ + +                ret = loc_copy(&local->loc2, &local->loc); +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +                           "loc_copy failed %s", loc->path); -int -dht_mknod (call_frame_t *frame, xlator_t *this, -           loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params) -{ -        xlator_t       *subvol     = NULL; -        int             op_errno   = -1; -        int             i          = 0; -        int             ret        = 0; -        dht_local_t    *local      = NULL; -        dht_conf_t     *conf       = NULL; +                    goto err; +                } -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); +                local->params = dict_ref(params); +                local->rdev = rdev; +                local->mode = mode; +                local->umask = umask; -        conf = this->private; +                loc_wipe(&local->loc); -        dht_get_du_info (frame, this, loc); +                ret = dht_build_parent_loc(this, &local->loc, loc, &op_errno); -        local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_LOC_FAILED, +                           "parent loc build failed"); +                    goto err; +                } -        subvol = dht_subvol_get_hashed (this, loc); -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no subvolume in layout for path=%s", -                              loc->path); -                op_errno = EIO; -                goto err; -        } +                ret = dht_mknod_lock(frame, subvol); -        /* Post remove-brick, the client layout may not be in sync with -        * disk layout because of lack of lookup. Hence,a mknod call -        * may fall on the decommissioned brick.  Hence, if the -        * hashed_subvol is part of decommissioned bricks  list, do a -        * lookup on parent dir. If a fix-layout is already done by the -        * remove-brick process, the parent directory layout will be in -        * sync with that of the disk. If fix-layout is still ending -        * on the parent directory, we can let the file get created on -        * the decommissioned brick which will be eventually migrated to -        * non-decommissioned brick based on the new layout. -        */ +                if (ret < 0) { +                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, +                           "locking parent failed"); +                    goto err; +                } -        if (conf->decommission_subvols_cnt) { -            for (i = 0; i < conf->subvolume_cnt; i++) { -                if (conf->decommissioned_bricks[i] && -                        conf->decommissioned_bricks[i] == subvol) { - -                        gf_msg_debug (this->name, 0, "hashed subvol:%s is " -                                      "part of decommission brick list for " -                                      "file: %s", subvol->name, loc->path); - -                        /* dht_refresh_layout needs directory info in -                         * local->loc. Hence, storing the parent_loc in -                         * local->loc and storing the create context in -                         * local->loc2. We will restore this information -                         * in dht_creation do */ - -                        ret = loc_copy (&local->loc2, &local->loc); -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_NO_MEMORY, -                                        "loc_copy failed %s", loc->path); - -                                goto err; -                        } - -                        local->params = dict_ref (params); -                        local->rdev = rdev; -                        local->mode = mode; -                        local->umask = umask; - -                        loc_wipe (&local->loc); - -                        ret = dht_build_parent_loc (this, &local->loc, loc, -                                                                 &op_errno); - -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_LOC_FAILED, -                                        "parent loc build failed"); -                                goto err; -                        } - -                        ret = dht_mknod_lock (frame, subvol); - -                        if (ret < 0) { -                                gf_msg (this->name, GF_LOG_ERROR, 0, -                                        DHT_MSG_INODE_LK_ERROR, -                                        "locking parent failed"); -                                goto err; -                        } - -                        goto done; -               } +                goto done;              }          } +    } -        dht_mknod_wind_to_avail_subvol (frame, this, subvol, loc, rdev, mode, -                                        umask, params); +    dht_mknod_wind_to_avail_subvol(frame, this, subvol, loc, rdev, mode, umask, +                                   params);  done: -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (mknod, frame, -1, op_errno, -                          NULL, NULL, NULL, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_symlink (call_frame_t *frame, xlator_t *this, -             const char *linkname, loc_t *loc, mode_t umask, dict_t *params) +dht_symlink(call_frame_t *frame, xlator_t *this, const char *linkname, +            loc_t *loc, mode_t umask, dict_t *params)  { -        xlator_t    *subvol = NULL; -        int          op_errno = -1; -        dht_local_t *local = NULL; +    xlator_t *subvol = NULL; +    int op_errno = -1; +    dht_local_t *local = NULL; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); -        local = dht_local_init (frame, loc, NULL, GF_FOP_SYMLINK); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    local = dht_local_init(frame, loc, NULL, GF_FOP_SYMLINK); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        subvol = dht_subvol_get_hashed (this, loc); -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "no subvolume in layout for path=%s", -                              loc->path); -                op_errno = EIO; -                goto err; -        } +    subvol = dht_subvol_get_hashed(this, loc); +    if (!subvol) { +        gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", +                     loc->path); +        op_errno = EIO; +        goto err; +    } -        gf_msg_trace (this->name, 0, -                      "creating %s on %s", loc->path, subvol->name); +    gf_msg_trace(this->name, 0, "creating %s on %s", loc->path, subvol->name); -        STACK_WIND_COOKIE (frame, dht_newfile_cbk, (void *)subvol, subvol, -                           subvol->fops->symlink, linkname, loc, umask, -                           params); +    STACK_WIND_COOKIE(frame, dht_newfile_cbk, (void *)subvol, subvol, +                      subvol->fops->symlink, linkname, loc, umask, params); -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (link, frame, -1, op_errno, -                          NULL, NULL, NULL, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, -            dict_t *xdata) +dht_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, +           dict_t *xdata)  { -        xlator_t    *cached_subvol = NULL; -        int          op_errno = -1; -        dht_local_t *local = NULL; +    xlator_t *cached_subvol = NULL; +    int op_errno = -1; +    dht_local_t *local = NULL; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); -        local = dht_local_init (frame, loc, NULL, GF_FOP_UNLINK); -        if (!local) { -                op_errno = ENOMEM; +    local = dht_local_init(frame, loc, NULL, GF_FOP_UNLINK); +    if (!local) { +        op_errno = ENOMEM; -                goto err; -        } +        goto err; +    } -        cached_subvol = local->cached_subvol; -        if (!cached_subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for path=%s", loc->path); -                op_errno = EINVAL; -                goto err; -        } +    cached_subvol = local->cached_subvol; +    if (!cached_subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", +                     loc->path); +        op_errno = EINVAL; +        goto err; +    } -        local->flags = xflag; -        STACK_WIND_COOKIE (frame, dht_unlink_cbk, cached_subvol, cached_subvol, -                           cached_subvol->fops->unlink, loc, xflag, xdata); +    local->flags = xflag; +    STACK_WIND_COOKIE(frame, dht_unlink_cbk, cached_subvol, cached_subvol, +                      cached_subvol->fops->unlink, loc, xflag, xdata); -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL); - -        return 0; -} - -int -dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -              int op_ret, int op_errno, -              inode_t *inode, struct iatt *stbuf, struct iatt *preparent, -              struct iatt *postparent, dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        int           ret = -1; -        gf_boolean_t  stbuf_merged = _gf_false; -        xlator_t     *subvol = NULL; -        call_frame_t *cleanup_frame = NULL; -        dht_local_t  *cleanup_local = NULL; - -        local = frame->local; - -        if (op_ret == -1) { -                /* Remove the linkto if exists */ -                if (local->linked) { -                        cleanup_frame = create_frame (this, this->ctx->pool); -                        if (cleanup_frame) { -                                cleanup_local = dht_local_init (cleanup_frame, -                                                                &local->loc2, -                                                                NULL, 0); -                                if (!cleanup_local || !local->link_subvol) { -                                        DHT_STACK_DESTROY (cleanup_frame); -                                        goto out; -                                } -                                cleanup_local->link_subvol = local->link_subvol; -                                FRAME_SU_DO (cleanup_frame, dht_local_t); -                                ret = synctask_new (this->ctx->env, -                                                    dht_remove_stale_linkto, -                                                    dht_remove_stale_linkto_cbk, -                                                    cleanup_frame, -                                                    cleanup_frame); -                        } -                } -                /* No continuation on DHT inode missing errors, as we should -                 * then have a good stbuf that states P2 happened. We would -                 * get inode missing if, the file completed migrated between -                 * the lookup and the link call */ -                goto out; +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(unlink, frame, -1, op_errno, NULL, NULL, NULL); + +    return 0; +} + +int +dht_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +             int op_errno, inode_t *inode, struct iatt *stbuf, +             struct iatt *preparent, struct iatt *postparent, dict_t *xdata) +{ +    dht_local_t *local = NULL; +    int ret = -1; +    gf_boolean_t stbuf_merged = _gf_false; +    xlator_t *subvol = NULL; +    call_frame_t *cleanup_frame = NULL; +    dht_local_t *cleanup_local = NULL; + +    local = frame->local; + +    if (op_ret == -1) { +        /* Remove the linkto if exists */ +        if (local->linked) { +            cleanup_frame = create_frame(this, this->ctx->pool); +            if (cleanup_frame) { +                cleanup_local = dht_local_init(cleanup_frame, &local->loc2, +                                               NULL, 0); +                if (!cleanup_local || !local->link_subvol) { +                    DHT_STACK_DESTROY(cleanup_frame); +                    goto out; +                } +                cleanup_local->link_subvol = local->link_subvol; +                FRAME_SU_DO(cleanup_frame, dht_local_t); +                ret = synctask_new(this->ctx->env, dht_remove_stale_linkto, +                                   dht_remove_stale_linkto_cbk, cleanup_frame, +                                   cleanup_frame); +            }          } - -        /* Update parent on success, even if P1/2 checks are positive. -         * The second call on success will further update the parent */ -        if (local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           preparent, 0); -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } - -        /* Update linkto attrs, if this is the first call and non-P2, -         * if we detect P2 then we need to trust the attrs from the -         * second call, not the first */ -        if (local->linked == _gf_true && -            ((local->call_cnt == 1 && !IS_DHT_MIGRATION_PHASE2 (stbuf)) -             || (local->call_cnt != 1 && -                 IS_DHT_MIGRATION_PHASE2 (&local->stbuf)))) { -                dht_iatt_merge (this, &local->stbuf, stbuf); -                stbuf_merged = _gf_true; -                dht_linkfile_attr_heal (frame, this); -        } - -        /* No further P1/2 checks if we are in the second iteration of -         * the call */ -        if (local->call_cnt != 1) { -                goto out; +        /* No continuation on DHT inode missing errors, as we should +         * then have a good stbuf that states P2 happened. We would +         * get inode missing if, the file completed migrated between +         * the lookup and the link call */ +        goto out; +    } + +    /* Update parent on success, even if P1/2 checks are positive. +     * The second call on success will further update the parent */ +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, preparent, 0); +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    } + +    /* Update linkto attrs, if this is the first call and non-P2, +     * if we detect P2 then we need to trust the attrs from the +     * second call, not the first */ +    if (local->linked == _gf_true && +        ((local->call_cnt == 1 && !IS_DHT_MIGRATION_PHASE2(stbuf)) || +         (local->call_cnt != 1 && IS_DHT_MIGRATION_PHASE2(&local->stbuf)))) { +        dht_iatt_merge(this, &local->stbuf, stbuf); +        stbuf_merged = _gf_true; +        dht_linkfile_attr_heal(frame, this); +    } + +    /* No further P1/2 checks if we are in the second iteration of +     * the call */ +    if (local->call_cnt != 1) { +        goto out; +    } else { +        /* Preserve the return values, in case the migration decides +         * to recreate the link on the same subvol that the current +         * hased for the link was created on. */ +        dht_iatt_merge(this, &local->preparent, preparent); +        dht_iatt_merge(this, &local->postparent, postparent); +        if (!stbuf_merged) { +            dht_iatt_merge(this, &local->stbuf, stbuf); +            stbuf_merged = _gf_true; +        } + +        local->inode = inode_ref(inode); +    } + +    local->op_ret = op_ret; +    local->op_errno = op_errno; +    local->rebalance.target_op_fn = dht_link2; +    dht_set_local_rebalance(this, local, stbuf, preparent, postparent, xdata); + +    /* Check if the rebalance phase2 is true */ +    if (IS_DHT_MIGRATION_PHASE2(stbuf)) { +        ret = dht_inode_ctx_get_mig_info(this, local->loc.inode, NULL, &subvol); +        if (!subvol) { +            /* Phase 2 of migration */ +            ret = dht_rebalance_complete_check(this, frame); +            if (!ret) +                return 0;          } else { -                /* Preserve the return values, in case the migration decides -                 * to recreate the link on the same subvol that the current -                 * hased for the link was created on. */ -                dht_iatt_merge (this, &local->preparent, preparent); -                dht_iatt_merge (this, &local->postparent, postparent); -                if (!stbuf_merged) { -                        dht_iatt_merge (this, &local->stbuf, stbuf); -                        stbuf_merged = _gf_true; -                } - -                local->inode = inode_ref (inode); -        } - -        local->op_ret = op_ret; -        local->op_errno = op_errno; -        local->rebalance.target_op_fn = dht_link2; -        dht_set_local_rebalance (this, local, stbuf, preparent, -                                 postparent, xdata); - -        /* Check if the rebalance phase2 is true */ -        if (IS_DHT_MIGRATION_PHASE2 (stbuf)) { -                ret = dht_inode_ctx_get_mig_info (this, local->loc.inode, NULL, -                                                  &subvol); -                if (!subvol) { -                        /* Phase 2 of migration */ -                        ret = dht_rebalance_complete_check (this, frame); -                        if (!ret) -                                return 0; -                } else { -                        dht_link2 (this, subvol, frame, 0); -                        return 0; -                } -        } - -        /* Check if the rebalance phase1 is true */ -        if (IS_DHT_MIGRATION_PHASE1 (stbuf)) { -                ret = dht_inode_ctx_get_mig_info (this, local->loc.inode, NULL, -                                                  &subvol); -                if (subvol) { -                        dht_link2 (this, subvol, frame, 0); -                        return 0; -                } -                ret = dht_rebalance_in_progress_check (this, frame); -                if (!ret) -                        return 0; -        } +            dht_link2(this, subvol, frame, 0); +            return 0; +        } +    } + +    /* Check if the rebalance phase1 is true */ +    if (IS_DHT_MIGRATION_PHASE1(stbuf)) { +        ret = dht_inode_ctx_get_mig_info(this, local->loc.inode, NULL, &subvol); +        if (subvol) { +            dht_link2(this, subvol, frame, 0); +            return 0; +        } +        ret = dht_rebalance_in_progress_check(this, frame); +        if (!ret) +            return 0; +    }  out: -        DHT_STRIP_PHASE1_FLAGS (stbuf); +    DHT_STRIP_PHASE1_FLAGS(stbuf); -        dht_set_fixed_dir_stat (preparent); -        dht_set_fixed_dir_stat (postparent); -        DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, -                          preparent, postparent, NULL); +    dht_set_fixed_dir_stat(preparent); +    dht_set_fixed_dir_stat(postparent); +    DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, +                     postparent, NULL); -        return 0; +    return 0;  } -  int -dht_link2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) +dht_link2(xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret)  { -        dht_local_t *local  = NULL; -        int          op_errno = EINVAL; - -        local = frame->local; -        if (!local) -                goto err; +    dht_local_t *local = NULL; +    int op_errno = EINVAL; -        op_errno = local->op_errno; +    local = frame->local; +    if (!local) +        goto err; -        if (we_are_not_migrating (ret)) { -                /* This dht xlator is not migrating the file. Unwind and -                 * pass on the original mode bits so the higher DHT layer -                 * can handle this. -                 */ -                dht_set_fixed_dir_stat (&local->preparent); -                dht_set_fixed_dir_stat (&local->postparent); +    op_errno = local->op_errno; -                DHT_STACK_UNWIND (link, frame, local->op_ret, op_errno, -                                  local->inode, -                                  &local->stbuf, &local->preparent, -                                  &local->postparent, NULL); -                return 0; -        } - -        if (subvol == NULL) { -                op_errno = EINVAL; -                goto err; -        } - -        /* Second call to create link file could result in EEXIST as the -         * first call created the linkto in the currently -         * migrating subvol, which could be the new hashed subvol */ -        if (local->link_subvol == subvol) { -                DHT_STRIP_PHASE1_FLAGS (&local->stbuf); -                dht_set_fixed_dir_stat (&local->preparent); -                dht_set_fixed_dir_stat (&local->postparent); -                DHT_STACK_UNWIND (link, frame, 0, 0, local->inode, -                                  &local->stbuf, &local->preparent, -                                  &local->postparent, NULL); - -                return 0; -        } - -        local->call_cnt = 2; - -        STACK_WIND (frame, dht_link_cbk, subvol, subvol->fops->link, -                    &local->loc, &local->loc2, local->xattr_req); +    if (we_are_not_migrating(ret)) { +        /* This dht xlator is not migrating the file. Unwind and +         * pass on the original mode bits so the higher DHT layer +         * can handle this. +         */ +        dht_set_fixed_dir_stat(&local->preparent); +        dht_set_fixed_dir_stat(&local->postparent); +        DHT_STACK_UNWIND(link, frame, local->op_ret, op_errno, local->inode, +                         &local->stbuf, &local->preparent, &local->postparent, +                         NULL);          return 0; -err: -        DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL, NULL); +    } -        return 0; -} +    if (subvol == NULL) { +        op_errno = EINVAL; +        goto err; +    } -int -dht_link_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, -                       inode_t *inode, struct iatt *stbuf, -                       struct iatt *preparent, struct iatt *postparent, -                       dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        xlator_t     *srcvol = NULL; +    /* Second call to create link file could result in EEXIST as the +     * first call created the linkto in the currently +     * migrating subvol, which could be the new hashed subvol */ +    if (local->link_subvol == subvol) { +        DHT_STRIP_PHASE1_FLAGS(&local->stbuf); +        dht_set_fixed_dir_stat(&local->preparent); +        dht_set_fixed_dir_stat(&local->postparent); +        DHT_STACK_UNWIND(link, frame, 0, 0, local->inode, &local->stbuf, +                         &local->preparent, &local->postparent, NULL); -        if (op_ret == -1) -                goto err; +        return 0; +    } -        local = frame->local; -        srcvol = local->linkfile.srcvol; +    local->call_cnt = 2; -        STACK_WIND (frame, dht_link_cbk, srcvol, srcvol->fops->link, -                    &local->loc, &local->loc2, local->xattr_req); - -        return 0; +    STACK_WIND(frame, dht_link_cbk, subvol, subvol->fops->link, &local->loc, +               &local->loc2, local->xattr_req); +    return 0;  err: -        DHT_STRIP_PHASE1_FLAGS (stbuf); -        dht_set_fixed_dir_stat (preparent); -        dht_set_fixed_dir_stat (postparent); -        DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent, -                          postparent, xdata); +    DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_link (call_frame_t *frame, xlator_t *this, -          loc_t *oldloc, loc_t *newloc, dict_t *xdata) +dht_link_linkfile_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int op_ret, int op_errno, inode_t *inode, +                      struct iatt *stbuf, struct iatt *preparent, +                      struct iatt *postparent, dict_t *xdata)  { -        xlator_t    *cached_subvol = NULL; -        xlator_t    *hashed_subvol = NULL; -        int          op_errno = -1; -        int          ret = -1; -        dht_local_t *local = NULL; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (oldloc, err); -        VALIDATE_OR_GOTO (newloc, err); +    dht_local_t *local = NULL; +    xlator_t *srcvol = NULL; -        local = dht_local_init (frame, oldloc, NULL, GF_FOP_LINK); -        if (!local) { -                op_errno = ENOMEM; +    if (op_ret == -1) +        goto err; -                goto err; -        } -        local->call_cnt = 1; +    local = frame->local; +    srcvol = local->linkfile.srcvol; -        cached_subvol = local->cached_subvol; -        if (!cached_subvol) { -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for path=%s", oldloc->path); -                op_errno = ENOENT; -                goto err; -        } +    STACK_WIND(frame, dht_link_cbk, srcvol, srcvol->fops->link, &local->loc, +               &local->loc2, local->xattr_req); -        hashed_subvol = dht_subvol_get_hashed (this, newloc); -        if (!hashed_subvol) { -                gf_msg_debug (this->name, 0, -                              "no subvolume in layout for path=%s", -                              newloc->path); -                op_errno = EIO; -                goto err; -        } +    return 0; -        ret = loc_copy (&local->loc2, newloc); -        if (ret == -1) { -                op_errno = ENOMEM; -                goto err; -        } -        if (xdata) -                local->xattr_req = dict_ref (xdata); - -        if (hashed_subvol != cached_subvol) { -                gf_uuid_copy (local->gfid, oldloc->inode->gfid); -                dht_linkfile_create (frame, dht_link_linkfile_cbk, this, -                                     cached_subvol, hashed_subvol, newloc); -        } else { -                STACK_WIND (frame, dht_link_cbk, -                            cached_subvol, cached_subvol->fops->link, -                            oldloc, newloc, xdata); -        } - -        return 0; +err: +    DHT_STRIP_PHASE1_FLAGS(stbuf); +    dht_set_fixed_dir_stat(preparent); +    dht_set_fixed_dir_stat(postparent); +    DHT_STACK_UNWIND(link, frame, op_ret, op_errno, inode, stbuf, preparent, +                     postparent, xdata); + +    return 0; +} + +int +dht_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, +         dict_t *xdata) +{ +    xlator_t *cached_subvol = NULL; +    xlator_t *hashed_subvol = NULL; +    int op_errno = -1; +    int ret = -1; +    dht_local_t *local = NULL; + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(oldloc, err); +    VALIDATE_OR_GOTO(newloc, err); + +    local = dht_local_init(frame, oldloc, NULL, GF_FOP_LINK); +    if (!local) { +        op_errno = ENOMEM; + +        goto err; +    } +    local->call_cnt = 1; + +    cached_subvol = local->cached_subvol; +    if (!cached_subvol) { +        gf_msg_debug(this->name, 0, "no cached subvolume for path=%s", +                     oldloc->path); +        op_errno = ENOENT; +        goto err; +    } + +    hashed_subvol = dht_subvol_get_hashed(this, newloc); +    if (!hashed_subvol) { +        gf_msg_debug(this->name, 0, "no subvolume in layout for path=%s", +                     newloc->path); +        op_errno = EIO; +        goto err; +    } + +    ret = loc_copy(&local->loc2, newloc); +    if (ret == -1) { +        op_errno = ENOMEM; +        goto err; +    } +    if (xdata) +        local->xattr_req = dict_ref(xdata); + +    if (hashed_subvol != cached_subvol) { +        gf_uuid_copy(local->gfid, oldloc->inode->gfid); +        dht_linkfile_create(frame, dht_link_linkfile_cbk, this, cached_subvol, +                            hashed_subvol, newloc); +    } else { +        STACK_WIND(frame, dht_link_cbk, cached_subvol, +                   cached_subvol->fops->link, oldloc, newloc, xdata); +    } + +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  } -  int -dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                int op_ret, int op_errno, -                fd_t *fd, inode_t *inode, struct iatt *stbuf, -                struct iatt *preparent, struct iatt *postparent, dict_t *xdata) +dht_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +               int op_errno, fd_t *fd, inode_t *inode, struct iatt *stbuf, +               struct iatt *preparent, struct iatt *postparent, dict_t *xdata)  { -        xlator_t     *prev = NULL; -        int           ret = -1; -        dht_local_t  *local = NULL; +    xlator_t *prev = NULL; +    int ret = -1; +    dht_local_t *local = NULL; -        local = frame->local; -        if (!local) { -                op_ret = -1; -                op_errno = EINVAL; -                goto out; -        } +    local = frame->local; +    if (!local) { +        op_ret = -1; +        op_errno = EINVAL; +        goto out; +    } -        if (op_ret == -1) -                goto out; +    if (op_ret == -1) +        goto out; -        prev = cookie; +    prev = cookie; -        if (local->loc.parent) { -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           preparent, 0); +    if (local->loc.parent) { +        dht_inode_ctx_time_update(local->loc.parent, this, preparent, 0); -                dht_inode_ctx_time_update (local->loc.parent, this, -                                           postparent, 1); -        } +        dht_inode_ctx_time_update(local->loc.parent, this, postparent, 1); +    } -        ret = dht_fd_ctx_set (this, fd, prev); -        if (ret != 0) { -                gf_msg_debug (this->name, 0, "Possible fd leak. " -                              "Could not set fd ctx for subvol %s", -                              prev->name); -        } +    ret = dht_fd_ctx_set(this, fd, prev); +    if (ret != 0) { +        gf_msg_debug(this->name, 0, +                     "Possible fd leak. " +                     "Could not set fd ctx for subvol %s", +                     prev->name); +    } +    ret = dht_layout_preset(this, prev, inode); +    if (ret != 0) { +        gf_msg_debug(this->name, 0, "could not set preset layout for subvol %s", +                     prev->name); +        op_ret = -1; +        op_errno = EINVAL; +        goto out; +    } -        ret = dht_layout_preset (this, prev, inode); -        if (ret != 0) { -                gf_msg_debug (this->name, 0, -                              "could not set preset layout for subvol %s", -                              prev->name); -                op_ret   = -1; -                op_errno = EINVAL; -                goto out; -        } - -        local->op_errno = op_errno; +    local->op_errno = op_errno; -        if (local->linked == _gf_true) { -                local->stbuf = *stbuf; -                dht_linkfile_attr_heal (frame, this); -        } +    if (local->linked == _gf_true) { +        local->stbuf = *stbuf; +        dht_linkfile_attr_heal(frame, this); +    }  out: -        DHT_STRIP_PHASE1_FLAGS (stbuf); -        dht_set_fixed_dir_stat (preparent); -        dht_set_fixed_dir_stat (postparent); +    DHT_STRIP_PHASE1_FLAGS(stbuf); +    dht_set_fixed_dir_stat(preparent); +    dht_set_fixed_dir_stat(postparent); -        if (local && local->lock[0].layout.parent_layout.locks) { -                /* store op_errno for failure case*/ -                local->op_errno = op_errno; -                local->refresh_layout_unlock (frame, this, op_ret, 1); +    if (local && local->lock[0].layout.parent_layout.locks) { +        /* store op_errno for failure case*/ +        local->op_errno = op_errno; +        local->refresh_layout_unlock(frame, this, op_ret, 1); -                if (op_ret == 0) { -                        DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, -                                          inode, stbuf, preparent, postparent, -                                          xdata); -                } -        } else { -                DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, -                                  stbuf, preparent, postparent, xdata); +        if (op_ret == 0) { +            DHT_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, +                             preparent, postparent, xdata);          } -        return 0; +    } else { +        DHT_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, stbuf, +                         preparent, postparent, xdata); +    } +    return 0;  }  int -dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie, -                                xlator_t *this, -                                int32_t op_ret, int32_t op_errno, -                                inode_t *inode, struct iatt *stbuf, -                                struct iatt *preparent, struct iatt *postparent, -                                dict_t *xdata) +dht_create_linkfile_create_cbk(call_frame_t *frame, void *cookie, +                               xlator_t *this, int32_t op_ret, int32_t op_errno, +                               inode_t *inode, struct iatt *stbuf, +                               struct iatt *preparent, struct iatt *postparent, +                               dict_t *xdata)  { -        dht_local_t     *local             = NULL; -        xlator_t        *cached_subvol     = NULL; -        dht_conf_t      *conf              = NULL; +    dht_local_t *local = NULL; +    xlator_t *cached_subvol = NULL; +    dht_conf_t *conf = NULL; -        local = frame->local; -        if (!local) { -                op_errno = EINVAL; -                goto err; -        } +    local = frame->local; +    if (!local) { +        op_errno = EINVAL; +        goto err; +    } -        if (op_ret == -1) { -                local->op_errno = op_errno; -                goto err; -        } +    if (op_ret == -1) { +        local->op_errno = op_errno; +        goto err; +    } -        conf = this->private; -        if (!conf) { -                local->op_errno = EINVAL; -                op_errno = EINVAL; -                goto err; -        } +    conf = this->private; +    if (!conf) { +        local->op_errno = EINVAL; +        op_errno = EINVAL; +        goto err; +    } -        cached_subvol = local->cached_subvol; +    cached_subvol = local->cached_subvol; -        if (local->params) { -                dict_del (local->params, conf->link_xattr_name); -                dict_del (local->params, GLUSTERFS_INTERNAL_FOP_KEY); -        } +    if (local->params) { +        dict_del(local->params, conf->link_xattr_name); +        dict_del(local->params, GLUSTERFS_INTERNAL_FOP_KEY); +    } -        STACK_WIND_COOKIE (frame, dht_create_cbk, cached_subvol, -                           cached_subvol, cached_subvol->fops->create, -                           &local->loc, local->flags, local->mode, -                           local->umask, local->fd, local->params); +    STACK_WIND_COOKIE(frame, dht_create_cbk, cached_subvol, cached_subvol, +                      cached_subvol->fops->create, &local->loc, local->flags, +                      local->mode, local->umask, local->fd, local->params); -        return 0; +    return 0;  err: -        if (local && local->lock[0].layout.parent_layout.locks) { -                local->refresh_layout_unlock (frame, this, -1, 1); -        } else { -                DHT_STACK_UNWIND (create, frame, -1, -                                  op_errno, NULL, NULL, NULL, -                                  NULL, NULL, NULL); -        } -        return 0; +    if (local && local->lock[0].layout.parent_layout.locks) { +        local->refresh_layout_unlock(frame, this, -1, 1); +    } else { +        DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, +                         NULL, NULL); +    } +    return 0;  }  int -dht_create_wind_to_avail_subvol (call_frame_t *frame, xlator_t *this, -                                 xlator_t *subvol, loc_t *loc, int32_t flags, -                                 mode_t mode, mode_t umask, fd_t *fd, -                                 dict_t *params) +dht_create_wind_to_avail_subvol(call_frame_t *frame, xlator_t *this, +                                xlator_t *subvol, loc_t *loc, int32_t flags, +                                mode_t mode, mode_t umask, fd_t *fd, +                                dict_t *params)  { -        dht_local_t     *local          = NULL; -        xlator_t        *avail_subvol   = NULL; +    dht_local_t *local = NULL; +    xlator_t *avail_subvol = NULL; -        local = frame->local; +    local = frame->local; -        if (!dht_is_subvol_filled (this, subvol)) { -                gf_msg_debug (this->name, 0, -                              "creating %s on %s", loc->path, -                              subvol->name); +    if (!dht_is_subvol_filled(this, subvol)) { +        gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, +                     subvol->name); -                STACK_WIND_COOKIE (frame, dht_create_cbk, subvol, -                                   subvol, subvol->fops->create, -                                   loc, flags, mode, umask, fd, params); +        STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, +                          subvol->fops->create, loc, flags, mode, umask, fd, +                          params); -        } else { -                avail_subvol = dht_free_disk_available_subvol (this, subvol, local); +    } else { +        avail_subvol = dht_free_disk_available_subvol(this, subvol, local); -                if (avail_subvol != subvol) { -                        local->params = dict_ref (params); -                        local->flags = flags; -                        local->mode = mode; -                        local->umask = umask; -                        local->cached_subvol = avail_subvol; -                        local->hashed_subvol = subvol; +        if (avail_subvol != subvol) { +            local->params = dict_ref(params); +            local->flags = flags; +            local->mode = mode; +            local->umask = umask; +            local->cached_subvol = avail_subvol; +            local->hashed_subvol = subvol; -                        gf_msg_debug (this->name, 0, -                                      "creating %s on %s (link at %s)", loc->path, -                                      avail_subvol->name, subvol->name); +            gf_msg_debug(this->name, 0, "creating %s on %s (link at %s)", +                         loc->path, avail_subvol->name, subvol->name); -                        dht_linkfile_create (frame, dht_create_linkfile_create_cbk, -                                             this, avail_subvol, subvol, loc); +            dht_linkfile_create(frame, dht_create_linkfile_create_cbk, this, +                                avail_subvol, subvol, loc); -                        goto out; -                } +            goto out; +        } -                gf_msg_debug (this->name, 0, -                              "creating %s on %s", loc->path, subvol->name); +        gf_msg_debug(this->name, 0, "creating %s on %s", loc->path, +                     subvol->name); -                STACK_WIND_COOKIE (frame, dht_create_cbk, subvol, -                                   subvol, subvol->fops->create, -                                   loc, flags, mode, umask, fd, params); -        } +        STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, +                          subvol->fops->create, loc, flags, mode, umask, fd, +                          params); +    }  out: -        return 0; +    return 0;  }  int -dht_build_parent_loc (xlator_t *this, loc_t *parent, loc_t *child, -                      int32_t *op_errno) +dht_build_parent_loc(xlator_t *this, loc_t *parent, loc_t *child, +                     int32_t *op_errno)  { -        inode_table_t   *table = NULL; -        int     ret = -1; +    inode_table_t *table = NULL; +    int ret = -1; -        if (!parent || !child) { -                if (op_errno) -                        *op_errno = EINVAL; -                goto out; -        } +    if (!parent || !child) { +        if (op_errno) +            *op_errno = EINVAL; +        goto out; +    } -        if (child->parent) { -                parent->inode = inode_ref (child->parent); -                if (!parent->inode) { -                        if (op_errno) -                                *op_errno = EINVAL; -                        goto out; -                } +    if (child->parent) { +        parent->inode = inode_ref(child->parent); +        if (!parent->inode) { +            if (op_errno) +                *op_errno = EINVAL; +            goto out; +        } -                gf_uuid_copy (parent->gfid, child->pargfid); +        gf_uuid_copy(parent->gfid, child->pargfid); -                ret = 0; +        ret = 0; -                goto out; -        } else { -                if (gf_uuid_is_null (child->pargfid)) { -                        if (op_errno) -                                *op_errno = EINVAL; -                        goto out; -                } +        goto out; +    } else { +        if (gf_uuid_is_null(child->pargfid)) { +            if (op_errno) +                *op_errno = EINVAL; +            goto out; +        } -                table = this->itable; +        table = this->itable; -                if (!table) { -                        if (op_errno) { -                                *op_errno = EINVAL; -                                goto out; -                        } -                } +        if (!table) { +            if (op_errno) { +                *op_errno = EINVAL; +                goto out; +            } +        } -                parent->inode = inode_find (table, child->pargfid); +        parent->inode = inode_find(table, child->pargfid); -                if (!parent->inode) { -                         if (op_errno) { -                                *op_errno = EINVAL; -                                goto out; -                        } -                } +        if (!parent->inode) { +            if (op_errno) { +                *op_errno = EINVAL; +                goto out; +            } +        } -                gf_uuid_copy (parent->gfid, child->pargfid); +        gf_uuid_copy(parent->gfid, child->pargfid); -                ret = 0; -        } +        ret = 0; +    }  out: -        return ret; +    return ret;  } -  int32_t -dht_create_do (call_frame_t *frame) +dht_create_do(call_frame_t *frame)  { -        dht_local_t     *local          = NULL; -        dht_layout_t    *refreshed      = NULL; -        xlator_t        *subvol         = NULL; -        xlator_t        *this           = NULL; -        dht_conf_t      *conf           = NULL; -        dht_methods_t   *methods        = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *refreshed = NULL; +    xlator_t *subvol = NULL; +    xlator_t *this = NULL; +    dht_conf_t *conf = NULL; +    dht_methods_t *methods = NULL; -        local = frame->local; +    local = frame->local; -        this = THIS; +    this = THIS; -        conf = this->private; +    conf = this->private; -        GF_VALIDATE_OR_GOTO (this->name, conf, err); +    GF_VALIDATE_OR_GOTO(this->name, conf, err); -        methods = &(conf->methods); +    methods = &(conf->methods); -        /* We don't need parent_loc anymore */ -        loc_wipe (&local->loc); +    /* We don't need parent_loc anymore */ +    loc_wipe(&local->loc); -        loc_copy (&local->loc, &local->loc2); +    loc_copy(&local->loc, &local->loc2); -        loc_wipe (&local->loc2); +    loc_wipe(&local->loc2); -        refreshed = local->selfheal.refreshed_layout; +    refreshed = local->selfheal.refreshed_layout; -        subvol = methods->layout_search (this, refreshed, local->loc.name); +    subvol = methods->layout_search(this, refreshed, local->loc.name); -        if (!subvol) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_HASHED_SUBVOL_GET_FAILED, "no subvolume in " -                        "layout for path=%s", local->loc.path); -                local->op_errno = ENOENT; -                goto err; -        } +    if (!subvol) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, +               "no subvolume in " +               "layout for path=%s", +               local->loc.path); +        local->op_errno = ENOENT; +        goto err; +    } -        dht_create_wind_to_avail_subvol (frame, this, subvol, &local->loc, -                                         local->flags, local->mode, -                                         local->umask, local->fd, local->params); -        return 0; +    dht_create_wind_to_avail_subvol(frame, this, subvol, &local->loc, +                                    local->flags, local->mode, local->umask, +                                    local->fd, local->params); +    return 0;  err: -        local->refresh_layout_unlock (frame, this, -1, 1); +    local->refresh_layout_unlock(frame, this, -1, 1); -        return 0; +    return 0;  }  int32_t -dht_create_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                         int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_create_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  }  int32_t -dht_create_finish (call_frame_t *frame, xlator_t *this, int op_ret, -                   int invoke_cbk) +dht_create_finish(call_frame_t *frame, xlator_t *this, int op_ret, +                  int invoke_cbk)  { -        dht_local_t  *local      = NULL, *lock_local = NULL; -        call_frame_t *lock_frame = NULL; -        int           lock_count = 0; - -        local = frame->local; -        lock_count = dht_lock_count (local->lock[0].layout.parent_layout.locks, -                                     local->lock[0].layout.parent_layout.lk_count); -        if (lock_count == 0) -                goto done; - -        lock_frame = copy_frame (frame); -        if (lock_frame == NULL) { -                goto done; -        } - -        lock_local = dht_local_init (lock_frame, &local->loc, NULL, -                                     lock_frame->root->op); -        if (lock_local == NULL) { -                goto done; -        } - -        lock_local->lock[0].layout.parent_layout.locks = local->lock[0].layout.parent_layout.locks; -        lock_local->lock[0].layout.parent_layout.lk_count = local->lock[0].layout.parent_layout.lk_count; - -        local->lock[0].layout.parent_layout.locks = NULL; -	local->lock[0].layout.parent_layout.lk_count = 0; - -        dht_unlock_inodelk (lock_frame, -                            lock_local->lock[0].layout.parent_layout.locks, -                            lock_local->lock[0].layout.parent_layout.lk_count, -                            dht_create_unlock_cbk); -        lock_frame = NULL; +    dht_local_t *local = NULL, *lock_local = NULL; +    call_frame_t *lock_frame = NULL; +    int lock_count = 0; + +    local = frame->local; +    lock_count = dht_lock_count(local->lock[0].layout.parent_layout.locks, +                                local->lock[0].layout.parent_layout.lk_count); +    if (lock_count == 0) +        goto done; + +    lock_frame = copy_frame(frame); +    if (lock_frame == NULL) { +        goto done; +    } + +    lock_local = dht_local_init(lock_frame, &local->loc, NULL, +                                lock_frame->root->op); +    if (lock_local == NULL) { +        goto done; +    } + +    lock_local->lock[0] +        .layout.parent_layout.locks = local->lock[0].layout.parent_layout.locks; +    lock_local->lock[0].layout.parent_layout.lk_count = +        local->lock[0].layout.parent_layout.lk_count; + +    local->lock[0].layout.parent_layout.locks = NULL; +    local->lock[0].layout.parent_layout.lk_count = 0; + +    dht_unlock_inodelk(lock_frame, +                       lock_local->lock[0].layout.parent_layout.locks, +                       lock_local->lock[0].layout.parent_layout.lk_count, +                       dht_create_unlock_cbk); +    lock_frame = NULL;  done: -        if (lock_frame != NULL) { -                DHT_STACK_DESTROY (lock_frame); -        } - -        if (op_ret == 0) -                return 0; +    if (lock_frame != NULL) { +        DHT_STACK_DESTROY(lock_frame); +    } -        DHT_STACK_UNWIND (create, frame, op_ret, local->op_errno, NULL, NULL, -                          NULL, NULL, NULL, NULL); +    if (op_ret == 0)          return 0; + +    DHT_STACK_UNWIND(create, frame, op_ret, local->op_errno, NULL, NULL, NULL, +                     NULL, NULL, NULL); +    return 0;  }  int32_t -dht_create_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                     int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_create_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t     *local = NULL; +    dht_local_t *local = NULL; -        local = frame->local; +    local = frame->local; -        if (!local) { -                goto err; -        } +    if (!local) { +        goto err; +    } -        if (op_ret < 0) { -                gf_msg ("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, -                        "Create lock failed for file: %s", local->loc2.name); +    if (op_ret < 0) { +        gf_msg("DHT", GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, +               "Create lock failed for file: %s", local->loc2.name); -                local->op_errno = op_errno; +        local->op_errno = op_errno; -                goto err; -        } +        goto err; +    } -        local->refresh_layout_unlock = dht_create_finish; +    local->refresh_layout_unlock = dht_create_finish; -        local->refresh_layout_done = dht_create_do; +    local->refresh_layout_done = dht_create_do; -        dht_refresh_layout (frame); +    dht_refresh_layout(frame); -        return 0; +    return 0;  err: -        dht_create_finish (frame, this, -1, 0); -        return 0; +    dht_create_finish(frame, this, -1, 0); +    return 0;  }  int32_t -dht_create_lock (call_frame_t *frame, xlator_t *subvol) +dht_create_lock(call_frame_t *frame, xlator_t *subvol)  { -        dht_local_t     *local          = NULL; -        int              count  = 1,    ret = -1; -        dht_lock_t     **lk_array       = NULL; +    dht_local_t *local = NULL; +    int count = 1, ret = -1; +    dht_lock_t **lk_array = NULL; -        GF_VALIDATE_OR_GOTO ("dht", frame, err); -        GF_VALIDATE_OR_GOTO (frame->this->name, frame->local, err); +    GF_VALIDATE_OR_GOTO("dht", frame, err); +    GF_VALIDATE_OR_GOTO(frame->this->name, frame->local, err); -        local = frame->local; +    local = frame->local; -        lk_array = GF_CALLOC (count, sizeof (*lk_array), gf_common_mt_pointer); +    lk_array = GF_CALLOC(count, sizeof(*lk_array), gf_common_mt_pointer); -        if (lk_array == NULL) -                goto err; +    if (lk_array == NULL) +        goto err; -        lk_array[0] = dht_lock_new (frame->this, subvol, &local->loc, F_RDLCK, -                                    DHT_LAYOUT_HEAL_DOMAIN, NULL, -                                    IGNORE_ENOENT_ESTALE); +    lk_array[0] = dht_lock_new(frame->this, subvol, &local->loc, F_RDLCK, +                               DHT_LAYOUT_HEAL_DOMAIN, NULL, +                               IGNORE_ENOENT_ESTALE); -        if (lk_array[0] == NULL) -                goto err; +    if (lk_array[0] == NULL) +        goto err; -        local->lock[0].layout.parent_layout.locks = lk_array; -        local->lock[0].layout.parent_layout.lk_count = count; +    local->lock[0].layout.parent_layout.locks = lk_array; +    local->lock[0].layout.parent_layout.lk_count = count; -        ret = dht_blocking_inodelk (frame, lk_array, count, -                                    dht_create_lock_cbk); +    ret = dht_blocking_inodelk(frame, lk_array, count, dht_create_lock_cbk); -        if (ret < 0) { -                local->lock[0].layout.parent_layout.locks = NULL; -                local->lock[0].layout.parent_layout.lk_count = 0; -                goto err; -        } +    if (ret < 0) { +        local->lock[0].layout.parent_layout.locks = NULL; +        local->lock[0].layout.parent_layout.lk_count = 0; +        goto err; +    } -        return 0; +    return 0;  err: -        if (lk_array != NULL) { -                dht_lock_array_free (lk_array, count); -                GF_FREE (lk_array); -        } +    if (lk_array != NULL) { +        dht_lock_array_free(lk_array, count); +        GF_FREE(lk_array); +    } -        return -1; +    return -1;  }  int -dht_create (call_frame_t *frame, xlator_t *this, -            loc_t *loc, int32_t flags, mode_t mode, -            mode_t umask, fd_t *fd, dict_t *params) +dht_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, +           mode_t mode, mode_t umask, fd_t *fd, dict_t *params)  { -        int             op_errno           = -1; -        xlator_t       *subvol             = NULL; -        xlator_t       *hashed_subvol      = NULL; -        dht_local_t    *local              = NULL; -        int             i                  = 0; -        dht_conf_t     *conf               = NULL; -        int             ret                = 0; +    int op_errno = -1; +    xlator_t *subvol = NULL; +    xlator_t *hashed_subvol = NULL; +    dht_local_t *local = NULL; +    int i = 0; +    dht_conf_t *conf = NULL; +    int ret = 0; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); -        conf = this->private; +    conf = this->private; -        dht_get_du_info (frame, this, loc); +    dht_get_du_info(frame, this, loc); -        local = dht_local_init (frame, loc, fd, GF_FOP_CREATE); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    local = dht_local_init(frame, loc, fd, GF_FOP_CREATE); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        if (dht_filter_loc_subvol_key (this, loc, &local->loc, -                                       &subvol)) { -                gf_msg (this->name, GF_LOG_INFO, 0, -                        DHT_MSG_SUBVOL_INFO, -                        "creating %s on %s (got create on %s)", -                        local->loc.path, subvol->name, loc->path); +    if (dht_filter_loc_subvol_key(this, loc, &local->loc, &subvol)) { +        gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_SUBVOL_INFO, +               "creating %s on %s (got create on %s)", local->loc.path, +               subvol->name, loc->path); -                /* Since lookup-optimize is enabled by default, we need -                 * to create the linkto file if required. -                 * Note this does not check for decommisioned bricks -                 * and min-free-disk limits as this is a debugging tool -                 * and not expected to be used in production. -                 */ -                hashed_subvol = dht_subvol_get_hashed (this, &local->loc); - -                if (hashed_subvol && (hashed_subvol != subvol)) { -                        /* Create the linkto file and then the data file */ -                        local->params = dict_ref (params); -                        local->flags = flags; -                        local->mode = mode; -                        local->umask = umask; -                        local->cached_subvol = subvol; -                        local->hashed_subvol = hashed_subvol; - -                        dht_linkfile_create (frame, -                                             dht_create_linkfile_create_cbk, -                                             this, subvol, hashed_subvol, -                                             &local->loc); -                        goto done; +        /* Since lookup-optimize is enabled by default, we need +         * to create the linkto file if required. +         * Note this does not check for decommisioned bricks +         * and min-free-disk limits as this is a debugging tool +         * and not expected to be used in production. +         */ +        hashed_subvol = dht_subvol_get_hashed(this, &local->loc); + +        if (hashed_subvol && (hashed_subvol != subvol)) { +            /* Create the linkto file and then the data file */ +            local->params = dict_ref(params); +            local->flags = flags; +            local->mode = mode; +            local->umask = umask; +            local->cached_subvol = subvol; +            local->hashed_subvol = hashed_subvol; + +            dht_linkfile_create(frame, dht_create_linkfile_create_cbk, this, +                                subvol, hashed_subvol, &local->loc); +            goto done; +        } +        /* We either don't have a hashed subvol or the hashed subvol is +         * the same as the one specified. No need to create the linkto +         * file as we expect a lookup everywhere if there are problems +         * with the parent layout +         */ +        STACK_WIND_COOKIE(frame, dht_create_cbk, subvol, subvol, +                          subvol->fops->create, &local->loc, flags, mode, umask, +                          fd, params); +        goto done; +    } + +    subvol = dht_subvol_get_hashed(this, loc); +    if (!subvol) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, +               "no subvolume in layout for path=%s", loc->path); + +        op_errno = EIO; +        goto err; +    } + +    /* Post remove-brick, the client layout may not be in sync with +     * disk layout because of lack of lookup. Hence,a create call +     * may fall on the decommissioned brick.  Hence, if the +     * hashed_subvol is part of decommissioned bricks  list, do a +     * lookup on parent dir. If a fix-layout is already done by the +     * remove-brick process, the parent directory layout will be in +     * sync with that of the disk. If fix-layout is still ending +     * on the parent directory, we can let the file get created on +     * the decommissioned brick which will be eventually migrated to +     * non-decommissioned brick based on the new layout. +     */ + +    if (conf->decommission_subvols_cnt) { +        for (i = 0; i < conf->subvolume_cnt; i++) { +            if (conf->decommissioned_bricks[i] && +                conf->decommissioned_bricks[i] == subvol) { +                gf_msg_debug(this->name, 0, +                             "hashed subvol:%s is " +                             "part of decommission brick list for " +                             "file: %s", +                             subvol->name, loc->path); + +                /* dht_refresh_layout needs directory info in +                 * local->loc. Hence, storing the parent_loc in +                 * local->loc and storing the create context in +                 * local->loc2. We will restore this information +                 * in dht_creation do */ + +                ret = loc_copy(&local->loc2, &local->loc); +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +                           "loc_copy failed %s", loc->path); + +                    goto err;                  } -                /* We either don't have a hashed subvol or the hashed subvol is -                 * the same as the one specified. No need to create the linkto -                 * file as we expect a lookup everywhere if there are problems -                 * with the parent layout -                 */ -                STACK_WIND_COOKIE (frame, dht_create_cbk, subvol, -                                   subvol, subvol->fops->create, &local->loc, -                                   flags, mode, umask, fd, params); -                goto done; -        } -        subvol = dht_subvol_get_hashed (this, loc); -        if (!subvol) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                        "no subvolume in layout for path=%s", -                        loc->path); +                local->params = dict_ref(params); +                local->flags = flags; +                local->mode = mode; +                local->umask = umask; -                op_errno = EIO; -                goto err; -        } +                loc_wipe(&local->loc); -       /* Post remove-brick, the client layout may not be in sync with -        * disk layout because of lack of lookup. Hence,a create call -        * may fall on the decommissioned brick.  Hence, if the -        * hashed_subvol is part of decommissioned bricks  list, do a -        * lookup on parent dir. If a fix-layout is already done by the -        * remove-brick process, the parent directory layout will be in -        * sync with that of the disk. If fix-layout is still ending -        * on the parent directory, we can let the file get created on -        * the decommissioned brick which will be eventually migrated to -        * non-decommissioned brick based on the new layout. -        */ +                ret = dht_build_parent_loc(this, &local->loc, loc, &op_errno); -        if (conf->decommission_subvols_cnt) { -            for (i = 0; i < conf->subvolume_cnt; i++) { -                if (conf->decommissioned_bricks[i] && -                        conf->decommissioned_bricks[i] == subvol) { - -                        gf_msg_debug (this->name, 0, "hashed subvol:%s is " -                                      "part of decommission brick list for " -                                      "file: %s", subvol->name, loc->path); - -                        /* dht_refresh_layout needs directory info in -                         * local->loc. Hence, storing the parent_loc in -                         * local->loc and storing the create context in -                         * local->loc2. We will restore this information -                         * in dht_creation do */ - -                        ret = loc_copy (&local->loc2, &local->loc); -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_NO_MEMORY, -                                        "loc_copy failed %s", loc->path); - -                                goto err; -                        } - -                        local->params = dict_ref (params); -                        local->flags = flags; -                        local->mode = mode; -                        local->umask = umask; - -                        loc_wipe (&local->loc); - -                        ret = dht_build_parent_loc (this, &local->loc, loc, -                                                                 &op_errno); - -                        if (ret) { -                                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                        DHT_MSG_LOC_FAILED, -                                        "parent loc build failed"); -                                goto err; -                        } - -                        ret = dht_create_lock (frame, subvol); - -                        if (ret < 0) { -                                gf_msg (this->name, GF_LOG_ERROR, 0, -                                        DHT_MSG_INODE_LK_ERROR, -                                        "locking parent failed"); -                                goto err; -                        } - -                        goto done; -               } +                if (ret) { +                    gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_LOC_FAILED, +                           "parent loc build failed"); +                    goto err; +                } + +                ret = dht_create_lock(frame, subvol); + +                if (ret < 0) { +                    gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_INODE_LK_ERROR, +                           "locking parent failed"); +                    goto err; +                } + +                goto done;              }          } +    } - -        dht_create_wind_to_avail_subvol (frame, this, subvol, loc, flags, mode, -                                         umask, fd, params); +    dht_create_wind_to_avail_subvol(frame, this, subvol, loc, flags, mode, +                                    umask, fd, params);  done: -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL, +                     NULL); -        return 0; +    return 0;  } -  int -dht_mkdir_selfheal_cbk (call_frame_t *frame, void *cookie, -                        xlator_t *this, -                        int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_mkdir_selfheal_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                       int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t   *local = NULL; -        dht_layout_t  *layout = NULL; +    dht_local_t *local = NULL; +    dht_layout_t *layout = NULL; -        local = frame->local; -        layout = local->selfheal.layout; +    local = frame->local; +    layout = local->selfheal.layout; -        FRAME_SU_UNDO (frame, dht_local_t); -        dht_set_fixed_dir_stat (&local->preparent); -        dht_set_fixed_dir_stat (&local->postparent); +    FRAME_SU_UNDO(frame, dht_local_t); +    dht_set_fixed_dir_stat(&local->preparent); +    dht_set_fixed_dir_stat(&local->postparent); -        if (op_ret == 0) { -                dht_layout_set (this, local->inode, layout); +    if (op_ret == 0) { +        dht_layout_set(this, local->inode, layout); -                dht_inode_ctx_time_update (local->inode, this, -                                           &local->stbuf, 1); -                if (local->loc.parent) { -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->preparent, 0); +        dht_inode_ctx_time_update(local->inode, this, &local->stbuf, 1); +        if (local->loc.parent) { +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->preparent, 0); -                        dht_inode_ctx_time_update (local->loc.parent, this, -                                                   &local->postparent, 1); -                } +            dht_inode_ctx_time_update(local->loc.parent, this, +                                      &local->postparent, 1);          } +    } -        DHT_STACK_UNWIND (mkdir, frame, op_ret, op_errno, -                          local->inode, &local->stbuf, &local->preparent, -                          &local->postparent, NULL); +    DHT_STACK_UNWIND(mkdir, frame, op_ret, op_errno, local->inode, +                     &local->stbuf, &local->preparent, &local->postparent, +                     NULL); -        return 0; +    return 0;  }  int -dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -               int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf, -               struct iatt *preparent, struct iatt *postparent, dict_t *xdata) +dht_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +              int op_errno, inode_t *inode, struct iatt *stbuf, +              struct iatt *preparent, struct iatt *postparent, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        int           ret = -1; -        gf_boolean_t subvol_filled = _gf_false; -        gf_boolean_t dir_exists = _gf_false; -        xlator_t     *prev = NULL; -        dht_layout_t *layout = NULL; - -        local = frame->local; -        prev  = cookie; -        layout = local->layout; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    int ret = -1; +    gf_boolean_t subvol_filled = _gf_false; +    gf_boolean_t dir_exists = _gf_false; +    xlator_t *prev = NULL; +    dht_layout_t *layout = NULL; -        subvol_filled = dht_is_subvol_filled (this, prev); +    local = frame->local; +    prev = cookie; +    layout = local->layout; -        LOCK (&frame->lock); -        { -                if (subvol_filled && (op_ret != -1)) { -                        ret = dht_layout_merge (this, layout, prev, -                                                -1, ENOSPC, NULL); -                } else { -                        if (op_ret == -1 && op_errno == EEXIST) { -                                /* Very likely just a race between mkdir and -                                   self-heal (from lookup of a concurrent mkdir -                                   attempt). -                                   Ignore error for now. layout setting will -                                   anyways fail if this was a different (old) -                                   pre-existing different directory. -                                */ -                                op_ret = 0; -                                dir_exists = _gf_true; -                        } -                        ret = dht_layout_merge (this, layout, prev, -                                                op_ret, op_errno, NULL); -                } -                if (ret) -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_LAYOUT_MERGE_FAILED, -                                "%s: failed to merge layouts for subvol %s", -                                local->loc.path, prev->name); - -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        goto unlock; -                } +    subvol_filled = dht_is_subvol_filled(this, prev); -                if (dir_exists) -                        goto unlock; +    LOCK(&frame->lock); +    { +        if (subvol_filled && (op_ret != -1)) { +            ret = dht_layout_merge(this, layout, prev, -1, ENOSPC, NULL); +        } else { +            if (op_ret == -1 && op_errno == EEXIST) { +                /* Very likely just a race between mkdir and +                   self-heal (from lookup of a concurrent mkdir +                   attempt). +                   Ignore error for now. layout setting will +                   anyways fail if this was a different (old) +                   pre-existing different directory. +                */ +                op_ret = 0; +                dir_exists = _gf_true; +            } +            ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, NULL); +        } +        if (ret) +            gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, +                   "%s: failed to merge layouts for subvol %s", local->loc.path, +                   prev->name); -                dht_iatt_merge (this, &local->stbuf, stbuf); -                dht_iatt_merge (this, &local->preparent, preparent); -                dht_iatt_merge (this, &local->postparent, postparent); +        if (op_ret == -1) { +            local->op_errno = op_errno; +            goto unlock;          } + +        if (dir_exists) +            goto unlock; + +        dht_iatt_merge(this, &local->stbuf, stbuf); +        dht_iatt_merge(this, &local->preparent, preparent); +        dht_iatt_merge(this, &local->postparent, postparent); +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                /*Unlock entrylk and inodelk once mkdir is done on all subvols*/ -                dht_unlock_namespace (frame, &local->lock[0]); -                FRAME_SU_DO (frame, dht_local_t); -                dht_selfheal_new_directory (frame, dht_mkdir_selfheal_cbk, -                                            layout); -        } +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        /*Unlock entrylk and inodelk once mkdir is done on all subvols*/ +        dht_unlock_namespace(frame, &local->lock[0]); +        FRAME_SU_DO(frame, dht_local_t); +        dht_selfheal_new_directory(frame, dht_mkdir_selfheal_cbk, layout); +    } -        return 0; +    return 0;  }  int -dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie, -                      xlator_t *this, int op_ret, int op_errno, -                      inode_t *inode, struct iatt *stbuf, -                      struct iatt *preparent, struct iatt *postparent, -                      dict_t *xdata); +dht_mkdir_hashed_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int op_ret, int op_errno, inode_t *inode, +                     struct iatt *stbuf, struct iatt *preparent, +                     struct iatt *postparent, dict_t *xdata);  int -dht_mkdir_helper (call_frame_t *frame, xlator_t *this, -                  loc_t *loc, mode_t mode, mode_t umask, dict_t *params) +dht_mkdir_helper(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, +                 mode_t umask, dict_t *params)  { -        dht_local_t  *local                   = NULL; -        dht_conf_t   *conf                    = NULL; -        int           op_errno                = -1, ret = -1; -        xlator_t     *hashed_subvol           = NULL; -        int32_t      *parent_disk_layout      = NULL; -        dht_layout_t *parent_layout           = NULL; -        char          pgfid[GF_UUID_BUF_SIZE] = {0}; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); -        VALIDATE_OR_GOTO (loc->path, err); -        VALIDATE_OR_GOTO (this->private, err); - -        gf_uuid_unparse (loc->parent->gfid, pgfid); - -        conf = this->private; -        local = frame->local; - -        if (local->op_ret == -1) { -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): refreshing parent layout " -                        "failed.", pgfid, loc->name, -                        loc->path); - -                op_errno = local->op_errno; -                goto err; -        } - -        local->op_ret = -1; - -        hashed_subvol = dht_subvol_get_hashed (this, loc); -        if (hashed_subvol == NULL) { -                gf_msg_debug (this->name, 0, -                              "mkdir (%s/%s) (path: %s): hashed subvol not " -                              "found", pgfid, loc->name, loc->path); -                op_errno = ENOENT; -                goto err; -        } - -        local->hashed_subvol = hashed_subvol; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = -1, ret = -1; +    xlator_t *hashed_subvol = NULL; +    int32_t *parent_disk_layout = NULL; +    dht_layout_t *parent_layout = NULL; +    char pgfid[GF_UUID_BUF_SIZE] = {0}; -        parent_layout = dht_layout_get (this, loc->parent); - -        ret = dht_disk_layout_extract_for_subvol (this, parent_layout, -                                                  hashed_subvol, -                                                  &parent_disk_layout); -        if (ret == -1) { -                gf_msg (this->name, GF_LOG_WARNING, EIO, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): " -                        "extracting in-memory layout of parent failed. ", -                        pgfid, loc->name, loc->path); -                goto err; -        } - -        if (memcmp (local->parent_disk_layout, parent_disk_layout, -                    sizeof (local->parent_disk_layout)) == 0) { -                gf_msg (this->name, GF_LOG_WARNING, EIO, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): loop detected. " -                        "parent layout didn't change even though " -                        "previous attempt of mkdir failed because of " -                        "in-memory layout not matching with that on disk.", -                        pgfid, loc->name, loc->path); -                op_errno = EIO; -                goto err; -        } - -        memcpy ((void *)local->parent_disk_layout, (void *)parent_disk_layout, -                sizeof (local->parent_disk_layout)); - -        dht_layout_unref (this, parent_layout); -        parent_layout = NULL; - -        ret = dict_set_str (params, GF_PREOP_PARENT_KEY, conf->xattr_name); -        if (ret < 0) { -                local->op_errno = -ret; -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): " -                        "setting %s key in params dictionary failed. ", -                        pgfid, loc->name, loc->path, GF_PREOP_PARENT_KEY); -                goto err; -        } +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); +    VALIDATE_OR_GOTO(loc->path, err); +    VALIDATE_OR_GOTO(this->private, err); -        ret = dict_set_bin (params, conf->xattr_name, parent_disk_layout, -                            4 * 4); -        if (ret < 0) { -                local->op_errno = -ret; -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "setting parent-layout in params dictionary failed. " -                        "mkdir (%s/%s) (path: %s)", pgfid, loc->name, -                        loc->path); -                goto err; -        } +    gf_uuid_unparse(loc->parent->gfid, pgfid); -        parent_disk_layout = NULL; +    conf = this->private; +    local = frame->local; -        STACK_WIND_COOKIE (frame, dht_mkdir_hashed_cbk, hashed_subvol, -                           hashed_subvol, hashed_subvol->fops->mkdir, -                           loc, mode, umask, params); +    if (local->op_ret == -1) { +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): refreshing parent layout " +               "failed.", +               pgfid, loc->name, loc->path); -        return 0; +        op_errno = local->op_errno; +        goto err; +    } + +    local->op_ret = -1; + +    hashed_subvol = dht_subvol_get_hashed(this, loc); +    if (hashed_subvol == NULL) { +        gf_msg_debug(this->name, 0, +                     "mkdir (%s/%s) (path: %s): hashed subvol not " +                     "found", +                     pgfid, loc->name, loc->path); +        op_errno = ENOENT; +        goto err; +    } + +    local->hashed_subvol = hashed_subvol; + +    parent_layout = dht_layout_get(this, loc->parent); + +    ret = dht_disk_layout_extract_for_subvol(this, parent_layout, hashed_subvol, +                                             &parent_disk_layout); +    if (ret == -1) { +        gf_msg(this->name, GF_LOG_WARNING, EIO, DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): " +               "extracting in-memory layout of parent failed. ", +               pgfid, loc->name, loc->path); +        goto err; +    } + +    if (memcmp(local->parent_disk_layout, parent_disk_layout, +               sizeof(local->parent_disk_layout)) == 0) { +        gf_msg(this->name, GF_LOG_WARNING, EIO, DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): loop detected. " +               "parent layout didn't change even though " +               "previous attempt of mkdir failed because of " +               "in-memory layout not matching with that on disk.", +               pgfid, loc->name, loc->path); +        op_errno = EIO; +        goto err; +    } + +    memcpy((void *)local->parent_disk_layout, (void *)parent_disk_layout, +           sizeof(local->parent_disk_layout)); + +    dht_layout_unref(this, parent_layout); +    parent_layout = NULL; + +    ret = dict_set_str(params, GF_PREOP_PARENT_KEY, conf->xattr_name); +    if (ret < 0) { +        local->op_errno = -ret; +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): " +               "setting %s key in params dictionary failed. ", +               pgfid, loc->name, loc->path, GF_PREOP_PARENT_KEY); +        goto err; +    } + +    ret = dict_set_bin(params, conf->xattr_name, parent_disk_layout, 4 * 4); +    if (ret < 0) { +        local->op_errno = -ret; +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "setting parent-layout in params dictionary failed. " +               "mkdir (%s/%s) (path: %s)", +               pgfid, loc->name, loc->path); +        goto err; +    } + +    parent_disk_layout = NULL; + +    STACK_WIND_COOKIE(frame, dht_mkdir_hashed_cbk, hashed_subvol, hashed_subvol, +                      hashed_subvol->fops->mkdir, loc, mode, umask, params); + +    return 0;  err: -        dht_unlock_namespace (frame, &local->lock[0]); +    dht_unlock_namespace(frame, &local->lock[0]); -        op_errno = local ? local->op_errno : op_errno; -        DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL, NULL); +    op_errno = local ? local->op_errno : op_errno; +    DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        if (parent_disk_layout != NULL) -                GF_FREE (parent_disk_layout); +    if (parent_disk_layout != NULL) +        GF_FREE(parent_disk_layout); -        if (parent_layout != NULL) -                dht_layout_unref (this, parent_layout); +    if (parent_layout != NULL) +        dht_layout_unref(this, parent_layout); -        return 0; +    return 0;  }  int -dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie, -                      xlator_t *this, int op_ret, int op_errno, -                      inode_t *inode, struct iatt *stbuf, -                      struct iatt *preparent, struct iatt *postparent, -                      dict_t *xdata) +dht_mkdir_hashed_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int op_ret, int op_errno, inode_t *inode, +                     struct iatt *stbuf, struct iatt *preparent, +                     struct iatt *postparent, dict_t *xdata)  { -        dht_local_t  *local                   = NULL; -        int           ret                     = -1; -        xlator_t     *prev                    = NULL; -        dht_layout_t *layout                  = NULL; -        dht_conf_t   *conf                    = NULL; -        int           i                       = 0; -        xlator_t     *hashed_subvol           = NULL; -        char          pgfid[GF_UUID_BUF_SIZE] = {0}; -        gf_boolean_t  parent_layout_changed   = _gf_false; -        call_stub_t  *stub                    = NULL; +    dht_local_t *local = NULL; +    int ret = -1; +    xlator_t *prev = NULL; +    dht_layout_t *layout = NULL; +    dht_conf_t *conf = NULL; +    int i = 0; +    xlator_t *hashed_subvol = NULL; +    char pgfid[GF_UUID_BUF_SIZE] = {0}; +    gf_boolean_t parent_layout_changed = _gf_false; +    call_stub_t *stub = NULL; -        VALIDATE_OR_GOTO (this->private, err); +    VALIDATE_OR_GOTO(this->private, err); -        local = frame->local; -        prev  = cookie; -        layout = local->layout; -        conf = this->private; -        hashed_subvol = local->hashed_subvol; +    local = frame->local; +    prev = cookie; +    layout = local->layout; +    conf = this->private; +    hashed_subvol = local->hashed_subvol; -        gf_uuid_unparse (local->loc.parent->gfid, pgfid); +    gf_uuid_unparse(local->loc.parent->gfid, pgfid); -        if (gf_uuid_is_null (local->loc.gfid) && !op_ret) -                gf_uuid_copy (local->loc.gfid, stbuf->ia_gfid); +    if (gf_uuid_is_null(local->loc.gfid) && !op_ret) +        gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); -        if (op_ret == -1) { -                local->op_errno = op_errno; - -                parent_layout_changed = (xdata && dict_get (xdata, GF_PREOP_CHECK_FAILED)) -                        ? 1 : 0; -                if (parent_layout_changed) { -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_PARENT_LAYOUT_CHANGED, -                                "mkdir (%s/%s) (path: %s): parent layout " -                                "changed. Attempting a refresh and then a " -                                "retry", pgfid, local->loc.name, -                                local->loc.path); - -                        stub = fop_mkdir_stub (frame, dht_mkdir_helper, -                                               &local->loc, local->mode, -                                               local->umask, local->params); -                        if (stub == NULL) { -                                goto err; -                        } - -                        dht_handle_parent_layout_change (this, stub); -                        stub = NULL; - -                        return 0; -                } +    if (op_ret == -1) { +        local->op_errno = op_errno; +        parent_layout_changed = (xdata && +                                 dict_get(xdata, GF_PREOP_CHECK_FAILED)) +                                    ? 1 +                                    : 0; +        if (parent_layout_changed) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_PARENT_LAYOUT_CHANGED, +                   "mkdir (%s/%s) (path: %s): parent layout " +                   "changed. Attempting a refresh and then a " +                   "retry", +                   pgfid, local->loc.name, local->loc.path); + +            stub = fop_mkdir_stub(frame, dht_mkdir_helper, &local->loc, +                                  local->mode, local->umask, local->params); +            if (stub == NULL) {                  goto err; -        } - -        dict_del (local->params, GF_PREOP_PARENT_KEY); -        dict_del (local->params, conf->xattr_name); +            } -        if (dht_is_subvol_filled (this, hashed_subvol)) -                ret = dht_layout_merge (this, layout, prev, -                                        -1, ENOSPC, NULL); -        else -                ret = dht_layout_merge (this, layout, prev, -                                        op_ret, op_errno, NULL); +            dht_handle_parent_layout_change(this, stub); +            stub = NULL; + +            return 0; +        } + +        goto err; +    } + +    dict_del(local->params, GF_PREOP_PARENT_KEY); +    dict_del(local->params, conf->xattr_name); + +    if (dht_is_subvol_filled(this, hashed_subvol)) +        ret = dht_layout_merge(this, layout, prev, -1, ENOSPC, NULL); +    else +        ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, NULL); + +    /* TODO: we may have to return from the function +       if layout merge fails. For now, lets just log an error */ +    if (ret) +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_LAYOUT_MERGE_FAILED, +               "%s: failed to merge layouts for subvol %s", local->loc.path, +               prev->name); + +    local->op_ret = 0; + +    dht_iatt_merge(this, &local->stbuf, stbuf); +    dht_iatt_merge(this, &local->preparent, preparent); +    dht_iatt_merge(this, &local->postparent, postparent); + +    local->call_cnt = conf->subvolume_cnt - 1; +    /* Delete internal mds xattr from params dict to avoid store +      internal mds xattr on other subvols +    */ +    dict_del(local->params, conf->mds_xattr_key); + +    if (gf_uuid_is_null(local->loc.gfid)) +        gf_uuid_copy(local->loc.gfid, stbuf->ia_gfid); + +    /* Set hashed subvol as a mds subvol on inode ctx */ +    /*if (!local->inode) +            local->inode  = inode_ref (inode); +    */ +    ret = dht_inode_ctx_mdsvol_set(local->inode, this, hashed_subvol); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, +               "Failed to set hashed subvol for %s on inode vol is %s", +               local->loc.path, hashed_subvol->name); +    } + +    if (local->call_cnt == 0) { +        /*Unlock namespace lock once mkdir is done on all subvols*/ +        dht_unlock_namespace(frame, &local->lock[0]); +        FRAME_SU_DO(frame, dht_local_t); +        dht_selfheal_directory(frame, dht_mkdir_selfheal_cbk, &local->loc, +                               layout); +        return 0; +    } + +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (conf->subvolumes[i] == hashed_subvol) +            continue; +        STACK_WIND_COOKIE(frame, dht_mkdir_cbk, conf->subvolumes[i], +                          conf->subvolumes[i], conf->subvolumes[i]->fops->mkdir, +                          &local->loc, local->mode, local->umask, +                          local->params); +    } + +    return 0; +err: +    if (local->op_ret != 0) { +        dht_unlock_namespace(frame, &local->lock[0]); +    } -        /* TODO: we may have to return from the function -           if layout merge fails. For now, lets just log an error */ -        if (ret) -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_LAYOUT_MERGE_FAILED, -                        "%s: failed to merge layouts for subvol %s", -                        local->loc.path, prev->name); +    DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        local->op_ret = 0; +    return 0; +} -        dht_iatt_merge (this, &local->stbuf, stbuf); -        dht_iatt_merge (this, &local->preparent, preparent); -        dht_iatt_merge (this, &local->postparent, postparent); +int +dht_mkdir_guard_parent_layout_cbk(call_frame_t *frame, xlator_t *this, +                                  loc_t *loc, mode_t mode, mode_t umask, +                                  dict_t *params) +{ +    dht_local_t *local = NULL; +    dht_conf_t *conf = 0; +    char pgfid[GF_UUID_BUF_SIZE] = {0}; +    int ret = -1; +    int32_t zero[1] = {0}; -        local->call_cnt = conf->subvolume_cnt - 1; -        /* Delete internal mds xattr from params dict to avoid store -          internal mds xattr on other subvols -        */ -        dict_del (local->params, conf->mds_xattr_key); +    local = frame->local; +    conf = this->private; -        if (gf_uuid_is_null (local->loc.gfid)) -                gf_uuid_copy (local->loc.gfid, stbuf->ia_gfid); +    gf_uuid_unparse(loc->parent->gfid, pgfid); -        /* Set hashed subvol as a mds subvol on inode ctx */ -        /*if (!local->inode) -                local->inode  = inode_ref (inode); -        */ -        ret = dht_inode_ctx_mdsvol_set (local->inode, this, hashed_subvol); -        if (ret) { -                gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_SET_INODE_CTX_FAILED, -                        "Failed to set hashed subvol for %s on inode vol is %s", -                        local->loc.path, hashed_subvol->name); -        } +    if (local->op_ret < 0) { +        gf_msg(this->name, GF_LOG_WARNING, local->op_errno, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): " +               "Acquiring lock on parent to guard against " +               "layout-change failed.", +               pgfid, loc->name, loc->path); +        goto err; +    } -        if (local->call_cnt == 0) { -                /*Unlock namespace lock once mkdir is done on all subvols*/ -                dht_unlock_namespace (frame, &local->lock[0]); -                FRAME_SU_DO (frame, dht_local_t); -                dht_selfheal_directory (frame, dht_mkdir_selfheal_cbk, -                                        &local->loc, layout); -                return 0; -        } +    local->op_ret = -1; +    /* Add internal MDS xattr on disk for hashed subvol +     */ +    ret = dht_dict_set_array(params, conf->mds_xattr_key, zero, 1); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value:key = %s for " +               "path %s", +               conf->mds_xattr_key, loc->path); +    } -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (conf->subvolumes[i] == hashed_subvol) -                        continue; -                STACK_WIND_COOKIE (frame, dht_mkdir_cbk, conf->subvolumes[i], -                                   conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->mkdir, -                                   &local->loc, local->mode, local->umask, -                                   local->params); -        } +    STACK_WIND_COOKIE(frame, dht_mkdir_hashed_cbk, local->hashed_subvol, +                      local->hashed_subvol, local->hashed_subvol->fops->mkdir, +                      loc, mode, umask, params); -        return 0; +    return 0;  err: -        if (local->op_ret != 0) { -                dht_unlock_namespace (frame, &local->lock[0]); -        } +    DHT_STACK_UNWIND(mkdir, frame, -1, local->op_errno, NULL, NULL, NULL, NULL, +                     NULL); + +    return 0; +} + +int +dht_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, +          mode_t umask, dict_t *params) +{ +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = EINVAL, ret = -1; +    xlator_t *hashed_subvol = NULL; +    char pgfid[GF_UUID_BUF_SIZE] = {0}; +    call_stub_t *stub = NULL; + +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); +    VALIDATE_OR_GOTO(loc->path, err); +    VALIDATE_OR_GOTO(this->private, err); + +    gf_uuid_unparse(loc->parent->gfid, pgfid); + +    conf = this->private; + +    if (!params || !dict_get(params, "gfid-req")) { +        op_errno = EPERM; +        gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, +                         DHT_MSG_GFID_NULL, +                         "mkdir: %s is received " +                         "without gfid-req %p", +                         loc->path, params); +        goto err; +    } + +    dht_get_du_info(frame, this, loc); + +    local = dht_local_init(frame, loc, NULL, GF_FOP_MKDIR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } + +    hashed_subvol = dht_subvol_get_hashed(this, loc); +    if (hashed_subvol == NULL) { +        gf_msg_debug(this->name, 0, "hashed subvol not found for %s", +                     loc->path); +        local->op_errno = EIO; +        goto err; +    } + +    local->hashed_subvol = hashed_subvol; +    local->mode = mode; +    local->umask = umask; +    if (params) +        local->params = dict_ref(params); + +    local->inode = inode_ref(loc->inode); + +    local->layout = dht_layout_new(this, conf->subvolume_cnt); +    if (!local->layout) { +        op_errno = ENOMEM; +        goto err; +    } + +    /* set the newly created directory hash to the commit hash +     * if the configuration option is set. If configuration option +     * is not set, the older clients may still be connecting to the +     * volume and hence we need to preserve the 1 in disk[0] part of the +     * layout xattr */ +    if (conf->lookup_optimize) +        local->layout->commit_hash = conf->vol_commit_hash; +    else +        local->layout->commit_hash = DHT_LAYOUT_HASH_INVALID; + +    stub = fop_mkdir_stub(frame, dht_mkdir_guard_parent_layout_cbk, loc, mode, +                          umask, params); +    if (stub == NULL) { +        gf_msg(this->name, GF_LOG_WARNING, ENOMEM, +               DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s): " +               "creating stub failed.", +               pgfid, loc->name, loc->path); +        local->op_errno = ENOMEM; +        goto err; +    } + +    ret = dht_guard_parent_layout_and_namespace(this, stub); +    if (ret < 0) { +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_PARENT_LAYOUT_CHANGED, +               "mkdir (%s/%s) (path: %s) cannot wind lock request to " +               "guard parent layout", +               pgfid, loc->name, loc->path); +        goto err; +    } + +    return 0; -        DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL, NULL); +err: +    op_errno = local ? local->op_errno : op_errno; +    DHT_STACK_UNWIND(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL); -        return 0; +    return 0;  }  int -dht_mkdir_guard_parent_layout_cbk (call_frame_t *frame, xlator_t *this, -                                   loc_t *loc, mode_t mode, mode_t umask, -                                   dict_t *params) +dht_rmdir_selfheal_cbk(call_frame_t *heal_frame, void *cookie, xlator_t *this, +                       int op_ret, int op_errno, dict_t *xdata)  { -        dht_local_t *local                    = NULL; -        dht_conf_t  *conf                     = 0; -        char          pgfid[GF_UUID_BUF_SIZE] = {0}; -        int          ret                      = -1; -        int32_t      zero[1]                  = {0}; - -        local = frame->local; -        conf  = this->private; +    dht_local_t *local = NULL; +    dht_local_t *heal_local = NULL; +    call_frame_t *main_frame = NULL; -        gf_uuid_unparse (loc->parent->gfid, pgfid); - -        if (local->op_ret < 0) { -                gf_msg (this->name, GF_LOG_WARNING, local->op_errno, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): " -                        "Acquiring lock on parent to guard against " -                        "layout-change failed.", pgfid, loc->name, loc->path); -                goto err; -        } - -        local->op_ret = -1; -        /* Add internal MDS xattr on disk for hashed subvol -        */ -        ret = dht_dict_set_array (params, conf->mds_xattr_key, zero, 1); -        if (ret) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value:key = %s for " -                        "path %s", conf->mds_xattr_key, loc->path); -        } +    heal_local = heal_frame->local; +    main_frame = heal_local->main_frame; +    local = main_frame->local; -        STACK_WIND_COOKIE (frame, dht_mkdir_hashed_cbk, local->hashed_subvol, -                           local->hashed_subvol, -                           local->hashed_subvol->fops->mkdir, -                           loc, mode, umask, params); +    DHT_STACK_DESTROY(heal_frame); +    dht_set_fixed_dir_stat(&local->preparent); +    dht_set_fixed_dir_stat(&local->postparent); -        return 0; -err: -        DHT_STACK_UNWIND (mkdir, frame, -1, local->op_errno, NULL, NULL, NULL, -                          NULL, NULL); +    DHT_STACK_UNWIND(rmdir, main_frame, local->op_ret, local->op_errno, +                     &local->preparent, &local->postparent, NULL); -        return 0; +    return 0;  }  int -dht_mkdir (call_frame_t *frame, xlator_t *this, -           loc_t *loc, mode_t mode, mode_t umask, dict_t *params) +dht_rmdir_hashed_subvol_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                            int op_ret, int op_errno, struct iatt *preparent, +                            struct iatt *postparent, dict_t *xdata)  { -        dht_local_t  *local                   = NULL; -        dht_conf_t   *conf                    = NULL; -        int           op_errno                = EINVAL, ret = -1; -        xlator_t     *hashed_subvol           = NULL; -        char          pgfid[GF_UUID_BUF_SIZE] = {0}; -        call_stub_t  *stub                    = NULL; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); -        VALIDATE_OR_GOTO (loc->path, err); -        VALIDATE_OR_GOTO (this->private, err); - -        gf_uuid_unparse (loc->parent->gfid, pgfid); +    dht_local_t *local = NULL; +    dht_local_t *heal_local = NULL; +    call_frame_t *heal_frame = NULL; +    dht_conf_t *conf = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        conf = this->private; - -        if (!params || !dict_get (params, "gfid-req")) { -                op_errno = EPERM; -                gf_msg_callingfn (this->name, GF_LOG_WARNING, op_errno, -                                  DHT_MSG_GFID_NULL, "mkdir: %s is received " -                                  "without gfid-req %p", loc->path, params); -                goto err; -        } +    local = frame->local; +    prev = cookie; +    conf = this->private; -        dht_get_du_info (frame, this, loc); +    gf_uuid_unparse(local->loc.gfid, gfid); -        local = dht_local_init (frame, loc, NULL, GF_FOP_MKDIR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            local->op_errno = op_errno; +            local->op_ret = -1; +            if (conf->subvolume_cnt != 1) { +                if (op_errno != ENOENT && op_errno != EACCES && +                    op_errno != ESTALE) { +                    local->need_selfheal = 1; +                } +            } -        hashed_subvol = dht_subvol_get_hashed (this, loc); -        if (hashed_subvol == NULL) { -                gf_msg_debug (this->name, 0, -                              "hashed subvol not found for %s", -                              loc->path); -                local->op_errno = EIO; -                goto err; +            gf_msg_debug(this->name, op_errno, +                         "rmdir on %s for %s failed " +                         "(gfid = %s)", +                         prev->name, local->loc.path, gfid); +            goto unlock;          } +        dht_iatt_merge(this, &local->preparent, preparent); +        dht_iatt_merge(this, &local->postparent, postparent); +    } +unlock: +    UNLOCK(&frame->lock); -        local->hashed_subvol = hashed_subvol; -        local->mode = mode; -        local->umask = umask; -        if (params) -                local->params = dict_ref (params); +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        if (local->need_selfheal) { +            dht_rmdir_unlock(frame, this); +            local->layout = dht_layout_get(this, local->loc.inode); -        local->inode  = inode_ref (loc->inode); +            /* TODO: neater interface needed below */ +            local->stbuf.ia_type = local->loc.inode->ia_type; -        local->layout = dht_layout_new (this, conf->subvolume_cnt); -        if (!local->layout) { -                op_errno = ENOMEM; -                goto err; -        } +            gf_uuid_copy(local->gfid, local->loc.inode->gfid); -        /* set the newly created directory hash to the commit hash -         * if the configuration option is set. If configuration option -         * is not set, the older clients may still be connecting to the -         * volume and hence we need to preserve the 1 in disk[0] part of the -         * layout xattr */ -        if (conf->lookup_optimize) -                local->layout->commit_hash = conf->vol_commit_hash; -        else -                local->layout->commit_hash = DHT_LAYOUT_HASH_INVALID; +            /* Use a different frame or else the rmdir op_ret is +             * overwritten by that of the selfheal */ +            heal_frame = copy_frame(frame); -        stub = fop_mkdir_stub (frame, dht_mkdir_guard_parent_layout_cbk, loc, -                               mode, umask, params); -        if (stub == NULL) { -                gf_msg (this->name, GF_LOG_WARNING, ENOMEM, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s): " -                        "creating stub failed.", pgfid, loc->name, loc->path); -                local->op_errno = ENOMEM; +            if (heal_frame == NULL) {                  goto err; -        } +            } -        ret = dht_guard_parent_layout_and_namespace (this, stub); -        if (ret < 0) { -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_PARENT_LAYOUT_CHANGED, -                        "mkdir (%s/%s) (path: %s) cannot wind lock request to " -                        "guard parent layout", pgfid, loc->name, loc->path); +            heal_local = dht_local_init(heal_frame, &local->loc, NULL, 0); +            if (!heal_local) { +                DHT_STACK_DESTROY(heal_frame);                  goto err; -        } - -        return 0; - -err: -        op_errno = local ? local->op_errno : op_errno; -        DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, -                          NULL, NULL); +            } -        return 0; -} +            heal_local->inode = inode_ref(local->loc.inode); +            heal_local->main_frame = frame; +            gf_uuid_copy(heal_local->gfid, local->loc.inode->gfid); +            dht_selfheal_restore(heal_frame, dht_rmdir_selfheal_cbk, +                                 &heal_local->loc, heal_local->layout); +            return 0; +        } else { +            if (local->loc.parent) { +                dht_inode_ctx_time_update(local->loc.parent, this, +                                          &local->preparent, 0); -int -dht_rmdir_selfheal_cbk (call_frame_t *heal_frame, void *cookie, xlator_t *this, -                        int op_ret, int op_errno, dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        dht_local_t  *heal_local = NULL; -        call_frame_t *main_frame = NULL; +                dht_inode_ctx_time_update(local->loc.parent, this, +                                          &local->postparent, 1); +            } -        heal_local = heal_frame->local; -        main_frame = heal_local->main_frame; -        local = main_frame->local; +            dht_set_fixed_dir_stat(&local->preparent); +            dht_set_fixed_dir_stat(&local->postparent); -        DHT_STACK_DESTROY (heal_frame); -        dht_set_fixed_dir_stat (&local->preparent); -        dht_set_fixed_dir_stat (&local->postparent); +            dht_rmdir_unlock(frame, this); +            DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, +                             &local->preparent, &local->postparent, NULL); +        } +    } -        DHT_STACK_UNWIND (rmdir, main_frame, local->op_ret, local->op_errno, -                          &local->preparent, &local->postparent, NULL); +    return 0; -        return 0; +err: +    DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, NULL, NULL, +                     NULL); +    return 0;  } -  int -dht_rmdir_hashed_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                             int op_ret, int op_errno, struct iatt *preparent, -                             struct iatt *postparent, dict_t *xdata) +dht_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, +              int op_errno, struct iatt *preparent, struct iatt *postparent, +              dict_t *xdata)  { -        dht_local_t  *local = NULL; -        dht_local_t  *heal_local = NULL; -        call_frame_t *heal_frame = NULL; -        dht_conf_t   *conf = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev = NULL; -        char gfid[GF_UUID_BUF_SIZE] ={0}; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; +    xlator_t *prev = NULL; +    int done = 0; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    dht_local_t *heal_local = NULL; +    call_frame_t *heal_frame = NULL; +    int ret = -1; -        local = frame->local; -        prev  = cookie; -        conf = this->private; +    local = frame->local; +    prev = cookie; -        gf_uuid_unparse(local->loc.gfid, gfid); +    LOCK(&frame->lock); +    { +        if (op_ret == -1) { +            if ((op_errno != ENOENT) && (op_errno != ESTALE)) { +                local->op_errno = op_errno; +                local->op_ret = -1; -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        local->op_errno = op_errno; -                        local->op_ret   = -1; -                        if (conf->subvolume_cnt != 1) { -                                if (op_errno != ENOENT && op_errno != EACCES -                                    && op_errno != ESTALE) { -                                        local->need_selfheal = 1; -                                } -                        } - -                        gf_msg_debug (this->name, op_errno, -                                      "rmdir on %s for %s failed " -                                      "(gfid = %s)", -                                      prev->name, local->loc.path, -                                      gfid); -                        goto unlock; -                } +                if (op_errno != EACCES) +                    local->need_selfheal = 1; +            } -                dht_iatt_merge (this, &local->preparent, preparent); -                dht_iatt_merge (this, &local->postparent, postparent); +            gf_uuid_unparse(local->loc.gfid, gfid); +            gf_msg_debug(this->name, op_errno, +                         "rmdir on %s for %s failed." +                         "(gfid = %s)", +                         prev->name, local->loc.path, gfid); +            goto unlock;          } + +        /* Track if rmdir succeeded on at least one subvol*/ +        local->fop_succeeded = 1; +        dht_iatt_merge(this, &local->preparent, preparent); +        dht_iatt_merge(this, &local->postparent, postparent); +    }  unlock: -        UNLOCK (&frame->lock); - -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -               if (local->need_selfheal) { -                        dht_rmdir_unlock (frame, this); -                        local->layout = -                                dht_layout_get (this, local->loc.inode); - -                        /* TODO: neater interface needed below */ -                        local->stbuf.ia_type = local->loc.inode->ia_type; - -                        gf_uuid_copy (local->gfid, local->loc.inode->gfid); - -                        /* Use a different frame or else the rmdir op_ret is -                         * overwritten by that of the selfheal */ - -                        heal_frame = copy_frame (frame); - -                        if (heal_frame == NULL) { -                                goto err; -                        } - -                        heal_local = dht_local_init (heal_frame, -                                                     &local->loc, -                                                     NULL, 0); -                        if (!heal_local) { -                                DHT_STACK_DESTROY (heal_frame); -                                goto err; -                        } - -                        heal_local->inode = inode_ref (local->loc.inode); -                        heal_local->main_frame = frame; -                        gf_uuid_copy (heal_local->gfid, local->loc.inode->gfid); - -                        dht_selfheal_restore (heal_frame, -                                              dht_rmdir_selfheal_cbk, -                                              &heal_local->loc, -                                              heal_local->layout); -                        return 0; -               } else { - -                        if (local->loc.parent) { -                                dht_inode_ctx_time_update (local->loc.parent, -                                                           this, -                                                           &local->preparent, -                                                           0); - -                                dht_inode_ctx_time_update (local->loc.parent, -                                                           this, -                                                           &local->postparent, -                                                           1); -                        } - -                        dht_set_fixed_dir_stat (&local->preparent); -                        dht_set_fixed_dir_stat (&local->postparent); - -                        dht_rmdir_unlock (frame, this); -                        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, -                                          local->op_errno, &local->preparent, -                                          &local->postparent, NULL); -               } -        } +    UNLOCK(&frame->lock); -        return 0; +    this_call_cnt = dht_frame_return(frame); -err: -        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, -                          local->op_errno, NULL, NULL, NULL); -        return 0; +    /* if local->hashed_subvol, we are yet to wind to hashed_subvol. */ +    if (local->hashed_subvol && (this_call_cnt == 1)) { +        done = 1; +    } else if (!local->hashed_subvol && !this_call_cnt) { +        done = 1; +    } -} +    if (done) { +        if (local->need_selfheal && local->fop_succeeded) { +            dht_rmdir_unlock(frame, this); +            local->layout = dht_layout_get(this, local->loc.inode); +            /* TODO: neater interface needed below */ +            local->stbuf.ia_type = local->loc.inode->ia_type; -int -dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -               int op_ret, int op_errno, struct iatt *preparent, -               struct iatt *postparent, dict_t *xdata) -{ -        dht_local_t  *local = NULL; -        int           this_call_cnt = 0; -        xlator_t     *prev = NULL; -        int           done = 0; -        char gfid[GF_UUID_BUF_SIZE] ={0}; -        dht_local_t  *heal_local = NULL; -        call_frame_t *heal_frame = NULL; -        int           ret        = -1; +            gf_uuid_copy(local->gfid, local->loc.inode->gfid); +            heal_frame = copy_frame(frame); +            if (heal_frame == NULL) { +                goto err; +            } -        local = frame->local; -        prev  = cookie; +            heal_local = dht_local_init(heal_frame, &local->loc, NULL, 0); +            if (!heal_local) { +                DHT_STACK_DESTROY(heal_frame); +                goto err; +            } +            heal_local->inode = inode_ref(local->loc.inode); +            heal_local->main_frame = frame; +            gf_uuid_copy(heal_local->gfid, local->loc.inode->gfid); +            ret = dht_selfheal_restore(heal_frame, dht_rmdir_selfheal_cbk, +                                       &heal_local->loc, heal_local->layout); +            if (ret) { +                DHT_STACK_DESTROY(heal_frame); +                goto err; +            } -        LOCK (&frame->lock); -        { -                if (op_ret == -1) { -                        if ((op_errno != ENOENT) && (op_errno != ESTALE)) { -                                local->op_errno = op_errno; -                                local->op_ret = -1; +        } else if (this_call_cnt) { +            /* If non-hashed subvol's have responded, proceed */ +            if (local->op_ret == 0) { +                /* Delete the dir from the hashed subvol if: +                 * The fop succeeded on at least one subvol +                 *  and did not fail on any +                 *  or +                 *  The fop failed with ENOENT/ESTALE on +                 *  all subvols */ + +                STACK_WIND_COOKIE(frame, dht_rmdir_hashed_subvol_cbk, +                                  local->hashed_subvol, local->hashed_subvol, +                                  local->hashed_subvol->fops->rmdir, +                                  &local->loc, local->flags, NULL); +            } else { +                /* hashed-subvol was non-NULL and rmdir failed on +                 * all non hashed-subvols. Unwind rmdir with +                 * local->op_ret and local->op_errno. */ +                dht_rmdir_unlock(frame, this); +                DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, +                                 &local->preparent, &local->postparent, NULL); -                                if (op_errno != EACCES) -                                        local->need_selfheal = 1; -                        } +                return 0; +            } +        } else if (!this_call_cnt) { +            /* All subvol's have responded, proceed */ -                        gf_uuid_unparse(local->loc.gfid, gfid); +            if (local->loc.parent) { +                dht_inode_ctx_time_update(local->loc.parent, this, +                                          &local->preparent, 0); -                        gf_msg_debug (this->name, op_errno, -                                      "rmdir on %s for %s failed." -                                      "(gfid = %s)", -                                      prev->name, local->loc.path, -                                      gfid); -                        goto unlock; -                } +                dht_inode_ctx_time_update(local->loc.parent, this, +                                          &local->postparent, 1); +            } -                /* Track if rmdir succeeded on at least one subvol*/ -                local->fop_succeeded = 1; -                dht_iatt_merge (this, &local->preparent, preparent); -                dht_iatt_merge (this, &local->postparent, postparent); -        } -unlock: -        UNLOCK (&frame->lock); - - -        this_call_cnt = dht_frame_return (frame); - -        /* if local->hashed_subvol, we are yet to wind to hashed_subvol. */ -        if (local->hashed_subvol && (this_call_cnt == 1)) { -                done = 1; -        } else if (!local->hashed_subvol && !this_call_cnt) { -                done = 1; -        } - - -        if (done) { -                if (local->need_selfheal && local->fop_succeeded) { -                        dht_rmdir_unlock (frame, this); -                        local->layout = -                                dht_layout_get (this, local->loc.inode); - -                        /* TODO: neater interface needed below */ -                        local->stbuf.ia_type = local->loc.inode->ia_type; - -                        gf_uuid_copy (local->gfid, local->loc.inode->gfid); -                        heal_frame = copy_frame (frame); -                        if (heal_frame == NULL) { -                                goto err; -                        } - -                        heal_local = dht_local_init (heal_frame, &local->loc, -                                                     NULL, 0); -                        if (!heal_local) { -                                DHT_STACK_DESTROY (heal_frame); -                                goto err; -                        } - -                        heal_local->inode = inode_ref (local->loc.inode); -                        heal_local->main_frame = frame; -                        gf_uuid_copy (heal_local->gfid, local->loc.inode->gfid); -                        ret = dht_selfheal_restore (heal_frame, -                                                    dht_rmdir_selfheal_cbk, -                                                    &heal_local->loc, -                                                    heal_local->layout); -                        if (ret) { -                                DHT_STACK_DESTROY (heal_frame); -                                goto err; -                        } - -                } else if (this_call_cnt) { -                        /* If non-hashed subvol's have responded, proceed */ -                        if (local->op_ret == 0) { -                                /* Delete the dir from the hashed subvol if: -                                 * The fop succeeded on at least one subvol -                                 *  and did not fail on any -                                 *  or -                                 *  The fop failed with ENOENT/ESTALE on -                                 *  all subvols */ - -                                STACK_WIND_COOKIE (frame, dht_rmdir_hashed_subvol_cbk, -                                                   local->hashed_subvol, -                                                   local->hashed_subvol, -                                                   local->hashed_subvol->fops->rmdir, -                                                   &local->loc, local->flags, NULL); -                        } else { -                         /* hashed-subvol was non-NULL and rmdir failed on -                          * all non hashed-subvols. Unwind rmdir with -                          * local->op_ret and local->op_errno. */ -                                dht_rmdir_unlock (frame, this); -                                DHT_STACK_UNWIND (rmdir, frame, local->op_ret, -                                          local->op_errno, &local->preparent, -                                          &local->postparent, NULL); - -                                return 0; - -                        } -                } else if (!this_call_cnt) { -                        /* All subvol's have responded, proceed */ - -                        if (local->loc.parent) { - -                                dht_inode_ctx_time_update (local->loc.parent, -                                                           this, -                                                           &local->preparent, -                                                           0); - -                                dht_inode_ctx_time_update (local->loc.parent, -                                                           this, -                                                           &local->postparent, -                                                           1); - -                        } - -                        dht_set_fixed_dir_stat (&local->preparent); -                        dht_set_fixed_dir_stat (&local->postparent); - -                        dht_rmdir_unlock (frame, this); -                        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, -                                          local->op_errno, &local->preparent, -                                          &local->postparent, NULL); -                } +            dht_set_fixed_dir_stat(&local->preparent); +            dht_set_fixed_dir_stat(&local->postparent); + +            dht_rmdir_unlock(frame, this); +            DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, +                             &local->preparent, &local->postparent, NULL);          } +    } -        return 0; +    return 0;  err: -        DHT_STACK_UNWIND (rmdir, frame, -1, local->op_errno, NULL, NULL, NULL); -        return 0; - +    DHT_STACK_UNWIND(rmdir, frame, -1, local->op_errno, NULL, NULL, NULL); +    return 0;  } -  int -dht_rmdir_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                      int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_rmdir_unlock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  } -  int -dht_rmdir_unlock (call_frame_t *frame, xlator_t *this) +dht_rmdir_unlock(call_frame_t *frame, xlator_t *this)  { -        dht_local_t  *local      = NULL, *lock_local = NULL; -        call_frame_t *lock_frame = NULL; -        int           lock_count = 0; +    dht_local_t *local = NULL, *lock_local = NULL; +    call_frame_t *lock_frame = NULL; +    int lock_count = 0; -        local = frame->local; +    local = frame->local; -        /* Unlock entrylk */ -        dht_unlock_entrylk_wrapper (frame, &local->lock[0].ns.directory_ns); +    /* Unlock entrylk */ +    dht_unlock_entrylk_wrapper(frame, &local->lock[0].ns.directory_ns); -        /* Unlock inodelk */ -        lock_count = dht_lock_count (local->lock[0].ns.parent_layout.locks, -                                     local->lock[0].ns.parent_layout.lk_count); +    /* Unlock inodelk */ +    lock_count = dht_lock_count(local->lock[0].ns.parent_layout.locks, +                                local->lock[0].ns.parent_layout.lk_count); -        if (lock_count == 0) -                goto done; +    if (lock_count == 0) +        goto done; -        lock_frame = copy_frame (frame); -        if (lock_frame == NULL) -                goto done; +    lock_frame = copy_frame(frame); +    if (lock_frame == NULL) +        goto done; -        lock_local = dht_local_init (lock_frame, &local->loc, NULL, -                                     lock_frame->root->op); -        if (lock_local == NULL) -                goto done; +    lock_local = dht_local_init(lock_frame, &local->loc, NULL, +                                lock_frame->root->op); +    if (lock_local == NULL) +        goto done; -        lock_local->lock[0].ns.parent_layout.locks = local->lock[0].ns.parent_layout.locks; -        lock_local->lock[0].ns.parent_layout.lk_count = local->lock[0].ns.parent_layout.lk_count; +    lock_local->lock[0].ns.parent_layout.locks = local->lock[0] +                                                     .ns.parent_layout.locks; +    lock_local->lock[0] +        .ns.parent_layout.lk_count = local->lock[0].ns.parent_layout.lk_count; -        local->lock[0].ns.parent_layout.locks = NULL; -        local->lock[0].ns.parent_layout.lk_count = 0; -        dht_unlock_inodelk (lock_frame, -                            lock_local->lock[0].ns.parent_layout.locks, -                            lock_local->lock[0].ns.parent_layout.lk_count, -                            dht_rmdir_unlock_cbk); -        lock_frame = NULL; +    local->lock[0].ns.parent_layout.locks = NULL; +    local->lock[0].ns.parent_layout.lk_count = 0; +    dht_unlock_inodelk(lock_frame, lock_local->lock[0].ns.parent_layout.locks, +                       lock_local->lock[0].ns.parent_layout.lk_count, +                       dht_rmdir_unlock_cbk); +    lock_frame = NULL;  done: -        if (lock_frame != NULL) { -                DHT_STACK_DESTROY (lock_frame); -        } +    if (lock_frame != NULL) { +        DHT_STACK_DESTROY(lock_frame); +    } -        return 0; +    return 0;  } -  int -dht_rmdir_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                    int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_rmdir_lock_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                   int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        dht_local_t  *local = NULL; -        dht_conf_t   *conf  = NULL; -        int           i     = 0; -        xlator_t     *hashed_subvol; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int i = 0; +    xlator_t *hashed_subvol; -        VALIDATE_OR_GOTO (this->private, err); +    VALIDATE_OR_GOTO(this->private, err); -        conf = this->private; -        local = frame->local; +    conf = this->private; +    local = frame->local; -        if (op_ret < 0) { -                gf_msg (this->name, GF_LOG_WARNING, op_errno, -                        DHT_MSG_INODE_LK_ERROR, -                        "acquiring entrylk after inodelk failed rmdir for %s)", -                        local->loc.path); +    if (op_ret < 0) { +        gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_INODE_LK_ERROR, +               "acquiring entrylk after inodelk failed rmdir for %s)", +               local->loc.path); -                local->op_ret = -1; -                local->op_errno = op_errno; -                goto err; -        } +        local->op_ret = -1; +        local->op_errno = op_errno; +        goto err; +    } -        hashed_subvol = local->hashed_subvol; -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (hashed_subvol && -                    (hashed_subvol == conf->subvolumes[i])) -                        continue; +    hashed_subvol = local->hashed_subvol; +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (hashed_subvol && (hashed_subvol == conf->subvolumes[i])) +            continue; -                STACK_WIND_COOKIE (frame, dht_rmdir_cbk, conf->subvolumes[i], -                                   conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->rmdir, -                                   &local->loc, local->flags, NULL); -        } +        STACK_WIND_COOKIE(frame, dht_rmdir_cbk, conf->subvolumes[i], +                          conf->subvolumes[i], conf->subvolumes[i]->fops->rmdir, +                          &local->loc, local->flags, NULL); +    } -        return 0; +    return 0;  err: -        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno, -                          &local->preparent, &local->postparent, NULL); +    DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, +                     &local->preparent, &local->postparent, NULL); -        return 0; +    return 0;  } -  int -dht_rmdir_do (call_frame_t *frame, xlator_t *this) +dht_rmdir_do(call_frame_t *frame, xlator_t *this)  { -        dht_local_t  *local = NULL; -        dht_conf_t   *conf = NULL; -        int           ret = -1; -        xlator_t     *hashed_subvol = NULL; -        char gfid[GF_UUID_BUF_SIZE] ={0}; +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int ret = -1; +    xlator_t *hashed_subvol = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        VALIDATE_OR_GOTO (this->private, err); +    VALIDATE_OR_GOTO(this->private, err); -        conf = this->private; -        local = frame->local; +    conf = this->private; +    local = frame->local; -        if (local->op_ret == -1) -                goto err; +    if (local->op_ret == -1) +        goto err; -        local->call_cnt = conf->subvolume_cnt; +    local->call_cnt = conf->subvolume_cnt; -        /* first remove from non-hashed_subvol */ -        hashed_subvol = dht_subvol_get_hashed (this, &local->loc); +    /* first remove from non-hashed_subvol */ +    hashed_subvol = dht_subvol_get_hashed(this, &local->loc); -        if (!hashed_subvol) { -                gf_uuid_unparse(local->loc.gfid, gfid); +    if (!hashed_subvol) { +        gf_uuid_unparse(local->loc.gfid, gfid); -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_HASHED_SUBVOL_GET_FAILED, -                        "Failed to get hashed subvol for %s (gfid = %s)", -                        local->loc.path, gfid); -        } else { -                local->hashed_subvol = hashed_subvol; -        } +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_HASHED_SUBVOL_GET_FAILED, +               "Failed to get hashed subvol for %s (gfid = %s)", +               local->loc.path, gfid); +    } else { +        local->hashed_subvol = hashed_subvol; +    } -        /* When DHT has only 1 child */ -        if (conf->subvolume_cnt == 1) { -                STACK_WIND_COOKIE (frame, dht_rmdir_hashed_subvol_cbk, -                                   conf->subvolumes[0], conf->subvolumes[0], -                                   conf->subvolumes[0]->fops->rmdir, -                                   &local->loc, local->flags, NULL); -                return 0; -        } +    /* When DHT has only 1 child */ +    if (conf->subvolume_cnt == 1) { +        STACK_WIND_COOKIE(frame, dht_rmdir_hashed_subvol_cbk, +                          conf->subvolumes[0], conf->subvolumes[0], +                          conf->subvolumes[0]->fops->rmdir, &local->loc, +                          local->flags, NULL); +        return 0; +    } -        local->current = &local->lock[0]; -        ret = dht_protect_namespace (frame, &local->loc, local->hashed_subvol, -                                     &local->current->ns, dht_rmdir_lock_cbk); -        if (ret < 0) { -                local->op_ret = -1; -                local->op_errno = errno ? errno : EINVAL; -                goto err; -        } +    local->current = &local->lock[0]; +    ret = dht_protect_namespace(frame, &local->loc, local->hashed_subvol, +                                &local->current->ns, dht_rmdir_lock_cbk); +    if (ret < 0) { +        local->op_ret = -1; +        local->op_errno = errno ? errno : EINVAL; +        goto err; +    } -        return 0; +    return 0;  err: -        dht_set_fixed_dir_stat (&local->preparent); -        dht_set_fixed_dir_stat (&local->postparent); +    dht_set_fixed_dir_stat(&local->preparent); +    dht_set_fixed_dir_stat(&local->postparent); -        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno, -                          &local->preparent, &local->postparent, NULL); -        return 0; +    DHT_STACK_UNWIND(rmdir, frame, local->op_ret, local->op_errno, +                     &local->preparent, &local->postparent, NULL); +    return 0;  } -  int -dht_rmdir_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                               int op_ret, int op_errno, struct iatt *preparent, -                               struct iatt *postparent, dict_t *xdata) +dht_rmdir_linkfile_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                              int op_ret, int op_errno, struct iatt *preparent, +                              struct iatt *postparent, dict_t *xdata)  { -        dht_local_t    *local = NULL; -        xlator_t       *prev = NULL; -        xlator_t       *src = NULL; -        call_frame_t   *readdirp_frame = NULL; -        dht_local_t    *readdirp_local = NULL; -        int             this_call_cnt = 0; -        char gfid[GF_UUID_BUF_SIZE] ={0}; - +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    xlator_t *src = NULL; +    call_frame_t *readdirp_frame = NULL; +    dht_local_t *readdirp_local = NULL; +    int this_call_cnt = 0; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        local  = frame->local; -        prev   = cookie; -        src    = prev; +    local = frame->local; +    prev = cookie; +    src = prev; +    readdirp_frame = local->main_frame; +    readdirp_local = readdirp_frame->local; -        readdirp_frame = local->main_frame; -        readdirp_local = readdirp_frame->local; +    gf_uuid_unparse(local->loc.gfid, gfid); -        gf_uuid_unparse(local->loc.gfid, gfid); - -        if (op_ret == 0) { -                gf_msg_trace (this->name, 0, -                              "Unlinked linkfile %s on %s, gfid = %s", -                              local->loc.path, src->name, gfid); -        } else { -                if (op_errno != ENOENT) { -                        readdirp_local->op_ret   = -1; -                        readdirp_local->op_errno = op_errno; -                } -                gf_msg_debug (this->name, op_errno, -                              "Unlink of %s on %s failed. (gfid = %s)", -                              local->loc.path, src->name, gfid); +    if (op_ret == 0) { +        gf_msg_trace(this->name, 0, "Unlinked linkfile %s on %s, gfid = %s", +                     local->loc.path, src->name, gfid); +    } else { +        if (op_errno != ENOENT) { +            readdirp_local->op_ret = -1; +            readdirp_local->op_errno = op_errno;          } +        gf_msg_debug(this->name, op_errno, +                     "Unlink of %s on %s failed. (gfid = %s)", local->loc.path, +                     src->name, gfid); +    } -        this_call_cnt = dht_frame_return (readdirp_frame); +    this_call_cnt = dht_frame_return(readdirp_frame); -        if (is_last_call (this_call_cnt)) -                dht_rmdir_readdirp_do (readdirp_frame, this); +    if (is_last_call(this_call_cnt)) +        dht_rmdir_readdirp_do(readdirp_frame, this); -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  } -  int -dht_rmdir_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                      int op_ret, int op_errno, inode_t *inode, -                      struct iatt *stbuf, dict_t *xattr, struct iatt *parent) +dht_rmdir_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                     int op_ret, int op_errno, inode_t *inode, +                     struct iatt *stbuf, dict_t *xattr, struct iatt *parent)  { -        dht_local_t    *local = NULL; -        xlator_t       *prev = NULL; -        xlator_t       *src = NULL; -        call_frame_t   *readdirp_frame = NULL; -        dht_local_t    *readdirp_local = NULL; -        int             this_call_cnt = 0; -        dht_conf_t     *conf = this->private; -        char               gfid[GF_UUID_BUF_SIZE] = {0}; +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    xlator_t *src = NULL; +    call_frame_t *readdirp_frame = NULL; +    dht_local_t *readdirp_local = NULL; +    int this_call_cnt = 0; +    dht_conf_t *conf = this->private; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        local = frame->local; -        prev  = cookie; -        src   = prev; +    local = frame->local; +    prev = cookie; +    src = prev; -        gf_msg_debug (this->name, 0, "dht_rmdir_lookup_cbk %s", -                      local->loc.path); +    gf_msg_debug(this->name, 0, "dht_rmdir_lookup_cbk %s", local->loc.path); -        readdirp_frame = local->main_frame; -        readdirp_local = readdirp_frame->local; +    readdirp_frame = local->main_frame; +    readdirp_local = readdirp_frame->local; -        if (op_ret != 0) { +    if (op_ret != 0) { +        gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_FILE_LOOKUP_FAILED, +               "lookup failed for %s on %s  (type=0%o)", local->loc.path, +               src->name, stbuf->ia_type); +        goto err; +    } -                gf_msg (this->name, GF_LOG_WARNING, op_errno, -                        DHT_MSG_FILE_LOOKUP_FAILED, -                        "lookup failed for %s on %s  (type=0%o)", -                        local->loc.path, src->name, stbuf->ia_type); -                goto err; -        } - -        if (!check_is_linkfile (inode, stbuf, xattr, conf->link_xattr_name)) { -                readdirp_local->op_ret  = -1; -                readdirp_local->op_errno = ENOTEMPTY; +    if (!check_is_linkfile(inode, stbuf, xattr, conf->link_xattr_name)) { +        readdirp_local->op_ret = -1; +        readdirp_local->op_errno = ENOTEMPTY; -                gf_uuid_unparse(local->loc.gfid, gfid); +        gf_uuid_unparse(local->loc.gfid, gfid); -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_NOT_LINK_FILE_ERROR, -                        "%s on %s is not a linkfile (type=0%o, gfid = %s)", -                        local->loc.path, src->name, stbuf->ia_type, gfid); -                goto err; -        } +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_NOT_LINK_FILE_ERROR, +               "%s on %s is not a linkfile (type=0%o, gfid = %s)", +               local->loc.path, src->name, stbuf->ia_type, gfid); +        goto err; +    } -        STACK_WIND_COOKIE (frame, dht_rmdir_linkfile_unlink_cbk, src, -                           src, src->fops->unlink, &local->loc, 0, NULL); -        return 0; +    STACK_WIND_COOKIE(frame, dht_rmdir_linkfile_unlink_cbk, src, src, +                      src->fops->unlink, &local->loc, 0, NULL); +    return 0;  err: -        this_call_cnt = dht_frame_return (readdirp_frame); -        if (is_last_call (this_call_cnt)) { -                dht_rmdir_readdirp_do (readdirp_frame, this); -        } +    this_call_cnt = dht_frame_return(readdirp_frame); +    if (is_last_call(this_call_cnt)) { +        dht_rmdir_readdirp_do(readdirp_frame, this); +    } -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  } -  int -dht_rmdir_cached_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                             int op_ret, int op_errno, inode_t *inode, -                             struct iatt *stbuf, dict_t *xattr, -                             struct iatt *parent) +dht_rmdir_cached_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                            int op_ret, int op_errno, inode_t *inode, +                            struct iatt *stbuf, dict_t *xattr, +                            struct iatt *parent)  { -        dht_local_t    *local             = NULL; -        xlator_t       *src               = NULL; -        call_frame_t   *readdirp_frame    = NULL; -        dht_local_t    *readdirp_local    = NULL; -        int             this_call_cnt     = 0; -        dht_conf_t     *conf              = this->private; -        dict_t         *xattrs            = NULL; -        int             ret               = 0; +    dht_local_t *local = NULL; +    xlator_t *src = NULL; +    call_frame_t *readdirp_frame = NULL; +    dht_local_t *readdirp_local = NULL; +    int this_call_cnt = 0; +    dht_conf_t *conf = this->private; +    dict_t *xattrs = NULL; +    int ret = 0; -        local = frame->local; -        src   = local->hashed_subvol; +    local = frame->local; +    src = local->hashed_subvol; +    /* main_frame here is the readdirp_frame */ -        /* main_frame here is the readdirp_frame */ +    readdirp_frame = local->main_frame; +    readdirp_local = readdirp_frame->local; -        readdirp_frame = local->main_frame; -        readdirp_local = readdirp_frame->local; +    gf_msg_debug(this->name, 0, "returning for %s ", local->loc.path); -        gf_msg_debug (this->name, 0, "returning for %s ", -                      local->loc.path); +    if (op_ret == 0) { +        readdirp_local->op_ret = -1; +        readdirp_local->op_errno = ENOTEMPTY; -        if (op_ret == 0) { -                readdirp_local->op_ret  = -1; -                readdirp_local->op_errno = ENOTEMPTY; +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_SUBVOL_ERROR, +               "%s found on cached subvol %s", local->loc.path, src->name); +        goto err; +    } else if (op_errno != ENOENT) { +        readdirp_local->op_ret = -1; +        readdirp_local->op_errno = op_errno; -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_SUBVOL_ERROR, -                        "%s found on cached subvol %s", -                        local->loc.path, src->name); -                goto err; -        } else if (op_errno != ENOENT) { -                readdirp_local->op_ret  = -1; -                readdirp_local->op_errno = op_errno; - -                gf_msg (this->name, GF_LOG_WARNING, op_errno, -                        DHT_MSG_SUBVOL_ERROR, -                        "%s not found on cached subvol %s", -                        local->loc.path, src->name); -                goto err; -        } +        gf_msg(this->name, GF_LOG_WARNING, op_errno, DHT_MSG_SUBVOL_ERROR, +               "%s not found on cached subvol %s", local->loc.path, src->name); +        goto err; +    } -        xattrs = dict_new (); -        if (!xattrs) { -                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                        DHT_MSG_NO_MEMORY, "dict_new failed"); -                goto err; -        } +    xattrs = dict_new(); +    if (!xattrs) { +        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +               "dict_new failed"); +        goto err; +    } -        ret = dict_set_uint32 (xattrs, conf->link_xattr_name, 256); -        if (ret) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value: key = %s", -                        conf->link_xattr_name); -                if (xattrs) -                        dict_unref (xattrs); -                goto err; -        } -        STACK_WIND_COOKIE (frame, dht_rmdir_lookup_cbk, src, src, -                           src->fops->lookup, &local->loc, xattrs); +    ret = dict_set_uint32(xattrs, conf->link_xattr_name, 256); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value: key = %s", +               conf->link_xattr_name);          if (xattrs) -                dict_unref (xattrs); - -        return 0; +            dict_unref(xattrs); +        goto err; +    } +    STACK_WIND_COOKIE(frame, dht_rmdir_lookup_cbk, src, src, src->fops->lookup, +                      &local->loc, xattrs); +    if (xattrs) +        dict_unref(xattrs); + +    return 0;  err: -        this_call_cnt = dht_frame_return (readdirp_frame); +    this_call_cnt = dht_frame_return(readdirp_frame); -        /* Once all the lookups/unlinks etc have returned, proceed to wind -         * readdirp on the subvol again until no entries are returned. -         * This is required if there are more entries than can be returned -         * in a single readdirp call. -         */ +    /* Once all the lookups/unlinks etc have returned, proceed to wind +     * readdirp on the subvol again until no entries are returned. +     * This is required if there are more entries than can be returned +     * in a single readdirp call. +     */ -        if (is_last_call (this_call_cnt)) -                dht_rmdir_readdirp_do (readdirp_frame, this); +    if (is_last_call(this_call_cnt)) +        dht_rmdir_readdirp_do(readdirp_frame, this); -        DHT_STACK_DESTROY (frame); -        return 0; +    DHT_STACK_DESTROY(frame); +    return 0;  } -  int -dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this, -                           gf_dirent_t *entries, xlator_t *src) +dht_rmdir_is_subvol_empty(call_frame_t *frame, xlator_t *this, +                          gf_dirent_t *entries, xlator_t *src)  { -        int                 ret          = 0; -        int                 build_ret    = 0; -        gf_dirent_t        *trav         = NULL; -        call_frame_t       *lookup_frame = NULL; -        dht_local_t        *lookup_local = NULL; -        dht_local_t        *local        = NULL; -        dict_t             *xattrs       = NULL; -        dht_conf_t         *conf         = this->private; -        xlator_t           *subvol       = NULL; -        char                gfid[GF_UUID_BUF_SIZE] = {0}; -        int                 count        = 0; -        gf_boolean_t        unwind        = _gf_false; - - -        local = frame->local; +    int ret = 0; +    int build_ret = 0; +    gf_dirent_t *trav = NULL; +    call_frame_t *lookup_frame = NULL; +    dht_local_t *lookup_local = NULL; +    dht_local_t *local = NULL; +    dict_t *xattrs = NULL; +    dht_conf_t *conf = this->private; +    xlator_t *subvol = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    int count = 0; +    gf_boolean_t unwind = _gf_false; -        list_for_each_entry (trav, &entries->list, list) { -                if (strcmp (trav->d_name, ".") == 0) -                        continue; -                if (strcmp (trav->d_name, "..") == 0) -                        continue; -                if (check_is_linkfile (NULL, (&trav->d_stat), trav->dict, -                                              conf->link_xattr_name)) { -                        count++; -                        continue; -                } +    local = frame->local; -                /* this entry is either a directory which is neither "." nor "..", -                   or a non directory which is not a linkfile. the directory is to -                   be treated as non-empty -                */ -                return 0; +    list_for_each_entry(trav, &entries->list, list) +    { +        if (strcmp(trav->d_name, ".") == 0) +            continue; +        if (strcmp(trav->d_name, "..") == 0) +            continue; +        if (check_is_linkfile(NULL, (&trav->d_stat), trav->dict, +                              conf->link_xattr_name)) { +            count++; +            continue;          } -        xattrs = dict_new (); -        if (!xattrs) { -                gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                        DHT_MSG_NO_MEMORY, "dict_new failed"); -                return -1; -        } +        /* this entry is either a directory which is neither "." nor "..", +           or a non directory which is not a linkfile. the directory is to +           be treated as non-empty +        */ +        return 0; +    } -        ret = dict_set_uint32 (xattrs, conf->link_xattr_name, 256); -        if (ret) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        DHT_MSG_DICT_SET_FAILED, -                        "Failed to set dictionary value: key = %s", -                        conf->link_xattr_name); +    xattrs = dict_new(); +    if (!xattrs) { +        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY, +               "dict_new failed"); +        return -1; +    } -                if (xattrs) -                        dict_unref (xattrs); -                return -1; -        } +    ret = dict_set_uint32(xattrs, conf->link_xattr_name, 256); +    if (ret) { +        gf_msg(this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +               "Failed to set dictionary value: key = %s", +               conf->link_xattr_name); -        local->call_cnt = count; -        ret = 0; +        if (xattrs) +            dict_unref(xattrs); +        return -1; +    } -        list_for_each_entry (trav, &entries->list, list) { -                if (strcmp (trav->d_name, ".") == 0) -                        continue; -                if (strcmp (trav->d_name, "..") == 0) -                        continue; +    local->call_cnt = count; +    ret = 0; -                lookup_frame = copy_frame (frame); +    list_for_each_entry(trav, &entries->list, list) +    { +        if (strcmp(trav->d_name, ".") == 0) +            continue; +        if (strcmp(trav->d_name, "..") == 0) +            continue; -                if (!lookup_frame) { -                        /* out of memory, let the rmdir fail -                           (as non-empty, unfortunately) */ -                        goto err; -                } +        lookup_frame = copy_frame(frame); -                lookup_local = dht_local_init (lookup_frame, NULL, NULL, -                                               GF_FOP_LOOKUP); -                if (!lookup_local) { -                        goto err; -                } +        if (!lookup_frame) { +            /* out of memory, let the rmdir fail +               (as non-empty, unfortunately) */ +            goto err; +        } -                lookup_frame->local = lookup_local; -                lookup_local->main_frame = frame; -                lookup_local->hashed_subvol = src; +        lookup_local = dht_local_init(lookup_frame, NULL, NULL, GF_FOP_LOOKUP); +        if (!lookup_local) { +            goto err; +        } -                build_ret = dht_build_child_loc (this, &lookup_local->loc, -                                                 &local->loc, trav->d_name); -                if (build_ret != 0) -                        goto err; +        lookup_frame->local = lookup_local; +        lookup_local->main_frame = frame; +        lookup_local->hashed_subvol = src; -                gf_uuid_copy (lookup_local->loc.gfid, trav->d_stat.ia_gfid); +        build_ret = dht_build_child_loc(this, &lookup_local->loc, &local->loc, +                                        trav->d_name); +        if (build_ret != 0) +            goto err; -                gf_uuid_unparse(lookup_local->loc.gfid, gfid); +        gf_uuid_copy(lookup_local->loc.gfid, trav->d_stat.ia_gfid); -                gf_msg_trace (this->name, 0, -                              "looking up %s on subvolume %s, gfid = %s", -                              lookup_local->loc.path, src->name, gfid); +        gf_uuid_unparse(lookup_local->loc.gfid, gfid); -                subvol = dht_linkfile_subvol (this, NULL, &trav->d_stat, -                                              trav->dict); -                if (!subvol) { +        gf_msg_trace(this->name, 0, "looking up %s on subvolume %s, gfid = %s", +                     lookup_local->loc.path, src->name, gfid); -                        gf_msg (this->name, GF_LOG_INFO, 0, -                                DHT_MSG_INVALID_LINKFILE, -                                "Linkfile does not have link subvolume. " -                                "path = %s, gfid = %s", -                                lookup_local->loc.path, gfid); +        subvol = dht_linkfile_subvol(this, NULL, &trav->d_stat, trav->dict); +        if (!subvol) { +            gf_msg(this->name, GF_LOG_INFO, 0, DHT_MSG_INVALID_LINKFILE, +                   "Linkfile does not have link subvolume. " +                   "path = %s, gfid = %s", +                   lookup_local->loc.path, gfid); -                        gf_msg_debug (this->name, 0, -                                      "looking up %s on subvol %s, gfid = %s", -                                      lookup_local->loc.path, src->name, gfid); +            gf_msg_debug(this->name, 0, "looking up %s on subvol %s, gfid = %s", +                         lookup_local->loc.path, src->name, gfid); -                        STACK_WIND_COOKIE (lookup_frame, dht_rmdir_lookup_cbk, -                                           src, src, src->fops->lookup, -                                           &lookup_local->loc, xattrs); -                } else { -                        gf_msg_debug (this->name, 0, -                                      "Looking up linkfile target %s on " -                                      " subvol %s, gfid = %s", -                                      lookup_local->loc.path, subvol->name, -                                      gfid); - -                        STACK_WIND (lookup_frame, dht_rmdir_cached_lookup_cbk, -                                    subvol, subvol->fops->lookup, -                                    &lookup_local->loc, xattrs); -                } -                ret++; +            STACK_WIND_COOKIE(lookup_frame, dht_rmdir_lookup_cbk, src, src, +                              src->fops->lookup, &lookup_local->loc, xattrs); +        } else { +            gf_msg_debug(this->name, 0, +                         "Looking up linkfile target %s on " +                         " subvol %s, gfid = %s", +                         lookup_local->loc.path, subvol->name, gfid); -                lookup_frame = NULL; -                lookup_local = NULL; +            STACK_WIND(lookup_frame, dht_rmdir_cached_lookup_cbk, subvol, +                       subvol->fops->lookup, &lookup_local->loc, xattrs);          } +        ret++; -        if (xattrs) -                dict_unref (xattrs); +        lookup_frame = NULL; +        lookup_local = NULL; +    } -        return ret; +    if (xattrs) +        dict_unref(xattrs); + +    return ret;  err: -        if (xattrs) -                dict_unref (xattrs); +    if (xattrs) +        dict_unref(xattrs); -        if (lookup_frame) -                DHT_STACK_DESTROY (lookup_frame); +    if (lookup_frame) +        DHT_STACK_DESTROY(lookup_frame); -        /* Handle the case where the wound calls have unwound before the -         * loop processing is done -         */ +    /* Handle the case where the wound calls have unwound before the +     * loop processing is done +     */ -        LOCK (&frame->lock); -        { -                local->op_ret = -1; -                local->op_errno = ENOTEMPTY; +    LOCK(&frame->lock); +    { +        local->op_ret = -1; +        local->op_errno = ENOTEMPTY; -                local->call_cnt -= (count - ret); -                if (!local->call_cnt) -                        unwind = _gf_true; -        } -        UNLOCK (&frame->lock); +        local->call_cnt -= (count - ret); +        if (!local->call_cnt) +            unwind = _gf_true; +    } +    UNLOCK(&frame->lock); -        if (!unwind) { -                return ret; -        } -        return 0; +    if (!unwind) { +        return ret; +    } +    return 0;  } - -  /*   * No more entries on this subvol. Proceed to the actual rmdir operation.   */  void -dht_rmdir_readdirp_done (call_frame_t *readdirp_frame, xlator_t *this) +dht_rmdir_readdirp_done(call_frame_t *readdirp_frame, xlator_t *this)  { +    call_frame_t *main_frame = NULL; +    dht_local_t *main_local = NULL; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; -        call_frame_t      *main_frame    = NULL; -        dht_local_t       *main_local         = NULL; -        dht_local_t       *local         = NULL; -        int                this_call_cnt = 0; - +    local = readdirp_frame->local; +    main_frame = local->main_frame; +    main_local = main_frame->local; -        local = readdirp_frame->local; -        main_frame = local->main_frame; -        main_local = main_frame->local; +    /* At least one readdirp failed. +     * This is a bit hit or miss - if readdirp failed on more than +     * one subvol, we don't know which error is returned. +     */ +    if (local->op_ret == -1) { +        main_local->op_ret = local->op_ret; +        main_local->op_errno = local->op_errno; +    } -        /* At least one readdirp failed. -         * This is a bit hit or miss - if readdirp failed on more than -         * one subvol, we don't know which error is returned. -         */ -        if (local->op_ret == -1) { -                main_local->op_ret = local->op_ret; -                main_local->op_errno = local->op_errno; -        } +    this_call_cnt = dht_frame_return(main_frame); -        this_call_cnt = dht_frame_return (main_frame); +    if (is_last_call(this_call_cnt)) +        dht_rmdir_do(main_frame, this); -        if (is_last_call (this_call_cnt)) -                dht_rmdir_do (main_frame, this); - - -        DHT_STACK_DESTROY (readdirp_frame); +    DHT_STACK_DESTROY(readdirp_frame);  } - -  int -dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                        int op_ret, int op_errno, gf_dirent_t *entries, -                        dict_t *xdata) +dht_rmdir_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                       int op_ret, int op_errno, gf_dirent_t *entries, +                       dict_t *xdata)  { -        dht_local_t  *local = NULL; -        xlator_t     *prev = NULL; -        xlator_t     *src = NULL; -        int           ret = 0; +    dht_local_t *local = NULL; +    xlator_t *prev = NULL; +    xlator_t *src = NULL; +    int ret = 0; +    local = frame->local; +    prev = cookie; +    src = prev; -        local = frame->local; -        prev  = cookie; -        src   = prev; - -        if (op_ret > 2) { -                ret = dht_rmdir_is_subvol_empty (frame, this, entries, src); - -                switch (ret) { -                case 0: /* non linkfiles exist */ -                        gf_msg_trace (this->name, 0, -                                      "readdir on %s for %s returned %d " -                                      "entries", prev->name, -                                      local->loc.path, op_ret); -                        local->op_ret = -1; -                        local->op_errno = ENOTEMPTY; -                        goto done; -                default: -                        /* @ret number of linkfiles are getting unlinked */ -                        gf_msg_trace (this->name, 0, -                                      "readdir on %s for %s found %d " -                                      "linkfiles", prev->name, -                                      local->loc.path, ret); -                        break; -                } +    if (op_ret > 2) { +        ret = dht_rmdir_is_subvol_empty(frame, this, entries, src); +        switch (ret) { +            case 0: /* non linkfiles exist */ +                gf_msg_trace(this->name, 0, +                             "readdir on %s for %s returned %d " +                             "entries", +                             prev->name, local->loc.path, op_ret); +                local->op_ret = -1; +                local->op_errno = ENOTEMPTY; +                goto done; +            default: +                /* @ret number of linkfiles are getting unlinked */ +                gf_msg_trace(this->name, 0, +                             "readdir on %s for %s found %d " +                             "linkfiles", +                             prev->name, local->loc.path, ret); +                break;          } +    } - -        if (ret) { -                return 0; -        } +    if (ret) { +        return 0; +    }  done: -        /* readdirp failed or no linkto files were found on this subvol */ +    /* readdirp failed or no linkto files were found on this subvol */ -        dht_rmdir_readdirp_done (frame, this); -        return 0; +    dht_rmdir_readdirp_done(frame, this); +    return 0;  }  /* Keep sending readdirp on the subvol until it returns no more entries @@ -10746,214 +10095,202 @@ done:   */  int -dht_rmdir_readdirp_do (call_frame_t *readdirp_frame, xlator_t *this) +dht_rmdir_readdirp_do(call_frame_t *readdirp_frame, xlator_t *this)  { -        dht_local_t *local  = NULL; - -        local = readdirp_frame->local; - -        if (local->op_ret == -1) { -                /* there is no point doing another readdirp on this -                 * subvol . */ -                dht_rmdir_readdirp_done (readdirp_frame, this); -                return 0; -        } - -        STACK_WIND_COOKIE (readdirp_frame, dht_rmdir_readdirp_cbk, -                           local->hashed_subvol, -                           local->hashed_subvol, -                           local->hashed_subvol->fops->readdirp, -                           local->fd, 4096, 0, local->xattr); +    dht_local_t *local = NULL; +    local = readdirp_frame->local; +    if (local->op_ret == -1) { +        /* there is no point doing another readdirp on this +         * subvol . */ +        dht_rmdir_readdirp_done(readdirp_frame, this);          return 0; +    } -} +    STACK_WIND_COOKIE(readdirp_frame, dht_rmdir_readdirp_cbk, +                      local->hashed_subvol, local->hashed_subvol, +                      local->hashed_subvol->fops->readdirp, local->fd, 4096, 0, +                      local->xattr); +    return 0; +}  int -dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                       int op_ret, int op_errno, fd_t *fd, dict_t *xdata) +dht_rmdir_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                      int op_ret, int op_errno, fd_t *fd, dict_t *xdata)  { -        dht_local_t  *local         = NULL; -        int           this_call_cnt = -1; -        xlator_t     *prev          = NULL; -        int           ret           = 0; -        dht_conf_t   *conf          = this->private; -        dict_t       *dict          = NULL; -        int           i             = 0; -        char          gfid[GF_UUID_BUF_SIZE] = {0}; -        dht_local_t  *readdirp_local = NULL; -        call_frame_t *readdirp_frame = NULL; -        int           cnt           = 0; +    dht_local_t *local = NULL; +    int this_call_cnt = -1; +    xlator_t *prev = NULL; +    int ret = 0; +    dht_conf_t *conf = this->private; +    dict_t *dict = NULL; +    int i = 0; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    dht_local_t *readdirp_local = NULL; +    call_frame_t *readdirp_frame = NULL; +    int cnt = 0; -        local = frame->local; -        prev  = cookie; +    local = frame->local; +    prev = cookie; +    this_call_cnt = dht_frame_return(frame); +    if (op_ret == -1) { +        gf_uuid_unparse(local->loc.gfid, gfid); -        this_call_cnt = dht_frame_return (frame); -        if (op_ret == -1) { -                gf_uuid_unparse(local->loc.gfid, gfid); - -                gf_msg_debug (this->name, op_errno, -                              "opendir on %s for %s failed, " -                              "gfid = %s,", -                              prev->name, local->loc.path, gfid); -                if ((op_errno != ENOENT) && (op_errno != ESTALE)) { -                        local->op_ret = -1; -                        local->op_errno = op_errno; -                } -                goto err; +        gf_msg_debug(this->name, op_errno, +                     "opendir on %s for %s failed, " +                     "gfid = %s,", +                     prev->name, local->loc.path, gfid); +        if ((op_errno != ENOENT) && (op_errno != ESTALE)) { +            local->op_ret = -1; +            local->op_errno = op_errno;          } +        goto err; +    } -        if (!is_last_call (this_call_cnt)) -                return 0; - -        if (local->op_ret == -1) -                goto err; - -        fd_bind (fd); +    if (!is_last_call(this_call_cnt)) +        return 0; -        dict = dict_new (); -        if (!dict) { -                local->op_ret = -1; -                local->op_errno = ENOMEM; -                goto err; -        } +    if (local->op_ret == -1) +        goto err; -        ret = dict_set_uint32 (dict, conf->link_xattr_name, 256); -        if (ret) -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_DICT_SET_FAILED, -                        "%s: Failed to set dictionary value:key = %s", -                        local->loc.path, conf->link_xattr_name); - -        cnt = local->call_cnt = conf->subvolume_cnt; +    fd_bind(fd); +    dict = dict_new(); +    if (!dict) { +        local->op_ret = -1; +        local->op_errno = ENOMEM; +        goto err; +    } -        /* Create a separate frame per subvol as we might need -         * to resend readdirp multiple times to get all the -         * entries. -         */ +    ret = dict_set_uint32(dict, conf->link_xattr_name, 256); +    if (ret) +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_DICT_SET_FAILED, +               "%s: Failed to set dictionary value:key = %s", local->loc.path, +               conf->link_xattr_name); -        for (i = 0; i < conf->subvolume_cnt; i++) { +    cnt = local->call_cnt = conf->subvolume_cnt; -                readdirp_frame = copy_frame (frame); +    /* Create a separate frame per subvol as we might need +     * to resend readdirp multiple times to get all the +     * entries. +     */ -                if (!readdirp_frame) { -                        cnt--; -                        /* Reduce the local->call_cnt as well */ -                        (void) dht_frame_return (frame); -                        continue; -                } +    for (i = 0; i < conf->subvolume_cnt; i++) { +        readdirp_frame = copy_frame(frame); -                readdirp_local = dht_local_init (readdirp_frame, &local->loc, -                                                 local->fd, 0); +        if (!readdirp_frame) { +            cnt--; +            /* Reduce the local->call_cnt as well */ +            (void)dht_frame_return(frame); +            continue; +        } -                if (!readdirp_local) { -                        DHT_STACK_DESTROY (readdirp_frame); -                        cnt--; -                        /* Reduce the local->call_cnt as well */ -                        dht_frame_return (frame); -                        continue; -                } -                readdirp_local->main_frame = frame; -                readdirp_local->op_ret = 0; -                readdirp_local->xattr = dict_ref (dict); -                /* overload this field to save the subvol info */ -                readdirp_local->hashed_subvol = conf->subvolumes[i]; +        readdirp_local = dht_local_init(readdirp_frame, &local->loc, local->fd, +                                        0); -                STACK_WIND_COOKIE (readdirp_frame, dht_rmdir_readdirp_cbk, -                                   conf->subvolumes[i], conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->readdirp, -                                   readdirp_local->fd, 4096, 0, -                                   readdirp_local->xattr); +        if (!readdirp_local) { +            DHT_STACK_DESTROY(readdirp_frame); +            cnt--; +            /* Reduce the local->call_cnt as well */ +            dht_frame_return(frame); +            continue;          } +        readdirp_local->main_frame = frame; +        readdirp_local->op_ret = 0; +        readdirp_local->xattr = dict_ref(dict); +        /* overload this field to save the subvol info */ +        readdirp_local->hashed_subvol = conf->subvolumes[i]; -        if (dict) -                dict_unref (dict); +        STACK_WIND_COOKIE(readdirp_frame, dht_rmdir_readdirp_cbk, +                          conf->subvolumes[i], conf->subvolumes[i], +                          conf->subvolumes[i]->fops->readdirp, +                          readdirp_local->fd, 4096, 0, readdirp_local->xattr); +    } -        /* Could not wind readdirp to any subvol */ +    if (dict) +        dict_unref(dict); -        if (!cnt) -                goto err; +    /* Could not wind readdirp to any subvol */ -        return 0; +    if (!cnt) +        goto err; + +    return 0;  err: -        if (is_last_call (this_call_cnt)) { -                dht_rmdir_do (frame, this); -        } +    if (is_last_call(this_call_cnt)) { +        dht_rmdir_do(frame, this); +    } -        return 0; +    return 0;  } -  int -dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, -           dict_t *xdata) +dht_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, +          dict_t *xdata)  { -        dht_local_t  *local  = NULL; -        dht_conf_t   *conf = NULL; -        int           op_errno = -1; -        int           i = -1; - -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); -        VALIDATE_OR_GOTO (loc->path, err); -        VALIDATE_OR_GOTO (this->private, err); +    dht_local_t *local = NULL; +    dht_conf_t *conf = NULL; +    int op_errno = -1; +    int i = -1; -        conf = this->private; +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); +    VALIDATE_OR_GOTO(loc->path, err); +    VALIDATE_OR_GOTO(this->private, err); -        local = dht_local_init (frame, loc, NULL, GF_FOP_RMDIR); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    conf = this->private; -        local->call_cnt = conf->subvolume_cnt; -        local->op_ret   = 0; -        local->fop_succeeded = 0; +    local = dht_local_init(frame, loc, NULL, GF_FOP_RMDIR); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        local->flags = flags; +    local->call_cnt = conf->subvolume_cnt; +    local->op_ret = 0; +    local->fop_succeeded = 0; -        local->fd = fd_create (local->loc.inode, frame->root->pid); -        if (!local->fd) { +    local->flags = flags; -                op_errno = ENOMEM; -                goto err; -        } +    local->fd = fd_create(local->loc.inode, frame->root->pid); +    if (!local->fd) { +        op_errno = ENOMEM; +        goto err; +    } -        if (flags) { -                return dht_rmdir_do (frame, this); -        } +    if (flags) { +        return dht_rmdir_do(frame, this); +    } -        for (i = 0; i < conf->subvolume_cnt; i++) { -                STACK_WIND_COOKIE (frame, dht_rmdir_opendir_cbk, -                                   conf->subvolumes[i], conf->subvolumes[i], -                                   conf->subvolumes[i]->fops->opendir, -                                   loc, local->fd, NULL); -        } +    for (i = 0; i < conf->subvolume_cnt; i++) { +        STACK_WIND_COOKIE(frame, dht_rmdir_opendir_cbk, conf->subvolumes[i], +                          conf->subvolumes[i], +                          conf->subvolumes[i]->fops->opendir, loc, local->fd, +                          NULL); +    } -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (rmdir, frame, -1, op_errno, -                          NULL, NULL, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(rmdir, frame, -1, op_errno, NULL, NULL, NULL); -        return 0; +    return 0;  }  int -dht_entrylk_cbk (call_frame_t *frame, void *cookie, -                 xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        DHT_STACK_UNWIND (entrylk, frame, op_ret, op_errno, xdata); -        return 0; +    DHT_STACK_UNWIND(entrylk, frame, op_ret, op_errno, xdata); +    return 0;  }  /* TODO @@ -10961,765 +10298,735 @@ dht_entrylk_cbk (call_frame_t *frame, void *cookie,   * as described in the bug 1311002.   */  int -dht_entrylk (call_frame_t *frame, xlator_t *this, -             const char *volume, loc_t *loc, const char *basename, -             entrylk_cmd cmd, entrylk_type type, dict_t *xdata) +dht_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, +            const char *basename, entrylk_cmd cmd, entrylk_type type, +            dict_t *xdata)  { -        xlator_t     *subvol = NULL; -        int           op_errno = -1; -        dht_local_t  *local = NULL; -        char          gfid[GF_UUID_BUF_SIZE] = {0}; +    xlator_t *subvol = NULL; +    int op_errno = -1; +    dht_local_t *local = NULL; +    char gfid[GF_UUID_BUF_SIZE] = {0}; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (loc, err); -        VALIDATE_OR_GOTO (loc->inode, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(loc, err); +    VALIDATE_OR_GOTO(loc->inode, err); -        local = dht_local_init (frame, loc, NULL, GF_FOP_ENTRYLK); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    local = dht_local_init(frame, loc, NULL, GF_FOP_ENTRYLK); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } +    subvol = local->cached_subvol; +    if (!subvol) { +        gf_uuid_unparse(loc->gfid, gfid); -        subvol = local->cached_subvol; -        if (!subvol) { -                gf_uuid_unparse(loc->gfid, gfid); - -                gf_msg_debug (this->name, 0, -                              "no cached subvolume for path=%s, " -                              "gfid = %s", loc->path, gfid); -                op_errno = EINVAL; -                goto err; -        } +        gf_msg_debug(this->name, 0, +                     "no cached subvolume for path=%s, " +                     "gfid = %s", +                     loc->path, gfid); +        op_errno = EINVAL; +        goto err; +    } -        local->call_cnt = 1; +    local->call_cnt = 1; -        STACK_WIND (frame, dht_entrylk_cbk, -                    subvol, subvol->fops->entrylk, -                    volume, loc, basename, cmd, type, xdata); +    STACK_WIND(frame, dht_entrylk_cbk, subvol, subvol->fops->entrylk, volume, +               loc, basename, cmd, type, xdata); -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(entrylk, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } -  int -dht_fentrylk_cbk (call_frame_t *frame, void *cookie, -                  xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, dict_t *xdata)  { -        DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, NULL); -        return 0; +    DHT_STACK_UNWIND(fentrylk, frame, op_ret, op_errno, NULL); +    return 0;  } -  int -dht_fentrylk (call_frame_t *frame, xlator_t *this, -              const char *volume, fd_t *fd, const char *basename, -              entrylk_cmd cmd, entrylk_type type, dict_t *xdata) +dht_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, +             const char *basename, entrylk_cmd cmd, entrylk_type type, +             dict_t *xdata)  { -        xlator_t     *subvol = NULL; -        int           op_errno = -1; -        char               gfid[GF_UUID_BUF_SIZE] = {0}; +    xlator_t *subvol = NULL; +    int op_errno = -1; +    char gfid[GF_UUID_BUF_SIZE] = {0}; +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); +    VALIDATE_OR_GOTO(fd, err); +    VALIDATE_OR_GOTO(fd->inode, err); -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); -        VALIDATE_OR_GOTO (fd, err); -        VALIDATE_OR_GOTO(fd->inode, err); +    gf_uuid_unparse(fd->inode->gfid, gfid); -        gf_uuid_unparse(fd->inode->gfid, gfid); +    subvol = dht_subvol_get_cached(this, fd->inode); +    if (!subvol) { +        gf_msg_debug(this->name, 0, +                     "No cached subvolume for fd=%p," +                     " gfid = %s", +                     fd, gfid); +        op_errno = EINVAL; +        goto err; +    } -        subvol = dht_subvol_get_cached (this, fd->inode); -        if (!subvol) { -                gf_msg_debug (this->name, 0, -                              "No cached subvolume for fd=%p," -                              " gfid = %s", fd, gfid); -                op_errno = EINVAL; -                goto err; -        } - -        STACK_WIND (frame, dht_fentrylk_cbk, -                    subvol, subvol->fops->fentrylk, -                    volume, fd, basename, cmd, type, xdata); +    STACK_WIND(frame, dht_fentrylk_cbk, subvol, subvol->fops->fentrylk, volume, +               fd, basename, cmd, type, xdata); -        return 0; +    return 0;  err: -        op_errno = (op_errno == -1) ? errno : op_errno; -        DHT_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL); +    op_errno = (op_errno == -1) ? errno : op_errno; +    DHT_STACK_UNWIND(fentrylk, frame, -1, op_errno, NULL); -        return 0; +    return 0;  } -  int32_t -dht_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -             int32_t op_ret, int32_t op_errno, dict_t *xdata) +dht_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +            int32_t op_errno, dict_t *xdata)  { -        dht_local_t  *local                   = NULL; -        int           this_call_cnt           = 0; +    dht_local_t *local = NULL; +    int this_call_cnt = 0; -        GF_VALIDATE_OR_GOTO ("dht", frame, out); -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); +    GF_VALIDATE_OR_GOTO("dht", frame, out); +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", frame->local, out); -        local = frame->local; +    local = frame->local; -        LOCK (&frame->lock); -        { -                if (op_ret < 0 && op_errno != ENOTCONN) { -                        local->op_errno = op_errno; -                        goto unlock; -                } -                local->op_ret = 0; +    LOCK(&frame->lock); +    { +        if (op_ret < 0 && op_errno != ENOTCONN) { +            local->op_errno = op_errno; +            goto unlock;          } +        local->op_ret = 0; +    }  unlock: -        UNLOCK (&frame->lock); +    UNLOCK(&frame->lock); -        this_call_cnt = dht_frame_return (frame); -        if (is_last_call (this_call_cnt)) { -                DHT_STACK_UNWIND (ipc, frame, local->op_ret, local->op_errno, -                                  NULL); -        } +    this_call_cnt = dht_frame_return(frame); +    if (is_last_call(this_call_cnt)) { +        DHT_STACK_UNWIND(ipc, frame, local->op_ret, local->op_errno, NULL); +    }  out: -        return 0; +    return 0;  } -  int32_t -dht_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +dht_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)  { -        dht_local_t  *local    = NULL; -        int           op_errno = EINVAL; -        dht_conf_t   *conf     = NULL; -        int           call_cnt = 0; -        int           i        = 0; +    dht_local_t *local = NULL; +    int op_errno = EINVAL; +    dht_conf_t *conf = NULL; +    int call_cnt = 0; +    int i = 0; -        VALIDATE_OR_GOTO (frame, err); -        VALIDATE_OR_GOTO (this, err); +    VALIDATE_OR_GOTO(frame, err); +    VALIDATE_OR_GOTO(this, err); -        if (op != GF_IPC_TARGET_UPCALL) -                goto wind_default; +    if (op != GF_IPC_TARGET_UPCALL) +        goto wind_default; -        VALIDATE_OR_GOTO (this->private, err); -        conf = this->private; +    VALIDATE_OR_GOTO(this->private, err); +    conf = this->private; -        local = dht_local_init (frame, NULL, NULL, GF_FOP_IPC); -        if (!local) { -                op_errno = ENOMEM; -                goto err; -        } +    local = dht_local_init(frame, NULL, NULL, GF_FOP_IPC); +    if (!local) { +        op_errno = ENOMEM; +        goto err; +    } -        call_cnt        = conf->subvolume_cnt; -        local->call_cnt = call_cnt; +    call_cnt = conf->subvolume_cnt; +    local->call_cnt = call_cnt; -        if (xdata) { -                if (dict_set_int8 (xdata, conf->xattr_name, 0) < 0) -                        goto err; -        } +    if (xdata) { +        if (dict_set_int8(xdata, conf->xattr_name, 0) < 0) +            goto err; +    } -        for (i = 0; i < call_cnt; i++) { -                STACK_WIND (frame, dht_ipc_cbk, conf->subvolumes[i], -                            conf->subvolumes[i]->fops->ipc, op, xdata); -        } +    for (i = 0; i < call_cnt; i++) { +        STACK_WIND(frame, dht_ipc_cbk, conf->subvolumes[i], +                   conf->subvolumes[i]->fops->ipc, op, xdata); +    } -        return 0; +    return 0;  err: -        DHT_STACK_UNWIND (ipc, frame, -1, op_errno, NULL); +    DHT_STACK_UNWIND(ipc, frame, -1, op_errno, NULL); -        return 0; +    return 0;  wind_default: -        STACK_WIND (frame, default_ipc_cbk, FIRST_CHILD (this), -                    FIRST_CHILD (this)->fops->ipc, op, xdata); -        return 0; +    STACK_WIND(frame, default_ipc_cbk, FIRST_CHILD(this), +               FIRST_CHILD(this)->fops->ipc, op, xdata); +    return 0;  } -  int -dht_forget (xlator_t *this, inode_t *inode) +dht_forget(xlator_t *this, inode_t *inode)  { -        uint64_t        ctx_int = 0; -        dht_inode_ctx_t *ctx    = NULL; -        dht_layout_t *layout = NULL; +    uint64_t ctx_int = 0; +    dht_inode_ctx_t *ctx = NULL; +    dht_layout_t *layout = NULL; -        inode_ctx_del (inode, this, &ctx_int); +    inode_ctx_del(inode, this, &ctx_int); -        if (!ctx_int) -                return 0; +    if (!ctx_int) +        return 0; -        ctx = (dht_inode_ctx_t *) (long) ctx_int; +    ctx = (dht_inode_ctx_t *)(long)ctx_int; -        layout = ctx->layout; -        ctx->layout = NULL; -        dht_layout_unref (this, layout); -        GF_FREE (ctx); +    layout = ctx->layout; +    ctx->layout = NULL; +    dht_layout_unref(this, layout); +    GF_FREE(ctx); -        return 0; +    return 0;  } -  int -dht_notify (xlator_t *this, int event, void *data, ...) +dht_notify(xlator_t *this, int event, void *data, ...)  { -        xlator_t                *subvol = NULL; -        int                      cnt    = -1; -        int                      i      = -1; -        dht_conf_t              *conf   = NULL; -        int                      ret    = -1; -        int                      propagate = 0; +    xlator_t *subvol = NULL; +    int cnt = -1; +    int i = -1; +    dht_conf_t *conf = NULL; +    int ret = -1; +    int propagate = 0; -        int                      had_heard_from_all = 0; -        int                      have_heard_from_all = 0; -        struct timeval           time = {0,}; -        gf_defrag_info_t        *defrag = NULL; -        dict_t                  *dict   = NULL; -        gf_defrag_type           cmd    = 0; -        dict_t                  *output = NULL; -        va_list                  ap; -        dht_methods_t           *methods = NULL; -        struct gf_upcall        *up_data = NULL; -        struct gf_upcall_cache_invalidation *up_ci = NULL; +    int had_heard_from_all = 0; +    int have_heard_from_all = 0; +    struct timeval time = { +        0, +    }; +    gf_defrag_info_t *defrag = NULL; +    dict_t *dict = NULL; +    gf_defrag_type cmd = 0; +    dict_t *output = NULL; +    va_list ap; +    dht_methods_t *methods = NULL; +    struct gf_upcall *up_data = NULL; +    struct gf_upcall_cache_invalidation *up_ci = NULL; -        conf = this->private; -        GF_VALIDATE_OR_GOTO (this->name, conf, out); +    conf = this->private; +    GF_VALIDATE_OR_GOTO(this->name, conf, out); -        methods = &(conf->methods); +    methods = &(conf->methods); -        /* had all subvolumes reported status once till now? */ -        had_heard_from_all = 1; -        for (i = 0; i < conf->subvolume_cnt; i++) { -                if (!conf->last_event[i]) { -                        had_heard_from_all = 0; -                } +    /* had all subvolumes reported status once till now? */ +    had_heard_from_all = 1; +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (!conf->last_event[i]) { +            had_heard_from_all = 0;          } +    } -        switch (event) { +    switch (event) {          case GF_EVENT_CHILD_UP: -                subvol = data; +            subvol = data; -                conf->gen++; +            conf->gen++; -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (subvol == conf->subvolumes[i]) { -                                cnt = i; -                                break; -                        } +            for (i = 0; i < conf->subvolume_cnt; i++) { +                if (subvol == conf->subvolumes[i]) { +                    cnt = i; +                    break;                  } +            } -                if (cnt == -1) { -                        gf_msg_debug (this->name, 0, -                                      "got GF_EVENT_CHILD_UP bad " -                                      "subvolume %s", -                                      subvol->name); -                        break; -                } +            if (cnt == -1) { +                gf_msg_debug(this->name, 0, +                             "got GF_EVENT_CHILD_UP bad " +                             "subvolume %s", +                             subvol->name); +                break; +            } -                gettimeofday (&time, NULL); -                LOCK (&conf->subvolume_lock); -                { -                        conf->subvolume_status[cnt] = 1; -                        conf->last_event[cnt] = event; -                        conf->subvol_up_time[cnt] = time.tv_sec; -                } -                UNLOCK (&conf->subvolume_lock); +            gettimeofday(&time, NULL); +            LOCK(&conf->subvolume_lock); +            { +                conf->subvolume_status[cnt] = 1; +                conf->last_event[cnt] = event; +                conf->subvol_up_time[cnt] = time.tv_sec; +            } +            UNLOCK(&conf->subvolume_lock); -                /* one of the node came back up, do a stat update */ -                dht_get_du_info_for_subvol (this, cnt); +            /* one of the node came back up, do a stat update */ +            dht_get_du_info_for_subvol(this, cnt); -                break; +            break;          case GF_EVENT_SOME_DESCENDENT_UP: -                subvol = data; -                conf->gen++; -                propagate = 1; +            subvol = data; +            conf->gen++; +            propagate = 1; -                break; +            break;          case GF_EVENT_SOME_DESCENDENT_DOWN: -                subvol = data; -                propagate = 1; +            subvol = data; +            propagate = 1; -                break; +            break;          case GF_EVENT_CHILD_DOWN: -                subvol = data; - -                if (conf->assert_no_child_down) { -                        gf_msg (this->name, GF_LOG_WARNING, 0, -                                DHT_MSG_CHILD_DOWN, -                                "Received CHILD_DOWN. Exiting"); -                        if (conf->defrag) { -                                gf_defrag_stop (conf, -                                                GF_DEFRAG_STATUS_FAILED, NULL); -                        } else { -                                kill (getpid(), SIGTERM); -                        } -                } - -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (subvol == conf->subvolumes[i]) { -                                cnt = i; -                                break; -                        } -                } +            subvol = data; -                if (cnt == -1) { -                        gf_msg_debug (this->name, 0, -                                      "got GF_EVENT_CHILD_DOWN bad " -                                      "subvolume %s", subvol->name); -                        break; +            if (conf->assert_no_child_down) { +                gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_CHILD_DOWN, +                       "Received CHILD_DOWN. Exiting"); +                if (conf->defrag) { +                    gf_defrag_stop(conf, GF_DEFRAG_STATUS_FAILED, NULL); +                } else { +                    kill(getpid(), SIGTERM);                  } +            } -                LOCK (&conf->subvolume_lock); -                { -                        conf->subvolume_status[cnt] = 0; -                        conf->last_event[cnt] = event; -                        conf->subvol_up_time[cnt] = 0; +            for (i = 0; i < conf->subvolume_cnt; i++) { +                if (subvol == conf->subvolumes[i]) { +                    cnt = i; +                    break;                  } -                UNLOCK (&conf->subvolume_lock); +            } -                for (i = 0; i < conf->subvolume_cnt; i++) -                        if (conf->last_event[i] != event) -                                event = GF_EVENT_SOME_DESCENDENT_DOWN; +            if (cnt == -1) { +                gf_msg_debug(this->name, 0, +                             "got GF_EVENT_CHILD_DOWN bad " +                             "subvolume %s", +                             subvol->name);                  break; +            } -        case GF_EVENT_CHILD_CONNECTING: -                subvol = data; +            LOCK(&conf->subvolume_lock); +            { +                conf->subvolume_status[cnt] = 0; +                conf->last_event[cnt] = event; +                conf->subvol_up_time[cnt] = 0; +            } +            UNLOCK(&conf->subvolume_lock); -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (subvol == conf->subvolumes[i]) { -                                cnt = i; -                                break; -                        } -                } +            for (i = 0; i < conf->subvolume_cnt; i++) +                if (conf->last_event[i] != event) +                    event = GF_EVENT_SOME_DESCENDENT_DOWN; +            break; -                if (cnt == -1) { -                        gf_msg_debug (this->name, 0, -                                      "got GF_EVENT_CHILD_CONNECTING" -                                      " bad subvolume %s", -                                      subvol->name); -                        break; -                } +        case GF_EVENT_CHILD_CONNECTING: +            subvol = data; -                LOCK (&conf->subvolume_lock); -                { -                        conf->last_event[cnt] = event; +            for (i = 0; i < conf->subvolume_cnt; i++) { +                if (subvol == conf->subvolumes[i]) { +                    cnt = i; +                    break;                  } -                UNLOCK (&conf->subvolume_lock); +            } +            if (cnt == -1) { +                gf_msg_debug(this->name, 0, +                             "got GF_EVENT_CHILD_CONNECTING" +                             " bad subvolume %s", +                             subvol->name);                  break; -        case GF_EVENT_VOLUME_DEFRAG: -        { -                if (!conf->defrag) { -                        return ret; -                } -                defrag = conf->defrag; +            } -                dict = data; -                va_start (ap, data); -                output = va_arg (ap, dict_t*); +            LOCK(&conf->subvolume_lock); +            { +                conf->last_event[cnt] = event; +            } +            UNLOCK(&conf->subvolume_lock); -                ret = dict_get_int32 (dict, "rebalance-command", -                                      (int32_t*)&cmd); -                if (ret) { -                        va_end (ap); -                        return ret; -                } -                LOCK (&defrag->lock); -                { -                        if (defrag->is_exiting) -                                goto unlock; -                        if ((cmd == GF_DEFRAG_CMD_STATUS) || -                            (cmd == GF_DEFRAG_CMD_STATUS_TIER) || -                            (cmd == GF_DEFRAG_CMD_DETACH_STATUS)) -                                gf_defrag_status_get (conf, output); -                        else if (cmd == GF_DEFRAG_CMD_START_DETACH_TIER) -                                gf_defrag_start_detach_tier(defrag); -                        else if (cmd == GF_DEFRAG_CMD_DETACH_START) -                                defrag->cmd = GF_DEFRAG_CMD_DETACH_START; -                        else if (cmd == GF_DEFRAG_CMD_STOP || -                                 cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER || -                                 cmd == GF_DEFRAG_CMD_DETACH_STOP) -                                gf_defrag_stop (conf, -                                                GF_DEFRAG_STATUS_STOPPED, output); -                        else if (cmd == GF_DEFRAG_CMD_PAUSE_TIER) -                                ret = gf_defrag_pause_tier (this, defrag); -                        else if (cmd == GF_DEFRAG_CMD_RESUME_TIER) -                                ret = gf_defrag_resume_tier (this, defrag); -                } -unlock: -                UNLOCK (&defrag->lock); -                va_end (ap); +            break; +        case GF_EVENT_VOLUME_DEFRAG: { +            if (!conf->defrag) {                  return ret; -                break; +            } +            defrag = conf->defrag; + +            dict = data; +            va_start(ap, data); +            output = va_arg(ap, dict_t *); + +            ret = dict_get_int32(dict, "rebalance-command", (int32_t *)&cmd); +            if (ret) { +                va_end(ap); +                return ret; +            } +            LOCK(&defrag->lock); +            { +                if (defrag->is_exiting) +                    goto unlock; +                if ((cmd == GF_DEFRAG_CMD_STATUS) || +                    (cmd == GF_DEFRAG_CMD_STATUS_TIER) || +                    (cmd == GF_DEFRAG_CMD_DETACH_STATUS)) +                    gf_defrag_status_get(conf, output); +                else if (cmd == GF_DEFRAG_CMD_START_DETACH_TIER) +                    gf_defrag_start_detach_tier(defrag); +                else if (cmd == GF_DEFRAG_CMD_DETACH_START) +                    defrag->cmd = GF_DEFRAG_CMD_DETACH_START; +                else if (cmd == GF_DEFRAG_CMD_STOP || +                         cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER || +                         cmd == GF_DEFRAG_CMD_DETACH_STOP) +                    gf_defrag_stop(conf, GF_DEFRAG_STATUS_STOPPED, output); +                else if (cmd == GF_DEFRAG_CMD_PAUSE_TIER) +                    ret = gf_defrag_pause_tier(this, defrag); +                else if (cmd == GF_DEFRAG_CMD_RESUME_TIER) +                    ret = gf_defrag_resume_tier(this, defrag); +            } +        unlock: +            UNLOCK(&defrag->lock); +            va_end(ap); +            return ret; +            break;          }          case GF_EVENT_UPCALL: -                up_data = (struct gf_upcall *)data; -                if (up_data->event_type != GF_UPCALL_CACHE_INVALIDATION) -                        break; -                up_ci = (struct gf_upcall_cache_invalidation *)up_data->data; - -                /* Since md-cache will be aggressively filtering lookups, -                 * the stale layout issue will be more pronounced. Hence -                 * when a layout xattr is changed by the rebalance process -                 * notify all the md-cache clients to invalidate the existing -                 * stat cache and send the lookup next time*/ -                if (up_ci->dict && dict_get (up_ci->dict, conf->xattr_name)) -                        up_ci->flags |= UP_EXPLICIT_LOOKUP; - -                /* TODO: Instead of invalidating iatt, update the new -                 * hashed/cached subvolume in dht inode_ctx */ -                if (IS_DHT_LINKFILE_MODE (&up_ci->stat)) -                        up_ci->flags |= UP_EXPLICIT_LOOKUP; - -                propagate = 1; +            up_data = (struct gf_upcall *)data; +            if (up_data->event_type != GF_UPCALL_CACHE_INVALIDATION)                  break; +            up_ci = (struct gf_upcall_cache_invalidation *)up_data->data; + +            /* Since md-cache will be aggressively filtering lookups, +             * the stale layout issue will be more pronounced. Hence +             * when a layout xattr is changed by the rebalance process +             * notify all the md-cache clients to invalidate the existing +             * stat cache and send the lookup next time*/ +            if (up_ci->dict && dict_get(up_ci->dict, conf->xattr_name)) +                up_ci->flags |= UP_EXPLICIT_LOOKUP; + +            /* TODO: Instead of invalidating iatt, update the new +             * hashed/cached subvolume in dht inode_ctx */ +            if (IS_DHT_LINKFILE_MODE(&up_ci->stat)) +                up_ci->flags |= UP_EXPLICIT_LOOKUP; + +            propagate = 1; +            break;          default: -                propagate = 1; -                break; -        } - +            propagate = 1; +            break; +    } + +    /* have all subvolumes reported status once by now? */ +    have_heard_from_all = 1; +    for (i = 0; i < conf->subvolume_cnt; i++) { +        if (!conf->last_event[i]) +            have_heard_from_all = 0; +    } + +    /* if all subvols have reported status, no need to hide anything +       or wait for anything else. Just propagate blindly */ +    if (have_heard_from_all) { +        propagate = 1; +    } + +    if (!had_heard_from_all && have_heard_from_all) { +        /* This is the first event which completes aggregation +           of events from all subvolumes. If at least one subvol +           had come up, propagate CHILD_UP, but only this time +        */ +        event = GF_EVENT_CHILD_DOWN; -        /* have all subvolumes reported status once by now? */ -        have_heard_from_all = 1;          for (i = 0; i < conf->subvolume_cnt; i++) { -                if (!conf->last_event[i]) -                        have_heard_from_all = 0; -        } - -        /* if all subvols have reported status, no need to hide anything -           or wait for anything else. Just propagate blindly */ -        if (have_heard_from_all) { -                propagate = 1; +            if (conf->last_event[i] == GF_EVENT_CHILD_UP) { +                event = GF_EVENT_CHILD_UP; +                break; +            } +            if (conf->last_event[i] == GF_EVENT_CHILD_CONNECTING) { +                event = GF_EVENT_CHILD_CONNECTING; +                /* continue to check other events for CHILD_UP */ +            }          } - -        if (!had_heard_from_all && have_heard_from_all) { -                /* This is the first event which completes aggregation -                   of events from all subvolumes. If at least one subvol -                   had come up, propagate CHILD_UP, but only this time -                */ -                event = GF_EVENT_CHILD_DOWN; - -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (conf->last_event[i] == GF_EVENT_CHILD_UP) { -                                event = GF_EVENT_CHILD_UP; -                                break; -                        } - -                        if (conf->last_event[i] == GF_EVENT_CHILD_CONNECTING) { -                                event = GF_EVENT_CHILD_CONNECTING; -                                /* continue to check other events for CHILD_UP */ -                        } -                } - -                /* Rebalance is started with assert_no_child_down. So we do -                 * not need to handle CHILD_DOWN event here. -                 * -                 * If there is a graph switch, we should not restart the -                 * rebalance daemon. Use 'run_defrag' to indicate if the -                 * thread has already started. -                 */ -                 if (conf->defrag && !run_defrag) { -                        if (methods->migration_needed(this)) { -                                run_defrag = 1; -                                ret = gf_thread_create(&conf->defrag->th, -                                                       NULL, -                                                       gf_defrag_start, this, -                                                       "dhtdg"); -                                if (ret) { -                                        GF_FREE (conf->defrag); -                                        conf->defrag = NULL; -                                        kill (getpid(), SIGTERM); -                                } -                        } +        /* Rebalance is started with assert_no_child_down. So we do +         * not need to handle CHILD_DOWN event here. +         * +         * If there is a graph switch, we should not restart the +         * rebalance daemon. Use 'run_defrag' to indicate if the +         * thread has already started. +         */ +        if (conf->defrag && !run_defrag) { +            if (methods->migration_needed(this)) { +                run_defrag = 1; +                ret = gf_thread_create(&conf->defrag->th, NULL, gf_defrag_start, +                                       this, "dhtdg"); +                if (ret) { +                    GF_FREE(conf->defrag); +                    conf->defrag = NULL; +                    kill(getpid(), SIGTERM);                  } +            }          } +    } -        ret = 0; -        if (propagate) -                ret = default_notify (this, event, data); +    ret = 0; +    if (propagate) +        ret = default_notify(this, event, data);  out: -        return ret; +    return ret;  }  int -dht_inode_ctx_layout_get (inode_t *inode, xlator_t *this, dht_layout_t **layout) +dht_inode_ctx_layout_get(inode_t *inode, xlator_t *this, dht_layout_t **layout)  { -        dht_inode_ctx_t         *ctx            = NULL; -        int                      ret            = -1; +    dht_inode_ctx_t *ctx = NULL; +    int ret = -1; -        ret = dht_inode_ctx_get (inode, this, &ctx); +    ret = dht_inode_ctx_get(inode, this, &ctx); -        if (!ret && ctx) { -                if (ctx->layout) { -                        if (layout) -                                *layout = ctx->layout; -                        ret = 0; -                } else { -                        ret = -1; -                } +    if (!ret && ctx) { +        if (ctx->layout) { +            if (layout) +                *layout = ctx->layout; +            ret = 0; +        } else { +            ret = -1;          } +    } -        return ret; +    return ret;  }  void -dht_log_new_layout_for_dir_selfheal (xlator_t *this, loc_t *loc, -                                 dht_layout_t *layout) -{ +dht_log_new_layout_for_dir_selfheal(xlator_t *this, loc_t *loc, +                                    dht_layout_t *layout) +{ +    char string[2048] = {0}; +    char *output_string = NULL; +    int len = 0; +    int off = 0; +    int i = 0; +    gf_loglevel_t log_level = gf_log_get_loglevel(); +    int ret = 0; + +    if (log_level < GF_LOG_INFO) +        return; -        char                    string[2048] = {0}; -        char                  *output_string = NULL; -        int                              len = 0; -        int                              off = 0; -        int                                i = 0; -        gf_loglevel_t             log_level = gf_log_get_loglevel(); -        int                              ret = 0; +    if (!layout) +        return; -        if (log_level < GF_LOG_INFO) -                return; +    if (!layout->cnt) +        return; -        if (!layout) -                return; +    if (!loc) +        return; -        if (!layout->cnt) -                return; +    if (!loc->path) +        return; -        if (!loc) -                return; +    ret = snprintf(string, sizeof(string), "Setting layout of %s with ", +                   loc->path); -        if (!loc->path) -                return; +    if (ret < 0) +        return; -        ret = snprintf (string, sizeof (string), "Setting layout of %s with ", -                        loc->path); +    len += ret; + +    /* Calculation  of total length of the string required to calloc +     * output_string. Log includes subvolume-name, start-range, end-range and +     * err value. +     * +     * This log will help to debug cases where: +     * a) Different processes set different layout of a directory. +     * b) Error captured in lookup, which will be filled in layout->err +     * (like ENOENT, ESTALE etc) +     */ + +    for (i = 0; i < layout->cnt; i++) { +        ret = snprintf(string, sizeof(string), +                       "[Subvol_name: %s, Err: %d , Start: " +                       "%" PRIu32 " , Stop: %" PRIu32 " , Hash: %" PRIu32 +                       " ], ", +                       layout->list[i].xlator->name, layout->list[i].err, +                       layout->list[i].start, layout->list[i].stop, +                       layout->list[i].commit_hash);          if (ret < 0) -                return; +            return;          len += ret; +    } -       /* Calculation  of total length of the string required to calloc -        * output_string. Log includes subvolume-name, start-range, end-range and -        * err value. -        * -        * This log will help to debug cases where: -        * a) Different processes set different layout of a directory. -        * b) Error captured in lookup, which will be filled in layout->err -        * (like ENOENT, ESTALE etc) -        */ - -        for (i = 0; i < layout->cnt; i++) { +    len++; -                ret  = snprintf (string, sizeof (string), -                                 "[Subvol_name: %s, Err: %d , Start: " -                                 "%"PRIu32 " , Stop: %"PRIu32 " , Hash: %" -                                 PRIu32 " ], ", -                                 layout->list[i].xlator->name, -                                 layout->list[i].err, layout->list[i].start, -                                 layout->list[i].stop, -                                 layout->list[i].commit_hash); +    output_string = GF_MALLOC(len + 1, gf_common_mt_char); -                if (ret < 0) -                        return; - -                len += ret; - -        } +    if (!output_string) +        return; -        len++; +    ret = snprintf(output_string, len + 1, "Setting layout of %s with ", +                   loc->path); -        output_string = GF_MALLOC (len + 1, gf_common_mt_char); +    if (ret < 0) +        goto err; -        if (!output_string) -                return; +    off += ret; -        ret = snprintf (output_string, len + 1, "Setting layout of %s with ", -                        loc->path); +    for (i = 0; i < layout->cnt; i++) { +        ret = snprintf(output_string + off, len - off, +                       "[Subvol_name: %s, Err: %d , Start: " +                       "%" PRIu32 " , Stop: %" PRIu32 " , Hash: %" PRIu32 +                       " ], ", +                       layout->list[i].xlator->name, layout->list[i].err, +                       layout->list[i].start, layout->list[i].stop, +                       layout->list[i].commit_hash);          if (ret < 0) -                goto err; +            goto err;          off += ret; +    } - -        for (i = 0; i < layout->cnt; i++) { - -                ret  =  snprintf (output_string + off, len - off, -                                  "[Subvol_name: %s, Err: %d , Start: " -                                  "%"PRIu32 " , Stop: %"PRIu32 " , Hash: %" -                                  PRIu32  " ], ", -                                  layout->list[i].xlator->name, -                                  layout->list[i].err, layout->list[i].start, -                                  layout->list[i].stop, -                                  layout->list[i].commit_hash); - -                if (ret < 0) -                        goto err; - -                off += ret; - -        } - -        gf_msg (this->name, GF_LOG_DEBUG, 0, DHT_MSG_LOG_FIXED_LAYOUT, -                "%s", output_string); +    gf_msg(this->name, GF_LOG_DEBUG, 0, DHT_MSG_LOG_FIXED_LAYOUT, "%s", +           output_string);  err: -        GF_FREE (output_string); +    GF_FREE(output_string);  } -int32_t dht_migration_get_dst_subvol(xlator_t *this, dht_local_t  *local) +int32_t +dht_migration_get_dst_subvol(xlator_t *this, dht_local_t *local)  { -        int ret = -1; +    int ret = -1; -        if (!local) -                goto out; +    if (!local) +        goto out; -        local->rebalance.target_node = -                dht_subvol_get_hashed (this, &local->loc); +    local->rebalance.target_node = dht_subvol_get_hashed(this, &local->loc); -        if (local->rebalance.target_node) -                ret = 0; +    if (local->rebalance.target_node) +        ret = 0;  out: -        return ret; +    return ret;  } -int32_t dht_migration_needed(xlator_t *this) +int32_t +dht_migration_needed(xlator_t *this)  { -        gf_defrag_info_t        *defrag = NULL; -        dht_conf_t              *conf   = NULL; -        int                      ret = 0; +    gf_defrag_info_t *defrag = NULL; +    dht_conf_t *conf = NULL; +    int ret = 0; -        conf = this->private; +    conf = this->private; -        GF_VALIDATE_OR_GOTO ("dht", conf, out); -        GF_VALIDATE_OR_GOTO ("dht", conf->defrag, out); +    GF_VALIDATE_OR_GOTO("dht", conf, out); +    GF_VALIDATE_OR_GOTO("dht", conf->defrag, out); -        defrag = conf->defrag; +    defrag = conf->defrag; -        if ((defrag->cmd != GF_DEFRAG_CMD_START_TIER) && -            (defrag->cmd != GF_DEFRAG_CMD_START_DETACH_TIER)) -                ret = 1; +    if ((defrag->cmd != GF_DEFRAG_CMD_START_TIER) && +        (defrag->cmd != GF_DEFRAG_CMD_START_DETACH_TIER)) +        ret = 1;  out: -        return ret; +    return ret;  } - -  /*  This function should not be called more then once during a FOP  handling path. It is valid only for for ops on files  */ -int32_t dht_set_local_rebalance (xlator_t *this, dht_local_t *local, -                                 struct iatt *stbuf, -                                 struct iatt *prebuf, struct iatt *postbuf, -                                 dict_t *xdata) +int32_t +dht_set_local_rebalance(xlator_t *this, dht_local_t *local, struct iatt *stbuf, +                        struct iatt *prebuf, struct iatt *postbuf, +                        dict_t *xdata)  { +    if (!local) +        return -1; -        if (!local) -                return -1; - -        if (local->rebalance.set) { -                gf_msg (this->name, GF_LOG_WARNING, 0, -                        DHT_MSG_REBAL_STRUCT_SET, -                        "local->rebalance already set"); -        } - +    if (local->rebalance.set) { +        gf_msg(this->name, GF_LOG_WARNING, 0, DHT_MSG_REBAL_STRUCT_SET, +               "local->rebalance already set"); +    } -        if (stbuf) -                memcpy (&local->rebalance.stbuf, stbuf, sizeof (struct iatt)); +    if (stbuf) +        memcpy(&local->rebalance.stbuf, stbuf, sizeof(struct iatt)); -        if (prebuf) -                memcpy (&local->rebalance.prebuf, prebuf, sizeof (struct iatt)); +    if (prebuf) +        memcpy(&local->rebalance.prebuf, prebuf, sizeof(struct iatt)); -        if (postbuf) -                memcpy (&local->rebalance.postbuf, postbuf, -                        sizeof (struct iatt)); +    if (postbuf) +        memcpy(&local->rebalance.postbuf, postbuf, sizeof(struct iatt)); -        if (xdata) -                local->rebalance.xdata = dict_ref (xdata); +    if (xdata) +        local->rebalance.xdata = dict_ref(xdata); -        local->rebalance.set = 1; +    local->rebalance.set = 1; -        return 0; +    return 0;  }  gf_boolean_t -dht_is_tier_xlator (xlator_t *this) +dht_is_tier_xlator(xlator_t *this)  { - -        if (strcmp (this->type, "cluster/tier") == 0) -                return _gf_true; -        return _gf_false; +    if (strcmp(this->type, "cluster/tier") == 0) +        return _gf_true; +    return _gf_false;  }  int32_t -dht_release (xlator_t *this, fd_t *fd) +dht_release(xlator_t *this, fd_t *fd)  { -        return dht_fd_ctx_destroy (this, fd); +    return dht_fd_ctx_destroy(this, fd);  }  int -dht_remove_stale_linkto (void *data) +dht_remove_stale_linkto(void *data)  { -        call_frame_t    *frame = NULL; -        dht_local_t     *local = NULL; -        xlator_t        *this  = NULL; -        dict_t          *xdata_in = NULL; -        int             ret = 0; +    call_frame_t *frame = NULL; +    dht_local_t *local = NULL; +    xlator_t *this = NULL; +    dict_t *xdata_in = NULL; +    int ret = 0; -        GF_VALIDATE_OR_GOTO ("dht", data, out); +    GF_VALIDATE_OR_GOTO("dht", data, out); -        frame = data; -        local = frame->local; -        this = frame->this; -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", local, out); -        GF_VALIDATE_OR_GOTO ("dht", local->link_subvol, out); +    frame = data; +    local = frame->local; +    this = frame->this; +    GF_VALIDATE_OR_GOTO("dht", this, out); +    GF_VALIDATE_OR_GOTO("dht", local, out); +    GF_VALIDATE_OR_GOTO("dht", local->link_subvol, out); -        xdata_in = dict_new (); -        if (!xdata_in) -                goto out; - -        ret = dht_fill_dict_to_avoid_unlink_of_migrating_file (xdata_in); -        if (ret) { -                  gf_msg (this->name, GF_LOG_WARNING, -ret, 0, -                                "Failed to set keys for stale linkto" -                                "deletion on path %s", local->loc.path); -                  goto out; -        } - -        ret = syncop_unlink (local->link_subvol, &local->loc, xdata_in, NULL); -        if (ret) { -                  gf_msg (this->name, GF_LOG_WARNING, -ret, 0, -                                "Removal of linkto failed" -                                " on path %s at subvol %s", -                                local->loc.path, local->link_subvol->name); +    xdata_in = dict_new(); +    if (!xdata_in) +        goto out; -        } +    ret = dht_fill_dict_to_avoid_unlink_of_migrating_file(xdata_in); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, -ret, 0, +               "Failed to set keys for stale linkto" +               "deletion on path %s", +               local->loc.path); +        goto out; +    } + +    ret = syncop_unlink(local->link_subvol, &local->loc, xdata_in, NULL); +    if (ret) { +        gf_msg(this->name, GF_LOG_WARNING, -ret, 0, +               "Removal of linkto failed" +               " on path %s at subvol %s", +               local->loc.path, local->link_subvol->name); +    }  out: -        if (xdata_in) -                dict_unref (xdata_in); -        return ret; +    if (xdata_in) +        dict_unref(xdata_in); +    return ret;  }  int -dht_remove_stale_linkto_cbk (int ret, call_frame_t *sync_frame, void *data) +dht_remove_stale_linkto_cbk(int ret, call_frame_t *sync_frame, void *data)  { -        DHT_STACK_DESTROY (sync_frame); -        return 0; +    DHT_STACK_DESTROY(sync_frame); +    return 0;  }  | 
