summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src
diff options
context:
space:
mode:
authorVenky Shankar <venky@gluster.com>2011-08-16 12:17:29 +0530
committerVijay Bellur <vijay@gluster.com>2011-08-24 06:41:39 -0700
commitd499cb8064f61b70bc37a7d6cbf0f0c3b219c342 (patch)
tree5a93bc707dd7a18e103e0ce686615711323f9775 /xlators/cluster/afr/src
parent6f1062f3473407cebfd5d902db2d2c6965dcf034 (diff)
afr/stripe: collect pathinfo xattr from all childs
Change-Id: Iec8b609e66ef21f4fdd6ee2ff3060f0b71d47ca0 BUG: 3046 Reviewed-on: http://review.gluster.com/237 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amar@gluster.com>
Diffstat (limited to 'xlators/cluster/afr/src')
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c125
-rw-r--r--xlators/cluster/afr/src/afr.h2
2 files changed, 126 insertions, 1 deletions
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index efeb952017a..0f934f8028f 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -665,6 +665,111 @@ afr_getxattr_unwind (call_frame_t *frame,
}
int32_t
+afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict)
+{
+ afr_local_t *local = NULL;
+ int32_t callcnt = 0;
+ int ret = 0;
+ char *pathinfo = NULL;
+ char *pathinfo_serz = NULL;
+ char pathinfo_cky[1024] = {0,};
+ dict_t *xattr = NULL;
+ long cky = 0;
+ int32_t padding = 0;
+ int32_t tlen = 0;
+
+ if (!frame || !frame->local || !this) {
+ gf_log (this->name, GF_LOG_ERROR, "possible NULL deref");
+ goto unlock;
+ }
+
+ local = frame->local;
+ cky = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (!dict || (op_ret < 0))
+ goto unlock;
+
+ if (!local->dict)
+ local->dict = dict_new ();
+
+ if (local->dict) {
+ ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo);
+ if (ret)
+ goto unlock;
+
+ pathinfo = gf_strdup (pathinfo);
+
+ snprintf (pathinfo_cky, 1024, "%s-%ld", GF_XATTR_PATHINFO_KEY, cky);
+ ret = dict_set_dynstr (local->dict, pathinfo_cky, pathinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo cookie key");
+ goto unlock;
+ }
+
+ local->cont.getxattr.pathinfo_len += strlen (pathinfo) + 1;
+ }
+ }
+ unlock:
+ if (frame)
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (!local->cont.getxattr.pathinfo_len)
+ goto unwind;
+
+ xattr = dict_new ();
+ if (!xattr)
+ goto unwind;
+
+ /* extra bytes for decorations (brackets and <>'s) */
+ padding = strlen (this->name) + strlen (AFR_PATHINFO_HEADER) + 4;
+ local->cont.getxattr.pathinfo_len += (padding + 2);
+
+ pathinfo_serz = GF_CALLOC (local->cont.getxattr.pathinfo_len, sizeof (char),
+ gf_common_mt_char);
+
+ if (!pathinfo_serz)
+ goto unwind;
+
+ /* the xlator info */
+ sprintf (pathinfo_serz, "(<"AFR_PATHINFO_HEADER"%s> ", this->name);
+
+ /* actual series of pathinfo */
+ ret = dict_serialize_value_with_delim (local->dict, pathinfo_serz + strlen (pathinfo_serz),
+ &tlen, ' ');
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Error serializing dictionary");
+ goto unwind;
+ }
+
+ /* closing part */
+ *(pathinfo_serz + padding + tlen) = ')';
+ *(pathinfo_serz + padding + tlen + 1) = '\0';
+
+ ret = dict_set_dynstr (xattr, GF_XATTR_PATHINFO_KEY, pathinfo_serz);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo key in dict");
+
+ unwind:
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
+
+ if (local->dict)
+ dict_unref (local->dict);
+
+ if (xattr)
+ dict_unref (xattr);
+ }
+
+ return ret;
+}
+
+int32_t
afr_getxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, const char *name)
{
@@ -694,7 +799,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
loc_copy (&local->loc, loc);
if (name)
- local->cont.getxattr.name = gf_strdup (name);
+ local->cont.getxattr.name = gf_strdup (name);
if (name) {
@@ -735,6 +840,24 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
return 0;
}
+ /*
+ * if we are doing getxattr with pathinfo as the key then we
+ * collect information from all childs
+ */
+ if (strncmp (name, GF_XATTR_PATHINFO_KEY,
+ strlen (GF_XATTR_PATHINFO_KEY)) == 0) {
+
+ local->call_count = priv->child_count;
+ for (i = 0; i < priv->child_count; i++) {
+ STACK_WIND_COOKIE (frame, afr_getxattr_pathinfo_cbk,
+ (void *) (long) i,
+ children[i], children[i]->fops->getxattr,
+ loc, name);
+ }
+
+ return 0;
+ }
+
if (*priv->vol_uuid) {
if ((match_uuid_local (name, priv->vol_uuid) == 0)
&& (-1 == frame->root->pid)) {
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index ef8ad2af262..6f40ded1274 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -33,6 +33,7 @@
#include "libxlator.h"
#define AFR_XATTR_PREFIX "trusted.afr"
+#define AFR_PATHINFO_HEADER "REPLICATE:"
struct _pump_private;
@@ -388,6 +389,7 @@ typedef struct _afr_local {
struct {
char *name;
int last_tried;
+ long pathinfo_len;
} getxattr;
struct {