diff options
| author | Avra Sengupta <asengupt@redhat.com> | 2016-05-10 12:13:18 +0530 |
|---|---|---|
| committer | Jeff Darcy <jdarcy@redhat.com> | 2016-05-25 11:52:44 -0700 |
| commit | f8f16595d8dd8c8a869630bb77b7fd1b42b97e08 (patch) | |
| tree | 8f8d7ff3739a16155331f0411501f94d8849513d /xlators/experimental/jbr-server/src/jbr.c | |
| parent | fb57ac1acb228301edb98f2fe7cf93471363eb4a (diff) | |
jbr: Making fop functions more modular to reuse more code
Putting bigger chunks of re-usable code like leader checks
and init into functions thereby reducing the size of the
'fop' call.
Introduced 'perform_local_op' in the 'fop' call, where
regular functions as of now just call dispatch, but fops
like 'lk' can do their fop specific operations.
Introduced selective_generate to allow certain functions
for a particular fop to be generated. The rest of the
functions can be customised and added in jbr.c
Change-Id: I3754ed68983e763329e14a2faef911428e36e4f0
BUG: 1336328
Signed-off-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-on: http://review.gluster.org/14355
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/experimental/jbr-server/src/jbr.c')
| -rw-r--r-- | xlators/experimental/jbr-server/src/jbr.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/xlators/experimental/jbr-server/src/jbr.c b/xlators/experimental/jbr-server/src/jbr.c index 984392c2f87..a342d3b83d5 100644 --- a/xlators/experimental/jbr-server/src/jbr.c +++ b/xlators/experimental/jbr-server/src/jbr.c @@ -190,6 +190,128 @@ jbr_mark_fd_dirty (xlator_t *this, jbr_local_t *local) #define RECON_TERM_XATTR "trusted.jbr.recon-term" #define RECON_INDEX_XATTR "trusted.jbr.recon-index" +int32_t +jbr_leader_checks_and_init (call_frame_t *frame, xlator_t *this, int *op_errno, + dict_t *xdata, fd_t *fd) +{ + jbr_local_t *local = NULL; + jbr_private_t *priv = NULL; + int32_t ret = -1; + gf_boolean_t result = _gf_false; + int from_leader = _gf_false; + int from_recon = _gf_false; + + GF_VALIDATE_OR_GOTO ("jbr", this, out); + priv = this->private; + GF_VALIDATE_OR_GOTO (this->name, priv, out); + GF_VALIDATE_OR_GOTO (this->name, op_errno, out); + GF_VALIDATE_OR_GOTO (this->name, frame, out); + + /* + * 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 out; + } + } 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; + } + + /* follower/recon path * + * just send it to local node * + */ + if (!from_leader && !from_recon) { + *op_errno = EREMOTE; + goto out; + } + } + + local = mem_get0(this->local_pool); + if (!local) { + goto out; + } + + if (fd) + local->fd = fd_ref(fd); + else + local->fd = NULL; + + INIT_LIST_HEAD(&local->qlinks); + frame->local = local; + + ret = 0; +out: + return ret; +} + +int32_t +jbr_initialize_xdata_set_attrs (xlator_t *this, dict_t **xdata) +{ + jbr_local_t *local = NULL; + jbr_private_t *priv = NULL; + int32_t ret = -1; + uint32_t ti = 0; + + GF_VALIDATE_OR_GOTO ("jbr", this, out); + priv = this->private; + GF_VALIDATE_OR_GOTO (this->name, priv, out); + GF_VALIDATE_OR_GOTO (this->name, xdata, out); + + if (!*xdata) { + *xdata = dict_new(); + if (!*xdata) { + gf_msg (this->name, GF_LOG_ERROR, ENOMEM, + J_MSG_MEM_ERR, "failed to allocate xdata"); + goto out; + } + } + + 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"); + goto out; + } + + 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 out; + } + + ret = 0; +out: + return ret; +} + #pragma generate uint8_t |
