diff options
Diffstat (limited to 'xlators/experimental/jbr-server/src/all-templates.c')
| -rw-r--r-- | xlators/experimental/jbr-server/src/all-templates.c | 263 | 
1 files changed, 145 insertions, 118 deletions
diff --git a/xlators/experimental/jbr-server/src/all-templates.c b/xlators/experimental/jbr-server/src/all-templates.c index 9b9a3e0be5e..adae2431157 100644 --- a/xlators/experimental/jbr-server/src/all-templates.c +++ b/xlators/experimental/jbr-server/src/all-templates.c @@ -9,9 +9,17 @@ int32_t  jbr_@NAME@ (call_frame_t *frame, xlator_t *this,              @LONG_ARGS@)  { -        jbr_private_t   *priv   = this->private; -        gf_boolean_t in_recon = _gf_false; -        int32_t recon_term, recon_index; +        jbr_private_t   *priv     = NULL; +        gf_boolean_t     in_recon = _gf_false; +        int32_t          op_errno = 0; +        int32_t          recon_term, recon_index; + +        GF_VALIDATE_OR_GOTO ("jbr", this, err); +        priv = this->private; +        GF_VALIDATE_OR_GOTO (this->name, priv, err); +        GF_VALIDATE_OR_GOTO (this->name, frame, err); + +        op_errno = EREMOTE;          /* allow reads during reconciliation       *           * TBD: allow "dirty" reads on non-leaders * @@ -32,14 +40,20 @@ jbr_@NAME@ (call_frame_t *frame, xlator_t *this,          return 0;  err: -        STACK_UNWIND_STRICT (@NAME@, frame, -1, EREMOTE, +        STACK_UNWIND_STRICT (@NAME@, frame, -1, op_errno,                               @ERROR_ARGS@);          return 0;  } +/* template-name read-perform_local_op */ +/* No "perform_local_op" function needed for @NAME@ */ +  /* template-name read-dispatch */  /* No "dispatch" function needed for @NAME@ */ +/* template-name read-call_dispatch */ +/* No "call_dispatch" function needed for @NAME@ */ +  /* template-name read-fan-in */  /* No "fan-in" function needed for @NAME@ */ @@ -54,70 +68,25 @@ int32_t  jbr_@NAME@ (call_frame_t *frame, xlator_t *this,              @LONG_ARGS@)  { -        jbr_local_t     *local          = NULL; -        jbr_private_t   *priv           = this->private; -        gf_boolean_t     result         = _gf_false; -        int             op_errno        = ENOMEM; -        int             from_leader; -        int             from_recon; -        uint32_t        ti = 0; - -        /* -         * Our first goal here is to avoid "split brain surprise" for users who -         * specify exactly 50% with two- or three-way replication.  That means -         * either a more-than check against half the total replicas or an -         * at-least check against half of our peers (one less).  Of the two, -         * only an at-least check supports the intuitive use of 100% to mean -         * all replicas must be present, because "more than 100%" will never -         * succeed regardless of which count we use.  This leaves us with a -         * slightly non-traditional definition of quorum ("at least X% of peers -         * not including ourselves") but one that's useful enough to be worth -         * it. -         * -         * Note that n_children and up_children *do* include the local -         * subvolume, so we need to subtract one in each case. -         */ -        if (priv->leader) { -                result = fop_quorum_check (this, (double)(priv->n_children - 1), -                                   (double)(priv->up_children - 1)); - -                if (result == _gf_false) { -                        /* Emulate the AFR client-side-quorum behavior. */ -                        gf_msg (this->name, GF_LOG_ERROR, EROFS, -                                J_MSG_QUORUM_NOT_MET, "Sufficient number of " -                                "subvolumes are not up to meet quorum."); -                        op_errno = EROFS; -                        goto err; -                } -        } else { -                if (xdata) { -                        from_leader = !!dict_get(xdata, JBR_TERM_XATTR); -                        from_recon = !!dict_get(xdata, RECON_TERM_XATTR) -                                  && !!dict_get(xdata, RECON_INDEX_XATTR); -                } else { -                        from_leader = from_recon = _gf_false; -                } +        jbr_local_t     *local         = NULL; +        jbr_private_t   *priv          = NULL; +        int32_t          ret           = -1; +        int              op_errno      = ENOMEM; -                /* follower/recon path        * -                 * just send it to local node * -                 */ -                if (!from_leader && !from_recon) { -                        op_errno = EREMOTE; -                        goto err; -                } -        } +        GF_VALIDATE_OR_GOTO ("jbr", this, err); +        priv = this->private; +        GF_VALIDATE_OR_GOTO (this->name, priv, err); +        GF_VALIDATE_OR_GOTO (this->name, frame, err); -        local = mem_get0(this->local_pool); -        if (!local) { -                goto err; -        }  #if defined(JBR_CG_NEED_FD) -        local->fd = fd_ref(fd); +        ret = jbr_leader_checks_and_init (frame, this, &op_errno, xdata, fd);  #else -        local->fd = NULL; +        ret = jbr_leader_checks_and_init (frame, this, &op_errno, xdata, NULL);  #endif -        INIT_LIST_HEAD(&local->qlinks); -        frame->local = local; +        if (ret) +                goto err; + +        local = frame->local;          /*           * If we let it through despite not being the leader, then we just want @@ -132,29 +101,9 @@ jbr_@NAME@ (call_frame_t *frame, xlator_t *this,                  return 0;          } -        if (!xdata) { -                xdata = dict_new(); -                if (!xdata) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                J_MSG_MEM_ERR, "failed to allocate xdata"); -                        goto err; -                } -        } - -        if (dict_set_int32(xdata, JBR_TERM_XATTR, priv->current_term) != 0) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        J_MSG_DICT_FLR, "failed to set jbr-term"); +        ret = jbr_initialize_xdata_set_attrs (this, &xdata); +        if (ret)                  goto err; -        } - -        LOCK(&priv->index_lock); -        ti = ++(priv->index); -        UNLOCK(&priv->index_lock); -        if (dict_set_int32(xdata, JBR_INDEX_XATTR, ti) != 0) { -                gf_msg (this->name, GF_LOG_ERROR, 0, -                        J_MSG_DICT_FLR, "failed to set index"); -                goto err; -        }          local->stub = fop_@NAME@_stub (frame, jbr_@NAME@_continue,                                         @SHORT_ARGS@); @@ -162,14 +111,77 @@ jbr_@NAME@ (call_frame_t *frame, xlator_t *this,                  goto err;          } +        /* +         * Can be used to just call_dispatch or be customised per fop to * +         * perform ops specific to that particular fop.                  * +         */ +        ret = jbr_@NAME@_perform_local_op (frame, this, &op_errno, +                                           @SHORT_ARGS@); +        if (ret) +                goto err; -#if defined(JBR_CG_QUEUE) -        jbr_inode_ctx_t         *ictx   = jbr_get_inode_ctx(this, fd->inode); +        return ret; +err: +        if (local) { +                if (local->stub) { +                        call_stub_destroy(local->stub); +                } +                if (local->qstub) { +                        call_stub_destroy(local->qstub); +                } +                if (local->fd) { +                        fd_unref(local->fd); +                } +                mem_put(local); +        } +        STACK_UNWIND_STRICT (@NAME@, frame, -1, op_errno, +                             @ERROR_ARGS@); +        return 0; +} + +/* template-name write-perform_local_op */ +int32_t +jbr_@NAME@_perform_local_op (call_frame_t *frame, xlator_t *this, int *op_errno, +                             @LONG_ARGS@) +{ +        int32_t          ret    = -1; + +        GF_VALIDATE_OR_GOTO ("jbr", this, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        GF_VALIDATE_OR_GOTO (this->name, op_errno, out); +        ret = jbr_@NAME@_call_dispatch (frame, this, op_errno, +                                        @SHORT_ARGS@); + +out: +        return ret; +} + +/* template-name write-call_dispatch */ +int32_t +jbr_@NAME@_call_dispatch (call_frame_t *frame, xlator_t *this, int *op_errno, +                          @LONG_ARGS@) +{ +        jbr_local_t     *local  = NULL; +        jbr_private_t   *priv   = NULL; +        int32_t          ret    = -1; +        xlator_list_t   *trav   = NULL; + +        GF_VALIDATE_OR_GOTO ("jbr", this, out); +        priv = this->private; +        GF_VALIDATE_OR_GOTO (this->name, priv, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        local = frame->local; +        GF_VALIDATE_OR_GOTO (this->name, local, out); +        GF_VALIDATE_OR_GOTO (this->name, op_errno, out); + +#if defined(JBR_CG_QUEUE) +        jbr_inode_ctx_t  *ictx  = jbr_get_inode_ctx(this, fd->inode);          if (!ictx) { -                op_errno = EIO; -                goto err; +                *op_errno = EIO; +                goto out;          } +          LOCK(&ictx->lock);                  if (ictx->active) {                          gf_msg_debug (this->name, 0, @@ -194,37 +206,23 @@ jbr_@NAME@ (call_frame_t *frame, xlator_t *this,                                                          @SHORT_ARGS@);                          if (!local->qstub) {                                  UNLOCK(&ictx->lock); -                                goto err; +                                goto out;                          }                          list_add_tail(&local->qlinks, &ictx->pqueue);                          ++(ictx->pending);                          UNLOCK(&ictx->lock); -                        return 0; +                        ret = 0; +                        goto out;                  } else {                          list_add_tail(&local->qlinks, &ictx->aqueue);                          ++(ictx->active);                  }          UNLOCK(&ictx->lock);  #endif +        ret = jbr_@NAME@_dispatch (frame, this, @SHORT_ARGS@); -        return jbr_@NAME@_dispatch (frame, this, @SHORT_ARGS@); - -err: -        if (local) { -                if (local->stub) { -                        call_stub_destroy(local->stub); -                } -                if (local->qstub) { -                        call_stub_destroy(local->qstub); -                } -                if (local->fd) { -                        fd_unref(local->fd); -                } -                mem_put(local); -        } -        STACK_UNWIND_STRICT (@NAME@, frame, -1, op_errno, -                             @ERROR_ARGS@); -        return 0; +out: +        return ret;  }  /* template-name write-dispatch */ @@ -232,10 +230,18 @@ int32_t  jbr_@NAME@_dispatch (call_frame_t *frame, xlator_t *this,                       @LONG_ARGS@)  { -        jbr_local_t     *local  = frame->local; -        jbr_private_t   *priv   = this->private; +        jbr_local_t     *local  = NULL; +        jbr_private_t   *priv   = NULL; +        int32_t          ret    = -1;          xlator_list_t   *trav; +        GF_VALIDATE_OR_GOTO ("jbr", this, out); +        priv = this->private; +        GF_VALIDATE_OR_GOTO (this->name, priv, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        local = frame->local; +        GF_VALIDATE_OR_GOTO (this->name, local, out); +          /*           * TBD: unblock pending request(s) if we fail after this point but           * before we get to jbr_@NAME@_complete (where that code currently @@ -251,7 +257,9 @@ jbr_@NAME@_dispatch (call_frame_t *frame, xlator_t *this,          }          /* TBD: variable Issue count */ -        return 0; +        ret = 0; +out: +        return ret;  }  /* template-name write-fan-in */ @@ -260,8 +268,14 @@ jbr_@NAME@_fan_in (call_frame_t *frame, void *cookie, xlator_t *this,                     int32_t op_ret, int32_t op_errno,                     @LONG_ARGS@)  { -        jbr_local_t     *local  = frame->local; -        uint8_t         call_count; +        jbr_local_t   *local  = NULL; +        int32_t        ret    = -1; +        uint8_t        call_count; + +        GF_VALIDATE_OR_GOTO ("jbr", this, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        local = frame->local; +        GF_VALIDATE_OR_GOTO (this->name, local, out);          gf_msg_trace (this->name, 0, "op_ret = %d, op_errno = %d\n",                        op_ret, op_errno); @@ -284,7 +298,9 @@ jbr_@NAME@_fan_in (call_frame_t *frame, void *cookie, xlator_t *this,                  call_resume(local->stub);          } -        return 0; +        ret = 0; +out: +        return ret;  }  /* template-name write-continue */ @@ -335,10 +351,16 @@ jbr_@NAME@_complete (call_frame_t *frame, void *cookie, xlator_t *this,                       int32_t op_ret, int32_t op_errno,                       @LONG_ARGS@)  { -        gf_boolean_t     result         = _gf_false; -        jbr_private_t   *priv           = this->private; +        gf_boolean_t     result    = _gf_false; +        jbr_private_t   *priv      = NULL; +        jbr_local_t     *local     = NULL; -        jbr_local_t *local = frame->local; +        GF_VALIDATE_OR_GOTO ("jbr", this, err); +        GF_VALIDATE_OR_GOTO (this->name, frame, err); +        priv = this->private; +        local = frame->local; +        GF_VALIDATE_OR_GOTO (this->name, priv, err); +        GF_VALIDATE_OR_GOTO (this->name, local, err);          /* If the fop failed on the leader, then reduce one succesful ack           * before calculating the fop quorum @@ -434,4 +456,9 @@ jbr_@NAME@_complete (call_frame_t *frame, void *cookie, xlator_t *this,          return 0; +err: +        STACK_UNWIND_STRICT (@NAME@, frame, -1, 0, +                             @SHORT_ARGS@); + +        return 0;  }  | 
