summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-syncop.c
diff options
context:
space:
mode:
authorMeghana Madhusudhan <mmadhusu@redhat.com>2015-04-20 10:41:47 +0530
committerNiels de Vos <ndevos@redhat.com>2015-05-07 02:08:43 -0700
commit4aad69a8f88acf384c812316aaa985cde2229cd7 (patch)
tree12318360918c95e89f7a40a24855e626cae0a014 /xlators/mgmt/glusterd/src/glusterd-syncop.c
parent6d82215ab95d95ace13465a3efd384e50942ea67 (diff)
NFS-Ganesha : Locking global options file
Global option gluster features.ganesha enable writes into the global 'option' file. The snapshot feature also writes into the same file. To handle concurrent multiple transactions correctly, a new lock has to be introduced on this file. Every operation using this file needs to contest for the new lock type. This is a back-port of the patch, http://review.gluster.org/#/c/10130/ Change-Id: I1fdd285814e615a13dbf8c88ad2b7ee311247f90 BUG: 1218963 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Reviewed-on: http://review.gluster.org/10606 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com> Tested-by: NetBSD Build System Reviewed-by: Avra Sengupta <asengupt@redhat.com>
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-syncop.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
index deb38a7dea9..859aa636885 100644
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
@@ -1440,6 +1440,8 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
int ret = -1;
xlator_t *this = NULL;
struct syncargs args = {0};
+ int32_t global = 0;
+ char *type = NULL;
this = THIS;
GF_ASSERT (this);
@@ -1479,7 +1481,13 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret,
}
rcu_read_unlock ();
} else {
- if (volname) {
+
+ ret = dict_get_int32 (op_ctx, "hold_global_locks", &global);
+ if (global)
+ type = "global";
+ else
+ type = "vol";
+ if (volname || global) {
rcu_read_lock ();
cds_list_for_each_entry_rcu (peerinfo, &conf->peers,
uuid_list) {
@@ -1537,9 +1545,9 @@ out:
if (conf->op_version < GD_OP_VERSION_3_6_0)
glusterd_unlock (MY_UUID);
else {
- if (volname) {
+ if (type) {
ret = glusterd_mgmt_v3_unlock (volname, MY_UUID,
- "vol");
+ type);
if (ret)
gf_log (this->name, GF_LOG_ERROR,
"Unable to release lock for %s",
@@ -1655,9 +1663,11 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
int32_t tmp_op = 0;
char *op_errstr = NULL;
char *tmp = NULL;
+ char *global = NULL;
char *volname = NULL;
xlator_t *this = NULL;
gf_boolean_t is_acquired = _gf_false;
+ gf_boolean_t is_global = _gf_false;
uuid_t *txn_id = NULL;
glusterd_op_info_t txn_opinfo = {{0},};
@@ -1714,6 +1724,12 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
}
} else {
+ ret = dict_get_str (op_ctx, "globalname", &global);
+ if (!ret) {
+ is_global = _gf_true;
+ goto global;
+ }
+
/* If no volname is given as a part of the command, locks will
* not be held */
ret = dict_get_str (op_ctx, "volname", &tmp);
@@ -1742,13 +1758,28 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req)
}
}
+global:
+ if (is_global) {
+ ret = glusterd_mgmt_v3_lock (global, MY_UUID, "global");
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to acquire lock for %s", global);
+ gf_asprintf (&op_errstr,
+ "Another transaction is in progress "
+ "for %s. Please try again after sometime.",
+ global);
+ is_global = _gf_false;
+ goto out;
+ }
+ }
+
is_acquired = _gf_true;
local_locking_done:
/* If no volname is given as a part of the command, locks will
* not be held */
- if (volname || (conf->op_version < GD_OP_VERSION_3_6_0)) {
+ if (volname || (conf->op_version < GD_OP_VERSION_3_6_0) || is_global) {
ret = gd_lock_op_phase (conf, op, op_ctx, &op_errstr, *txn_id,
&txn_opinfo);
if (ret) {
@@ -1784,9 +1815,15 @@ local_locking_done:
out:
op_ret = ret;
if (txn_id) {
- (void) gd_unlock_op_phase (conf, op, &op_ret, req, op_ctx,
- op_errstr, volname, is_acquired,
- *txn_id, &txn_opinfo);
+ if (volname)
+ (void) gd_unlock_op_phase (conf, op, &op_ret, req, op_ctx,
+ op_errstr, volname, is_acquired,
+ *txn_id, &txn_opinfo);
+ if (global)
+ (void) gd_unlock_op_phase (conf, op, &op_ret, req, op_ctx,
+ op_errstr, global, is_acquired,
+ *txn_id, &txn_opinfo);
+
/* Clearing the transaction opinfo */
ret = glusterd_clear_txn_opinfo (txn_id);