diff options
| author | Raghavendra G <raghavendra@gluster.com> | 2012-03-27 15:31:50 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vijay@gluster.com> | 2012-04-27 00:26:39 -0700 | 
| commit | 4213745eba97ffe1e2bdb13446fe2fd87e7c6fef (patch) | |
| tree | 4a0f54d60f18a611688cf3522f8a3b50cdf9e55e | |
| parent | ecb818902e4ee7491aaeae21226b62a0ab806370 (diff) | |
features/quota: update inode ctx in reconfigure.
Till this patch, quota was relying on lookups after reconfigure, for
new limits to be effective. However, this might be restrictive for
users who don't want to change directories after resetting quota
limits.
Change-Id: I236aa31fdc7dcbc01d40d38c9b5b7b0a28a4d2ea
BUG: 802905
Signed-off-by: Raghavendra G <raghavendra@gluster.com>
Reviewed-on: http://review.gluster.com/3022
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Mohammed Junaid <junaid@redhat.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Tested-by: Amar Tumballi <amarts@redhat.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
| -rw-r--r-- | xlators/features/quota/src/quota.c | 180 | ||||
| -rw-r--r-- | xlators/features/quota/src/quota.h | 10 | 
2 files changed, 159 insertions, 31 deletions
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 436fb1b1cb1..7d5f74e9cc8 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -580,16 +580,20 @@ 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)  { -        int32_t            ret    = -1; -        char               found  = 0; -        quota_local_t     *local  = NULL; -        quota_inode_ctx_t *ctx    = NULL; -        quota_dentry_t    *dentry = NULL; -        int64_t           *size   = 0; -        uint64_t           value  = 0; +        int32_t            ret        = -1; +        char               found      = 0; +        quota_local_t     *local      = NULL; +        quota_inode_ctx_t *ctx        = NULL; +        quota_dentry_t    *dentry     = NULL; +        int64_t           *size       = 0; +        uint64_t           value      = 0; +        limits_t          *limit_node = NULL; +        quota_priv_t      *priv       = NULL;          local = frame->local; +        priv = this->private; +          inode_ctx_get (inode, this, &value);          ctx = (quota_inode_ctx_t *)(unsigned long)value; @@ -600,6 +604,18 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto unwind;          } +        LOCK (&priv->lock); +        { +                list_for_each_entry (limit_node, &priv->limit_head, +                                     limit_list) { +                        if (strcmp (local->loc.path, limit_node->path) == 0) { +                                uuid_copy (limit_node->gfid, buf->ia_gfid); +                                break; +                        } +                } +        } +        UNLOCK (&priv->lock); +          ret = quota_inode_ctx_get (local->loc.inode, local->limit, this, dict,                                     buf, &ctx, 1);          if ((ret == -1) || (ctx == NULL)) { @@ -3012,22 +3028,23 @@ quota_forget (xlator_t *this, inode_t *inode)  int -quota_parse_limits (quota_priv_t *priv, xlator_t *this, dict_t *xl_options) +quota_parse_limits (quota_priv_t *priv, xlator_t *this, dict_t *xl_options, +                    struct list_head *old_list)  {          int32_t       ret       = -1;          char         *str       = NULL;          char         *str_val   = NULL; -        char         *path      = NULL; +        char         *path      = NULL, *saveptr = NULL;          uint64_t      value     = 0; -        limits_t     *quota_lim = NULL; +        limits_t     *quota_lim = NULL, *old = NULL;          ret = dict_get_str (xl_options, "limit-set", &str);          if (str) { -                path = strtok (str, ":"); +                path = strtok_r (str, ":", &saveptr);                  while (path) { -                        str_val = strtok (NULL, ","); +                        str_val = strtok_r (NULL, ",", &saveptr);                          ret = gf_string2bytesize (str_val, &value);                          if (ret != 0) @@ -3042,20 +3059,40 @@ quota_parse_limits (quota_priv_t *priv, xlator_t *this, dict_t *xl_options)                          gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64,                                  quota_lim->path, quota_lim->value); -                        list_add_tail ("a_lim->limit_list, -                                       &priv->limit_head); +                        if (old_list != NULL) { +                                list_for_each_entry (old, old_list, +                                                     limit_list) { +                                        if (strcmp (old->path, quota_lim->path) +                                            == 0) { +                                                uuid_copy (quota_lim->gfid, +                                                           old->gfid); +                                                break; +                                        } +                                } +                        } + +                        LOCK (&priv->lock); +                        { +                                list_add_tail ("a_lim->limit_list, +                                               &priv->limit_head); +                        } +                        UNLOCK (&priv->lock); -                        path = strtok (NULL, ":"); +                        path = strtok_r (NULL, ":", &saveptr);                  }          } else {                  gf_log (this->name, GF_LOG_INFO,                          "no \"limit-set\" option provided");          } -        list_for_each_entry (quota_lim, &priv->limit_head, limit_list) { -                gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64, quota_lim->path, -                        quota_lim->value); +        LOCK (&priv->lock); +        { +                list_for_each_entry (quota_lim, &priv->limit_head, limit_list) { +                        gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64, +                                quota_lim->path, quota_lim->value); +                }          } +        UNLOCK (&priv->lock);          ret = 0;  err: @@ -3086,9 +3123,11 @@ init (xlator_t *this)          INIT_LIST_HEAD (&priv->limit_head); +        LOCK_INIT (&priv->lock); +          this->private = priv; -        ret = quota_parse_limits (priv, this, this->options); +        ret = quota_parse_limits (priv, this, this->options, NULL);          if (ret) {                  goto err; @@ -3110,23 +3149,81 @@ err:  } +void +__quota_reconfigure_inode_ctx (xlator_t *this, inode_t *inode, limits_t *limit) +{ +        int                ret = -1; +        quota_inode_ctx_t *ctx = NULL; + +        GF_VALIDATE_OR_GOTO ("quota", this, out); +        GF_VALIDATE_OR_GOTO (this->name, inode, out); +        GF_VALIDATE_OR_GOTO (this->name, limit, out); + +        ret = quota_inode_ctx_get (inode, limit->value, this, NULL, NULL, &ctx, +                                   1); +        if ((ret == -1) || (ctx == NULL)) { +                gf_log (this->name, GF_LOG_WARNING, "cannot create quota " +                        "context in inode(gfid:%s)", +                        uuid_utoa (inode->gfid)); +                goto out; +        } + +        LOCK (&ctx->lock); +        { +                ctx->limit = limit->value; +        } +        UNLOCK (&ctx->lock); + +out: +        return; +} + + +void +__quota_reconfigure (xlator_t *this, inode_table_t *itable, limits_t *limit) +{ +        inode_t *inode = NULL; + +        if ((this == NULL) || (itable == NULL) || (limit == NULL)) { +                goto out; +        } + +        if (!uuid_is_null (limit->gfid)) { +                inode = inode_find (itable, limit->gfid); +        } else { +                inode = inode_resolve (itable, limit->path); +        } + +        if (inode != NULL) { +                __quota_reconfigure_inode_ctx (this, inode, limit); +        } + +out: +        return; +} + +  int  reconfigure (xlator_t *this, dict_t *options)  { -        int32_t          ret    = -1; -        quota_priv_t    *priv   = NULL; -        limits_t        *limit  = NULL; -        limits_t        *next   = NULL; +        int32_t           ret   = -1; +        quota_priv_t     *priv  = NULL; +        limits_t         *limit = NULL, *next = NULL, *new = NULL; +        struct list_head  head  = {0, }; +        xlator_t         *top   = NULL; +        char              found = 0;          priv = this->private; -        list_for_each_entry_safe (limit, next, &priv->limit_head, limit_list) { -                list_del (&limit->limit_list); +        INIT_LIST_HEAD (&head); -                GF_FREE (limit); +        LOCK (&priv->lock); +        { +                list_splice_init (&priv->limit_head, &head);          } +        UNLOCK (&priv->lock); -        ret = quota_parse_limits (priv, this, options); +        ret = quota_parse_limits (priv, this, options, &head);          if (ret == -1) {                  gf_log ("quota", GF_LOG_WARNING,                          "quota reconfigure failed, " @@ -3134,6 +3231,35 @@ reconfigure (xlator_t *this, dict_t *options)                  goto out;          } +        LOCK (&priv->lock); +        { +                list_for_each_entry (limit, &priv->limit_head, limit_list) { +                        top = ((glusterfs_ctx_t *)this->ctx)->active->top; + +                        __quota_reconfigure (this, top->itable, limit); +                } + +                list_for_each_entry_safe (limit, next, &head, limit_list) { +                        found = 0; +                        list_for_each_entry (new, &priv->limit_head, +                                             limit_list) { +                                if (strcmp (new->path, limit->path) == 0) { +                                        found = 1; +                                        break; +                                } +                        } + +                        if (!found) { +                                limit->value = -1; +                                __quota_reconfigure (this, top->itable, limit); +                        } + +                        list_del_init (&limit->limit_list); +                        GF_FREE (limit); +                } +        } +        UNLOCK (&priv->lock); +          GF_OPTION_RECONF ("timeout", priv->timeout, options, int64, out);          ret = 0; diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h index 79b4d07e351..cf9c4f9b769 100644 --- a/xlators/features/quota/src/quota.h +++ b/xlators/features/quota/src/quota.h @@ -154,16 +154,18 @@ struct quota_local {  typedef struct quota_local quota_local_t;  struct quota_priv { -        int64_t  timeout; -        struct list_head limit_head; +        int64_t           timeout; +        struct list_head  limit_head; +        gf_lock_t         lock;  };  typedef struct quota_priv quota_priv_t;  struct limits {          struct list_head  limit_list;          char             *path; -        int64_t          value; +        int64_t           value; +        uuid_t            gfid;  }; -typedef struct limits limits_t; +typedef struct limits     limits_t;  uint64_t cn = 1;  | 
