diff options
-rw-r--r-- | cli/src/cli-rpc-ops.c | 11 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs.h | 7 | ||||
-rw-r--r-- | tests/bugs/quota/bug-1243798.t | 4 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 4 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe-helpers.c | 2 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 4 | ||||
-rw-r--r-- | xlators/features/marker/src/marker-quota-helper.c | 10 | ||||
-rw-r--r-- | xlators/features/marker/src/marker-quota.c | 72 | ||||
-rw-r--r-- | xlators/features/marker/src/marker-quota.h | 34 | ||||
-rw-r--r-- | xlators/features/marker/src/marker.c | 237 | ||||
-rw-r--r-- | xlators/features/marker/src/marker.h | 1 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.c | 6 | ||||
-rw-r--r-- | xlators/lib/src/libxlator.h | 4 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 28 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 9 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 8 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 1 |
19 files changed, 352 insertions, 97 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 562c176a2f9..9c42356b594 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3074,9 +3074,9 @@ print_quota_list_from_mountdir (cli_local_t *local, char *mountdir, GF_ASSERT (path); if (type == GF_QUOTA_OPTION_TYPE_LIST) - key = "trusted.glusterfs.quota.limit-set"; + key = QUOTA_LIMIT_KEY; else - key = "trusted.glusterfs.quota.limit-objects"; + key = QUOTA_LIMIT_OBJECTS_KEY; ret = sys_lgetxattr (mountdir, key, (void *)&limits, sizeof (limits)); @@ -3104,8 +3104,7 @@ print_quota_list_from_mountdir (cli_local_t *local, char *mountdir, limits.hl = ntoh64 (limits.hl); limits.sl = ntoh64 (limits.sl); - xattr_size = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", - NULL, 0); + xattr_size = sys_lgetxattr (mountdir, QUOTA_SIZE_KEY, NULL, 0); if (xattr_size < (sizeof (int64_t) * 2) && type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) { ret = -1; @@ -3114,13 +3113,13 @@ print_quota_list_from_mountdir (cli_local_t *local, char *mountdir, * and the xattr healing is not completed. */ } else if (xattr_size > (sizeof (int64_t) * 2)) { - ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", + ret = sys_lgetxattr (mountdir, QUOTA_SIZE_KEY, &used_space, sizeof (used_space)); } else if (xattr_size > 0) { /* This is for compatibility. * Older version had only file usage */ - ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size", + ret = sys_lgetxattr (mountdir, QUOTA_SIZE_KEY, &(used_space.size), sizeof (used_space.size)); used_space.file_count = 0; used_space.dir_count = 0; diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 4c7f9f517e3..4825ebd5274 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -84,9 +84,6 @@ #define GF_XATTR_LOCKINFO_KEY "trusted.glusterfs.lockinfo" #define GF_XATTR_GET_REAL_FILENAME_KEY "glusterfs.get_real_filename:" #define GF_XATTR_USER_PATHINFO_KEY "glusterfs.pathinfo" -#define QUOTA_LIMIT_KEY "trusted.glusterfs.quota.limit-set" -#define QUOTA_LIMIT_OBJECTS_KEY "trusted.glusterfs.quota.limit-objects" -#define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup" #define GF_INTERNAL_IGNORE_DEEM_STATFS "ignore-deem-statfs" #define GF_READDIR_SKIP_DIRS "readdir-filter-directories" @@ -156,7 +153,11 @@ #define GF_XATTR_STIME_PATTERN "trusted.glusterfs.*.stime" #define GF_XATTR_TRIGGER_SYNC "glusterfs.geo-rep.trigger-sync" +/* quota xattrs */ #define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size" +#define QUOTA_LIMIT_KEY "trusted.glusterfs.quota.limit-set" +#define QUOTA_LIMIT_OBJECTS_KEY "trusted.glusterfs.quota.limit-objects" +#define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup" /* Index xlator related */ #define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid" diff --git a/tests/bugs/quota/bug-1243798.t b/tests/bugs/quota/bug-1243798.t index dc53c6928ec..9917b5dc7a1 100644 --- a/tests/bugs/quota/bug-1243798.t +++ b/tests/bugs/quota/bug-1243798.t @@ -33,8 +33,8 @@ sleep 2 #Remove size and contri xattr from /dir1 #Remove contri xattr from /dir1/dir2 -setfattr -x trusted.glusterfs.quota.size $B0/$V0/dir1 -setfattr -x trusted.glusterfs.quota.00000000-0000-0000-0000-000000000001.contri $B0/$V0/dir1 +setfattr -x trusted.glusterfs.quota.size.1 $B0/$V0/dir1 +setfattr -x trusted.glusterfs.quota.00000000-0000-0000-0000-000000000001.contri.1 $B0/$V0/dir1 contri=$(getfattr -d -m . -e hex $B0/$V0/dir1/dir2 | grep contri | awk -F= '{print $1}') setfattr -x $contri $B0/$V0/dir1/dir2 diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index acbe3f40eea..f289d69ceaf 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -3245,8 +3245,8 @@ dht_getxattr (call_frame_t *frame, xlator_t *this, return 0; } - if (key && (!strcmp (GF_XATTR_QUOTA_LIMIT_LIST, key) || - !strcmp (GF_XATTR_QUOTA_LIMIT_LIST_OBJECT, key))) { + if (key && (!strcmp (QUOTA_LIMIT_KEY, key) || + !strcmp (QUOTA_LIMIT_OBJECTS_KEY, key))) { /* quota hardlimit and aggregated size of a directory is stored * in inode contexts of each brick. Hence its good enough that * we send getxattr for this key to any brick. diff --git a/xlators/cluster/stripe/src/stripe-helpers.c b/xlators/cluster/stripe/src/stripe-helpers.c index 3c12809d625..02ee6a43d7c 100644 --- a/xlators/cluster/stripe/src/stripe-helpers.c +++ b/xlators/cluster/stripe/src/stripe-helpers.c @@ -51,7 +51,7 @@ stripe_aggregate (dict_t *this, char *key, data_t *value, void *data) dst = data; - if (strcmp (key, GF_XATTR_QUOTA_SIZE_KEY) == 0) { + if (strcmp (key, QUOTA_SIZE_KEY) == 0) { ret = dict_get_bin (dst, key, (void **)&size); if (ret < 0) { size = GF_CALLOC (1, sizeof (int64_t), diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 5184ccdb959..78479129620 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -5515,8 +5515,8 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this, loc_copy (&local->loc, loc); - if (name && strncmp (name, GF_XATTR_QUOTA_SIZE_KEY, - strlen (GF_XATTR_QUOTA_SIZE_KEY)) == 0) { + if (name && strncmp (name, QUOTA_SIZE_KEY, + strlen (QUOTA_SIZE_KEY)) == 0) { local->wind_count = priv->child_count; for (i = 0, trav=this->children; i < priv->child_count; i++, diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c index 5611c1d8bdc..d1fabccf18e 100644 --- a/xlators/features/marker/src/marker-quota-helper.c +++ b/xlators/features/marker/src/marker-quota-helper.c @@ -255,19 +255,19 @@ mq_dict_set_contribution (xlator_t *this, dict_t *dict, loc_t *loc, uuid_t gfid, char *contri_key) { int32_t ret = -1; - char key[CONTRI_KEY_MAX] = {0, }; + char key[QUOTA_KEY_MAX] = {0, }; GF_VALIDATE_OR_GOTO ("marker", this, out); GF_VALIDATE_OR_GOTO ("marker", dict, out); GF_VALIDATE_OR_GOTO ("marker", loc, out); if (gfid && !gf_uuid_is_null(gfid)) { - GET_CONTRI_KEY (key, gfid, ret); + GET_CONTRI_KEY (this, key, gfid, ret); } else if (loc->parent) { - GET_CONTRI_KEY (key, loc->parent->gfid, ret); + GET_CONTRI_KEY (this, key, loc->parent->gfid, ret); } else { /* nameless lookup, fetch contributions to all parents */ - GET_CONTRI_KEY (key, NULL, ret); + GET_CONTRI_KEY (this, key, NULL, ret); } if (ret < 0) @@ -278,7 +278,7 @@ mq_dict_set_contribution (xlator_t *this, dict_t *dict, loc_t *loc, goto out; if (contri_key) - strncpy (contri_key, key, CONTRI_KEY_MAX); + strncpy (contri_key, key, QUOTA_KEY_MAX); out: if (ret < 0) diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c index 77b0021196c..39f199bb849 100644 --- a/xlators/features/marker/src/marker-quota.c +++ b/xlators/features/marker/src/marker-quota.c @@ -206,10 +206,12 @@ _quota_dict_get_meta (xlator_t *this, dict_t *dict, char *key, } int32_t -quota_dict_set_size_meta (dict_t *dict, const quota_meta_t *meta) +quota_dict_set_size_meta (xlator_t *this, dict_t *dict, + const quota_meta_t *meta) { - int32_t ret = -ENOMEM; - quota_meta_t *value = NULL; + int32_t ret = -ENOMEM; + quota_meta_t *value = NULL; + char size_key[QUOTA_KEY_MAX] = {0, }; value = GF_CALLOC (2, sizeof (quota_meta_t), gf_common_quota_meta_t); if (value == NULL) { @@ -223,7 +225,10 @@ quota_dict_set_size_meta (dict_t *dict, const quota_meta_t *meta) value[1].file_count = 0; value[1].dir_count = hton64 (1); - ret = dict_set_bin (dict, QUOTA_SIZE_KEY, value, + GET_SIZE_KEY (this, size_key, ret); + if (ret < 0) + goto out; + ret = dict_set_bin (dict, size_key, value, (sizeof (quota_meta_t) * 2)); if (ret < 0) { gf_log_callingfn ("quota", GF_LOG_ERROR, "dict set failed"); @@ -280,7 +285,8 @@ mq_are_xattrs_set (xlator_t *this, loc_t *loc, gf_boolean_t *contri_set, gf_boolean_t *size_set) { int32_t ret = -1; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; + char size_key[QUOTA_KEY_MAX] = {0, }; quota_meta_t meta = {0, }; struct iatt stbuf = {0,}; dict_t *dict = NULL; @@ -292,7 +298,7 @@ mq_are_xattrs_set (xlator_t *this, loc_t *loc, gf_boolean_t *contri_set, goto out; } - ret = mq_req_xattr (this, loc, dict, contri_key); + ret = mq_req_xattr (this, loc, dict, contri_key, size_key); if (ret < 0) goto out; @@ -311,8 +317,7 @@ mq_are_xattrs_set (xlator_t *this, loc_t *loc, gf_boolean_t *contri_set, *contri_set = _gf_true; *size_set = _gf_true; if (loc->inode->ia_type == IA_IFDIR) { - ret = quota_dict_get_inode_meta (rsp_dict, QUOTA_SIZE_KEY, - &meta); + ret = quota_dict_get_inode_meta (rsp_dict, size_key, &meta); if (ret < 0 || meta.dir_count == 0) *size_set = _gf_false; } @@ -356,7 +361,7 @@ mq_create_size_xattrs (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) goto out; } - ret = quota_dict_set_size_meta (dict, &size); + ret = quota_dict_set_size_meta (this, dict, &size); if (ret < 0) goto out; @@ -577,7 +582,8 @@ _mq_get_metadata (xlator_t *this, loc_t *loc, quota_meta_t *contri, { int32_t ret = -1; quota_meta_t meta = {0, }; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; + char size_key[QUOTA_KEY_MAX] = {0, }; dict_t *dict = NULL; dict_t *rsp_dict = NULL; struct iatt stbuf = {0,}; @@ -595,7 +601,10 @@ _mq_get_metadata (xlator_t *this, loc_t *loc, quota_meta_t *contri, } if (size && loc->inode->ia_type == IA_IFDIR) { - ret = dict_set_int64 (dict, QUOTA_SIZE_KEY, 0); + GET_SIZE_KEY (this, size_key, ret); + if (ret < 0) + goto out; + ret = dict_set_int64 (dict, size_key, 0); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "dict_set failed."); goto out; @@ -620,7 +629,7 @@ _mq_get_metadata (xlator_t *this, loc_t *loc, quota_meta_t *contri, if (size) { if (loc->inode->ia_type == IA_IFDIR) { - ret = quota_dict_get_meta (rsp_dict, QUOTA_SIZE_KEY, + ret = quota_dict_get_meta (rsp_dict, size_key, &meta); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, @@ -749,9 +758,9 @@ mq_remove_contri (xlator_t *this, loc_t *loc, quota_inode_ctx_t *ctx, inode_contribution_t *contri, quota_meta_t *delta) { int32_t ret = -1; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; - GET_CONTRI_KEY (contri_key, contri->gfid, ret); + GET_CONTRI_KEY (this, contri_key, contri->gfid, ret); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "get contri_key " "failed for %s", uuid_utoa(contri->gfid)); @@ -798,7 +807,7 @@ mq_update_contri (xlator_t *this, loc_t *loc, inode_contribution_t *contri, quota_meta_t *delta) { int32_t ret = -1; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; dict_t *dict = NULL; GF_VALIDATE_OR_GOTO ("marker", loc, out); @@ -818,7 +827,7 @@ mq_update_contri (xlator_t *this, loc_t *loc, inode_contribution_t *contri, goto out; } - GET_CONTRI_KEY (contri_key, contri->gfid, ret); + GET_CONTRI_KEY (this, contri_key, contri->gfid, ret); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "get contri_key " "failed for %s", uuid_utoa(contri->gfid)); @@ -884,7 +893,7 @@ mq_update_size (xlator_t *this, loc_t *loc, quota_meta_t *delta) goto out; } - ret = quota_dict_set_size_meta (dict, delta); + ret = quota_dict_set_size_meta (this, dict, delta); if (ret < 0) goto out; @@ -1795,12 +1804,13 @@ mq_inspect_directory_xattr (xlator_t *this, quota_inode_ctx_t *ctx, inode_contribution_t *contribution, loc_t *loc, dict_t *dict, struct iatt buf) { - int32_t ret = 0; + int32_t ret = -1; int8_t dirty = -1; quota_meta_t size = {0, }; quota_meta_t contri = {0, }; quota_meta_t delta = {0, }; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; + char size_key[QUOTA_KEY_MAX] = {0, }; gf_boolean_t status = _gf_false; ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty); @@ -1812,13 +1822,16 @@ mq_inspect_directory_xattr (xlator_t *this, quota_inode_ctx_t *ctx, dirty = 0; } - ret = _quota_dict_get_meta (this, dict, QUOTA_SIZE_KEY, &size, + GET_SIZE_KEY (this, size_key, ret); + if (ret < 0) + goto out; + ret = _quota_dict_get_meta (this, dict, size_key, &size, IA_IFDIR, _gf_false); if (ret < 0) goto create_xattr; if (!loc_is_root(loc)) { - GET_CONTRI_KEY (contri_key, contribution->gfid, ret); + GET_CONTRI_KEY (this, contri_key, contribution->gfid, ret); if (ret < 0) goto out; @@ -1883,7 +1896,7 @@ mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx, quota_meta_t size = {0, }; quota_meta_t contri = {0, }; quota_meta_t delta = {0, }; - char contri_key[CONTRI_KEY_MAX] = {0, }; + char contri_key[QUOTA_KEY_MAX] = {0, }; gf_boolean_t status = _gf_false; LOCK (&ctx->lock); @@ -1898,7 +1911,7 @@ mq_inspect_file_xattr (xlator_t *this, quota_inode_ctx_t *ctx, } UNLOCK (&ctx->lock); - GET_CONTRI_KEY (contri_key, contribution->gfid, ret); + GET_CONTRI_KEY (this, contri_key, contribution->gfid, ret); if (ret < 0) goto out; @@ -1975,9 +1988,10 @@ out: int32_t mq_req_xattr (xlator_t *this, loc_t *loc, dict_t *dict, - char *contri_key) + char *contri_key, char *size_key) { - int32_t ret = -1; + int32_t ret = -1; + char key[QUOTA_KEY_MAX] = {0, }; GF_VALIDATE_OR_GOTO ("marker", this, out); GF_VALIDATE_OR_GOTO ("marker", loc, out); @@ -1990,7 +2004,13 @@ mq_req_xattr (xlator_t *this, loc_t *loc, dict_t *dict, goto out; } - ret = dict_set_uint64 (dict, QUOTA_SIZE_KEY, 0); + GET_SIZE_KEY (this, key, ret); + if (ret < 0) + goto out; + if (size_key) + strncpy (size_key, key, QUOTA_KEY_MAX); + + ret = dict_set_uint64 (dict, key, 0); if (ret < 0) goto out; diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h index f96584e6ed5..304c0ffa2a0 100644 --- a/xlators/features/marker/src/marker-quota.h +++ b/xlators/features/marker/src/marker-quota.h @@ -19,7 +19,7 @@ #define QUOTA_DIRTY_KEY "trusted.glusterfs.quota.dirty" #define CONTRIBUTION "contri" -#define CONTRI_KEY_MAX 512 +#define QUOTA_KEY_MAX 512 #define READDIR_BUF 4096 @@ -56,22 +56,40 @@ ret = 0; \ } while (0); -#define GET_CONTRI_KEY(var, _gfid, _ret) \ +#define GET_CONTRI_KEY(_this, var, _gfid, _ret) \ do { \ + marker_conf_t *_priv = _this->private; \ if (_gfid != NULL) { \ char _gfid_unparsed[40]; \ gf_uuid_unparse (_gfid, _gfid_unparsed); \ - _ret = snprintf (var, CONTRI_KEY_MAX, \ + _ret = snprintf (var, QUOTA_KEY_MAX, \ QUOTA_XATTR_PREFIX \ - ".%s.%s." CONTRIBUTION, "quota", \ - _gfid_unparsed); \ + ".%s.%s." CONTRIBUTION ".%d", \ + "quota", _gfid_unparsed, \ + _priv->version); \ } else { \ - _ret = snprintf (var, CONTRI_KEY_MAX, \ + _ret = snprintf (var, QUOTA_KEY_MAX, \ QUOTA_XATTR_PREFIX \ - ".%s.." CONTRIBUTION, "quota"); \ + ".%s.." CONTRIBUTION ".%d", \ + "quota", _priv->version); \ } \ } while (0) +#define GET_QUOTA_KEY(_this, var, key, _ret) \ + do { \ + marker_conf_t *_priv = _this->private; \ + if (_priv->version > 0) \ + _ret = snprintf (var, QUOTA_KEY_MAX, "%s.%d", \ + key, _priv->version); \ + else \ + _ret = snprintf (var, QUOTA_KEY_MAX, "%s", key); \ + } while (0) + +#define GET_SIZE_KEY(_this, var, _ret) \ + { \ + GET_QUOTA_KEY (_this, var, QUOTA_SIZE_KEY, _ret); \ + } + #define QUOTA_SAFE_INCREMENT(lock, var) \ do { \ LOCK (lock); \ @@ -112,7 +130,7 @@ struct inode_contribution { typedef struct inode_contribution inode_contribution_t; int32_t -mq_req_xattr (xlator_t *, loc_t *, dict_t *, char *); +mq_req_xattr (xlator_t *, loc_t *, dict_t *, char *, char *); int32_t mq_xattr_state (xlator_t *, loc_t *, dict_t *, struct iatt); diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c index e579417810f..34e0fe73fec 100644 --- a/xlators/features/marker/src/marker.c +++ b/xlators/features/marker/src/marker.c @@ -23,7 +23,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, @@ -36,6 +36,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) { @@ -334,7 +408,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); @@ -346,6 +420,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"); @@ -371,6 +457,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; } @@ -379,13 +466,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) @@ -423,7 +526,6 @@ out: return 0; } - int32_t marker_setxattr_done (call_frame_t *frame) { @@ -1200,7 +1302,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; @@ -1237,7 +1339,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; @@ -1301,7 +1404,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, }; @@ -1322,7 +1425,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; @@ -1349,7 +1452,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; @@ -1368,7 +1471,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; @@ -2292,6 +2395,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; @@ -2555,12 +2662,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; @@ -2597,14 +2719,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)) { @@ -2619,10 +2753,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); @@ -2654,9 +2785,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; @@ -2664,6 +2795,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; @@ -2678,7 +2813,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); @@ -2710,7 +2846,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); @@ -2734,6 +2869,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) @@ -2792,10 +2934,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: @@ -2811,6 +2959,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; @@ -2818,6 +2967,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), @@ -2831,7 +2984,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, @@ -2980,6 +3133,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); @@ -3004,6 +3158,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); @@ -3059,6 +3225,7 @@ init (xlator_t *this) priv = this->private; priv->feature_enabled = 0; + priv->version = 0; LOCK_INIT (&priv->lock); @@ -3076,6 +3243,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); diff --git a/xlators/features/marker/src/marker.h b/xlators/features/marker/src/marker.h index 650acd84d1b..6921ebd45e5 100644 --- a/xlators/features/marker/src/marker.h +++ b/xlators/features/marker/src/marker.h @@ -142,6 +142,7 @@ struct marker_conf{ char *marker_xattr; uint64_t quota_lk_owner; gf_lock_t lock; + int32_t version; }; typedef struct marker_conf marker_conf_t; diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index f0ee8797206..53753559c5b 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -874,6 +874,12 @@ quota_build_ancestry (inode_t *inode, quota_ancestry_built_t ancestry_cbk, goto err; } + op_ret = dict_set_int8 (xdata_req, QUOTA_LIMIT_OBJECTS_KEY, 1); + if (op_ret < 0) { + op_errno = -op_ret; + goto err; + } + op_ret = dict_set_int8 (xdata_req, GET_ANCESTRY_DENTRY_KEY, 1); if (op_ret < 0) { op_errno = -op_ret; diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h index 3329ecf5d4d..53ea404cd73 100644 --- a/xlators/lib/src/libxlator.h +++ b/xlators/lib/src/libxlator.h @@ -26,10 +26,6 @@ #define UUID_SIZE 36 #define MARKER_UUID_TYPE 1 #define MARKER_XTIME_TYPE 2 -#define GF_XATTR_QUOTA_SIZE_KEY "trusted.glusterfs.quota.size" -#define GF_XATTR_QUOTA_LIMIT_LIST "trusted.limit.list" -#define GF_XATTR_QUOTA_LIMIT_LIST_OBJECT "trusted.limit.objects" - typedef int32_t (*xlator_specf_unwind_t) (call_frame_t *frame, int op_ret, int op_errno, diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 863c87e40bf..b8efcf12eeb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -1207,8 +1207,7 @@ glusterd_remove_quota_limit (char *volname, char *path, char **op_errstr, } if (type == GF_QUOTA_OPTION_TYPE_REMOVE) { - ret = sys_lremovexattr (abspath, - "trusted.glusterfs.quota.limit-set"); + ret = sys_lremovexattr (abspath, QUOTA_LIMIT_KEY); if (ret) { gf_asprintf (op_errstr, "removexattr failed on %s. " "Reason : %s", abspath, strerror (errno)); @@ -1217,8 +1216,7 @@ glusterd_remove_quota_limit (char *volname, char *path, char **op_errstr, } if (type == GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS) { - ret = sys_lremovexattr (abspath, - "trusted.glusterfs.quota.limit-objects"); + ret = sys_lremovexattr (abspath, QUOTA_LIMIT_OBJECTS_KEY); if (ret) { gf_asprintf (op_errstr, "removexattr failed on %s. " "Reason : %s", abspath, strerror (errno)); @@ -1494,19 +1492,33 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } + + if (GF_QUOTA_OPTION_TYPE_ENABLE == type) + volinfo->quota_version++; + ret = glusterd_store_volinfo (volinfo, + GLUSTERD_VOLINFO_VER_AC_INCREMENT); + if (ret) { + if (GF_QUOTA_OPTION_TYPE_ENABLE == type) + volinfo->quota_version--; + goto out; + } + ret = glusterd_create_volfiles_and_notify_services (volinfo); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_VOLFILE_CREATE_FAIL, "Unable to re-create " "volfiles"); + if (GF_QUOTA_OPTION_TYPE_ENABLE == type) { + /* rollback volinfo */ + volinfo->quota_version--; + ret = glusterd_store_volinfo (volinfo, + GLUSTERD_VOLINFO_VER_AC_INCREMENT); + } + ret = -1; goto out; } - ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); - if (ret) - goto out; - if (GLUSTERD_STATUS_STARTED == volinfo->status) { if (priv->op_version == GD_OP_VERSION_MIN) ret = priv->nfs_svc.manager (&(priv->nfs_svc), NULL, 0); diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index b9991b36c68..6d4fce23463 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -1008,6 +1008,12 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) goto out; } + snprintf (buf, sizeof (buf), "%d", volinfo->quota_version); + ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_QUOTA_VERSION, + buf); + if (ret) + goto out; + ret = glusterd_volume_write_tier_details (fd, volinfo); ret = glusterd_volume_write_snap_details (fd, volinfo); @@ -2666,6 +2672,9 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo) } else if (!strncmp (key, GLUSTERD_STORE_KEY_COLD_TYPE, strlen (key))) { volinfo->tier_info.cold_type = atoi (value); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_QUOTA_VERSION, + strlen (GLUSTERD_STORE_KEY_VOL_QUOTA_VERSION))) { + volinfo->quota_version = atoi (value); } else { if (is_key_glusterd_hooks_friendly (key)) { diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index fdde2196633..7335c0a8445 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -58,6 +58,7 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_PARENT_VOLNAME "parent_volname" #define GLUSTERD_STORE_KEY_VOL_OP_VERSION "op-version" #define GLUSTERD_STORE_KEY_VOL_CLIENT_OP_VERSION "client-op-version" +#define GLUSTERD_STORE_KEY_VOL_QUOTA_VERSION "quota-version" #define GLUSTERD_STORE_KEY_COLD_TYPE "cold_type" #define GLUSTERD_STORE_KEY_COLD_COUNT "cold_count" diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index ff56c9f3f39..06c60f37751 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -2489,6 +2489,9 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, snprintf (key, sizeof (key), "%s%d.caps", prefix, count); ret = dict_set_int32 (dict, key, volinfo->caps); + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s%d.quota-version", prefix, count); + ret = dict_set_int32 (dict, key, volinfo->quota_version); out: GF_FREE (volume_id_str); GF_FREE (rebalance_id_str); @@ -3569,6 +3572,11 @@ glusterd_import_volinfo (dict_t *peer_data, int count, /*This is not present in older glusterfs versions, so ignore ret value*/ ret = dict_get_int32 (peer_data, key, &new_volinfo->caps); + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "%s%d.quota_version", prefix, count); + /*This is not present in older glusterfs versions, so ignore ret value*/ + ret = dict_get_int32 (peer_data, key, &new_volinfo->quota_version); + ret = glusterd_import_bricks (peer_data, count, new_volinfo, prefix); if (ret) goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 6c32c9bd980..571b23f3519 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1864,6 +1864,7 @@ brick_graph_add_marker (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, xlator_t *xl = NULL; char tstamp_file[PATH_MAX] = {0,}; char volume_id[64] = {0,}; + char buf[32] = {0,}; if (!graph || !volinfo || !set_dict) goto out; @@ -1881,6 +1882,11 @@ brick_graph_add_marker (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, if (ret) goto out; + snprintf (buf, sizeof (buf), "%d", volinfo->quota_version); + ret = xlator_set_option (xl, "quota-version", buf); + if (ret) + goto out; + out: return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 2c0012c0399..5beff25c286 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -407,6 +407,7 @@ struct glusterd_volinfo_ { gd_quorum_status_t quorum_status; glusterd_snapdsvc_t snapd; + int32_t quota_version; }; typedef enum gd_snap_status_ { |