diff options
author | Raghavendra G <rgowdapp@redhat.com> | 2013-08-13 10:52:12 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2013-08-26 11:12:22 +0530 |
commit | ed7679e5bcc65b61ae1c36d6eb0292ccdf191345 (patch) | |
tree | 57ea9f930686f0efe4dfd5e1cde877296e10037c | |
parent | 29e13bd002a5b467b1f40709f3d65c6043bb4185 (diff) |
posix/marker-quota/marker-enforcer: introduce and use GET_ANCESTRY_DENTRY_KEY
A getxattr on key GET_ANCESTRY_DENTRY_KEY to storage/posix would
return a list of direntries which can be used to construct inode
contexts of individual translators. The result of getxattr on this key
can be viewed as similar to readdirp_cbk with the difference that the
dentries returned here represent various paths from that inode till
root rather than the children of a directory.
This patch also modifies marker/quota and enforcer to utilize this
key.
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Change-Id: I7132e7d56f2fac0f8749f51227d9f2ef27f9d354
BUG: 969461
-rw-r--r-- | xlators/features/marker/src/marker-quota-helper.c | 30 | ||||
-rw-r--r-- | xlators/features/marker/src/marker-quota.c | 4 | ||||
-rw-r--r-- | xlators/features/marker/src/marker-quota.h | 21 | ||||
-rw-r--r-- | xlators/features/marker/src/marker.c | 45 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.c | 158 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.h | 23 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 165 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 46 |
8 files changed, 374 insertions, 118 deletions
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c index af5fed13..0c51aa75 100644 --- a/xlators/features/marker/src/marker-quota-helper.c +++ b/xlators/features/marker/src/marker-quota-helper.c @@ -154,9 +154,10 @@ out: inode_contribution_t * -__mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) +__mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, + loc_t *loc) { - int32_t ret = 0; + int32_t ret = 0; inode_contribution_t *contribution = NULL; if (!loc->parent) { @@ -170,9 +171,10 @@ __mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *l goto out; } - list_for_each_entry (contribution, &ctx->contribution_head, contri_list) { + list_for_each_entry (contribution, &ctx->contribution_head, + contri_list) { if (loc->parent && - uuid_compare (contribution->gfid, loc->parent->gfid) == 0) { + uuid_compare (contribution->gfid, loc->parent->gfid) == 0) { goto out; } } @@ -196,14 +198,16 @@ out: inode_contribution_t * -mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) +mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, + loc_t *loc) { inode_contribution_t *contribution = NULL; if ((ctx == NULL) || (loc == NULL)) return NULL; - if (strcmp (loc->path, "/") == 0) + if (((loc->path) && (strcmp (loc->path, "/") == 0)) + || (!loc->path && uuid_is_null (loc->pargfid))) return NULL; LOCK (&ctx->lock); @@ -226,12 +230,16 @@ mq_dict_set_contribution (xlator_t *this, dict_t *dict, GF_VALIDATE_OR_GOTO ("marker", this, out); GF_VALIDATE_OR_GOTO ("marker", dict, out); GF_VALIDATE_OR_GOTO ("marker", loc, out); - GF_VALIDATE_OR_GOTO ("marker", loc->parent, out); - GET_CONTRI_KEY (contri_key, loc->parent->gfid, ret); - if (ret < 0) { - ret = -1; - goto out; + if (loc->parent) { + GET_CONTRI_KEY (contri_key, loc->parent->gfid, ret); + if (ret < 0) { + ret = -1; + goto out; + } + } else { + /* nameless lookup, fetch contributions to all parents */ + GET_CONTRI_KEY (contri_key, NULL, ret); } ret = dict_set_int64 (dict, contri_key, 0); diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c index fea7c5f0..e0028b34 100644 --- a/xlators/features/marker/src/marker-quota.c +++ b/xlators/features/marker/src/marker-quota.c @@ -2106,7 +2106,7 @@ mq_inspect_directory_xattr (xlator_t *this, } } - if (strcmp (loc->path, "/") != 0) { + if (!loc->path || (loc->path && strcmp (loc->path, "/") != 0)) { contribution = mq_add_new_contribution_node (this, ctx, loc); if (contribution == NULL) { if (!uuid_is_null (loc->inode->gfid)) @@ -2274,7 +2274,7 @@ mq_req_xattr (xlator_t *this, goto set_size; //if not "/" then request contribution - if (strcmp (loc->path, "/") == 0) + if (loc->path && strcmp (loc->path, "/") == 0) goto set_size; ret = mq_dict_set_contribution (this, dict, loc); diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h index ae30d1a3..42def9d2 100644 --- a/xlators/features/marker/src/marker-quota.h +++ b/xlators/features/marker/src/marker-quota.h @@ -59,13 +59,20 @@ ret = 0; \ } while (0); -#define GET_CONTRI_KEY(var, _gfid, _ret) \ - do { \ - char _gfid_unparsed[40]; \ - uuid_unparse (_gfid, _gfid_unparsed); \ - _ret = snprintf (var, CONTRI_KEY_MAX, QUOTA_XATTR_PREFIX \ - ".%s.%s." CONTRIBUTION, "quota", \ - _gfid_unparsed); \ +#define GET_CONTRI_KEY(var, _gfid, _ret) \ + do { \ + if (_gfid != NULL) { \ + char _gfid_unparsed[40]; \ + uuid_unparse (_gfid, _gfid_unparsed); \ + _ret = snprintf (var, CONTRI_KEY_MAX, \ + QUOTA_XATTR_PREFIX \ + ".%s.%s." CONTRIBUTION, "quota", \ + _gfid_unparsed); \ + } else { \ + _ret = snprintf (var, CONTRI_KEY_MAX, \ + QUOTA_XATTR_PREFIX \ + ".%s.." CONTRIBUTION, "quota"); \ + } \ } while (0); #define QUOTA_SAFE_INCREMENT(lock, var) \ diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c index 73c289d4..51e56260 100644 --- a/xlators/features/marker/src/marker.c +++ b/xlators/features/marker/src/marker.c @@ -281,6 +281,38 @@ marker_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { + gf_dirent_t *head = NULL, *entry = NULL; + loc_t loc = {0, }; + inode_t *parent = NULL; + int ret = 0; + + ret = dict_get_bin (dict, GET_ANCESTRY_DENTRY_KEY, (void **)&head); + + if ((ret == 0) && head) { + list_for_each_entry (entry, &head->list, list) { + if (entry->inode == entry->inode->table->root) { + loc.path = gf_strdup ("/"); + inode_unref (parent); + parent = NULL; + } + + loc.inode = inode_ref (entry->inode); + + if (parent != NULL) { + loc.parent = inode_ref (parent); + uuid_copy (loc.pargfid, parent->gfid); + } + + uuid_copy (loc.gfid, entry->inode->gfid); + + mq_xattr_state (this, &loc, entry->dict, entry->d_stat); + + inode_unref (parent); + parent = inode_ref (entry->inode); + loc_wipe (&loc); + } + } + if (cookie) { gf_log (this->name, GF_LOG_DEBUG, "Filtering the quota extended attributes"); @@ -303,13 +335,16 @@ marker_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, priv = this->private; - if (priv == NULL || (priv->feature_enabled & GF_XTIME) == 0) - goto wind; - gf_log (this->name, GF_LOG_DEBUG, "USER:PID = %d", frame->root->pid); - ret = call_from_special_client (frame, this, name); -wind: + if ((priv->feature_enabled & GF_QUOTA) && name + && (strcmp (name, GET_ANCESTRY_DENTRY_KEY) == 0) + && xdata) + mq_req_xattr (this, loc, xdata); + + if (priv && priv->feature_enabled & GF_XTIME) + ret = call_from_special_client (frame, this, name); + if (ret == _gf_false) { if (name == NULL) { /* Signifies that marker translator diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 17bb8d01..e634a4ae 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -18,6 +18,10 @@ int32_t quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, char *name, uuid_t par); +int +quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict, + loc_t *loc, struct iatt *buf, int32_t *op_errno); + struct volume_options options[]; @@ -73,7 +77,7 @@ quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) { int ret = -1; - if (!loc || ((inode == NULL) && ((parent == NULL) || (path == NULL)))) + if (!loc || (inode == NULL)) return ret; if (inode) { @@ -85,21 +89,17 @@ quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) loc->parent = inode_ref (parent); } - loc->path = gf_strdup (path); - if (!loc->path) { - goto loc_wipe; - } + if (path != NULL) { + loc->path = gf_strdup (path); - loc->name = strrchr (loc->path, '/'); - if (loc->name) { - loc->name++; - } else { - goto loc_wipe; + loc->name = strrchr (loc->path, '/'); + if (loc->name) { + loc->name++; + } } ret = 0; -loc_wipe: if (ret < 0) { loc_wipe (loc); } @@ -372,6 +372,10 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { quota_local_t *local = NULL; inode_t *parent = NULL; + gf_dirent_t *head = NULL, *entry = NULL; + loc_t loc = {0, }; + int ret = 0; + dict_t *tmp = NULL; if (op_ret < 0) goto err; @@ -385,6 +389,37 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto err; } + tmp = dict_new (); + + ret = dict_get_bin (dict, GET_ANCESTRY_DENTRY_KEY, (void **)&head); + + if (ret == 0 && head) { + list_for_each_entry (entry, &head->list, list) { + if (__is_root_gfid (entry->inode->gfid)) { + /* Multiple paths to this inode from root are + * stored in this dentry list one of after the + * other. Stumbling upon a root inode means, + * we are about to process a new path. + */ + parent = entry->inode; + continue; + } + + uuid_copy (loc.gfid, entry->inode->gfid); + + loc.inode = inode_ref (entry->inode); + loc.parent = inode_ref (parent); + loc.name = entry->d_name; + + quota_fill_inodectx (this, entry->inode, entry->dict, + &loc, &entry->d_stat, &op_errno); + + parent = entry->inode; + + loc_wipe (&loc); + } + } + quota_check_limit (frame, parent, this, NULL, NULL); return 0; @@ -398,6 +433,7 @@ quota_build_ancestry (call_frame_t *frame, inode_t *inode, xlator_t *this) { quota_local_t *local = NULL; int ret = -1; + dict_t *xdata = NULL; local = frame->local; @@ -417,15 +453,22 @@ quota_build_ancestry (call_frame_t *frame, inode_t *inode, xlator_t *this) if (ret < 0) { ret = -ENOMEM; - goto out; + goto err; } - /* This would ask posix layer to construct dentry chain till root */ - STACK_WIND (frame, quota_build_ancestry_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getxattr, &local->validate_loc, - GET_ANCESTRY_DENTRY_KEY, NULL); + xdata = dict_new (); + + ret = dict_set_int8 (xdata, QUOTA_LIMIT_KEY, 1); + if (ret < 0) + goto err; + + /* This would ask posix layer to construct dentry chain till root */ + STACK_WIND (frame, quota_build_ancestry_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->getxattr, &local->validate_loc, + GET_ANCESTRY_DENTRY_KEY, xdata); + ret = 0; -out: +err: return ret; } @@ -438,6 +481,7 @@ quota_validate (call_frame_t *frame, inode_t *inode, xlator_t *this) quota_priv_t *priv = NULL; local = frame->local; + priv = this->private; LOCK (&local->lock); { @@ -678,10 +722,9 @@ quota_inode_ctx_get (inode_t *inode, int64_t hard_lim, int64_t soft_lim, } -int32_t -quota_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 *dict, struct iatt *postparent) +int +quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict, + loc_t *loc, struct iatt *buf, int32_t *op_errno) { int32_t ret = -1; char found = 0; @@ -694,7 +737,7 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (dict != NULL) { ret = dict_get_bin (dict, QUOTA_LIMIT_KEY, (void **) &ptr); - limit = ptr; + limit = (quota_limit_t *)ptr; if (limit) { hard_lim = ntoh64 (limit->hard_lim); @@ -702,7 +745,6 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } } - local = frame->local; inode_ctx_get (inode, this, &value); ctx = (quota_inode_ctx_t *)(unsigned long)value; @@ -711,7 +753,7 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, && (hard_lim < 0) && !((IA_ISREG (buf->ia_type)) || (IA_ISLNK (buf->ia_type))))) { ret = 0; - goto unwind; + goto out; } if (hard_lim > 0) { @@ -724,9 +766,9 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, gf_log (this->name, GF_LOG_WARNING, "cannot create quota " "context in inode(gfid:%s)", uuid_utoa (inode->gfid)); - op_ret = -1; - op_errno = ENOMEM; - goto unwind; + ret = -1; + *op_errno = ENOMEM; + goto out; } LOCK (&ctx->lock); @@ -740,12 +782,12 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto unlock; } - if (local->loc.name == NULL) + if (loc->name == NULL) goto unlock; list_for_each_entry (dentry, &ctx->parents, next) { - if ((strcmp (dentry->name, local->loc.name) == 0) && - (uuid_compare (local->loc.parent->gfid, + if ((strcmp (dentry->name, loc->name) == 0) && + (uuid_compare (loc->parent->gfid, dentry->par) == 0)) { found = 1; break; @@ -754,8 +796,8 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!found) { dentry = __quota_dentry_new (ctx, - (char *)local->loc.name, - local->loc.parent->gfid); + (char *)loc->name, + loc->parent->gfid); if (dentry == NULL) { /* gf_log (this->name, GF_LOG_WARNING, @@ -764,8 +806,8 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, PRId64", gfid:%s)", uuid_utoa (local->loc.inode->gfid)); */ - op_ret = -1; - op_errno = ENOMEM; + ret = -1; + *op_errno = ENOMEM; goto unlock; } } @@ -773,6 +815,25 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&ctx->lock); +out: + return ret; +} + +int32_t +quota_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 *dict, struct iatt *postparent) +{ + quota_local_t *local = NULL; + + if (op_ret < 0) + goto unwind; + + local = frame->local; + + op_ret = quota_fill_inodectx (this, inode, dict, &local->loc, buf, + &op_errno); + unwind: QUOTA_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf, dict, postparent); @@ -1055,9 +1116,17 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, local->link_count = parents; local->stub = stub; - list_for_each_entry (dentry, &ctx->parents, next) { - quota_check_limit (frame, fd->inode, this, dentry->name, - dentry->par); + if (parents == 0) { + /* nameless lookup on this inode, allow quota to reconstruct + * ancestry as part of check_limit. + */ + local->link_count = 1; + quota_check_limit (frame, fd->inode, this, NULL, NULL); + } else { + list_for_each_entry (dentry, &ctx->parents, next) { + quota_check_limit (frame, fd->inode, this, dentry->name, + dentry->par); + } } return 0; @@ -3383,10 +3452,19 @@ quota_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, local->stub = stub; local->link_count = parents; - list_for_each_entry (dentry, &ctx->parents, next) { - quota_check_limit (frame, fd->inode, this, dentry->name, - dentry->par); + if (parents == 0) { + /* nameless lookup on this inode, allow quota to reconstruct + * ancestry as part of check_limit. + */ + local->link_count = 1; + quota_check_limit (frame, fd->inode, this, NULL, NULL); + } else { + list_for_each_entry (dentry, &ctx->parents, next) { + quota_check_limit (frame, fd->inode, this, dentry->name, + dentry->par); + } } + return 0; unwind: diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h index 4d7e4e27..f9572031 100644 --- a/xlators/features/quota/src/quota.h +++ b/xlators/features/quota/src/quota.h @@ -37,7 +37,6 @@ #include "compat-errno.h" #include "protocol-common.h" -#define QUOTA_XATTR_PREFIX "trusted." #define DIRTY "dirty" #define SIZE "size" #define CONTRIBUTION "contri" @@ -104,11 +103,17 @@ #define GET_CONTRI_KEY(var, _vol_name, _gfid, _ret) \ do { \ char _gfid_unparsed[40]; \ - uuid_unparse (_gfid, _gfid_unparsed); \ - _ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \ - "%s.%s." CONTRIBUTION, \ - _vol_name, _gfid_unparsed); \ - } while (0) + if (_gfid != NULL) { \ + uuid_unparse (_gfid, _gfid_unparsed); \ + _ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \ + "%s.%s." CONTRIBUTION, \ + _vol_name, _gfid_unparsed); \ + } else { \ + _ret = gf_asprintf (var, QUOTA_XATTR_PREFIX \ + "%s.." CONTRIBUTION, \ + _vol_name); \ + } \ + } while (0) #define GET_CONTRI_KEY_OR_GOTO(var, _vol_name, _gfid, label) \ @@ -186,10 +191,12 @@ struct quota_priv { }; typedef struct quota_priv quota_priv_t; -typedef struct quota_limit { +struct quota_limit { int64_t hard_lim; int64_t soft_lim_percent; -} __attribute__ ((packed)) quota_limit_t ; +} __attribute__ ((packed)); + +typedef struct quota_limit quota_limit_t; int quota_enforcer_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 2fa55eda..efc1ef13 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -51,6 +51,8 @@ char *marker_xattrs[] = {"trusted.glusterfs.quota.*", "trusted.glusterfs.*.xtime", NULL}; +char *marker_contri_key = "trusted.*.*.contri"; + static char* posix_ignore_xattrs[] = { "gfid-req", GLUSTERFS_ENTRYLK_COUNT, @@ -101,14 +103,142 @@ out: } static int +_posix_xattr_get_set_from_backend (posix_xattr_filler_t *filler, char *key) +{ + ssize_t xattr_size = -1; + int ret = 0; + char *value = NULL; + + xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); + + if (xattr_size > 0) { + value = GF_CALLOC (1, xattr_size + 1, + gf_posix_mt_char); + if (!value) + goto out; + + xattr_size = sys_lgetxattr (filler->real_path, key, value, + xattr_size); + if (xattr_size <= 0) { + gf_log (filler->this->name, GF_LOG_WARNING, + "getxattr failed. path: %s, key: %s", + filler->real_path, key); + GF_FREE (value); + goto out; + } + + value[xattr_size] = '\0'; + ret = dict_set_bin (filler->xattr, key, + value, xattr_size); + if (ret < 0) { + gf_log (filler->this->name, GF_LOG_DEBUG, + "dict set failed. path: %s, key: %s", + filler->real_path, key); + GF_FREE (value); + goto out; + } + } + ret = 0; +out: + return ret; +} + +static int gf_posix_xattr_enotsup_log; + +static int +_posix_get_marker_all_contributions (posix_xattr_filler_t *filler) +{ + ssize_t size = -1, remaining_size = -1, list_offset = 0; + int ret = -1; + char *list = NULL, key[4096] = {0, }; + + size = sys_llistxattr (filler->real_path, NULL, 0); + if (size == -1) { + if ((errno == ENOTSUP) || (errno == ENOSYS)) { + GF_LOG_OCCASIONALLY (gf_posix_xattr_enotsup_log, + THIS->name, GF_LOG_WARNING, + "Extended attributes not " + "supported (try remounting brick" + " with 'user_xattr' flag)"); + + } else { + gf_log (THIS->name, GF_LOG_WARNING, + "listxattr failed on %s: %s", + filler->real_path, strerror (errno)); + + } + + goto out; + } + + if (size == 0) { + ret = 0; + goto out; + } + + list = alloca (size + 1); + if (!list) { + goto out; + } + + size = sys_llistxattr (filler->real_path, list, size); + if (size <= 0) { + ret = size; + goto out; + } + + remaining_size = size; + list_offset = 0; + + while (remaining_size > 0) { + if (*(list + list_offset) == '\0') + break; + strcpy (key, list + list_offset); + if (fnmatch (marker_contri_key, key, 0) == 0) { + ret = _posix_xattr_get_set_from_backend (filler, key); + } + + remaining_size -= strlen (key) + 1; + list_offset += strlen (key) + 1; + } + + ret = 0; + +out: + return ret; +} + +static int +_posix_get_marker_quota_contributions (posix_xattr_filler_t *filler, char *key) +{ + char *saveptr = NULL, *token = NULL, *tmp_key = NULL; + char *ptr = NULL; + int i = 0, ret = 0; + + tmp_key = ptr = gf_strdup (key); + for (i = 0; i < 4; i++) { + token = strtok_r (tmp_key, ".", &saveptr); + tmp_key = NULL; + } + + if (strncmp (token, "contri", strlen ("contri")) == 0) { + ret = _posix_get_marker_all_contributions (filler); + } else { + ret = _posix_xattr_get_set_from_backend (filler, key); + } + + GF_FREE (ptr); + + return ret; +} + +static int _posix_xattr_get_set (dict_t *xattr_req, char *key, data_t *data, void *xattrargs) { posix_xattr_filler_t *filler = xattrargs; - char *value = NULL; - ssize_t xattr_size = -1; int ret = -1; char *databuf = NULL; int _fd = -1; @@ -182,35 +312,10 @@ _posix_xattr_get_set (dict_t *xattr_req, "Failed to set dictionary value for %s", key); } + } else if (fnmatch (marker_contri_key, key, 0) == 0) { + ret = _posix_get_marker_quota_contributions (filler, key); } else { - xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0); - - if (xattr_size > 0) { - value = GF_CALLOC (1, xattr_size + 1, - gf_posix_mt_char); - if (!value) - return -1; - - xattr_size = sys_lgetxattr (filler->real_path, key, value, - xattr_size); - if (xattr_size <= 0) { - gf_log (filler->this->name, GF_LOG_WARNING, - "getxattr failed. path: %s, key: %s", - filler->real_path, key); - GF_FREE (value); - return -1; - } - - value[xattr_size] = '\0'; - ret = dict_set_bin (filler->xattr, key, - value, xattr_size); - if (ret < 0) { - gf_log (filler->this->name, GF_LOG_DEBUG, - "dict set failed. path: %s, key: %s", - filler->real_path, key); - GF_FREE (value); - } - } + ret = _posix_xattr_get_set_from_backend (filler, key); } out: return 0; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 0e84afcf..415f007d 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -109,8 +109,8 @@ posix_lookup (call_frame_t *frame, xlator_t *this, /* The Hidden directory should be for housekeeping purpose and it should not get any gfid on it */ - if (__is_root_gfid (loc->pargfid) && - (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) { + if (__is_root_gfid (loc->pargfid) && loc->name + && (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) { gf_log (this->name, GF_LOG_WARNING, "Lookup issued on %s, which is not permitted", GF_HIDDEN_PATH); @@ -2789,8 +2789,8 @@ posix_get_ancestry_directory (xlator_t *this, char *real_path, loc_t *loc, ssize_t size = 0, handle_size = 0; char *value = NULL; struct posix_private *priv = NULL; + gf_dirent_t *head = NULL; char dirpath[PATH_MAX+1] = {0,}; - gf_dirent_t head = {{{0,}, }, }; inode_t *inode = NULL; int ret = -1; @@ -2800,7 +2800,8 @@ posix_get_ancestry_directory (xlator_t *this, char *real_path, loc_t *loc, + SLEN(HANDLE_PFX) + SLEN("/") + SLEN("00/") + SLEN("00/") + SLEN(UUID0_STR) + 1 /* '\0' */; - INIT_LIST_HEAD (&head.list); + head = gf_dirent_for_name (""); + INIT_LIST_HEAD (&head->list); ret = posix_make_ancestryfromgfid (this, dirpath, PATH_MAX + 1, head, type | POSIX_ANCESTRY_PATH, @@ -2834,9 +2835,7 @@ posix_get_ancestry_directory (xlator_t *this, char *real_path, loc_t *loc, if (type & POSIX_ANCESTRY_DENTRY) { /*bug!! set correct size */ ret = dict_set_static_bin (dict, GET_ANCESTRY_DENTRY_KEY, - head.next, sizeof (head)); - - list_del_init (&head.list); + head, sizeof (*head)); } out: @@ -2868,12 +2867,14 @@ posix_get_ancestry_non_directory (xlator_t *this, char *real_path, loc_t *loc, inode_t *parent = NULL; inode_t *linked_inode = NULL; ssize_t size = 0; - gf_dirent_t head = {{{0, }, }, }; + gf_dirent_t *head = NULL; gf_dirent_t *gf_entry = NULL; priv = this->private; - INIT_LIST_HEAD (&head); + head = gf_dirent_for_name (""); + + INIT_LIST_HEAD (&head->list); size = sys_llistxattr (real_path, NULL, 0); if (size == -1) { @@ -2930,12 +2931,16 @@ posix_get_ancestry_non_directory (xlator_t *this, char *real_path, loc_t *loc, strlen (PGFID_XATTR_KEY_PREFIX)) != 0) goto next; - op_ret = sys_lgetxattr (real_path, key, &nlink_samepgfid, + op_ret = sys_lgetxattr (real_path, key, + &nlink_samepgfid, sizeof(nlink_samepgfid)); if (op_ret == -1) { *op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, "getxattr failed on " - "%s: key = %s (%s)", real_path, key, + gf_log (this->name, GF_LOG_ERROR, + "getxattr failed on " + "%s: key = %s (%s)", + real_path, + key, strerror (*op_errno)); goto out; } @@ -2947,6 +2952,7 @@ posix_get_ancestry_non_directory (xlator_t *this, char *real_path, loc_t *loc, handle_size = priv->base_path_length + SLEN("/") + SLEN(HANDLE_PFX) + SLEN("/") + SLEN("00/") + SLEN("00/") + SLEN(UUID0_STR) + 1 /* '\0' */; + /* constructing the absolute real path of parent dir */ strcpy (dirpath, priv->base_path); pathlen = PATH_MAX + 1 - priv->base_path_length; @@ -3082,7 +3088,7 @@ posix_get_ancestry_non_directory (xlator_t *this, char *real_path, loc_t *loc, if (type & POSIX_ANCESTRY_DENTRY) { /* bug!!! set correct size */ op_ret = dict_set_static_bin (dict, GET_ANCESTRY_DENTRY_KEY, - head.next, sizeof (head)); + head, sizeof (*head)); if (op_ret < 0) { gf_log (this->name, GF_LOG_WARNING, "dict set " "operation on %s for the key %s " @@ -3093,7 +3099,7 @@ posix_get_ancestry_non_directory (xlator_t *this, char *real_path, loc_t *loc, } /* bug!!! return correct serialized length */ - op_ret += sizeof (head); + op_ret += sizeof (*head); } out: @@ -3446,8 +3452,18 @@ out: STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, NULL); - if (dict) + if (dict) { + gf_dirent_t *head = NULL; + ret = dict_get_bin (dict, GET_ANCESTRY_DENTRY_KEY, + (void **)&head); + if (ret >= 0) { + gf_dirent_free (head); + GF_FREE (head); + dict_del (dict, GET_ANCESTRY_DENTRY_KEY); + } + dict_unref (dict); + } return 0; } |