summaryrefslogtreecommitdiffstats
path: root/xlators/features/changetimerecorder/src/ctr-helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/changetimerecorder/src/ctr-helper.h')
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.h854
1 files changed, 0 insertions, 854 deletions
diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h
deleted file mode 100644
index 517fbb0b7de..00000000000
--- a/xlators/features/changetimerecorder/src/ctr-helper.h
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- 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.
-*/
-
-#ifndef __CTR_HELPER_H
-#define __CTR_HELPER_H
-
-#include <glusterfs/xlator.h>
-#include "ctr_mem_types.h"
-#include <glusterfs/iatt.h>
-#include <glusterfs/glusterfs.h>
-#include <glusterfs/xlator.h>
-#include <glusterfs/defaults.h>
-#include <glusterfs/logging.h>
-#include <glusterfs/common-utils.h>
-#include <time.h>
-#include <sys/time.h>
-#include <pthread.h>
-
-#include "gfdb_data_store.h"
-#include "ctr-xlator-ctx.h"
-#include "ctr-messages.h"
-
-#define CTR_DEFAULT_HARDLINK_EXP_PERIOD 300 /* Five mins */
-#define CTR_DEFAULT_INODE_EXP_PERIOD 300 /* Five mins */
-
-typedef struct ctr_query_cbk_args {
- int query_fd;
- int count;
-} ctr_query_cbk_args_t;
-
-/*CTR Xlator Private structure*/
-typedef struct gf_ctr_private {
- gf_boolean_t enabled;
- char *ctr_db_path;
- gf_boolean_t ctr_hot_brick;
- gf_boolean_t ctr_record_wind;
- gf_boolean_t ctr_record_unwind;
- gf_boolean_t ctr_record_counter;
- gf_boolean_t ctr_record_metadata_heat;
- gf_boolean_t ctr_link_consistency;
- gfdb_db_type_t gfdb_db_type;
- gfdb_sync_type_t gfdb_sync_type;
- gfdb_conn_node_t *_db_conn;
- uint64_t ctr_lookupheal_link_timeout;
- uint64_t ctr_lookupheal_inode_timeout;
- gf_boolean_t compact_active;
- gf_boolean_t compact_mode_switched;
- pthread_mutex_t compact_lock;
-} gf_ctr_private_t;
-
-/*
- * gf_ctr_local_t is the ctr xlator local data structure that is stored in
- * the call_frame of each FOP.
- *
- * gfdb_db_record: The gf_ctr_local contains a gfdb_db_record object, which is
- * used by the insert_record() api from the libgfdb. The gfdb_db_record object
- * will contain all the inode and hardlink(only for dentry fops: create,
- * mknod,link, unlink, rename).The ctr_local is keep alive till the unwind
- * call and will be release during the unwind. The same gfdb_db_record will
- * used for the unwind insert_record() api, to record unwind in the database.
- *
- * ia_inode_type in gf_ctr_local will tell the type of the inode. This is
- * important for during the unwind path. As we will not have the inode during
- * the unwind path. We would have include this in the gfdb_db_record itself
- * but currently we record only file inode information.
- *
- * is_internal_fop in gf_ctr_local will tell us if this is a internal fop and
- * take special/no action. We don't record change/access times or increement
- * heat counter for internal fops from rebalancer.
- * */
-typedef struct gf_ctr_local {
- gfdb_db_record_t gfdb_db_record;
- ia_type_t ia_inode_type;
- gf_boolean_t is_internal_fop;
- gf_special_pid_t client_pid;
-} gf_ctr_local_t;
-/*
- * Easy access of gfdb_db_record of ctr_local
- * */
-#define CTR_DB_REC(ctr_local) (ctr_local->gfdb_db_record)
-
-/*Clear db record*/
-#define CLEAR_CTR_DB_RECORD(ctr_local) \
- do { \
- ctr_local->gfdb_db_record.gfdb_fop_path = GFDB_FOP_INVALID; \
- memset(&(ctr_local->gfdb_db_record.gfdb_wind_change_time), 0, \
- sizeof(gfdb_time_t)); \
- memset(&(ctr_local->gfdb_db_record.gfdb_unwind_change_time), 0, \
- sizeof(gfdb_time_t)); \
- gf_uuid_clear(ctr_local->gfdb_db_record.gfid); \
- gf_uuid_clear(ctr_local->gfdb_db_record.pargfid); \
- memset(ctr_local->gfdb_db_record.file_name, 0, GF_NAME_MAX + 1); \
- memset(ctr_local->gfdb_db_record.old_file_name, 0, GF_NAME_MAX + 1); \
- ctr_local->gfdb_db_record.gfdb_fop_type = GFDB_FOP_INVALID_OP; \
- ctr_local->ia_inode_type = IA_INVAL; \
- } while (0)
-
-static gf_ctr_local_t *
-init_ctr_local_t(xlator_t *this)
-{
- gf_ctr_local_t *ctr_local = NULL;
-
- GF_ASSERT(this);
-
- ctr_local = mem_get0(this->local_pool);
- if (!ctr_local) {
- gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND,
- "Error while creating ctr local");
- goto out;
- }
-
- CLEAR_CTR_DB_RECORD(ctr_local);
-out:
- return ctr_local;
-}
-
-static void
-free_ctr_local(gf_ctr_local_t *ctr_local)
-{
- if (ctr_local)
- mem_put(ctr_local);
-}
-
-/******************************************************************************
- *
- *
- * Context Carrier Structures
- *
- *
- * ****************************************************************************/
-
-/*
- * Context Carrier structures are used to carry relevant information about
- * inodes and links from the fops calls to the ctr_insert_wind.
- * These structure just have pointers to the original data and donot
- * do a deep copy of any data. This info is deep copied to
- * ctr_local->gfdb_db_record and passed to insert_record() api of libgfdb. This
- * info remains persistent for the unwind in ctr_local->gfdb_db_record
- * and once used will be destroyed.
- *
- * gf_ctr_link_context_t : Context structure for hard links
- * gf_ctr_inode_context_t : Context structure for inodes
- *
- * */
-
-/*Context Carrier Structure for hard links*/
-typedef struct gf_ctr_link_context {
- uuid_t *pargfid;
- const char *basename;
-} gf_ctr_link_context_t;
-
-/*Context Carrier Structure for inodes*/
-typedef struct gf_ctr_inode_context {
- ia_type_t ia_type;
- uuid_t *gfid;
- uuid_t *old_gfid;
- gf_ctr_link_context_t *new_link_cx;
- gf_ctr_link_context_t *old_link_cx;
- gfdb_fop_type_t fop_type;
- gfdb_fop_path_t fop_path;
- gf_boolean_t is_internal_fop;
- /* Indicating metadata fops */
- gf_boolean_t is_metadata_fop;
-} gf_ctr_inode_context_t;
-
-/*******************Util Macros for Context Carrier Structures*****************/
-
-/*Checks if ctr_link_cx is sane!*/
-#define IS_CTR_LINK_CX_SANE(ctr_link_cx) \
- do { \
- if (ctr_link_cx) { \
- if (ctr_link_cx->pargfid) \
- GF_ASSERT(*(ctr_link_cx->pargfid)); \
- GF_ASSERT(ctr_link_cx->basename); \
- }; \
- } while (0)
-
-/*Clear and fill the ctr_link_context with values*/
-#define FILL_CTR_LINK_CX(ctr_link_cx, _pargfid, _basename, label) \
- do { \
- GF_VALIDATE_OR_GOTO("ctr", ctr_link_cx, label); \
- GF_VALIDATE_OR_GOTO("ctr", _pargfid, label); \
- GF_VALIDATE_OR_GOTO("ctr", _basename, label); \
- memset(ctr_link_cx, 0, sizeof(*ctr_link_cx)); \
- ctr_link_cx->pargfid = &_pargfid; \
- ctr_link_cx->basename = _basename; \
- } while (0)
-
-#define NEW_LINK_CX(ctr_inode_cx) ctr_inode_cx->new_link_cx
-
-#define OLD_LINK_CX(ctr_inode_cx) ctr_inode_cx->old_link_cx
-
-/*Checks if ctr_inode_cx is sane!*/
-#define IS_CTR_INODE_CX_SANE(ctr_inode_cx) \
- do { \
- GF_ASSERT(ctr_inode_cx); \
- GF_ASSERT(ctr_inode_cx->gfid); \
- GF_ASSERT(*(ctr_inode_cx->gfid)); \
- GF_ASSERT(ctr_inode_cx->fop_type != GFDB_FOP_INVALID_OP); \
- GF_ASSERT(ctr_inode_cx->fop_path != GFDB_FOP_INVALID); \
- IS_CTR_LINK_CX_SANE(NEW_LINK_CX(ctr_inode_cx)); \
- IS_CTR_LINK_CX_SANE(OLD_LINK_CX(ctr_inode_cx)); \
- } while (0)
-
-/*Clear and fill the ctr_inode_context with values*/
-#define FILL_CTR_INODE_CONTEXT(ctr_inode_cx, _ia_type, _gfid, _new_link_cx, \
- _old_link_cx, _fop_type, _fop_path) \
- do { \
- GF_ASSERT(ctr_inode_cx); \
- GF_ASSERT(_gfid); \
- GF_ASSERT(_fop_type != GFDB_FOP_INVALID_OP); \
- GF_ASSERT(_fop_path != GFDB_FOP_INVALID); \
- memset(ctr_inode_cx, 0, sizeof(*ctr_inode_cx)); \
- ctr_inode_cx->ia_type = _ia_type; \
- ctr_inode_cx->gfid = &_gfid; \
- IS_CTR_LINK_CX_SANE(NEW_LINK_CX(ctr_inode_cx)); \
- if (_new_link_cx) \
- NEW_LINK_CX(ctr_inode_cx) = _new_link_cx; \
- IS_CTR_LINK_CX_SANE(OLD_LINK_CX(ctr_inode_cx)); \
- if (_old_link_cx) \
- OLD_LINK_CX(ctr_inode_cx) = _old_link_cx; \
- ctr_inode_cx->fop_type = _fop_type; \
- ctr_inode_cx->fop_path = _fop_path; \
- } while (0)
-
-/******************************************************************************
- *
- * Util functions or macros used by
- * insert wind and insert unwind
- *
- * ****************************************************************************/
-/* Free ctr frame local */
-static inline void
-ctr_free_frame_local(call_frame_t *frame)
-{
- if (frame) {
- free_ctr_local((gf_ctr_local_t *)frame->local);
- frame->local = NULL;
- }
-}
-
-/* Setting GF_REQUEST_LINK_COUNT_XDATA in dict
- * that has to be sent to POSIX Xlator to send
- * link count in unwind path.
- * return 0 for success with not creation of dict
- * return 1 for success with creation of dict
- * return -1 for failure.
- * */
-static inline int
-set_posix_link_request(xlator_t *this, dict_t **xdata)
-{
- int ret = -1;
- gf_boolean_t is_created = _gf_false;
-
- GF_VALIDATE_OR_GOTO("ctr", this, out);
- GF_VALIDATE_OR_GOTO(this->name, xdata, out);
-
- /*create xdata if NULL*/
- if (!*xdata) {
- *xdata = dict_new();
- is_created = _gf_true;
- ret = 1;
- } else {
- ret = 0;
- }
-
- if (!*xdata) {
- gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_XDATA_NULL,
- "xdata is NULL :Cannot send "
- "GF_REQUEST_LINK_COUNT_XDATA to posix");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_int32(*xdata, GF_REQUEST_LINK_COUNT_XDATA, 1);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED,
- "Failed setting GF_REQUEST_LINK_COUNT_XDATA");
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- if (ret == -1) {
- if (*xdata && is_created) {
- dict_unref(*xdata);
- }
- }
- return ret;
-}
-
-/*
- * If a bitrot fop
- * */
-#define BITROT_FOP(frame) \
- (frame->root->pid == GF_CLIENT_PID_BITD || \
- frame->root->pid == GF_CLIENT_PID_SCRUB)
-
-/*
- * If a rebalancer fop
- * */
-#define REBALANCE_FOP(frame) (frame->root->pid == GF_CLIENT_PID_DEFRAG)
-
-/*
- * If its a tiering rebalancer fop
- * */
-#define TIER_REBALANCE_FOP(frame) \
- (frame->root->pid == GF_CLIENT_PID_TIER_DEFRAG)
-
-/*
- * If its a AFR SELF HEAL
- * */
-#define AFR_SELF_HEAL_FOP(frame) (frame->root->pid == GF_CLIENT_PID_SELF_HEALD)
-
-/*
- * if a rebalancer fop goto
- * */
-#define CTR_IF_REBALANCE_FOP_THEN_GOTO(frame, label) \
- do { \
- if (REBALANCE_FOP(frame)) \
- goto label; \
- } while (0)
-
-/*
- * Internal fop
- *
- * */
-static inline gf_boolean_t
-is_internal_fop(call_frame_t *frame, dict_t *xdata)
-{
- gf_boolean_t ret = _gf_false;
-
- GF_ASSERT(frame);
- GF_ASSERT(frame->root);
-
- if (AFR_SELF_HEAL_FOP(frame)) {
- ret = _gf_true;
- }
- if (BITROT_FOP(frame)) {
- ret = _gf_true;
- }
- if (REBALANCE_FOP(frame) || TIER_REBALANCE_FOP(frame)) {
- ret = _gf_true;
- if (xdata && dict_get(xdata, CTR_ATTACH_TIER_LOOKUP)) {
- ret = _gf_false;
- }
- }
- if (xdata && dict_get(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
- ret = _gf_true;
- }
-
- return ret;
-}
-
-#define CTR_IF_INTERNAL_FOP_THEN_GOTO(frame, dict, label) \
- do { \
- if (is_internal_fop(frame, dict)) \
- goto label; \
- } while (0)
-
-/* if fop has failed exit */
-#define CTR_IF_FOP_FAILED_THEN_GOTO(this, op_ret, op_errno, label) \
- do { \
- if (op_ret == -1) { \
- gf_msg_trace(this->name, 0, "Failed fop with %s", \
- strerror(op_errno)); \
- goto label; \
- }; \
- } while (0)
-
-/*
- * IS CTR Xlator is disabled then goto to label
- * */
-#define CTR_IS_DISABLED_THEN_GOTO(this, label) \
- do { \
- gf_ctr_private_t *_priv = NULL; \
- GF_ASSERT(this); \
- GF_ASSERT(this->private); \
- _priv = this->private; \
- if (!_priv->_db_conn) \
- goto label; \
- } while (0)
-
-/*
- * IS CTR record metadata heat is disabled then goto to label
- * */
-#define CTR_RECORD_METADATA_HEAT_IS_DISABLED_THEN_GOTO(this, label) \
- do { \
- gf_ctr_private_t *_priv = NULL; \
- GF_ASSERT(this); \
- GF_ASSERT(this->private); \
- _priv = this->private; \
- if (!_priv->ctr_record_metadata_heat) \
- goto label; \
- } while (0)
-
-int
-fill_db_record_for_unwind(xlator_t *this, gf_ctr_local_t *ctr_local,
- gfdb_fop_type_t fop_type, gfdb_fop_path_t fop_path);
-
-int
-fill_db_record_for_wind(xlator_t *this, gf_ctr_local_t *ctr_local,
- gf_ctr_inode_context_t *ctr_inode_cx);
-
-/*******************************************************************************
- * CTR INSERT WIND
- * *****************************************************************************
- * Function used to insert/update record into the database during a wind fop
- * This function creates ctr_local structure into the frame of the fop
- * call.
- * ****************************************************************************/
-
-static inline int
-ctr_insert_wind(call_frame_t *frame, xlator_t *this,
- gf_ctr_inode_context_t *ctr_inode_cx)
-{
- int ret = -1;
- gf_ctr_private_t *_priv = NULL;
- gf_ctr_local_t *ctr_local = NULL;
-
- GF_ASSERT(frame);
- GF_ASSERT(frame->root);
- GF_ASSERT(this);
- IS_CTR_INODE_CX_SANE(ctr_inode_cx);
-
- _priv = this->private;
- GF_ASSERT(_priv);
-
- GF_ASSERT(_priv->_db_conn);
-
- /*If record_wind option of CTR is on record wind for
- * regular files only*/
- if (_priv->ctr_record_wind && ctr_inode_cx->ia_type != IA_IFDIR) {
- frame->local = init_ctr_local_t(this);
- if (!frame->local) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND,
- "WIND: Error while creating ctr local");
- goto out;
- };
- ctr_local = frame->local;
- ctr_local->client_pid = frame->root->pid;
- ctr_local->is_internal_fop = ctr_inode_cx->is_internal_fop;
-
- /* Decide whether to record counters or not */
- CTR_DB_REC(ctr_local).do_record_counters = _gf_false;
- /* If record counter is enabled */
- if (_priv->ctr_record_counter) {
- /* If not a internal fop */
- if (!(ctr_local->is_internal_fop)) {
- /* If its a metadata fop AND
- * record metadata heat
- * OR
- * its NOT a metadata fop */
- if ((ctr_inode_cx->is_metadata_fop &&
- _priv->ctr_record_metadata_heat) ||
- (!ctr_inode_cx->is_metadata_fop)) {
- CTR_DB_REC(ctr_local).do_record_counters = _gf_true;
- }
- }
- }
-
- /* Decide whether to record times or not
- * For non internal FOPS record times as usual*/
- CTR_DB_REC(ctr_local).do_record_times = _gf_false;
- if (!ctr_local->is_internal_fop) {
- /* If its a metadata fop AND
- * record metadata heat
- * OR
- * its NOT a metadata fop */
- if ((ctr_inode_cx->is_metadata_fop &&
- _priv->ctr_record_metadata_heat) ||
- (!ctr_inode_cx->is_metadata_fop)) {
- CTR_DB_REC(ctr_local).do_record_times =
- (_priv->ctr_record_wind || _priv->ctr_record_unwind);
- }
- }
- /* when its a internal FOPS*/
- else {
- /* Record times only for create
- * i.e when the inode is created */
- CTR_DB_REC(ctr_local).do_record_times = (isdentrycreatefop(
- ctr_inode_cx->fop_type))
- ? _gf_true
- : _gf_false;
- }
-
- /*Fill the db record for insertion*/
- ret = fill_db_record_for_wind(this, ctr_local, ctr_inode_cx);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_FILL_CTR_LOCAL_ERROR_WIND,
- "WIND: Error filling ctr local");
- goto out;
- }
-
- /*Insert the db record*/
- ret = insert_record(_priv->_db_conn, &ctr_local->gfdb_db_record);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_INSERT_RECORD_WIND_FAILED,
- "WIND: Inserting of record failed!");
- goto out;
- }
- }
- ret = 0;
-out:
-
- if (ret) {
- free_ctr_local(ctr_local);
- frame->local = NULL;
- }
-
- return ret;
-}
-
-/*******************************************************************************
- * CTR INSERT UNWIND
- * *****************************************************************************
- * Function used to insert/update record into the database during a unwind fop
- * This function destroys ctr_local structure into the frame of the fop
- * call at the end.
- * ****************************************************************************/
-static inline int
-ctr_insert_unwind(call_frame_t *frame, xlator_t *this, gfdb_fop_type_t fop_type,
- gfdb_fop_path_t fop_path)
-{
- int ret = -1;
- gf_ctr_private_t *_priv = NULL;
- gf_ctr_local_t *ctr_local = NULL;
-
- GF_ASSERT(frame);
- GF_ASSERT(this);
-
- _priv = this->private;
- GF_ASSERT(_priv);
-
- GF_ASSERT(_priv->_db_conn);
-
- ctr_local = frame->local;
-
- if (ctr_local && (_priv->ctr_record_unwind || isdentryfop(fop_type)) &&
- (ctr_local->ia_inode_type != IA_IFDIR)) {
- CTR_DB_REC(ctr_local).do_record_uwind_time = _priv->ctr_record_unwind;
-
- ret = fill_db_record_for_unwind(this, ctr_local, fop_type, fop_path);
- if (ret == -1) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND,
- "UNWIND: Error filling ctr local");
- goto out;
- }
-
- ret = insert_record(_priv->_db_conn, &ctr_local->gfdb_db_record);
- if (ret == -1) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND,
- "UNWIND: Error filling ctr local");
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-/******************************************************************************
- * Delete file/flink record/s from db
- * ****************************************************************************/
-static inline int
-ctr_delete_hard_link_from_db(xlator_t *this, uuid_t gfid, uuid_t pargfid,
- char *basename, gfdb_fop_type_t fop_type,
- gfdb_fop_path_t fop_path)
-{
- int ret = -1;
- gfdb_db_record_t gfdb_db_record;
- gf_ctr_private_t *_priv = NULL;
-
- _priv = this->private;
- GF_VALIDATE_OR_GOTO(this->name, _priv, out);
- GF_VALIDATE_OR_GOTO(this->name, (!gf_uuid_is_null(gfid)), out);
- GF_VALIDATE_OR_GOTO(this->name, (!gf_uuid_is_null(pargfid)), out);
- GF_VALIDATE_OR_GOTO(this->name, (fop_type == GFDB_FOP_DENTRY_WRITE), out);
- GF_VALIDATE_OR_GOTO(
- this->name, (fop_path == GFDB_FOP_UNDEL || GFDB_FOP_UNDEL_ALL), out);
-
- /* Set gfdb_db_record to 0 */
- memset(&gfdb_db_record, 0, sizeof(gfdb_db_record));
-
- /* Copy basename */
- if (snprintf(gfdb_db_record.file_name, GF_NAME_MAX, "%s", basename) >=
- GF_NAME_MAX)
- goto out;
-
- /* Copy gfid into db record */
- gf_uuid_copy(gfdb_db_record.gfid, gfid);
-
- /* Copy pargid into db record */
- gf_uuid_copy(gfdb_db_record.pargfid, pargfid);
-
- gfdb_db_record.gfdb_fop_path = fop_path;
- gfdb_db_record.gfdb_fop_type = fop_type;
-
- /*send delete request to db*/
- ret = insert_record(_priv->_db_conn, &gfdb_db_record);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_INSERT_RECORD_WIND_FAILED,
- "Failed to delete record. %s", basename);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/******************************* Hard link function ***************************/
-
-static inline gf_boolean_t
-__is_inode_expired(ctr_xlator_ctx_t *ctr_xlator_ctx, gf_ctr_private_t *_priv,
- gfdb_time_t *current_time)
-{
- gf_boolean_t ret = _gf_false;
- uint64_t time_diff = 0;
-
- GF_ASSERT(ctr_xlator_ctx);
- GF_ASSERT(_priv);
- GF_ASSERT(current_time);
-
- time_diff = current_time->tv_sec - ctr_xlator_ctx->inode_heal_period;
-
- ret = (time_diff >= _priv->ctr_lookupheal_inode_timeout) ? _gf_true
- : _gf_false;
- return ret;
-}
-
-static inline gf_boolean_t
-__is_hardlink_expired(ctr_hard_link_t *ctr_hard_link, gf_ctr_private_t *_priv,
- gfdb_time_t *current_time)
-{
- gf_boolean_t ret = _gf_false;
- uint64_t time_diff = 0;
-
- GF_ASSERT(ctr_hard_link);
- GF_ASSERT(_priv);
- GF_ASSERT(current_time);
-
- time_diff = current_time->tv_sec - ctr_hard_link->hardlink_heal_period;
-
- ret = ret || (time_diff >= _priv->ctr_lookupheal_link_timeout) ? _gf_true
- : _gf_false;
-
- return ret;
-}
-
-/* Return values of heal*/
-typedef enum ctr_heal_ret_val {
- CTR_CTX_ERROR = -1,
- /* No healing required */
- CTR_TRY_NO_HEAL = 0,
- /* Try healing hard link */
- CTR_TRY_HARDLINK_HEAL = 1,
- /* Try healing inode */
- CTR_TRY_INODE_HEAL = 2,
-} ctr_heal_ret_val_t;
-
-/**
- * @brief Function to add hard link to the inode context variable.
- * The inode context maintainences a in-memory list. This is used
- * smart healing of database.
- * @param frame of the FOP
- * @param this is the Xlator instant
- * @param inode
- * @return Return ctr_heal_ret_val_t
- */
-
-static inline ctr_heal_ret_val_t
-add_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode)
-{
- ctr_heal_ret_val_t ret_val = CTR_TRY_NO_HEAL;
- int ret = -1;
- gf_ctr_local_t *ctr_local = NULL;
- ctr_xlator_ctx_t *ctr_xlator_ctx = NULL;
- ctr_hard_link_t *ctr_hard_link = NULL;
- gf_ctr_private_t *_priv = NULL;
- gfdb_time_t current_time = {0};
-
- GF_ASSERT(frame);
- GF_ASSERT(this);
- GF_ASSERT(inode);
- GF_ASSERT(this->private);
-
- _priv = this->private;
-
- ctr_local = frame->local;
- if (!ctr_local) {
- goto out;
- }
-
- ctr_xlator_ctx = init_ctr_xlator_ctx(this, inode);
- if (!ctr_xlator_ctx) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED,
- "Failed accessing ctr inode context");
- goto out;
- }
-
- LOCK(&ctr_xlator_ctx->lock);
-
- /* Check if the hard link already exists
- * in the ctr inode context*/
- ctr_hard_link = ctr_search_hard_link_ctx(this, ctr_xlator_ctx,
- CTR_DB_REC(ctr_local).pargfid,
- CTR_DB_REC(ctr_local).file_name);
- /* if there then ignore */
- if (ctr_hard_link) {
- ret = gettimeofday(&current_time, NULL);
- if (ret == -1) {
- gf_log(this->name, GF_LOG_ERROR, "Failed to get current time");
- ret_val = CTR_CTX_ERROR;
- goto unlock;
- }
-
- if (__is_hardlink_expired(ctr_hard_link, _priv, &current_time)) {
- ctr_hard_link->hardlink_heal_period = current_time.tv_sec;
- ret_val = ret_val | CTR_TRY_HARDLINK_HEAL;
- }
-
- if (__is_inode_expired(ctr_xlator_ctx, _priv, &current_time)) {
- ctr_xlator_ctx->inode_heal_period = current_time.tv_sec;
- ret_val = ret_val | CTR_TRY_INODE_HEAL;
- }
-
- goto unlock;
- }
-
- /* Add the hard link to the list*/
- ret = ctr_add_hard_link(this, ctr_xlator_ctx, CTR_DB_REC(ctr_local).pargfid,
- CTR_DB_REC(ctr_local).file_name);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_ADD_HARDLINK_TO_CTR_INODE_CONTEXT_FAILED,
- "Failed to add hardlink to the ctr inode context");
- ret_val = CTR_CTX_ERROR;
- goto unlock;
- }
-
- ret_val = CTR_TRY_NO_HEAL;
-unlock:
- UNLOCK(&ctr_xlator_ctx->lock);
-out:
- return ret_val;
-}
-
-static inline int
-delete_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- ctr_xlator_ctx_t *ctr_xlator_ctx = NULL;
- gf_ctr_local_t *ctr_local = NULL;
-
- GF_ASSERT(frame);
- GF_ASSERT(this);
- GF_ASSERT(inode);
-
- ctr_local = frame->local;
- if (!ctr_local) {
- goto out;
- }
-
- ctr_xlator_ctx = get_ctr_xlator_ctx(this, inode);
- if (!ctr_xlator_ctx) {
- /* Since there is no ctr inode context so nothing more to do */
- ret = 0;
- goto out;
- }
-
- ret = ctr_delete_hard_link(this, ctr_xlator_ctx,
- CTR_DB_REC(ctr_local).pargfid,
- CTR_DB_REC(ctr_local).file_name);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_DELETE_HARDLINK_FAILED,
- "Failed to delete hard link");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static inline int
-update_hard_link_ctx(call_frame_t *frame, xlator_t *this, inode_t *inode)
-{
- int ret = -1;
- ctr_xlator_ctx_t *ctr_xlator_ctx = NULL;
- gf_ctr_local_t *ctr_local = NULL;
-
- GF_ASSERT(frame);
- GF_ASSERT(this);
- GF_ASSERT(inode);
-
- ctr_local = frame->local;
- if (!ctr_local) {
- goto out;
- }
-
- ctr_xlator_ctx = init_ctr_xlator_ctx(this, inode);
- if (!ctr_xlator_ctx) {
- gf_msg(this->name, GF_LOG_ERROR, 0,
- CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED,
- "Failed accessing ctr inode context");
- goto out;
- }
-
- ret = ctr_update_hard_link(
- this, ctr_xlator_ctx, CTR_DB_REC(ctr_local).pargfid,
- CTR_DB_REC(ctr_local).file_name, CTR_DB_REC(ctr_local).old_pargfid,
- CTR_DB_REC(ctr_local).old_file_name);
- if (ret) {
- gf_msg(this->name, GF_LOG_ERROR, 0, CTR_MSG_DELETE_HARDLINK_FAILED,
- "Failed to delete hard link");
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-/******************************************************************************
- *
- * CTR xlator init related functions
- *
- *
- * ****************************************************************************/
-int
-extract_db_params(xlator_t *this, dict_t *params_dict, gfdb_db_type_t db_type);
-
-int
-extract_ctr_options(xlator_t *this, gf_ctr_private_t *_priv);
-
-#endif