From baaa7286ed6b70121efa6a83a8adb3a2f1ec45da Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Fri, 15 Apr 2011 07:05:38 +0000 Subject: cluster/stripe: aggregate xattrs holding quota-size in lookup and getxattr calls. Signed-off-by: Raghavendra G Signed-off-by: Anand Avati BUG: 2760 (Quota: stripe volume not showing the quota size properly) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2760 --- xlators/cluster/stripe/src/stripe.c | 122 +++++++++++++++++++++++++++++++++++- xlators/cluster/stripe/src/stripe.h | 7 ++- 2 files changed, 125 insertions(+), 4 deletions(-) (limited to 'xlators/cluster') diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index de1602614..a06d275df 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -35,6 +35,7 @@ #include "stripe.h" #include "libxlator.h" +#include "byte-order.h" void stripe_local_wipe (stripe_local_t *local) @@ -44,6 +45,10 @@ stripe_local_wipe (stripe_local_t *local) loc_wipe (&local->loc); loc_wipe (&local->loc2); + if (local->xattr != NULL) { + dict_unref (local->xattr); + } + out: return; } @@ -212,6 +217,61 @@ out: return 0; } + +void +stripe_aggregate (dict_t *this, char *key, data_t *value, void *data) +{ + dict_t *dst = NULL; + int64_t *ptr = 0, *size = NULL; + int32_t ret = -1; + + dst = data; + + if (strcmp (key, GF_XATTR_QUOTA_SIZE_KEY) == 0) { + ret = dict_get_bin (dst, key, (void **)&size); + if (ret < 0) { + size = GF_CALLOC (1, sizeof (int64_t), + gf_common_mt_char); + if (size == NULL) { + gf_log ("stripe", GF_LOG_WARNING, + "memory allocation failed"); + return; + } + ret = dict_set_bin (dst, key, size, sizeof (int64_t)); + if (ret < 0) { + gf_log ("stripe", GF_LOG_WARNING, + "stripe aggregate dict set failed"); + GF_FREE (size); + return; + } + } + + ptr = data_to_bin (value); + if (ptr == NULL) { + gf_log ("stripe", GF_LOG_WARNING, "data to bin failed"); + return; + } + + *size = hton64 (ntoh64 (*size) + ntoh64 (*ptr)); + } + + return; +} + + +void +stripe_aggregate_xattr (dict_t *dst, dict_t *src) +{ + if ((dst == NULL) || (src == NULL)) { + goto out; + } + + dict_foreach (src, stripe_aggregate, dst); +out: + return; +} + + int32_t stripe_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, @@ -257,8 +317,14 @@ stripe_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->stbuf = *buf; local->postparent = *postparent; local->inode = inode_ref (inode); + } + + if (local->dict == NULL) { local->dict = dict_ref (dict); + } else { + stripe_aggregate_xattr (local->dict, dict); } + local->stbuf_blocks += buf->ia_blocks; local->postparent_blocks += postparent->ia_blocks; @@ -4162,9 +4228,49 @@ stripe_getxattr_unwind (call_frame_t *frame, return 0; } + +int +stripe_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, dict_t *xattr) +{ + int call_cnt = 0; + stripe_local_t *local = NULL; + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (frame->local, out); + + local = frame->local; + + LOCK (&frame->lock); + { + call_cnt = --local->wind_count; + } + UNLOCK (&frame->lock); + + if (!xattr || (op_ret < 0)) + goto out; + + local->op_ret = 0; + + if (!local->xattr) { + local->xattr = dict_ref (xattr); + } else { + stripe_aggregate_xattr (local->xattr, xattr); + } + +out: + if (!call_cnt) { + STRIPE_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, + local->xattr); + } + + return 0; +} + + int32_t stripe_getxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *name) + loc_t *loc, const char *name) { stripe_local_t *local = NULL; xlator_list_t *trav = NULL; @@ -4218,6 +4324,20 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this, return 0; } + if (name && strncmp (name, GF_XATTR_QUOTA_SIZE_KEY, + strlen (GF_XATTR_QUOTA_SIZE_KEY) == 0)) { + local->wind_count = priv->child_count; + + for (i = 0, trav=this->children; i < priv->child_count; i++, + trav = trav->next) { + STACK_WIND (frame, stripe_getxattr_cbk, + trav->xlator, trav->xlator->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/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h index 73aec6ae0..2d7b92dd5 100644 --- a/xlators/cluster/stripe/src/stripe.h +++ b/xlators/cluster/stripe/src/stripe.h @@ -139,8 +139,8 @@ struct stripe_local { blkcnt_t postparent_blocks; struct readv_replies *replies; - struct statvfs statvfs_buf; - dir_entry_t *entry; + struct statvfs statvfs_buf; + dir_entry_t *entry; int8_t revalidate; int8_t failed; @@ -179,7 +179,8 @@ struct stripe_local { fd_t *fd; void *value; struct iobref *iobref; - gf_dirent_t entries; + gf_dirent_t entries; + dict_t *xattr; }; typedef struct stripe_local stripe_local_t; -- cgit