summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/stripe
diff options
context:
space:
mode:
authorVenky Shankar <venky@gluster.com>2011-07-01 00:18:53 +0000
committerAnand Avati <avati@gluster.com>2011-07-12 05:37:51 -0700
commit4c55f76d6a4d13ec1ed3cffd31ff4acc3d3122f0 (patch)
treebdc9a5522e30adee821e53f2bb5613e7296aa95d /xlators/cluster/stripe
parent1a82b4539b69390dfb1a158c420385c7ad5d999f (diff)
afr/stripe: collect pathinfo xattrs from all childs
Signed-off-by: Venky Shankar <venky@gluster.com> Signed-off-by: Anand Avati <avati@gluster.com> BUG: 3046 (getxattr for afr should returns realpath from all childs) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=3046
Diffstat (limited to 'xlators/cluster/stripe')
-rw-r--r--xlators/cluster/stripe/src/stripe-mem-types.h1
-rw-r--r--xlators/cluster/stripe/src/stripe.c178
-rw-r--r--xlators/cluster/stripe/src/stripe.h12
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 2d2757e86..c376a1fc9 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 07c77c9df..390471961 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 6934244a7..a6b9375b4 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 */