diff options
Diffstat (limited to 'xlators/features')
-rw-r--r-- | xlators/features/barrier/src/barrier.c | 2 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-barrier.c | 60 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 7 | ||||
-rw-r--r-- | xlators/features/changelog/src/changelog.c | 36 |
4 files changed, 99 insertions, 6 deletions
diff --git a/xlators/features/barrier/src/barrier.c b/xlators/features/barrier/src/barrier.c index 74973499d56..f2d8d9632ec 100644 --- a/xlators/features/barrier/src/barrier.c +++ b/xlators/features/barrier/src/barrier.c @@ -654,7 +654,7 @@ struct volume_options options[] = { }, { .key = {"barrier-timeout"}, .type = GF_OPTION_TYPE_TIME, - .default_value = "120", + .default_value = BARRIER_TIMEOUT, .description = "After 'timeout' seconds since the time 'barrier' " "option was set to \"on\", acknowledgements to file " "operations are no longer blocked and previously " diff --git a/xlators/features/changelog/src/changelog-barrier.c b/xlators/features/changelog/src/changelog-barrier.c index c20eed85b1c..2c237708cf4 100644 --- a/xlators/features/changelog/src/changelog-barrier.c +++ b/xlators/features/changelog/src/changelog-barrier.c @@ -52,9 +52,42 @@ chlog_barrier_dequeue_all (xlator_t *this, struct list_head *queue) { call_stub_t *stub = NULL; + gf_log (this->name, GF_LOG_INFO, + "Dequeuing all the changelog barriered fops"); + while ((stub = __chlog_barrier_dequeue (this, queue))) call_resume (stub); + gf_log (this->name, GF_LOG_INFO, + "Dequeuing changelog barriered fops is finished"); + return; +} + +/* Function called on changelog barrier timeout */ +void +chlog_barrier_timeout (void *data) +{ + xlator_t *this = NULL; + changelog_priv_t *priv = NULL; + struct list_head queue = {0,}; + + this = data; + THIS = this; + priv = this->private; + + INIT_LIST_HEAD (&queue); + + gf_log (this->name, GF_LOG_ERROR, + "Disabling changelog barrier because of the timeout."); + + LOCK (&priv->lock); + { + __chlog_barrier_disable (this, &queue); + } + UNLOCK (&priv->lock); + + chlog_barrier_dequeue_all (this, &queue); + return; } @@ -63,8 +96,35 @@ void __chlog_barrier_disable (xlator_t *this, struct list_head *queue) { changelog_priv_t *priv = this->private; + int ret = 0; + GF_ASSERT (priv); + + if (priv->timer) { + ret = gf_timer_call_cancel (this->ctx, priv->timer); + priv->timer = NULL; + } list_splice_init (&priv->queue, queue); priv->queue_size = 0; priv->barrier_enabled = _gf_false; } + +/* Enable chagelog barrier enable with timer */ +int +__chlog_barrier_enable (xlator_t *this, changelog_priv_t *priv) +{ + int ret = -1; + + priv->timer = gf_timer_call_after (this->ctx, priv->timeout, + chlog_barrier_timeout, (void *)this); + if (!priv->timer) { + gf_log (this->name, GF_LOG_CRITICAL, + "Couldn't add changelog barrier timeout event."); + goto out; + } + + priv->barrier_enabled = _gf_true; + ret = 0; +out: + return ret; +} diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index 987af190b9c..03108d36f7d 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -280,6 +280,9 @@ struct changelog_priv { gf_boolean_t barrier_enabled; struct list_head queue; uint32_t queue_size; + gf_timer_t *timer; + struct timespec timeout; + }; struct changelog_local { @@ -433,6 +436,8 @@ void __chlog_barrier_enqueue (xlator_t *this, call_stub_t *stub); void __chlog_barrier_disable (xlator_t *this, struct list_head *queue); void chlog_barrier_dequeue_all (xlator_t *this, struct list_head *queue); call_stub_t *__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue); +int __chlog_barrier_enable (xlator_t *this, changelog_priv_t *priv); + /* macros */ @@ -563,6 +568,6 @@ call_stub_t *__chlog_barrier_dequeue (xlator_t *this, struct list_head *queue); goto label; \ } \ } while (0) -/* End: Geo-Rep snapshot dependency changes */ +/* End: Geo-Rep snapshot dependency changes */ #endif /* _CHANGELOG_HELPERS_H */ diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index 0b982148f44..4ed7cc7f0e9 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -1281,6 +1281,16 @@ changelog_assign_encoding (changelog_priv_t *priv, char *enc) } } +static void +changelog_assign_barrier_timeout(changelog_priv_t *priv, uint32_t timeout) +{ + LOCK (&priv->lock); + { + priv->timeout.tv_sec = timeout; + } + UNLOCK (&priv->lock); +} + /* cleanup any helper threads that are running */ static void changelog_cleanup_helper_threads (xlator_t *this, changelog_priv_t *priv) @@ -1444,9 +1454,7 @@ notify (xlator_t *this, int event, void *data, ...) if (event == GF_EVENT_TRANSLATOR_OP) { dict = data; - /*TODO: Also barrier option is persistent. Need to - * decide on the brick crash scenarios. - */ + barrier = dict_get_str_boolean (dict, "barrier", DICT_DEFAULT); switch (barrier) { @@ -1540,9 +1548,14 @@ notify (xlator_t *this, int event, void *data, ...) /* Start changelog barrier */ LOCK (&priv->lock); { - priv->barrier_enabled = _gf_true; + ret = __chlog_barrier_enable (this, priv); } UNLOCK (&priv->lock); + if (ret == -1) { + changelog_barrier_cleanup (this, priv, &queue); + goto out; + } + gf_log(this->name, GF_LOG_DEBUG, "Enabled changelog barrier"); @@ -1786,6 +1799,7 @@ reconfigure (xlator_t *this, dict_t *options) changelog_log_data_t cld = {0,}; char htime_dir[PATH_MAX] = {0,}; struct timeval tv = {0,}; + uint32_t timeout = 0; priv = this->private; if (!priv) @@ -1840,6 +1854,9 @@ reconfigure (xlator_t *this, dict_t *options) priv->rollover_time, options, int32, out); GF_OPTION_RECONF ("fsync-interval", priv->fsync_interval, options, int32, out); + GF_OPTION_RECONF ("changelog-barrier-timeout", + timeout, options, time, out); + changelog_assign_barrier_timeout (priv, timeout); if (active_now || active_earlier) { ret = changelog_fill_rollover_data (&cld, !active_now); @@ -1898,6 +1915,7 @@ init (xlator_t *this) changelog_priv_t *priv = NULL; gf_boolean_t cond_lock_init = _gf_false; char htime_dir[PATH_MAX] = {0,}; + uint32_t timeout = 0; GF_VALIDATE_OR_GOTO ("changelog", this, out); @@ -1977,6 +1995,8 @@ init (xlator_t *this) GF_OPTION_INIT ("rollover-time", priv->rollover_time, int32, out); GF_OPTION_INIT ("fsync-interval", priv->fsync_interval, int32, out); + GF_OPTION_INIT ("changelog-barrier-timeout", timeout, time, out); + priv->timeout.tv_sec = timeout; changelog_encode_change(priv); @@ -2127,6 +2147,14 @@ struct volume_options options[] = { .description = "do not open CHANGELOG file with O_SYNC mode." " instead perform fsync() at specified intervals" }, + { .key = {"changelog-barrier-timeout"}, + .type = GF_OPTION_TYPE_TIME, + .default_value = BARRIER_TIMEOUT, + .description = "After 'timeout' seconds since the time 'barrier' " + "option was set to \"on\", unlink/rmdir/rename " + "operations are no longer blocked and previously " + "blocked fops are allowed to go through" + }, {.key = {NULL} }, }; |