diff options
Diffstat (limited to 'xlators/features/marker/src/marker-quota-helper.c')
| -rw-r--r-- | xlators/features/marker/src/marker-quota-helper.c | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c new file mode 100644 index 000000000..af5fed132 --- /dev/null +++ b/xlators/features/marker/src/marker-quota-helper.c @@ -0,0 +1,414 @@ +/* + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "locking.h" +#include "marker-quota.h" +#include "marker-common.h" +#include "marker-quota-helper.h" +#include "marker-mem-types.h" + +int +mq_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) +{ + int ret = -1; + + GF_VALIDATE_OR_GOTO ("marker", loc, out); + GF_VALIDATE_OR_GOTO ("marker", inode, out); + GF_VALIDATE_OR_GOTO ("marker", path, out); + /* Not checking for parent because while filling + * loc of root, parent will be NULL + */ + + if (inode) { + loc->inode = inode_ref (inode); + } + + if (parent) + loc->parent = inode_ref (parent); + + loc->path = gf_strdup (path); + if (!loc->path) { + gf_log ("loc fill", GF_LOG_ERROR, "strdup failed"); + goto loc_wipe; + } + + loc->name = strrchr (loc->path, '/'); + if (loc->name) + loc->name++; + else + goto loc_wipe; + + ret = 0; +loc_wipe: + if (ret < 0) + loc_wipe (loc); +out: + return ret; +} + + +int32_t +mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc) +{ + char *resolvedpath = NULL; + inode_t *parent = NULL; + int ret = -1; + + if ((!inode) || (!loc)) + return ret; + + if ((inode) && __is_root_gfid (inode->gfid)) { + loc->parent = NULL; + goto ignore_parent; + } + + if (parent_gfid == NULL) + parent = inode_parent (inode, 0, NULL); + else + parent = inode_find (inode->table, + (unsigned char *) parent_gfid); + + if (parent == NULL) + goto err; + +ignore_parent: + ret = inode_path (inode, NULL, &resolvedpath); + if (ret < 0) + goto err; + + ret = mq_loc_fill (loc, inode, parent, resolvedpath); + if (ret < 0) + goto err; + +err: + if (parent) + inode_unref (parent); + + GF_FREE (resolvedpath); + + return ret; +} + + +quota_inode_ctx_t * +mq_alloc_inode_ctx () +{ + int32_t ret = -1; + quota_inode_ctx_t *ctx = NULL; + + QUOTA_ALLOC (ctx, quota_inode_ctx_t, ret); + if (ret == -1) + goto out; + + ctx->size = 0; + ctx->dirty = 0; + ctx->updation_status = _gf_false; + LOCK_INIT (&ctx->lock); + INIT_LIST_HEAD (&ctx->contribution_head); +out: + return ctx; +} + +inode_contribution_t * +mq_get_contribution_node (inode_t *inode, quota_inode_ctx_t *ctx) +{ + inode_contribution_t *contri = NULL; + inode_contribution_t *temp = NULL; + + if (!inode || !ctx) + goto out; + + list_for_each_entry (temp, &ctx->contribution_head, contri_list) { + if (uuid_compare (temp->gfid, inode->gfid) == 0) { + contri = temp; + goto out; + } + } +out: + return contri; +} + + +int32_t +mq_delete_contribution_node (dict_t *dict, char *key, + inode_contribution_t *contribution) +{ + if (dict_get (dict, key) != NULL) + goto out; + + QUOTA_FREE_CONTRIBUTION_NODE (contribution); +out: + return 0; +} + + +inode_contribution_t * +__mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) +{ + int32_t ret = 0; + inode_contribution_t *contribution = NULL; + + if (!loc->parent) { + if (!uuid_is_null (loc->pargfid)) + loc->parent = inode_find (loc->inode->table, + loc->pargfid); + if (!loc->parent) + loc->parent = inode_parent (loc->inode, loc->pargfid, + loc->name); + if (!loc->parent) + goto out; + } + + list_for_each_entry (contribution, &ctx->contribution_head, contri_list) { + if (loc->parent && + uuid_compare (contribution->gfid, loc->parent->gfid) == 0) { + goto out; + } + } + + QUOTA_ALLOC (contribution, inode_contribution_t, ret); + if (ret == -1) + goto out; + + contribution->contribution = 0; + + uuid_copy (contribution->gfid, loc->parent->gfid); + + LOCK_INIT (&contribution->lock); + INIT_LIST_HEAD (&contribution->contri_list); + + list_add_tail (&contribution->contri_list, &ctx->contribution_head); + +out: + return contribution; +} + + +inode_contribution_t * +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) + return NULL; + + LOCK (&ctx->lock); + { + contribution = __mq_add_new_contribution_node (this, ctx, loc); + } + UNLOCK (&ctx->lock); + + return contribution; +} + + +int32_t +mq_dict_set_contribution (xlator_t *this, dict_t *dict, + loc_t *loc) +{ + int32_t ret = -1; + char contri_key [512] = {0, }; + + 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; + } + + ret = dict_set_int64 (dict, contri_key, 0); + if (ret < 0) { + gf_log (this->name, GF_LOG_WARNING, + "unable to set dict value on %s.", + loc->path); + goto out; + } + + ret = 0; +out: + return ret; +} + + +int32_t +mq_inode_ctx_get (inode_t *inode, xlator_t *this, + quota_inode_ctx_t **ctx) +{ + int32_t ret = -1; + uint64_t ctx_int = 0; + marker_inode_ctx_t *mark_ctx = NULL; + + GF_VALIDATE_OR_GOTO ("marker", inode, out); + GF_VALIDATE_OR_GOTO ("marker", this, out); + GF_VALIDATE_OR_GOTO ("marker", ctx, out); + + ret = inode_ctx_get (inode, this, &ctx_int); + if (ret < 0) { + ret = -1; + *ctx = NULL; + goto out; + } + + mark_ctx = (marker_inode_ctx_t *) (unsigned long)ctx_int; + if (mark_ctx->quota_ctx == NULL) { + ret = -1; + goto out; + } + + *ctx = mark_ctx->quota_ctx; + + ret = 0; + +out: + return ret; +} + + +quota_inode_ctx_t * +__mq_inode_ctx_new (inode_t *inode, xlator_t *this) +{ + int32_t ret = -1; + quota_inode_ctx_t *quota_ctx = NULL; + marker_inode_ctx_t *mark_ctx = NULL; + + ret = marker_force_inode_ctx_get (inode, this, &mark_ctx); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, + "marker_force_inode_ctx_get() failed"); + goto out; + } + + LOCK (&inode->lock); + { + if (mark_ctx->quota_ctx == NULL) { + quota_ctx = mq_alloc_inode_ctx (); + if (quota_ctx == NULL) { + ret = -1; + goto unlock; + } + mark_ctx->quota_ctx = quota_ctx; + } else { + quota_ctx = mark_ctx->quota_ctx; + } + + ret = 0; + } +unlock: + UNLOCK (&inode->lock); +out: + return quota_ctx; +} + + +quota_inode_ctx_t * +mq_inode_ctx_new (inode_t * inode, xlator_t *this) +{ + return __mq_inode_ctx_new (inode, this); +} + +quota_local_t * +mq_local_new () +{ + quota_local_t *local = NULL; + + local = mem_get0 (THIS->local_pool); + if (!local) + goto out; + + local->ref = 1; + LOCK_INIT (&local->lock); + + local->ctx = NULL; + local->contri = NULL; + +out: + return local; +} + +quota_local_t * +mq_local_ref (quota_local_t *local) +{ + LOCK (&local->lock); + { + local->ref ++; + } + UNLOCK (&local->lock); + + return local; +} + + +int32_t +mq_local_unref (xlator_t *this, quota_local_t *local) +{ + int32_t ref = 0; + if (local == NULL) + goto out; + + QUOTA_SAFE_DECREMENT (&local->lock, local->ref, ref); + + if (ref != 0) + goto out; + + if (local->fd != NULL) + fd_unref (local->fd); + + loc_wipe (&local->loc); + + loc_wipe (&local->parent_loc); + + LOCK_DESTROY (&local->lock); + + mem_put (local); +out: + return 0; +} + + +inode_contribution_t * +mq_get_contribution_from_loc (xlator_t *this, loc_t *loc) +{ + int32_t ret = 0; + quota_inode_ctx_t *ctx = NULL; + inode_contribution_t *contribution = NULL; + + ret = mq_inode_ctx_get (loc->inode, this, &ctx); + if (ret < 0) { + gf_log_callingfn (this->name, GF_LOG_WARNING, + "cannot get marker-quota context from inode " + "(gfid:%s, path:%s)", + uuid_utoa (loc->inode->gfid), loc->path); + goto err; + } + + contribution = mq_get_contribution_node (loc->parent, ctx); + if (contribution == NULL) { + gf_log_callingfn (this->name, GF_LOG_WARNING, + "inode (gfid:%s, path:%s) has " + "no contribution towards parent (gfid:%s)", + uuid_utoa (loc->inode->gfid), + loc->path, uuid_utoa (loc->parent->gfid)); + goto err; + } + +err: + return contribution; +} |
