summaryrefslogtreecommitdiffstats
path: root/xlators/features/changetimerecorder
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/changetimerecorder')
-rw-r--r--xlators/features/changetimerecorder/src/changetimerecorder.c121
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.c10
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.h108
-rw-r--r--xlators/features/changetimerecorder/src/ctr-xlator-ctx.c35
-rw-r--r--xlators/features/changetimerecorder/src/ctr-xlator-ctx.h4
5 files changed, 256 insertions, 22 deletions
diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c
index 1fdeb7c76ca..703df496e95 100644
--- a/xlators/features/changetimerecorder/src/changetimerecorder.c
+++ b/xlators/features/changetimerecorder/src/changetimerecorder.c
@@ -114,7 +114,7 @@ ctr_lookup_wind(call_frame_t *frame,
/*Don't record time at all*/
CTR_DB_REC(ctr_local).do_record_times = _gf_false;
- /*Copy gfid into db record*/
+ /* Copy gfid into db record*/
gf_uuid_copy (CTR_DB_REC(ctr_local).gfid,
*(ctr_inode_cx->gfid));
@@ -131,6 +131,12 @@ ctr_lookup_wind(call_frame_t *frame,
strcpy (CTR_DB_REC(ctr_local).file_path,
NEW_LINK_CX(ctr_inode_cx)->basepath);
+ /* Since we are in lookup we can ignore errors while
+ * Inserting in the DB, because there may be many
+ * to write to the DB attempts for healing.
+ * We dont want to log all failed attempts and
+ * bloat the log*/
+ ctr_local->gfdb_db_record.ignore_errors = _gf_true;
}
ret = 0;
@@ -171,8 +177,11 @@ ctr_lookup_unwind (call_frame_t *frame,
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,
+ gf_msg (this->name,
+ _gfdb_log_level (GF_LOG_ERROR,
+ ctr_local->
+ gfdb_db_record.ignore_errors),
+ 0, CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND,
"UNWIND: Error filling ctr local");
goto out;
}
@@ -198,9 +207,11 @@ ctr_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)
{
- int ret = -1;
- ctr_xlator_ctx_t *ctr_xlator_ctx;
- gf_ctr_local_t *ctr_local = NULL;
+ int ret = -1;
+ ctr_xlator_ctx_t *ctr_xlator_ctx = NULL;
+ gf_ctr_local_t *ctr_local = NULL;
+ ctr_heal_ret_val_t ret_val = CTR_CTX_ERROR;
+ gf_boolean_t _is_heal_needed = _gf_false;
CTR_IS_DISABLED_THEN_GOTO(this, out);
CTR_IF_INTERNAL_FOP_THEN_GOTO (frame, dict, out);
@@ -223,34 +234,70 @@ ctr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
+ /* if the lookup is for dht link donot record*/
+ if (dht_is_linkfile (buf, dict)) {
+ gf_msg_trace (this->name, 0, "Ignoring Lookup "
+ "for dht link file");
+ goto out;
+ }
+
ctr_local = frame->local;
/*Assign the proper inode type*/
ctr_local->ia_inode_type = inode->ia_type;
+ /* Copy gfid directly from inode */
+ gf_uuid_copy (CTR_DB_REC(ctr_local).gfid, inode->gfid);
+
+ /* Checking if gfid and parent gfid is valid */
+ if (gf_uuid_is_null(CTR_DB_REC(ctr_local).gfid) ||
+ gf_uuid_is_null(CTR_DB_REC(ctr_local).pargfid)) {
+ gf_msg_trace (this->name, 0,
+ "Invalid GFID");
+ goto out;
+ }
+
/* if its a first entry
* then mark the ctr_record for create
* A create will attempt a file and a hard link created in the db*/
ctr_xlator_ctx = get_ctr_xlator_ctx (this, inode);
if (!ctr_xlator_ctx) {
+ /* This marks inode heal */
CTR_DB_REC(ctr_local).gfdb_fop_type = GFDB_FOP_CREATE_WRITE;
+ _is_heal_needed = _gf_true;
}
/* Copy the correct gfid from resolved inode */
gf_uuid_copy (CTR_DB_REC(ctr_local).gfid, inode->gfid);
/* Add hard link to the list */
- ret = add_hard_link_ctx (frame, this, inode);
- if (ret < 0) {
- gf_msg_trace (this->name, 0, "Failed adding hard link");
+ ret_val = add_hard_link_ctx (frame, this, inode);
+ if (ret_val == CTR_CTX_ERROR) {
+ gf_msg_trace (this->name, 0,
+ "Failed adding hardlink to list");
goto out;
}
+ /* If inode needs healing then heal the hardlink also */
+ else if (ret_val & CTR_TRY_INODE_HEAL) {
+ /* This marks inode heal */
+ CTR_DB_REC(ctr_local).gfdb_fop_type = GFDB_FOP_CREATE_WRITE;
+ _is_heal_needed = _gf_true;
+ }
+ /* If hardlink needs healing */
+ else if (ret_val & CTR_TRY_HARDLINK_HEAL) {
+ _is_heal_needed = _gf_true;
+ }
- /* Inserts the ctr_db_record populated by ctr_lookup_wind
+ /* If lookup heal needed */
+ if (!_is_heal_needed)
+ goto out;
+
+ /* FINALLY HEAL : Inserts the ctr_db_record populated by ctr_lookup_wind
* in to the db. It also destroys the frame->local
* created by ctr_lookup_wind */
ret = ctr_lookup_unwind(frame, this);
if (ret) {
- gf_msg_trace (this->name, 0, "Failed inserting link wind");
+ gf_msg_trace (this->name, 0,
+ "Failed healing/inserting link");
}
@@ -793,6 +840,7 @@ ctr_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
/*Last link that was deleted*/
else if (remaining_links == 1) {
+
ret = ctr_insert_unwind(frame, this, GFDB_FOP_DENTRY_WRITE,
GFDB_FOP_UNDEL_ALL);
if (ret) {
@@ -819,6 +867,7 @@ ctr_unlink (call_frame_t *frame, xlator_t *this,
gf_ctr_link_context_t ctr_link_cx;
gf_ctr_link_context_t *_link_cx = &ctr_link_cx;
gf_boolean_t is_xdata_created = _gf_false;
+ struct iatt dummy_stat = {0};
GF_ASSERT (frame);
@@ -835,6 +884,12 @@ ctr_unlink (call_frame_t *frame, xlator_t *this,
/*Internal FOP*/
_inode_cx->is_internal_fop = CTR_IS_INTERNAL_FOP(frame, xdata);
+ /* If its a internal FOP and dht link file donot record*/
+ if (_inode_cx->is_internal_fop &&
+ dht_is_linkfile (&dummy_stat, xdata)) {
+ goto out;
+ }
+
/*record into the database*/
ret = ctr_insert_wind(frame, this, _inode_cx);
if (ret) {
@@ -1014,12 +1069,13 @@ ctr_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct iatt *postparent, dict_t *xdata)
{
int ret = -1;
+ ctr_heal_ret_val_t ret_val = CTR_CTX_ERROR;
CTR_IS_DISABLED_THEN_GOTO(this, out);
/* Add hard link to the list */
- ret = add_hard_link_ctx (frame, this, inode);
- if (ret) {
+ ret_val = add_hard_link_ctx (frame, this, inode);
+ if (ret_val == CTR_CTX_ERROR) {
gf_msg_trace (this->name, 0, "Failed adding hard link");
}
@@ -1053,6 +1109,7 @@ ctr_mknod (call_frame_t *frame, xlator_t *this,
uuid_t *ptr_gfid = &gfid;
CTR_IS_DISABLED_THEN_GOTO(this, out);
+ CTR_IF_INTERNAL_FOP_THEN_GOTO (frame, xdata, out);
GF_ASSERT(frame);
GF_ASSERT(frame->root);
@@ -1073,9 +1130,6 @@ ctr_mknod (call_frame_t *frame, xlator_t *this,
*ptr_gfid, _link_cx, NULL,
GFDB_FOP_CREATE_WRITE, GFDB_FOP_WIND);
- /*Internal FOP*/
- _inode_cx->is_internal_fop = CTR_IS_INTERNAL_FOP(frame, xdata);
-
/*record into the database*/
ret = ctr_insert_wind(frame, this, _inode_cx);
if (ret) {
@@ -1140,6 +1194,7 @@ ctr_create (call_frame_t *frame, xlator_t *this,
void *uuid_req = NULL;
uuid_t gfid = {0,};
uuid_t *ptr_gfid = &gfid;
+ struct iatt dummy_stat = {0};
CTR_IS_DISABLED_THEN_GOTO(this, out);
@@ -1167,6 +1222,12 @@ ctr_create (call_frame_t *frame, xlator_t *this,
/*Internal FOP*/
_inode_cx->is_internal_fop = CTR_IS_INTERNAL_FOP(frame, xdata);
+ /* If its a internal FOP and dht link file donot record*/
+ if (_inode_cx->is_internal_fop &&
+ dht_is_linkfile (&dummy_stat, xdata)) {
+ goto out;
+ }
+
/*record into the database*/
ret = ctr_insert_wind(frame, this, &ctr_inode_cx);
if (ret) {
@@ -1222,6 +1283,7 @@ ctr_link (call_frame_t *frame, xlator_t *this,
gf_ctr_inode_context_t *_inode_cx = &ctr_inode_cx;
gf_ctr_link_context_t ctr_link_cx;
gf_ctr_link_context_t *_link_cx = &ctr_link_cx;
+ struct iatt dummy_stat = {0};
CTR_IS_DISABLED_THEN_GOTO(this, out);
@@ -1240,6 +1302,13 @@ ctr_link (call_frame_t *frame, xlator_t *this,
/*Internal FOP*/
_inode_cx->is_internal_fop = CTR_IS_INTERNAL_FOP(frame, xdata);
+ /* If its a internal FOP and dht link file donot record*/
+ if (_inode_cx->is_internal_fop &&
+ dht_is_linkfile (&dummy_stat, xdata)) {
+ goto out;
+ }
+
+
/*record into the database*/
ret = ctr_insert_wind(frame, this, _inode_cx);
if (ret) {
@@ -1334,6 +1403,14 @@ reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("ctr_link_consistency", _priv->ctr_link_consistency,
options, bool, out);
+ GF_OPTION_RECONF ("ctr_inode_heal_expire_period",
+ _priv->ctr_inode_heal_expire_period,
+ options, uint64, out);
+
+ GF_OPTION_RECONF ("ctr_hardlink_heal_expire_period",
+ _priv->ctr_hardlink_heal_expire_period,
+ options, uint64, out);
+
GF_OPTION_RECONF ("record-exit", _priv->ctr_record_unwind, options,
bool, out);
@@ -1385,6 +1462,10 @@ init (xlator_t *this)
_priv->gfdb_sync_type = GFDB_DB_SYNC;
_priv->enabled = _gf_true;
_priv->_db_conn = NULL;
+ _priv->ctr_hardlink_heal_expire_period =
+ CTR_DEFAULT_HARDLINK_EXP_PERIOD;
+ _priv->ctr_inode_heal_expire_period =
+ CTR_DEFAULT_INODE_EXP_PERIOD;
/*Extract ctr xlator options*/
ret_db = extract_ctr_options (this, _priv);
@@ -1549,6 +1630,14 @@ struct volume_options options[] = {
.value = {"on", "off"},
.default_value = "off"
},
+ { .key = {"ctr_hardlink_heal_expire_period"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "300"
+ },
+ { .key = {"ctr_inode_heal_expire_period"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "300"
+ },
{ .key = {"hot-brick"},
.type = GF_OPTION_TYPE_BOOL,
.value = {"on", "off"},
diff --git a/xlators/features/changetimerecorder/src/ctr-helper.c b/xlators/features/changetimerecorder/src/ctr-helper.c
index c4d97695bd0..f5d4c474674 100644
--- a/xlators/features/changetimerecorder/src/ctr-helper.c
+++ b/xlators/features/changetimerecorder/src/ctr-helper.c
@@ -276,6 +276,16 @@ int extract_ctr_options (xlator_t *this, gf_ctr_private_t *_priv) {
GF_OPTION_INIT ("ctr_link_consistency", _priv->ctr_link_consistency,
bool, out);
+ /*Extract ctr_inode_heal_expire_period */
+ GF_OPTION_INIT ("ctr_inode_heal_expire_period",
+ _priv->ctr_inode_heal_expire_period,
+ uint64, out);
+
+ /*Extract ctr_hardlink_heal_expire_period*/
+ GF_OPTION_INIT ("ctr_hardlink_heal_expire_period",
+ _priv->ctr_hardlink_heal_expire_period,
+ uint64, out);
+
/*Extract flag for hot tier brick*/
GF_OPTION_INIT ("hot-brick", _priv->ctr_hot_brick, bool, out);
diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h
index a3df9716eaa..82a0c8bc93c 100644
--- a/xlators/features/changetimerecorder/src/ctr-helper.h
+++ b/xlators/features/changetimerecorder/src/ctr-helper.h
@@ -31,6 +31,9 @@
#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 */
+
/*CTR Xlator Private structure*/
typedef struct gf_ctr_private {
gf_boolean_t enabled;
@@ -43,6 +46,8 @@ typedef struct gf_ctr_private {
gfdb_db_type_t gfdb_db_type;
gfdb_sync_type_t gfdb_sync_type;
gfdb_conn_node_t *_db_conn;
+ uint64_t ctr_hardlink_heal_expire_period;
+ uint64_t ctr_inode_heal_expire_period;
} gf_ctr_private_t;
@@ -472,19 +477,91 @@ out:
/******************************* Hard link function ***************************/
-static inline int
+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_inode_heal_expire_period) ?
+ _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_hardlink_heal_expire_period) ?
+ _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) {
@@ -509,7 +586,29 @@ add_hard_link_ctx (call_frame_t *frame,
CTR_DB_REC(ctr_local).file_name);
/* if there then ignore */
if (ctr_hard_link) {
- ret = 1;
+
+ 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;
}
@@ -521,14 +620,15 @@ add_hard_link_ctx (call_frame_t *frame,
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 = 0;
+ ret_val = CTR_TRY_NO_HEAL;
unlock:
UNLOCK (&ctr_xlator_ctx->lock);
out:
- return ret;
+ return ret_val;
}
static inline int
diff --git a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c
index a91a2bbefc0..b8f6f0301d9 100644
--- a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c
+++ b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.c
@@ -10,6 +10,8 @@
#include "ctr-xlator-ctx.h"
#include "ctr-messages.h"
+#include <time.h>
+#include <sys/time.h>
#define IS_THE_ONLY_HARDLINK(ctr_hard_link)\
(ctr_hard_link->list.next == ctr_hard_link->list.prev)
@@ -63,13 +65,14 @@ out:
/* Please lock the ctr_xlator_ctx before using this function */
int
-ctr_add_hard_link (xlator_t *this,
+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;
+ struct timeval current_time = {0};
GF_ASSERT (this);
GF_ASSERT (ctr_xlator_ctx);
@@ -98,10 +101,19 @@ ctr_add_hard_link (xlator_t *this,
goto error;
}
+ ret = gettimeofday (&current_time, NULL);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get current time");
+ goto error;
+ }
+
/*Add the hard link to the list*/
list_add_tail (&ctr_hard_link->list,
&ctr_xlator_ctx->hardlink_list);
+ ctr_hard_link->hardlink_heal_period = current_time.tv_sec;
+
/*aal izz well!*/
ret = 0;
goto out;
@@ -169,8 +181,9 @@ ctr_update_hard_link (xlator_t *this,
uuid_t old_pgfid,
const char *old_base_name)
{
- int ret = -1;
+ int ret = -1;
ctr_hard_link_t *ctr_hard_link = NULL;
+ struct timeval current_time = {0};
GF_ASSERT (this);
GF_ASSERT (ctr_xlator_ctx);
@@ -212,6 +225,15 @@ ctr_update_hard_link (xlator_t *this,
goto out;
}
+ ret = gettimeofday (&current_time, NULL);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get current time");
+ ctr_hard_link->hardlink_heal_period = 0;
+ } else {
+ ctr_hard_link->hardlink_heal_period = current_time.tv_sec;
+ }
+
ret = 0;
out:
@@ -284,6 +306,7 @@ init_ctr_xlator_ctx (xlator_t *this,
int ret = -1;
uint64_t _addr = 0;
ctr_xlator_ctx_t *ctr_xlator_ctx = NULL;
+ struct timeval current_time = {0};
GF_ASSERT (this);
GF_ASSERT (inode);
@@ -316,6 +339,14 @@ init_ctr_xlator_ctx (xlator_t *this,
INIT_LIST_HEAD (&ctr_xlator_ctx->hardlink_list);
+ ret = gettimeofday (&current_time, NULL);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get current time");
+ goto out;
+ }
+
+ ctr_xlator_ctx->inode_heal_period = current_time.tv_sec;
}
ret = 0;
out:
diff --git a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h
index bc935014fc6..7f1c6cb1712 100644
--- a/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h
+++ b/xlators/features/changetimerecorder/src/ctr-xlator-ctx.h
@@ -25,6 +25,9 @@
typedef struct ctr_hard_link {
uuid_t pgfid;
char *base_name;
+ /* Hardlink expiry : Defines the expiry period after which a
+ * database heal is attempted. */
+ uint64_t hardlink_heal_period;
struct list_head list;
} ctr_hard_link_t;
@@ -32,6 +35,7 @@ typedef struct ctr_xlator_ctx {
/* This represents the looked up hardlinks
* NOTE: This doesn't represent all physical hardlinks of the inode*/
struct list_head hardlink_list;
+ uint64_t inode_heal_period;
gf_lock_t lock;
} ctr_xlator_ctx_t;