diff options
Diffstat (limited to 'xlators/cluster/stripe/src')
| -rw-r--r-- | xlators/cluster/stripe/src/stripe-mem-types.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 178 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.h | 12 | 
3 files changed, 191 insertions, 0 deletions
diff --git a/xlators/cluster/stripe/src/stripe-mem-types.h b/xlators/cluster/stripe/src/stripe-mem-types.h index 2d2757e86a8..c376a1fc93f 100644 --- a/xlators/cluster/stripe/src/stripe-mem-types.h +++ b/xlators/cluster/stripe/src/stripe-mem-types.h @@ -34,6 +34,7 @@ enum gf_stripe_mem_types_ {          gf_stripe_mt_xlator_t,          gf_stripe_mt_stripe_private_t,          gf_stripe_mt_stripe_options, +        gf_stripe_mt_xattr_sort_t,          gf_stripe_mt_end  };  #endif diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 07c77c9dfc7..39047196120 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -4246,6 +4246,166 @@ out:          return 0;  } +int32_t +stripe_pathinfo_aggregate (char *buffer, stripe_local_t *local, int32_t *total) +{ +        int32_t              i     = 0; +        int32_t              ret   = -1; +        int32_t              len   = 0; +        char                *sbuf  = NULL; +        stripe_xattr_sort_t *xattr = NULL; + +        if (!buffer || !local || !local->xattr_list) +                goto out; + +        sbuf = buffer; + +        for (i = 0; i < local->nallocs; i++) { +                xattr = local->xattr_list + i; +                len = xattr->pathinfo_len; + +                if (len && xattr && xattr->pathinfo) { +                        memcpy (buffer, xattr->pathinfo, len); +                        buffer += len; +                        *buffer++ = ' '; +                } +        } + +        *--buffer = '\0'; +        if (total) +                *total = buffer - sbuf; +        ret = 0; + + out: +        return ret; +} + +int32_t +stripe_free_pathinfo_str (stripe_local_t *local) +{ +        int32_t              i     = 0; +        int32_t              ret   = -1; +        stripe_xattr_sort_t *xattr = NULL; + +        if (!local || !local->xattr_list) +                goto out; + +        for (i = 0; i < local->nallocs; i++) { +                xattr = local->xattr_list + i; + +                if (xattr && xattr->pathinfo) +                        GF_FREE (xattr->pathinfo); +        } + +        ret = 0; + out: +        return ret; +} + +int32_t +stripe_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie, +                             xlator_t *this, int32_t op_ret, int32_t op_errno, +                             dict_t *dict) { +        stripe_local_t      *local         = NULL; +        int32_t              callcnt       = 0; +        int32_t              ret           = -1; +        long                 cky           = 0; +        char                *pathinfo      = NULL; +        char                *pathinfo_serz = NULL; +        int32_t              padding       = 0; +        int32_t              tlen          = 0; +        char stripe_size_str[20]           = {0,}; +        stripe_xattr_sort_t *xattr         = NULL; +        dict_t              *stripe_xattr  = NULL; + +        if (!frame || !frame->local || !this) { +                gf_log (this->name, GF_LOG_ERROR, "Possible NULL deref"); +                return ret; +        } + +        local = frame->local; +        cky = (long) cookie; + +        LOCK (&frame->lock); +        { +                callcnt = --local->wind_count; + +                if (!dict || (op_ret < 0)) +                        goto out; + +                if (!local->xattr_list) +                        local->xattr_list = (stripe_xattr_sort_t *) GF_CALLOC (local->nallocs, +                                                                               sizeof (stripe_xattr_sort_t), +                                                                               gf_stripe_mt_xattr_sort_t); + +                if (local->xattr_list) { +                        ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo); +                        if (ret) +                                goto out; + +                        xattr = local->xattr_list + (int32_t) cky; + +                        pathinfo = gf_strdup (pathinfo); +                        xattr->pos = cky; +                        xattr->pathinfo = pathinfo; +                        xattr->pathinfo_len = strlen (pathinfo); + +                        local->xattr_total_len += strlen (pathinfo) + 1; +                } +        } + out: +        UNLOCK (&frame->lock); + +        if (!callcnt) { +                if (!local->xattr_total_len) +                        goto unwind; + +                stripe_xattr = dict_new (); +                if (!stripe_xattr) +                        goto unwind; + +                snprintf (stripe_size_str, 20, "%ld", local->stripe_size); + +                /* extra bytes for decorations (brackets and <>'s) */ +                padding = strlen (this->name) + strlen (STRIPE_PATHINFO_HEADER) +                        + strlen (stripe_size_str) + 7; +                local->xattr_total_len += (padding + 2); + +                pathinfo_serz = GF_CALLOC (local->xattr_total_len, sizeof (char), +                                           gf_common_mt_char); +                if (!pathinfo_serz) +                        goto unwind; + +                /* xlator info */ +                sprintf (pathinfo_serz, "(<"STRIPE_PATHINFO_HEADER"%s:[%s]> ", this->name, stripe_size_str); + +                ret = stripe_pathinfo_aggregate (pathinfo_serz + padding, local, &tlen); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, "Cannot aggregate pathinfo list"); +                        goto unwind; +                } + +                *(pathinfo_serz + padding + tlen) = ')'; +                *(pathinfo_serz + padding + tlen + 1) = '\0'; + +                ret = dict_set_dynstr (stripe_xattr, GF_XATTR_PATHINFO_KEY, pathinfo_serz); +                if (ret) +                        gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo key in dict"); + +        unwind: +                STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, stripe_xattr); + +                ret = stripe_free_pathinfo_str (local); + +                if (local->xattr_list) +                        GF_FREE (local->xattr_list); + +                if (stripe_xattr) +                        dict_unref (stripe_xattr); +        } + +        return ret; +}  int32_t  stripe_getxattr (call_frame_t *frame, xlator_t *this, @@ -4317,6 +4477,24 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,                  return 0;          } +        if (name && (strncmp (name, GF_XATTR_PATHINFO_KEY, +                              strlen (GF_XATTR_PATHINFO_KEY)) == 0)) { +                local->stripe_size = stripe_get_matching_bs (loc->path, +                                                             priv->pattern, +                                                             priv->block_size); +                local->nallocs = local->wind_count = priv->child_count; + +                for (i = 0, trav = this->children; i < priv->child_count; i++, +                     trav = trav->next) { +                        STACK_WIND_COOKIE (frame, stripe_getxattr_pathinfo_cbk, +                                           (void *) (long) i, trav->xlator, +                                           trav->xlator->fops->getxattr, +                                           loc, name); +                } + +                return 0; +        } +          if (name &&(*priv->vol_uuid)) {                  if ((match_uuid_local (name, priv->vol_uuid) == 0)                      && (-1 == frame->root->pid)) { diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h index 6934244a7a6..a6b9375b451 100644 --- a/xlators/cluster/stripe/src/stripe.h +++ b/xlators/cluster/stripe/src/stripe.h @@ -37,6 +37,8 @@  #include <fnmatch.h>  #include <signal.h> +#define STRIPE_PATHINFO_HEADER "STRIPE:" +  #define STRIPE_STACK_UNWIND(fop, frame, params ...) do {           \                  stripe_local_t *__local = NULL;                    \ @@ -62,6 +64,12 @@                  }                                         \          } while (0) +typedef struct stripe_xattr_sort { +        int32_t  pos; +        int32_t  pathinfo_len; +        char    *pathinfo; +} stripe_xattr_sort_t; +  /**   * struct stripe_options : This keeps the pattern and the block-size   *     information, which is used for striping on a file. @@ -165,6 +173,10 @@ struct stripe_local {          /* For File I/O fops */          dict_t              *dict; +        stripe_xattr_sort_t *xattr_list; +        int32_t              xattr_total_len; +        int32_t              nallocs; +          struct marker_str    marker;          /* General usage */  | 
