diff options
Diffstat (limited to 'xlators/features/marker/src/marker-quota-helper.c')
| -rw-r--r-- | xlators/features/marker/src/marker-quota-helper.c | 599 |
1 files changed, 283 insertions, 316 deletions
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c index a559da808f8..ecd85d67b2b 100644 --- a/xlators/features/marker/src/marker-quota-helper.c +++ b/xlators/features/marker/src/marker-quota-helper.c @@ -1,413 +1,380 @@ -/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. +/* + 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 <glusterfs/locking.h> #include "marker-quota.h" #include "marker-common.h" #include "marker-quota-helper.h" #include "marker-mem-types.h" int -quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) +mq_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path) { - int ret = -1; + int ret = -1; - if (!loc) - return ret; + 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); - loc->ino = inode->ino; - } + if (inode) { + loc->inode = inode_ref(inode); + } - if (parent) - loc->parent = inode_ref (parent); + 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; - } + if (!gf_uuid_is_null(inode->gfid)) + gf_uuid_copy(loc->gfid, inode->gfid); - loc->name = strrchr (loc->path, '/'); - if (loc->name) - loc->name++; - else - goto loc_wipe; + loc->path = gf_strdup(path); + if (!loc->path) { + gf_log("loc fill", GF_LOG_ERROR, "strdup failed"); + goto out; + } - ret = 0; -loc_wipe: - if (ret < 0) - loc_wipe (loc); + loc->name = strrchr(loc->path, '/'); + if (loc->name) + loc->name++; + else + goto out; - return ret; -} + ret = 0; +out: + if (ret < 0) + loc_wipe(loc); + + return ret; +} int32_t -quota_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc) +mq_inode_loc_fill(const char *parent_gfid, inode_t *inode, loc_t *loc) { - char *resolvedpath = NULL; - inode_t *parent = NULL; - int ret = -1; + char *resolvedpath = NULL; + inode_t *parent = NULL; + quota_inode_ctx_t *ctx = NULL; + xlator_t *this = NULL; + int ret = -1; + + this = THIS; + + if (inode == NULL) { + gf_log_callingfn("marker", GF_LOG_ERROR, + "loc fill failed, " + "inode is NULL"); + return ret; + } - if ((!inode) || (!loc)) - return ret; + if (loc == NULL) + return ret; - if ((inode) && (inode->ino == 1)) { - loc->parent = NULL; - goto ignore_parent; - } + 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_gfid == NULL) + parent = inode_parent(inode, 0, NULL); + else + parent = inode_find(inode->table, (unsigned char *)parent_gfid); - if (parent == NULL) - goto err; + if (parent == NULL) { + gf_log("marker", GF_LOG_ERROR, "parent is NULL for %s", + uuid_utoa(inode->gfid)); + goto err; + } ignore_parent: - ret = inode_path (inode, NULL, &resolvedpath); - if (ret < 0) - goto err; - - ret = quota_loc_fill (loc, inode, parent, resolvedpath); - if (ret < 0) - goto err; + ret = inode_path(inode, NULL, &resolvedpath); + if (ret < 0) { + gf_log("marker", GF_LOG_ERROR, "failed to resolve path for %s", + uuid_utoa(inode->gfid)); + goto err; + } + + ret = mq_loc_fill(loc, inode, parent, resolvedpath); + if (ret < 0) + goto err; + + ret = mq_inode_ctx_get(inode, this, &ctx); + if (ret < 0 || ctx == NULL) + ctx = mq_inode_ctx_new(inode, this); + if (ctx == NULL) { + gf_log(this->name, GF_LOG_WARNING, + "mq_inode_ctx_new " + "failed for %s", + uuid_utoa(inode->gfid)); + ret = -1; + goto err; + } + ret = 0; err: - if (parent) - inode_unref (parent); + if (parent) + inode_unref(parent); - GF_FREE (resolvedpath); + GF_FREE(resolvedpath); - return ret; + return ret; } - quota_inode_ctx_t * -quota_alloc_inode_ctx () +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; - LOCK_INIT (&ctx->lock); - INIT_LIST_HEAD (&ctx->contribution_head); + 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; + return ctx; } -inode_contribution_t * -get_contribution_node (inode_t *inode, quota_inode_ctx_t *ctx) +static void +mq_contri_fini(inode_contribution_t *contri) { - inode_contribution_t *contri = NULL; - inode_contribution_t *temp = NULL; - - GF_VALIDATE_OR_GOTO ("marker", inode, out); - GF_VALIDATE_OR_GOTO ("marker", ctx, 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; + LOCK_DESTROY(&contri->lock); + GF_FREE(contri); } - -int32_t -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 * -__add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) +mq_contri_init(inode_t *inode) { - int32_t ret = 0; - inode_contribution_t *contribution = NULL; + inode_contribution_t *contri = NULL; + int32_t ret = 0; - list_for_each_entry (contribution, &ctx->contribution_head, contri_list) { - if (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; + QUOTA_ALLOC(contri, inode_contribution_t, ret); + if (ret == -1) + goto out; - uuid_copy (contribution->gfid, loc->parent->gfid); + GF_REF_INIT(contri, mq_contri_fini); - LOCK_INIT (&contribution->lock); + contri->contribution = 0; + contri->file_count = 0; + contri->dir_count = 0; + gf_uuid_copy(contri->gfid, inode->gfid); - list_add_tail (&contribution->contri_list, &ctx->contribution_head); + LOCK_INIT(&contri->lock); + INIT_LIST_HEAD(&contri->contri_list); out: - return contribution; + return contri; } - inode_contribution_t * -add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) +mq_get_contribution_node(inode_t *inode, quota_inode_ctx_t *ctx) { - inode_contribution_t *contribution = NULL; + inode_contribution_t *contri = NULL; + inode_contribution_t *temp = NULL; - if ((ctx == NULL) || (loc == NULL)) - return NULL; + if (!inode || !ctx) + goto out; - if (strcmp (loc->path, "/") == 0) - return NULL; + LOCK(&ctx->lock); + { + if (list_empty(&ctx->contribution_head)) + goto unlock; - LOCK (&ctx->lock); + list_for_each_entry(temp, &ctx->contribution_head, contri_list) { - contribution = __add_new_contribution_node (this, ctx, loc); + if (gf_uuid_compare(temp->gfid, inode->gfid) == 0) { + contri = temp; + GF_REF_GET(contri); + break; + } } - UNLOCK (&ctx->lock); + } +unlock: + UNLOCK(&ctx->lock); - return contribution; +out: + return contri; } - -int32_t -dict_set_contribution (xlator_t *this, dict_t *dict, - loc_t *loc) +inode_contribution_t * +__mq_add_new_contribution_node(xlator_t *this, quota_inode_ctx_t *ctx, + 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); - - GET_CONTRI_KEY (contri_key, loc->parent->gfid, ret); - if (ret < 0) { - ret = -1; - goto out; + inode_contribution_t *contribution = NULL; + + if (!loc->parent) { + if (!gf_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 && + gf_uuid_compare(contribution->gfid, loc->parent->gfid) == 0) { + 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; - } + contribution = mq_contri_init(loc->parent); + if (contribution == NULL) + goto out; + + list_add_tail(&contribution->contri_list, &ctx->contribution_head); - ret = 0; out: - return ret; + return contribution; } - -int32_t -quota_inode_ctx_get (inode_t *inode, xlator_t *this, - quota_inode_ctx_t **ctx) +inode_contribution_t * +mq_add_new_contribution_node(xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc) { - 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; - } + inode_contribution_t *contribution = NULL; - mark_ctx = (marker_inode_ctx_t *) (unsigned long)ctx_int; - if (mark_ctx->quota_ctx == NULL) { - ret = -1; - goto out; - } + if ((ctx == NULL) || (loc == NULL)) + return NULL; - *ctx = mark_ctx->quota_ctx; + if (((loc->path) && (strcmp(loc->path, "/") == 0)) || + (!loc->path && gf_uuid_is_null(loc->pargfid))) + return NULL; - ret = 0; + LOCK(&ctx->lock); + { + contribution = __mq_add_new_contribution_node(this, ctx, loc); + if (contribution) + GF_REF_GET(contribution); + } + UNLOCK(&ctx->lock); -out: - return ret; + return contribution; } - -quota_inode_ctx_t * -__quota_inode_ctx_new (inode_t *inode, xlator_t *this) +int32_t +mq_dict_set_contribution(xlator_t *this, dict_t *dict, loc_t *loc, uuid_t gfid, + char *contri_key) { - 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; + int32_t ret = -1; + 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(this, key, gfid, ret); + } else if (loc->parent) { + GET_CONTRI_KEY(this, key, loc->parent->gfid, ret); + } else { + /* nameless lookup, fetch contributions to all parents */ + GET_CONTRI_KEY(this, key, NULL, ret); + } + + if (ret < 0) + goto out; + + ret = dict_set_int64(dict, key, 0); + if (ret < 0) + goto out; + + if (contri_key) + if (snprintf(contri_key, QUOTA_KEY_MAX, "%s", key) >= QUOTA_KEY_MAX) { + ret = -1; + goto out; } - LOCK (&inode->lock); - { - if (mark_ctx->quota_ctx == NULL) { - quota_ctx = quota_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; -} + if (ret < 0) + gf_log_callingfn(this ? this->name : "Marker", GF_LOG_ERROR, + "dict set failed"); - -quota_inode_ctx_t * -quota_inode_ctx_new (inode_t * inode, xlator_t *this) -{ - return __quota_inode_ctx_new (inode, this); + return ret; } -quota_local_t * -quota_local_new () +int32_t +mq_inode_ctx_get(inode_t *inode, xlator_t *this, quota_inode_ctx_t **ctx) { - int32_t ret = -1; - quota_local_t *local = NULL; + 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); - QUOTA_ALLOC (local, quota_local_t, ret); - if (ret < 0) - goto out; + ret = inode_ctx_get(inode, this, &ctx_int); + if (ret < 0) { + ret = -1; + *ctx = NULL; + goto out; + } - local->ref = 1; - local->delta = 0; - local->err = 0; - LOCK_INIT (&local->lock); + mark_ctx = (marker_inode_ctx_t *)(unsigned long)ctx_int; + if (mark_ctx->quota_ctx == NULL) { + ret = -1; + goto out; + } - memset (&local->loc, 0, sizeof (loc_t)); - memset (&local->parent_loc, 0, sizeof (loc_t)); + *ctx = mark_ctx->quota_ctx; - local->ctx = NULL; - local->contri = NULL; + ret = 0; out: - return local; + return ret; } -quota_local_t * -quota_local_ref (quota_local_t *local) +quota_inode_ctx_t * +__mq_inode_ctx_new(inode_t *inode, xlator_t *this) { - LOCK (&local->lock); - { - local->ref ++; + 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; } - UNLOCK (&local->lock); - - return local; -} - - -int32_t -quota_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); + ret = 0; + } +unlock: + UNLOCK(&inode->lock); out: - return 0; + return quota_ctx; } - -inode_contribution_t * -get_contribution_from_loc (xlator_t *this, loc_t *loc) +quota_inode_ctx_t * +mq_inode_ctx_new(inode_t *inode, xlator_t *this) { - int32_t ret = 0; - quota_inode_ctx_t *ctx = NULL; - inode_contribution_t *contribution = NULL; - - ret = quota_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 " - "(ino: %"PRId64", gfid:%s, path:%s)", - loc->inode->ino, - uuid_utoa (loc->inode->gfid), - loc->path); - goto err; - } - - contribution = get_contribution_node (loc->parent, ctx); - if (contribution == NULL) { - gf_log_callingfn (this->name, GF_LOG_WARNING, - "inode (ino:%"PRId64", gfid:%s, path:%s ) has" - " no contribution towards parent (ino:%"PRId64 - ", gfid:%s)", loc->inode->ino, - uuid_utoa (loc->inode->gfid), - loc->path, loc->parent->ino, - uuid_utoa (loc->parent->gfid)); - goto err; - } - -err: - return contribution; + return __mq_inode_ctx_new(inode, this); } |
