summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c197
1 files changed, 152 insertions, 45 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 54fc1dc1195..208e319b336 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -57,6 +57,8 @@
#include "posix-gfid-path.h"
#include <glusterfs/events.h>
#include "glusterfsd.h"
+#include "glusterfs/syncop.h"
+#include "timer-wheel.h"
#include <sys/types.h>
char *marker_xattrs[] = {"trusted.glusterfs.quota.*",
@@ -1409,81 +1411,181 @@ janitor_walker(const char *fpath, const struct stat *sb, int typeflag,
return 0; /* 0 = FTW_CONTINUE */
}
-static struct posix_fd *
-janitor_get_next_fd(xlator_t *this)
+void
+__posix_janitor_timer_start(xlator_t *this);
+
+static int
+posix_janitor_task_done(int ret, call_frame_t *frame, void *data)
{
+ xlator_t *this = NULL;
struct posix_private *priv = NULL;
- struct posix_fd *pfd = NULL;
- struct timespec timeout;
+ this = data;
+ priv = this->private;
+
+ LOCK(&priv->lock);
+ {
+ __posix_janitor_timer_start(this);
+ }
+ UNLOCK(&priv->lock);
+
+ return 0;
+}
+
+static int
+posix_janitor_task(void *data)
+{
+ xlator_t *this = NULL;
+ struct posix_private *priv = NULL;
+ xlator_t *old_this = NULL;
+
+ time_t now;
+
+ this = data;
+ priv = this->private;
+ /* We need THIS to be set for janitor_walker */
+ old_this = THIS;
+ THIS = this;
+
+ time(&now);
+ if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
+ if (priv->disable_landfill_purge) {
+ gf_msg_debug(this->name, 0,
+ "Janitor would have "
+ "cleaned out %s, but purge"
+ "is disabled.",
+ priv->trash_path);
+ } else {
+ gf_msg_trace(this->name, 0, "janitor cleaning out %s",
+ priv->trash_path);
+
+ nftw(priv->trash_path, janitor_walker, 32, FTW_DEPTH | FTW_PHYS);
+ }
+ priv->last_landfill_check = now;
+ }
+
+ THIS = old_this;
+
+ return 0;
+}
+
+static void
+posix_janitor_task_initator(struct gf_tw_timer_list *timer, void *data,
+ unsigned long calltime)
+{
+ xlator_t *this = NULL;
+ int ret = 0;
+
+ this = data;
+
+ ret = synctask_new(this->ctx->env, posix_janitor_task,
+ posix_janitor_task_done, NULL, this);
+ if (ret < 0) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_THREAD_FAILED,
+ "spawning janitor "
+ "thread failed");
+ }
+
+ return;
+}
+
+void
+__posix_janitor_timer_start(xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ struct gf_tw_timer_list *timer = NULL;
+
+ priv = this->private;
+ timer = priv->janitor;
+
+ INIT_LIST_HEAD(&timer->entry);
+ timer->expires = priv->janitor_sleep_duration;
+ timer->function = posix_janitor_task_initator;
+ timer->data = this;
+ gf_tw_add_timer(this->ctx->tw->timer_wheel, timer);
+
+ return;
+}
+
+void
+posix_janitor_timer_start(xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ struct gf_tw_timer_list *timer = NULL;
priv = this->private;
- pthread_mutex_lock(&priv->janitor_lock);
+ LOCK(&priv->lock);
{
- if (list_empty(&priv->janitor_fds)) {
+ if (!priv->janitor) {
+ timer = GF_CALLOC(1, sizeof(struct gf_tw_timer_list),
+ gf_common_mt_tw_timer_list);
+ if (!timer) {
+ goto unlock;
+ }
+ priv->janitor = timer;
+ __posix_janitor_timer_start(this);
+ }
+ }
+unlock:
+ UNLOCK(&priv->lock);
+
+ return;
+}
+
+static struct posix_fd *
+janitor_get_next_fd(glusterfs_ctx_t *ctx, int32_t janitor_sleep)
+{
+ struct posix_fd *pfd = NULL;
+
+ struct timespec timeout;
+
+ pthread_mutex_lock(&ctx->janitor_lock);
+ {
+ if (list_empty(&ctx->janitor_fds)) {
time(&timeout.tv_sec);
- timeout.tv_sec += priv->janitor_sleep_duration;
+ timeout.tv_sec += janitor_sleep;
timeout.tv_nsec = 0;
- pthread_cond_timedwait(&priv->janitor_cond, &priv->janitor_lock,
+ pthread_cond_timedwait(&ctx->janitor_cond, &ctx->janitor_lock,
&timeout);
goto unlock;
}
- pfd = list_entry(priv->janitor_fds.next, struct posix_fd, list);
+ pfd = list_entry(ctx->janitor_fds.next, struct posix_fd, list);
- list_del(priv->janitor_fds.next);
+ list_del(ctx->janitor_fds.next);
}
unlock:
- pthread_mutex_unlock(&priv->janitor_lock);
+ pthread_mutex_unlock(&ctx->janitor_lock);
return pfd;
}
static void *
-posix_janitor_thread_proc(void *data)
+posix_ctx_janitor_thread_proc(void *data)
{
xlator_t *this = NULL;
- struct posix_private *priv = NULL;
struct posix_fd *pfd;
-
- time_t now;
+ glusterfs_ctx_t *ctx = NULL;
+ struct posix_private *priv = NULL;
+ int32_t sleep_duration = 0;
this = data;
- priv = this->private;
-
+ ctx = THIS->ctx;
THIS = this;
+ priv = this->private;
+ sleep_duration = priv->janitor_sleep_duration;
while (1) {
- time(&now);
- if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
- if (priv->disable_landfill_purge) {
- gf_msg_debug(this->name, 0,
- "Janitor would have "
- "cleaned out %s, but purge"
- "is disabled.",
- priv->trash_path);
- } else {
- gf_msg_trace(this->name, 0, "janitor cleaning out %s",
- priv->trash_path);
-
- nftw(priv->trash_path, janitor_walker, 32,
- FTW_DEPTH | FTW_PHYS);
- }
- priv->last_landfill_check = now;
- }
-
- pfd = janitor_get_next_fd(this);
+ pfd = janitor_get_next_fd(ctx, sleep_duration);
if (pfd) {
if (pfd->dir == NULL) {
gf_msg_trace(this->name, 0, "janitor: closing file fd=%d",
pfd->fd);
sys_close(pfd->fd);
} else {
- gf_msg_debug(this->name, 0,
- "janitor: closing"
- " dir fd=%p",
+ gf_msg_debug(this->name, 0, "janitor: closing dir fd=%p",
pfd->dir);
sys_closedir(pfd->dir);
}
@@ -1496,18 +1598,25 @@ posix_janitor_thread_proc(void *data)
}
void
-posix_spawn_janitor_thread(xlator_t *this)
+posix_spawn_ctx_janitor_thread(xlator_t *this)
{
struct posix_private *priv = NULL;
int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
priv = this->private;
+ ctx = THIS->ctx;
LOCK(&priv->lock);
{
- if (!priv->janitor_present) {
- ret = gf_thread_create(&priv->janitor, NULL,
- posix_janitor_thread_proc, this, "posixjan");
+ if (!ctx->janitor) {
+ pthread_mutex_init(&ctx->janitor_lock, NULL);
+ pthread_cond_init(&ctx->janitor_cond, NULL);
+ INIT_LIST_HEAD(&ctx->janitor_fds);
+
+ ret = gf_thread_create(&ctx->janitor, NULL,
+ posix_ctx_janitor_thread_proc, this,
+ "posixctxjan");
if (ret < 0) {
gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_THREAD_FAILED,
@@ -1515,8 +1624,6 @@ posix_spawn_janitor_thread(xlator_t *this)
"thread failed");
goto unlock;
}
-
- priv->janitor_present = _gf_true;
}
}
unlock: