/* Copyright (c) 2014 Red Hat, Inc. 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 __BARRIER_H__ #define __BARRIER_H__ #include "barrier-mem-types.h" #include "xlator.h" #include "timer.h" #include "call-stub.h" #define BARRIER_SAFE_ASSIGN(lock, to, value) \ do { \ LOCK (&(lock)); \ { \ to = value; \ } \ UNLOCK (&(lock)); \ } while (0) #define BARRIER_FOP_CBK(fop_name, label, frame, this, params ...) \ do { \ barrier_priv_t *_priv = NULL; \ call_stub_t *_stub = NULL; \ gf_boolean_t _barrier_enabled= _gf_false; \ struct list_head queue = {0, }; \ \ INIT_LIST_HEAD (&queue); \ \ _priv = this->private; \ GF_ASSERT (_priv); \ \ LOCK (&_priv->lock); \ { \ if (_priv->barrier_enabled) { \ _barrier_enabled = _priv->barrier_enabled;\ \ _stub = fop_##fop_name##_cbk_stub \ (frame, \ default_##fop_name##_cbk_resume,\ params); \ if (!_stub) { \ __barrier_disable (this, &queue);\ goto unlock; \ } \ \ __barrier_enqueue (this, _stub); \ } \ } \ unlock: \ UNLOCK (&_priv->lock); \ \ if (_stub) \ goto label; \ \ if (_barrier_enabled && !_stub) { \ gf_log (this->name, GF_LOG_CRITICAL, \ "Failed to barrier FOPs, disabling " \ "barrier. FOP: %s, ERROR: %s", \ #fop_name, strerror (ENOMEM)); \ barrier_dequeue_all (this, &queue); \ } \ \ STACK_UNWIND_STRICT (fop_name, frame, params); \ goto label; \ } while (0) typedef struct { gf_timer_t *timer; gf_boolean_t barrier_enabled; gf_lock_t lock; struct list_head queue; struct timespec timeout; uint32_t queue_size; } barrier_priv_t; int __barrier_enable (xlator_t *this, barrier_priv_t *priv); void __barrier_enqueue (xlator_t *this, call_stub_t *stub); void __barrier_disable (xlator_t *this, struct list_head *queue); void barrier_timeout (void *data); void barrier_dequeue_all (xlator_t *this, struct list_head *queue); call_stub_t *__barrier_dequeue (xlator_t *this, struct list_head *queue); #endif