diff options
Diffstat (limited to 'xlators/features/changetimerecorder/src/ctr-xlator-ctx.c')
-rw-r--r-- | xlators/features/changetimerecorder/src/ctr-xlator-ctx.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c new file mode 100644 index 00000000000..927c8542c4e --- /dev/null +++ b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c @@ -0,0 +1,370 @@ +/* + Copyright (c) 2015 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. +*/ + +#include "ctr-xlator-ctx.h" + +#define IS_THE_ONLY_HARDLINK(ctr_hard_link)\ + (ctr_hard_link->list.next == ctr_hard_link->list.prev) + + +static inline void +fini_ctr_hard_link (ctr_hard_link_t **ctr_hard_link) { + + GF_ASSERT (ctr_hard_link); + + if (*ctr_hard_link) + return; + GF_FREE ((*ctr_hard_link)->base_name); + GF_FREE (*ctr_hard_link); + *ctr_hard_link = NULL; +} + + +/* Please lock the ctr_xlator_ctx before using this function */ +ctr_hard_link_t * +ctr_search_hard_link_ctx (xlator_t *this, + ctr_xlator_ctx_t *ctr_xlator_ctx, + uuid_t pgfid, + const char *base_name) +{ + ctr_hard_link_t *_hard_link = NULL; + ctr_hard_link_t *searched_hardlink = NULL; + + GF_ASSERT (this); + GF_ASSERT (ctr_xlator_ctx); + + if (pgfid == NULL || base_name == NULL) + goto out; + + /*linear search*/ + list_for_each_entry (_hard_link, &ctr_xlator_ctx->hardlink_list, list) { + if (gf_uuid_compare (_hard_link->pgfid, pgfid) == 0 + && _hard_link->base_name + && strcmp(_hard_link->base_name, base_name) == 0) { + searched_hardlink = _hard_link; + break; + } + } + +out: + return searched_hardlink; +} + + + + +/* Please lock the ctr_xlator_ctx before using this function */ +int +ctr_add_hard_link (xlator_t *this, + ctr_xlator_ctx_t *ctr_xlator_ctx, + uuid_t pgfid, + const char *base_name) +{ + int ret = -1; + ctr_hard_link_t *ctr_hard_link = NULL; + + GF_ASSERT (this); + GF_ASSERT (ctr_xlator_ctx); + + if (pgfid == NULL || base_name == NULL) + goto out; + + ctr_hard_link = GF_CALLOC (1, sizeof (*ctr_hard_link), + gf_ctr_mt_hard_link_t); + if (!ctr_hard_link) { + gf_log (this->name, GF_LOG_ERROR, "Failed allocating " + "ctr_hard_link"); + goto out; + } + + /*Initialize the ctr_hard_link object and + * Assign the values : parent GFID and basename*/ + INIT_LIST_HEAD (&ctr_hard_link->list); + gf_uuid_copy (ctr_hard_link->pgfid, pgfid); + ret = gf_asprintf(&ctr_hard_link->base_name, "%s", base_name); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed copying basename" + "to ctr_hard_link"); + goto error; + } + + /*Add the hard link to the list*/ + list_add_tail (&ctr_hard_link->list, + &ctr_xlator_ctx->hardlink_list); + + /*aal izz well!*/ + ret = 0; + goto out; +error: + GF_FREE (ctr_hard_link); +out: + return ret; +} + +static void +__delete_hard_link_from_list (ctr_hard_link_t **ctr_hard_link) +{ + GF_ASSERT (ctr_hard_link); + GF_ASSERT (*ctr_hard_link); + + /*Remove hard link from list*/ + list_del(&(*ctr_hard_link)->list); + fini_ctr_hard_link (ctr_hard_link); +} + + +int +ctr_delete_hard_link (xlator_t *this, + ctr_xlator_ctx_t *ctr_xlator_ctx, + uuid_t pgfid, + const char *base_name) +{ + int ret = -1; + ctr_hard_link_t *ctr_hard_link = NULL; + + GF_ASSERT (this); + GF_ASSERT (ctr_xlator_ctx); + + + LOCK (&ctr_xlator_ctx->lock); + + /*Check if the hard link is present */ + ctr_hard_link = ctr_search_hard_link_ctx (this, ctr_xlator_ctx, + pgfid, base_name); + if (!ctr_hard_link) { + gf_log (this->name, GF_LOG_ERROR, "Hard link doesnt exist" + " in the list"); + goto out; + } + + __delete_hard_link_from_list (&ctr_hard_link); + ctr_hard_link = NULL; + + ret = 0; +out: + UNLOCK (&ctr_xlator_ctx->lock); + + return ret; +} + + + + +int +ctr_update_hard_link (xlator_t *this, + ctr_xlator_ctx_t *ctr_xlator_ctx, + uuid_t pgfid, + const char *base_name, + uuid_t old_pgfid, + const char *old_base_name) +{ + int ret = -1; + ctr_hard_link_t *ctr_hard_link = NULL; + + GF_ASSERT (this); + GF_ASSERT (ctr_xlator_ctx); + + + LOCK (&ctr_xlator_ctx->lock); + + /*Check if the hard link is present */ + ctr_hard_link = ctr_search_hard_link_ctx (this, ctr_xlator_ctx, + old_pgfid, old_base_name); + if (!ctr_hard_link) { + gf_log (this->name, GF_LOG_TRACE, "Hard link doesnt exist" + " in the list"); + /* Since the hard link is not present in the list + * we add it to the list */ + ret = ctr_add_hard_link (this, ctr_xlator_ctx, + pgfid, base_name); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed adding" + "hard link to the list"); + goto out; + } + ret = 0; + goto out; + } + + /* update the hard link */ + gf_uuid_copy (ctr_hard_link->pgfid, pgfid); + GF_FREE (&ctr_hard_link->base_name); + ret = gf_asprintf(&ctr_hard_link->base_name, "%s", base_name); + if (ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed copying basename" + "to ctr_hard_link"); + /* delete the corrupted entry */ + __delete_hard_link_from_list (&ctr_hard_link); + ctr_hard_link = NULL; + goto out; + } + + ret = 0; + +out: + UNLOCK (&ctr_xlator_ctx->lock); + + return ret; +} + + + + +/* Delete all hardlinks */ +static inline int +ctr_delete_all_hard_link (xlator_t *this, + ctr_xlator_ctx_t *ctr_xlator_ctx) +{ + int ret = -1; + ctr_hard_link_t *ctr_hard_link = NULL; + ctr_hard_link_t *tmp = NULL; + + GF_ASSERT (ctr_xlator_ctx); + + LOCK (&ctr_xlator_ctx->lock); + + list_for_each_entry_safe(ctr_hard_link, tmp, + &ctr_xlator_ctx->hardlink_list, list) + { + /*Remove hard link from list*/ + __delete_hard_link_from_list (&ctr_hard_link); + ctr_hard_link = NULL; + + } + + + UNLOCK (&ctr_xlator_ctx->lock); + + ret = 0; + + return ret; +} + + +/* Please lock the inode before using this function */ +static inline ctr_xlator_ctx_t * +__get_ctr_xlator_ctx (xlator_t *this, + inode_t *inode) +{ + int ret = 0; + uint64_t _addr = 0; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + + GF_ASSERT (this); + GF_ASSERT (inode); + + ret = __inode_ctx_get (inode, this, &_addr); + if (ret < 0) + _addr = 0; + if (_addr != 0) { + ctr_xlator_ctx = (ctr_xlator_ctx_t *) (long)_addr; + } + + return ctr_xlator_ctx; +} + + +ctr_xlator_ctx_t * +init_ctr_xlator_ctx (xlator_t *this, + inode_t *inode) +{ + int ret = -1; + uint64_t _addr = 0; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + + GF_ASSERT (this); + GF_ASSERT (inode); + + LOCK (&inode->lock); + { + ctr_xlator_ctx = __get_ctr_xlator_ctx (this, inode); + if (ctr_xlator_ctx) { + ret = 0; + goto out; + } + ctr_xlator_ctx = GF_CALLOC (1, sizeof (*ctr_xlator_ctx), + gf_ctr_mt_xlator_ctx); + if (!ctr_xlator_ctx) + goto out; + + ret = LOCK_INIT (&ctr_xlator_ctx->lock); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed init lock %s", strerror(ret)); + goto out; + } + _addr = (uint64_t) ctr_xlator_ctx; + + ret = __inode_ctx_set (inode, this, &_addr); + if (ret) { + goto out; + } + + INIT_LIST_HEAD (&ctr_xlator_ctx->hardlink_list); + + } + ret = 0; +out: + if (ret) { + GF_FREE (ctr_xlator_ctx); + ctr_xlator_ctx = NULL; + } + + UNLOCK (&inode->lock); + + return ctr_xlator_ctx; +} + + + + +void +fini_ctr_xlator_ctx (xlator_t *this, + inode_t *inode) +{ + int ret = 0; + uint64_t _addr = 0; + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + + + inode_ctx_del (inode, this, &_addr); + if (!_addr) + return; + + ctr_xlator_ctx = (ctr_xlator_ctx_t *) (long) _addr; + + ret = ctr_delete_all_hard_link (this, ctr_xlator_ctx); + if (ret) { + gf_log (this->name, GF_LOG_WARNING , "Failed deleting all hard" + " links from inode context"); + } + + LOCK_DESTROY (&ctr_xlator_ctx->lock); + + GF_FREE (ctr_xlator_ctx); + +} + + + + +ctr_xlator_ctx_t * +get_ctr_xlator_ctx (xlator_t *this, + inode_t *inode) +{ + ctr_xlator_ctx_t *ctr_xlator_ctx = NULL; + + LOCK (&inode->lock); + ctr_xlator_ctx = __get_ctr_xlator_ctx (this, inode); + UNLOCK (&inode->lock); + + return ctr_xlator_ctx; +} + |