diff options
| author | Pavan Sondur <pavan@gluster.com> | 2010-09-30 02:25:31 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-09-30 11:19:24 -0700 | 
| commit | af18c636c44b1ea56296850e55afe0e4b2ce845c (patch) | |
| tree | 40f8470ec000b96d61b3f8d53286aa0812c9d921 /xlators/cluster/afr/src | |
| parent | 760daf28898cbb8b5072551735bebee16450ba08 (diff) | |
protocol/client: cluster/afr: Support lock recovery and self heal.
Signed-off-by: Pavan Vilas Sondur <pavan@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 865 (Add locks recovery support in GlusterFS)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=865
Diffstat (limited to 'xlators/cluster/afr/src')
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 31 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-lk-common.c | 101 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-mem-types.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.c | 3 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 17 | 
5 files changed, 150 insertions, 3 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 64e22c3229e..9d9f5d0414d 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1197,6 +1197,16 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)                  fd_ctx->up_count   = priv->up_count;                  fd_ctx->down_count = priv->down_count; +                fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on), +                                               priv->child_count, +                                               gf_afr_mt_char); +                if (!fd_ctx->locked_on) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Out of memory"); +                        ret = -ENOMEM; +                        goto unlock; +                } +                  ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);                  INIT_LIST_HEAD (&fd_ctx->entries); @@ -1426,6 +1436,9 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)                  if (fd_ctx->opened_on)                          GF_FREE (fd_ctx->opened_on); +                if (fd_ctx->locked_on) +                        GF_FREE (fd_ctx->locked_on); +                  GF_FREE (fd_ctx);          } @@ -2298,8 +2311,9 @@ int32_t  afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,              int32_t op_ret, int32_t op_errno, struct flock *lock)  { -        afr_local_t *local = NULL; -        afr_private_t *priv = NULL; +	afr_local_t *local = NULL; +	afr_private_t *priv = NULL; +        int            ret  = 0;          int child_index = -1; @@ -2339,7 +2353,18 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          } else {                  /* locking has succeeded on all nodes that are up */ -                AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno, +                ret = afr_mark_locked_nodes (this, local->fd, +                                             local->cont.lk.locked_nodes); +                if (ret) +                        gf_log (this->name, GF_LOG_DEBUG, +                                "Could not save locked nodes info in fdctx"); + +                ret = afr_save_locked_fd (this, local->fd); +                if (ret) +                        gf_log (this->name, GF_LOG_DEBUG, +                                "Could not save locked fd"); + +		AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,                                    &local->cont.lk.ret_flock);          } diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c index ee53d1d7bfb..de95a6c763b 100644 --- a/xlators/cluster/afr/src/afr-lk-common.c +++ b/xlators/cluster/afr/src/afr-lk-common.c @@ -1678,3 +1678,104 @@ afr_unlock (call_frame_t *frame, xlator_t *this)          return 0;  } + +int +afr_mark_locked_nodes (xlator_t *this, fd_t *fd, +                       unsigned char *locked_nodes) +{ +        afr_private_t *priv  = NULL; +        afr_fd_ctx_t  *fdctx = NULL; +        uint64_t       tmp   = 0; +        int            ret   = 0; + +        priv = this->private; + +        afr_fd_ctx_set (this, fd); +        if (ret < 0) +                goto out; + +        ret = fd_ctx_get (fd, this, &tmp); +        fdctx = (afr_fd_ctx_t *) (long) tmp; + +        GF_ASSERT (fdctx->locked_on); + +        memcpy (fdctx->locked_on, locked_nodes, +                priv->child_count); + +out: +        return ret; +} + +static int +__is_fd_saved (xlator_t *this, fd_t *fd) +{ +        afr_locked_fd_t *locked_fd = NULL; +        afr_private_t   *priv      = NULL; +        int              found     = 0; + +        priv = this->private; + +        list_for_each_entry (locked_fd, &priv->saved_fds, list) { +                if (locked_fd->fd == fd) { +                        found = 1; +                        break; +                } +        } + +        return found; +} + +static int +__afr_save_locked_fd (xlator_t *this, fd_t *fd) +{ +        afr_private_t   *priv      = NULL; +        afr_locked_fd_t *locked_fd = NULL; +        int              ret       = 0; + +        priv = this->private; + +        locked_fd = GF_CALLOC (1, sizeof (*locked_fd), +                               gf_afr_mt_locked_fd); +        if (!locked_fd) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Out of memory"); +                ret = -1; +                goto out; +        } + +        INIT_LIST_HEAD (&locked_fd->list); + +        list_add_tail (&locked_fd->list, &priv->saved_fds); + +out: +        return ret; +} + +int +afr_save_locked_fd (xlator_t *this, fd_t *fd) +{ +        afr_private_t   *priv      = NULL; +        int              ret       = 0; + +        priv = this->private; + +        pthread_mutex_lock (&priv->mutex); +        { +                if (__is_fd_saved (this, fd)) { +                        gf_log (this->name, GF_LOG_DEBUG, +                                "fd=%p already saved", fd); +                        goto unlock; +                } + +                ret = __afr_save_locked_fd (this, fd); +                if (ret) { +                        gf_log (this->name, GF_LOG_DEBUG, +                                "fd=%p could not be saved"); +                        goto unlock; +                } +        } +unlock: +        pthread_mutex_unlock (&priv->mutex); + +        return ret; +} diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h index c1a86b8275b..31a80e8f57a 100644 --- a/xlators/cluster/afr/src/afr-mem-types.h +++ b/xlators/cluster/afr/src/afr-mem-types.h @@ -41,6 +41,7 @@ enum gf_afr_mem_types_ {          gf_afr_mt_loc_t,          gf_afr_mt_entry_name,          gf_afr_mt_pump_priv, +        gf_afr_mt_locked_fd,          gf_afr_mt_end  };  #endif diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 09094bdbe58..69b281d973e 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -641,6 +641,9 @@ init (xlator_t *this)          priv->first_lookup = 1;          priv->root_inode = NULL; +        pthread_mutex_init (&priv->mutex, NULL); +        INIT_LIST_HEAD (&priv->saved_fds); +  	ret = 0;  out:  	return ret; diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 26f2c989f4e..68b4a1e305e 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -85,6 +85,9 @@ typedef struct _afr_private {  	struct _pump_private *pump_private; /* Set if we are loaded as pump */          int                   use_afr_in_pump; + +        pthread_mutex_t  mutex; +        struct list_head saved_fds;   /* list of fds on which locks have succeeded */  } afr_private_t;  typedef struct { @@ -262,6 +265,11 @@ typedef struct {  } afr_internal_lock_t; +typedef struct _afr_locked_fd { +        fd_t  *fd; +        struct list_head list; +} afr_locked_fd_t; +  typedef struct _afr_local {  	unsigned int call_count;  	unsigned int success_count; @@ -619,6 +627,8 @@ typedef struct {          int  hit, miss;          gf_boolean_t failed_over;          struct list_head entries; /* needed for readdir failover */ + +        unsigned char *locked_on; /* which subvolumes locks have been successful */  } afr_fd_ctx_t; @@ -655,6 +665,13 @@ int32_t  afr_notify (xlator_t *this, int32_t event,              void *data, ...); +int +afr_save_locked_fd (xlator_t *this, fd_t *fd); + +int +afr_mark_locked_nodes (xlator_t *this, fd_t *fd, +                       unsigned char *locked_nodes); +  void  afr_set_lk_owner (call_frame_t *frame, xlator_t *this);  | 
