summaryrefslogtreecommitdiffstats
path: root/xlators/features/marker/src/marker.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/marker/src/marker.c')
-rw-r--r--xlators/features/marker/src/marker.c237
1 files changed, 207 insertions, 30 deletions
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index c80237a3684..41c3e1dc74d 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -27,7 +27,7 @@
#define _GF_UID_GID_CHANGED 1
-static char *quota_external_xattrs[] = {
+static char *mq_ext_xattrs[] = {
QUOTA_SIZE_KEY,
QUOTA_LIMIT_KEY,
QUOTA_LIMIT_OBJECTS_KEY,
@@ -40,6 +40,80 @@ fini (xlator_t *this);
int32_t
marker_start_setxattr (call_frame_t *, xlator_t *);
+/* When client/quotad request for quota xattrs,
+ * replace the key-name by adding the version number
+ * in end of the key-name.
+ * In the cbk, result value of xattrs for original
+ * key-name.
+ * Below function marker_key_replace_with_ver and
+ * marker_key_set_ver is used for setting/removing
+ * version for the key-name
+ */
+int
+marker_key_replace_with_ver (xlator_t *this, dict_t *dict)
+{
+ int ret = -1;
+ int i = 0;
+ marker_conf_t *priv = NULL;
+ char key[QUOTA_KEY_MAX] = {0, };
+
+ priv = this->private;
+
+ if (dict == NULL || priv->version <= 0) {
+ ret = 0;
+ goto out;
+ }
+
+ for (i = 0; mq_ext_xattrs[i]; i++) {
+ if (dict_get (dict, mq_ext_xattrs[i])) {
+ GET_QUOTA_KEY (this, key, mq_ext_xattrs[i], ret);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_set (dict, key,
+ dict_get (dict, mq_ext_xattrs[i]));
+ if (ret < 0)
+ goto out;
+
+ dict_del (dict, mq_ext_xattrs[i]);
+ }
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int
+marker_key_set_ver (xlator_t *this, dict_t *dict)
+{
+ int ret = -1;
+ int i = -1;
+ marker_conf_t *priv = NULL;
+ char key[QUOTA_KEY_MAX] = {0, };
+
+ priv = this->private;
+
+ if (dict == NULL || priv->version <= 0) {
+ ret = 0;
+ goto out;
+ }
+
+ for (i = 0; mq_ext_xattrs[i]; i++) {
+ GET_QUOTA_KEY (this, key, mq_ext_xattrs[i], ret);
+ if (ret < 0)
+ goto out;
+
+ if (dict_get (dict, key))
+ dict_set (dict, mq_ext_xattrs[i], dict_get (dict, key));
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
marker_local_t *
marker_local_ref (marker_local_t *local)
{
@@ -336,7 +410,7 @@ marker_filter_internal_xattrs (xlator_t *this, dict_t *xattrs)
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- ext = quota_external_xattrs;
+ ext = mq_ext_xattrs;
dict_foreach_match (xattrs, _is_quota_internal_xattr, ext,
dict_remove_foreach_fn, NULL);
@@ -348,6 +422,18 @@ 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)
{
+ int32_t ret = -1;
+
+ if (op_ret < 0)
+ goto unwind;
+
+ ret = marker_key_set_ver (this, dict);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
if (cookie) {
gf_log (this->name, GF_LOG_DEBUG,
"Filtering the quota extended attributes");
@@ -373,6 +459,7 @@ marker_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
marker_filter_internal_xattrs (frame->this, dict);
}
+unwind:
MARKER_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
return 0;
}
@@ -381,13 +468,29 @@ int32_t
marker_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- gf_boolean_t is_true = _gf_false;
- marker_conf_t *priv = NULL;
- unsigned long cookie = 0;
- marker_local_t *local = NULL;
+ gf_boolean_t is_true = _gf_false;
+ marker_conf_t *priv = NULL;
+ unsigned long cookie = 0;
+ marker_local_t *local = NULL;
+ char key[QUOTA_KEY_MAX] = {0, };
+ int32_t ret = -1;
+ int32_t i = 0;
priv = this->private;
+ if (name) {
+ for (i = 0; mq_ext_xattrs[i]; i++) {
+ if (strcmp (name, mq_ext_xattrs[i]))
+ continue;
+
+ GET_QUOTA_KEY (this, key, mq_ext_xattrs[i], ret);
+ if (ret < 0)
+ goto out;
+ name = key;
+ break;
+ }
+ }
+
frame->local = mem_get0 (this->local_pool);
local = frame->local;
if (local == NULL)
@@ -425,7 +528,6 @@ out:
return 0;
}
-
int32_t
marker_setxattr_done (call_frame_t *frame)
{
@@ -1202,7 +1304,7 @@ marker_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
marker_local_t *oplocal = NULL;
call_stub_t *stub = NULL;
int32_t ret = 0;
- char contri_key[CONTRI_KEY_MAX] = {0, };
+ char contri_key[QUOTA_KEY_MAX] = {0, };
loc_t newloc = {0, };
local = (marker_local_t *) frame->local;
@@ -1239,7 +1341,8 @@ marker_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->stub = stub;
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
+ GET_CONTRI_KEY (this, contri_key, oplocal->loc.parent->gfid,
+ ret);
if (ret < 0) {
local->err = ENOMEM;
goto quota_err;
@@ -1303,7 +1406,7 @@ marker_do_rename (call_frame_t *frame, void *cookie, xlator_t *this,
{
marker_local_t *local = NULL;
marker_local_t *oplocal = NULL;
- char contri_key[CONTRI_KEY_MAX] = {0, };
+ char contri_key[QUOTA_KEY_MAX] = {0, };
int32_t ret = 0;
quota_meta_t contribution = {0, };
@@ -1324,7 +1427,7 @@ marker_do_rename (call_frame_t *frame, void *cookie, xlator_t *this,
goto err;
}
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
+ GET_CONTRI_KEY (this, contri_key, oplocal->loc.parent->gfid, ret);
if (ret < 0) {
local->err = errno ? errno : ENOMEM;
goto err;
@@ -1351,7 +1454,7 @@ marker_get_oldpath_contribution (call_frame_t *lk_frame, void *cookie,
call_frame_t *frame = NULL;
marker_local_t *local = NULL;
marker_local_t *oplocal = NULL;
- char contri_key[CONTRI_KEY_MAX] = {0, };
+ char contri_key[QUOTA_KEY_MAX] = {0, };
int32_t ret = 0;
local = lk_frame->local;
@@ -1370,7 +1473,7 @@ marker_get_oldpath_contribution (call_frame_t *lk_frame, void *cookie,
local->lk_frame = NULL;
}
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
+ GET_CONTRI_KEY (this, contri_key, oplocal->loc.parent->gfid, ret);
if (ret < 0) {
local->err = errno ? errno : ENOMEM;
goto err;
@@ -2294,6 +2397,10 @@ marker_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
return 0;
}
+ ret = marker_key_replace_with_ver (this, dict);
+ if (ret < 0)
+ goto err;
+
if (priv->feature_enabled == 0)
goto wind;
@@ -2557,12 +2664,27 @@ int32_t
marker_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
+ int32_t ret = -1;
+ int32_t i = 0;
+ marker_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
+ char key[QUOTA_KEY_MAX] = {0, };
priv = this->private;
+ if (name) {
+ for (i = 0; mq_ext_xattrs[i]; i++) {
+ if (strcmp (name, mq_ext_xattrs[i]))
+ continue;
+
+ GET_QUOTA_KEY (this, key, mq_ext_xattrs[i], ret);
+ if (ret < 0)
+ goto err;
+ name = key;
+ break;
+ }
+ }
+
if (priv->feature_enabled == 0)
goto wind;
@@ -2599,14 +2721,26 @@ marker_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)
{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
- dict_t *xattrs = NULL;
+ marker_conf_t *priv = NULL;
+ marker_local_t *local = NULL;
+ dict_t *xattrs = NULL;
+ int32_t ret = -1;
+
priv = this->private;
+ local = (marker_local_t *) frame->local;
+ frame->local = NULL;
if (op_ret == -1) {
gf_log (this->name, GF_LOG_TRACE, "lookup failed with %s",
strerror (op_errno));
+ goto unwind;
+ }
+
+ ret = marker_key_set_ver (this, dict);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
}
if (dict && __has_quota_xattrs (dict)) {
@@ -2621,10 +2755,7 @@ marker_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
xattrs = dict_ref (dict);
}
- local = (marker_local_t *) frame->local;
-
- frame->local = NULL;
-
+unwind:
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
xattrs, postparent);
@@ -2656,9 +2787,9 @@ int32_t
marker_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
+ int32_t ret = 0;
+ marker_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
priv = this->private;
@@ -2666,6 +2797,10 @@ marker_lookup (call_frame_t *frame, xlator_t *this,
if (!xattr_req)
goto err;
+ ret = marker_key_replace_with_ver (this, xattr_req);
+ if (ret < 0)
+ goto err;
+
if (priv->feature_enabled == 0)
goto wind;
@@ -2680,7 +2815,8 @@ marker_lookup (call_frame_t *frame, xlator_t *this,
goto err;
if ((priv->feature_enabled & GF_QUOTA))
- mq_req_xattr (this, loc, xattr_req, NULL);
+ mq_req_xattr (this, loc, xattr_req, NULL, NULL);
+
wind:
STACK_WIND (frame, marker_lookup_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
@@ -2712,7 +2848,6 @@ marker_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
-
list_for_each_entry (entry, &entries->list, list) {
if (entry->inode == entry->inode->table->root) {
inode_unref (parent);
@@ -2736,6 +2871,13 @@ marker_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_unref (parent);
parent = inode_ref (entry->inode);
loc_wipe (&loc);
+
+ ret = marker_key_set_ver (this, entry->dict);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ break;
+ }
}
if (parent)
@@ -2794,10 +2936,16 @@ marker_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
mq_xattr_state (this, &loc, entry->dict, entry->d_stat);
-
loc_wipe (&loc);
GF_FREE (resolvedpath);
resolvedpath = NULL;
+
+ ret = marker_key_set_ver (this, entry->dict);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
}
unwind:
@@ -2813,6 +2961,7 @@ marker_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
marker_conf_t *priv = NULL;
loc_t loc = {0, };
marker_local_t *local = NULL;
+ int ret = -1;
priv = this->private;
@@ -2820,6 +2969,10 @@ marker_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if (!dict)
goto unwind;
+ ret = marker_key_replace_with_ver (this, dict);
+ if (ret < 0)
+ goto unwind;
+
if (dict_get (dict, GET_ANCESTRY_DENTRY_KEY)) {
STACK_WIND (frame, marker_build_ancestry_cbk,
FIRST_CHILD(this),
@@ -2833,7 +2986,7 @@ marker_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
loc.parent = local->loc.inode = inode_ref (fd->inode);
- mq_req_xattr (this, &loc, dict, NULL);
+ mq_req_xattr (this, &loc, dict, NULL, NULL);
}
STACK_WIND (frame, marker_readdirp_cbk,
@@ -2982,6 +3135,7 @@ reconfigure (xlator_t *this, dict_t *options)
data_t *data = NULL;
gf_boolean_t flag = _gf_false;
marker_conf_t *priv = NULL;
+ int32_t version = 0;
GF_ASSERT (this);
GF_ASSERT (this->private);
@@ -3006,6 +3160,18 @@ reconfigure (xlator_t *this, dict_t *options)
priv->feature_enabled |= GF_INODE_QUOTA;
}
+ data = dict_get (options, "quota-version");
+ if (data)
+ ret = gf_string2int32 (data->data, &version);
+
+ if (priv->feature_enabled) {
+ if (version >= 0)
+ priv->version = version;
+ else
+ gf_log (this->name, GF_LOG_ERROR, "Invalid quota "
+ "version %d", priv->version);
+ }
+
data = dict_get (options, "xtime");
if (data) {
ret = gf_string2boolean (data->data, &flag);
@@ -3061,6 +3227,7 @@ init (xlator_t *this)
priv = this->private;
priv->feature_enabled = 0;
+ priv->version = 0;
LOCK_INIT (&priv->lock);
@@ -3078,6 +3245,16 @@ init (xlator_t *this)
priv->feature_enabled |= GF_INODE_QUOTA;
}
+ data = dict_get (options, "quota-version");
+ if (data)
+ ret = gf_string2int32 (data->data, &priv->version);
+
+ if (priv->feature_enabled && priv->version < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Invalid quota version %d",
+ priv->version);
+ goto err;
+ }
+
data = dict_get (options, "xtime");
if (data) {
ret = gf_string2boolean (data->data, &flag);