summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2013-08-13 10:52:12 +0530
committerRaghavendra G <rgowdapp@redhat.com>2013-08-26 11:12:22 +0530
commited7679e5bcc65b61ae1c36d6eb0292ccdf191345 (patch)
tree57ea9f930686f0efe4dfd5e1cde877296e10037c
parent29e13bd002a5b467b1f40709f3d65c6043bb4185 (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.c30
-rw-r--r--xlators/features/marker/src/marker-quota.c4
-rw-r--r--xlators/features/marker/src/marker-quota.h21
-rw-r--r--xlators/features/marker/src/marker.c45
-rw-r--r--xlators/features/quota/src/quota.c158
-rw-r--r--xlators/features/quota/src/quota.h23
-rw-r--r--xlators/storage/posix/src/posix-helpers.c165
-rw-r--r--xlators/storage/posix/src/posix.c46
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;
}