diff options
| author | vmallika <vmallika@redhat.com> | 2015-04-30 16:50:47 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2015-05-06 10:48:46 -0700 | 
| commit | b054985d2f7db9ab72759c988db11feb855a1b5e (patch) | |
| tree | 65868f66cd616df79cc3b27c0a014a4c539febe1 | |
| parent | e79edf35178f2558d6afb262444294380b76d740 (diff) | |
quota/marker: turn off inode quotas by default
inode quota is a new feature implemented in glusterfs-3.7
if quota is enabled in the older version and is upgraded
to a new version, we can hit setxattr spike during self-heal
of inode quotas. So, when a quota is enabled, turn off
inode-quotas with a xlator option.
With this patch, we still account for inode quotas but only
when a write operation is performed for a particular file.
User will be able to query inode quotas once the Inode-quota
xlator option is enabled.
Change-Id: I52fb28bf7024989ce7bb08ac63a303bf3ec1ec9a
BUG: 1209430
Signed-off-by: vmallika <vmallika@redhat.com>
Signed-off-by: Sachin Pandit <spandit@redhat.com>
Reviewed-on: http://review.gluster.org/10152
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 54 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 23 | ||||
| -rw-r--r-- | cli/src/cli.h | 3 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 1 | ||||
| -rw-r--r-- | xlators/features/marker/src/marker-quota.c | 55 | ||||
| -rw-r--r-- | xlators/features/marker/src/marker.c | 15 | ||||
| -rw-r--r-- | xlators/features/marker/src/marker.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 54 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 106 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 7 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 8 | 
13 files changed, 289 insertions, 42 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 5437b38d3a6..99ef7014d2d 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -926,6 +926,60 @@ out:  }  int32_t +cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **options) +{ +        dict_t          *dict    = NULL; +        char            *volname = NULL; +        int              ret     = -1; + +        GF_ASSERT (words); +        GF_ASSERT (options); + +        dict = dict_new (); +        if (!dict) { +                gf_log ("cli", GF_LOG_ERROR, "dict_new failed"); +                goto out; +        } + +        if (wordcount != 4) +                goto out; + +        volname = (char *)words[2]; +        if (!volname) { +                ret = -1; +                goto out; +        } + +        /* Validate the volume name here itself */ +        if (cli_validate_volname (volname) < 0) +                goto out; + +        ret = dict_set_str (dict, "volname", volname); +        if (ret < 0) +                goto out; + +        if (strcmp (words[3], "enable") != 0) { +                cli_out ("Invalid quota option : %s", words[3]); +                ret = -1; +                goto out; +        } + +        ret = dict_set_int32 (dict, "type", +                              GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS); +        if (ret < 0) +                goto out; + +        *options = dict; +out: +        if (ret < 0) { +                if (dict) +                        dict_destroy (dict); +        } + +        return ret; +} + +int32_t  cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)  {          dict_t          *dict    = NULL; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 9340067e256..0dfb647b92c 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1515,11 +1515,20 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,                                 "configuration. Do you want to continue?";          //parse **words into options dictionary -        ret = cli_cmd_quota_parse (words, wordcount, &options); -        if (ret < 0) { -                cli_usage_out (word->pattern); -                parse_err = 1; -                goto out; +        if (strcmp (words[1], "inode-quota") == 0) { +                ret = cli_cmd_inode_quota_parse (words, wordcount, &options); +                if (ret < 0) { +                        cli_usage_out (word->pattern); +                        parse_err = 1; +                        goto out; +                } +        } else { +                ret = cli_cmd_quota_parse (words, wordcount, &options); +                if (ret < 0) { +                        cli_usage_out (word->pattern); +                        parse_err = 1; +                        goto out; +                }          }          ret = dict_get_int32 (options, "type", &type); @@ -2649,6 +2658,10 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_quota_cbk,            "quota translator specific operations"}, +        { "volume inode-quota <VOLNAME> enable", +          cli_cmd_quota_cbk, +          "quota translator specific operations"}, +           { "volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick <brick>] [list-cnt <value>] |\n"             "volume top <VOLNAME> {read-perf|write-perf} [bs <size> count <count>] [brick <brick>] [list-cnt <value>]",             cli_cmd_volume_top_cbk, diff --git a/cli/src/cli.h b/cli/src/cli.h index 243935230d1..27558a7830c 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -242,6 +242,9 @@ int32_t  cli_cmd_quota_parse (const char **words, int wordcount, dict_t **opt);  int32_t +cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **opt); + +int32_t  cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **opt);  int32_t diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index dbc2fa52494..1a1dfcc9e87 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -81,6 +81,7 @@ enum gf_quota_type {          GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS,          GF_QUOTA_OPTION_TYPE_LIST_OBJECTS,          GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS, +        GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS,          GF_QUOTA_OPTION_TYPE_MAX  }; diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c index e99dfe2331e..e9351ed4e88 100644 --- a/xlators/features/marker/src/marker-quota.c +++ b/xlators/features/marker/src/marker-quota.c @@ -2037,6 +2037,38 @@ err:          return -1;  } +int32_t +_quota_dict_get_meta (xlator_t *this, dict_t *dict, char *key, +                      quota_meta_t *meta, ia_type_t ia_type, +                      gf_boolean_t add_delta) +{ +        int32_t             ret     = 0; +        marker_conf_t      *priv    = NULL; + +        priv = this->private; + +        ret = quota_dict_get_meta (dict, key, meta); +        if (ret == -2 && (priv->feature_enabled & GF_INODE_QUOTA) == 0) { +                /* quota_dict_get_meta returns -2 if +                 * inode quota xattrs are not present. +                 * if inode quota self heal is turned off, +                 * then we should skip healing inode quotas +                 */ + +                gf_log (this->name, GF_LOG_DEBUG, "inode quota disabled. " +                        "inode quota self heal will not be performed"); +                ret = 0; +                if (add_delta) { +                        if (ia_type == IA_IFDIR) +                                meta->dir_count = 1; +                        else +                                meta->file_count = 1; +                } +        } + +        return ret; +} +  void  mq_compute_delta (quota_meta_t *delta, const quota_meta_t *op1,                    const quota_meta_t *op2) @@ -2116,7 +2148,8 @@ mq_are_xattrs_set (xlator_t *this, loc_t *loc, gf_boolean_t *result,          *result = _gf_true;          if (loc->inode->ia_type == IA_IFDIR) { -                ret = quota_dict_get_meta (rsp_dict, QUOTA_SIZE_KEY, &meta); +                ret = _quota_dict_get_meta (this, rsp_dict, QUOTA_SIZE_KEY, +                                            &meta, IA_IFDIR, _gf_false);                  if (ret < 0 || meta.dir_count == 0) {                          ret = 0;                          *result = _gf_false; @@ -2126,7 +2159,8 @@ mq_are_xattrs_set (xlator_t *this, loc_t *loc, gf_boolean_t *result,          }          if (!loc_is_root(loc)) { -                ret = quota_dict_get_meta (rsp_dict, contri_key, &meta); +                ret = _quota_dict_get_meta (this, rsp_dict, contri_key, +                                            &meta, IA_IFREG, _gf_false);                  if (ret < 0) {                          ret = 0;                          *result = _gf_false; @@ -2392,8 +2426,9 @@ _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, -                                                   &meta); +                        ret = _quota_dict_get_meta (this, rsp_dict, +                                                    QUOTA_SIZE_KEY, &meta, +                                                    IA_IFDIR, _gf_true);                          if (ret < 0) {                                  gf_log (this->name, GF_LOG_ERROR,                                          "dict_get failed."); @@ -2411,7 +2446,8 @@ _mq_get_metadata (xlator_t *this, loc_t *loc, quota_meta_t *contri,          }          if (contri && !loc_is_root(loc)) { -                ret = quota_dict_get_meta (rsp_dict, contri_key, &meta); +                ret = _quota_dict_get_meta (this, rsp_dict, contri_key, &meta, +                                            loc->inode->ia_type, _gf_false);                  if (ret < 0) {                          contri->size = 0;                          contri->file_count = 0; @@ -3419,7 +3455,8 @@ mq_inspect_directory_xattr_task (void *opaque)          if (ret < 0)                  goto out; -        ret = quota_dict_get_meta (dict, QUOTA_SIZE_KEY, &size); +        ret = _quota_dict_get_meta (this, dict, QUOTA_SIZE_KEY, &size, +                                    IA_IFDIR, _gf_false);          if (ret < 0)                  goto out; @@ -3428,7 +3465,8 @@ mq_inspect_directory_xattr_task (void *opaque)                  if (ret < 0)                          goto err; -                ret = quota_dict_get_meta (dict, contri_key, &contri); +                ret = _quota_dict_get_meta (this, dict, contri_key, &contri, +                                            IA_IFDIR, _gf_false);                  if (ret < 0)                          goto out; @@ -3544,7 +3582,8 @@ mq_inspect_file_xattr_task (void *opaque)                  if (ret < 0)                          continue; -                ret = quota_dict_get_meta (dict, contri_key, &contri); +                ret = _quota_dict_get_meta (this, dict, contri_key, &contri, +                                            IA_IFREG, _gf_true);                  if (ret < 0) {                          ret = mq_create_xattrs_blocking_txn (this, loc);                  } else { diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c index 046df1fc44c..a465723c1bb 100644 --- a/xlators/features/marker/src/marker.c +++ b/xlators/features/marker/src/marker.c @@ -3043,6 +3043,13 @@ reconfigure (xlator_t *this, dict_t *options)                  }          } +        data = dict_get (options, "inode-quota"); +        if (data) { +                ret = gf_string2boolean (data->data, &flag); +                if (ret == 0 && flag == _gf_true) +                        priv->feature_enabled |= GF_INODE_QUOTA; +        } +          data = dict_get (options, "xtime");          if (data) {                  ret = gf_string2boolean (data->data, &flag); @@ -3113,6 +3120,13 @@ init (xlator_t *this)                  }          } +        data = dict_get (options, "inode-quota"); +        if (data) { +                ret = gf_string2boolean (data->data, &flag); +                if (ret == 0 && flag == _gf_true) +                        priv->feature_enabled |= GF_INODE_QUOTA; +        } +          data = dict_get (options, "xtime");          if (data) {                  ret = gf_string2boolean (data->data, &flag); @@ -3206,6 +3220,7 @@ struct volume_options options[] = {          {.key = {"volume-uuid"}},          {.key = {"timestamp-file"}},          {.key = {"quota"}}, +        {.key = {"inode-quota"} },          {.key = {"xtime"}},          {.key = {"gsync-force-xtime"}},          {.key = {NULL}} diff --git a/xlators/features/marker/src/marker.h b/xlators/features/marker/src/marker.h index b2d58d23f6c..aadd8776637 100644 --- a/xlators/features/marker/src/marker.h +++ b/xlators/features/marker/src/marker.h @@ -31,6 +31,7 @@ enum {          GF_QUOTA             = 1,          GF_XTIME             = 2,          GF_XTIME_GSYNC_FORCE = 4, +        GF_INODE_QUOTA       = 8,  };  /*initialize the local variable*/ diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index dfb3a2666d7..04cc75f545d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -428,23 +428,49 @@ glusterd_check_quota_cmd (char *key, char *value, char *errstr, size_t size)                  if (ret)                          goto out;                  if (b) { -                          snprintf (errstr, size," 'gluster " -                                    "volume set <VOLNAME> %s %s' is " -                                    "deprecated. Use 'gluster volume " -                                    "quota <VOLNAME> enable' instead.", -                                     key, value); -                          ret = -1; -                          goto out; +                        snprintf (errstr, size, " 'gluster " +                                  "volume set <VOLNAME> %s %s' is " +                                  "deprecated. Use 'gluster volume " +                                  "quota <VOLNAME> enable' instead.", +                                   key, value); +                        ret = -1; +                        goto out; +                } else { +                        snprintf (errstr, size, " 'gluster " +                                  "volume set <VOLNAME> %s %s' is " +                                  "deprecated. Use 'gluster volume " +                                  "quota <VOLNAME> disable' instead.", +                                   key, value); +                        ret = -1; +                        goto out; +                } +        } else if ((strcmp (key, "inode-quota") == 0) || +                   (strcmp (key, "features.inode-quota") == 0)) { +                ret = gf_string2boolean (value, &b); +                if (ret) +                        goto out; +                if (b) { +                        snprintf (errstr, size, " 'gluster " +                                  "volume set <VOLNAME> %s %s' is " +                                  "deprecated. Use 'gluster volume " +                                  "inode-quota <VOLNAME> enable' instead.", +                                  key, value); +                        ret = -1; +                        goto out;                  } else { -                          snprintf (errstr, size, " 'gluster " -                                    "volume set <VOLNAME> %s %s' is " -                                    "deprecated. Use 'gluster volume " -                                    "quota <VOLNAME> disable' instead.", -                                     key, value); -                          ret = -1; -                          goto out; +                        /* inode-quota disable not supported, +                         * use quota disable +                         */ +                        snprintf (errstr, size, " 'gluster " +                                  "volume set <VOLNAME> %s %s' is " +                                  "deprecated. Use 'gluster volume " +                                  "quota <VOLNAME> disable' instead.", +                                   key, value); +                        ret = -1; +                        goto out;                  }          } +          ret = 0;  out:          return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 9f2aa8ec9de..adf6662afae 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -58,6 +58,7 @@ const char *gd_quota_op_list[GF_QUOTA_OPTION_TYPE_MAX + 1] = {          [GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS]      = "limit-objects",          [GF_QUOTA_OPTION_TYPE_LIST_OBJECTS]       = "list-objects",          [GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS]     = "remove-objects", +        [GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS]     = "enable-objects",          [GF_QUOTA_OPTION_TYPE_MAX]                = NULL  }; @@ -266,7 +267,8 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname,                  }                  runinit (&runner); -                if (type == GF_QUOTA_OPTION_TYPE_ENABLE) +                if (type == GF_QUOTA_OPTION_TYPE_ENABLE || +                    type == GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS)                          runner_add_args (&runner, "/usr/bin/find", ".",                                           "-exec", "/usr/bin/stat",                                           "{}", "\\", ";", NULL); @@ -348,11 +350,66 @@ out:  }  int32_t +glusterd_inode_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr, +                             gf_boolean_t *crawl) +{ +        int32_t         ret     = -1; +        xlator_t        *this   = NULL; + +        this = THIS; +        GF_ASSERT (this); + +        GF_VALIDATE_OR_GOTO (this->name, volinfo, out); +        GF_VALIDATE_OR_GOTO (this->name, crawl, out); +        GF_VALIDATE_OR_GOTO (this->name, op_errstr, out); + +        if (glusterd_is_volume_started (volinfo) == 0) { +                *op_errstr = gf_strdup ("Volume is stopped, start volume " +                                        "to enable inode quota."); +                ret = -1; +                goto out; +        } + +        ret = glusterd_check_if_quota_trans_enabled (volinfo); +        if (ret != 0) { +                *op_errstr = gf_strdup ("Quota is disabled. Enabling quota " +                                        "will enable inode quota"); +                ret = -1; +                goto out; +        } + +        if (glusterd_is_volume_inode_quota_enabled (volinfo)) { +                *op_errstr = gf_strdup ("Inode Quota is already enabled"); +                ret = -1; +                goto out; +        } + +        ret = dict_set_dynstr_with_alloc (volinfo->dict, +                                          VKEY_FEATURES_INODE_QUOTA, "on"); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "dict set failed"); +                goto out; +        } + +        *crawl = _gf_true; + +        ret = glusterd_store_quota_config (volinfo, NULL, NULL, +                                           GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS, +                                           op_errstr); + +        ret = 0; +out: +        if (ret && op_errstr && !*op_errstr) +                gf_asprintf (op_errstr, "Enabling inode quota on volume %s has " +                             "been unsuccessful", volinfo->volname); +        return ret; +} + +int32_t  glusterd_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr,                         gf_boolean_t *crawl)  {          int32_t         ret     = -1; -        char            *quota_status = NULL;          xlator_t        *this         = NULL;          this = THIS; @@ -376,15 +433,15 @@ glusterd_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr,                  goto out;          } -        quota_status = gf_strdup ("on"); -        if (!quota_status) { -                gf_log (this->name, GF_LOG_ERROR, "memory allocation failed"); -                ret = -1; +        ret = dict_set_dynstr_with_alloc (volinfo->dict, VKEY_FEATURES_QUOTA, +                                          "on"); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "dict set failed");                  goto out;          } -        ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, -                               quota_status); +        ret = dict_set_dynstr_with_alloc (volinfo->dict, +                                          VKEY_FEATURES_INODE_QUOTA, "on");          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, "dict set failed");                  goto out; @@ -410,7 +467,6 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr,  {          int32_t    ret            = -1;          int        i              =  0; -        char      *quota_status   = NULL;          char      *value          = NULL;          xlator_t  *this           = NULL;          glusterd_conf_t *conf     = NULL; @@ -435,14 +491,15 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr,                  goto out;          } -        quota_status = gf_strdup ("off"); -        if (!quota_status) { -                gf_log (this->name, GF_LOG_ERROR, "memory allocation failed"); -                ret = -1; +        ret = dict_set_dynstr_with_alloc (volinfo->dict, VKEY_FEATURES_QUOTA, +                                          "off"); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "dict set failed");                  goto out;          } -        ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status); +        ret = dict_set_dynstr_with_alloc (volinfo->dict, +                                          VKEY_FEATURES_INODE_QUOTA, "off");          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, "dict set failed");                  goto out; @@ -793,7 +850,8 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,                  goto out;          /* Just create empty quota.conf file if create */ -        if (GF_QUOTA_OPTION_TYPE_ENABLE == opcode) { +        if (GF_QUOTA_OPTION_TYPE_ENABLE == opcode || +            GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS == opcode) {                  modified = _gf_true;                  goto out;          } @@ -1251,6 +1309,13 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                                  goto out;                          break; +                case GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS: +                        ret = glusterd_inode_quota_enable (volinfo, op_errstr, +                                                           &start_crawl); +                        if (ret < 0) +                                goto out; +                        break; +                  case GF_QUOTA_OPTION_TYPE_DISABLE:                          ret = glusterd_quota_disable (volinfo, op_errstr,                                                        &start_crawl); @@ -1563,6 +1628,16 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  goto out;          } +        if (type > GF_QUOTA_OPTION_TYPE_VERSION_OBJECTS) { +                if (!glusterd_is_volume_inode_quota_enabled (volinfo) && +                    type != GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS) { +                        *op_errstr = gf_strdup ("Inode Quota is disabled, " +                                                "please enable inode quota"); +                        ret = -1; +                        goto out; +                } +        } +          if (!glusterd_is_quota_supported (type, op_errstr)) {                  ret = -1;                  goto out; @@ -1578,6 +1653,7 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict)          switch (type) {          case GF_QUOTA_OPTION_TYPE_ENABLE: +        case GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS:          case GF_QUOTA_OPTION_TYPE_LIST:          case GF_QUOTA_OPTION_TYPE_LIST_OBJECTS:                  /* Fuse mount req. only for enable & list-usage options*/ diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 0f80354cdcc..40248d34614 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -8789,6 +8789,13 @@ glusterd_is_volume_quota_enabled (glusterd_volinfo_t *volinfo)  }  int +glusterd_is_volume_inode_quota_enabled (glusterd_volinfo_t *volinfo) +{ +        return (glusterd_volinfo_get_boolean (volinfo, +                                              VKEY_FEATURES_INODE_QUOTA)); +} + +int  glusterd_is_bitrot_enabled (glusterd_volinfo_t *volinfo)  {          return glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_BITROT); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 39c4442b72b..15bbf2268f7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -527,6 +527,9 @@ int  glusterd_is_volume_quota_enabled (glusterd_volinfo_t *volinfo);  int +glusterd_is_volume_inode_quota_enabled (glusterd_volinfo_t *volinfo); + +int  glusterd_is_bitrot_enabled (glusterd_volinfo_t *volinfo);  gf_boolean_t diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index 4575049ada9..571a13c02f4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -32,6 +32,7 @@  #define VKEY_MARKER_XTIME_FORCE   GEOREP".ignore-pid-check"  #define VKEY_CHANGELOG            "changelog.changelog"  #define VKEY_FEATURES_QUOTA       "features.quota" +#define VKEY_FEATURES_INODE_QUOTA "features.inode-quota"  #define VKEY_FEATURES_TRASH       "features.trash"  #define VKEY_FEATURES_BITROT      "features.bitrot"  #define VKEY_FEATURES_SCRUB       "features.scrub" diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 9f751c90f3d..699985c2718 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1264,6 +1264,14 @@ struct volopt_map_entry glusterd_volopt_map[] = {            .flags       = OPT_FLAG_FORCE,            .op_version  = 1          }, +        { .key         = VKEY_FEATURES_INODE_QUOTA, +          .voltype     = "features/marker", +          .option      = "inode-quota", +          .value       = "off", +          .type        = NO_DOC, +          .flags       = OPT_FLAG_FORCE, +          .op_version  = 1 +        },          { .key         = VKEY_FEATURES_BITROT,            .voltype     = "features/bitrot",  | 
