summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2019-11-07 15:18:30 +0530
committerRavishankar N <ravishankar@redhat.com>2019-11-28 07:17:00 +0000
commitfce5f68bc72d448490a0d41be494ac54a9181b3c (patch)
tree5c2661ce52553b8c27dbe11cb4d1924cafe109ec
parent8424df172339d3b2b65bc022e5c8f150f8826dba (diff)
afr: make heal info lockless
Changes in locks xlator: Added support for per-domain inodelk count requests. Caller needs to set GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS key in the dict and then set each key with name 'GLUSTERFS_INODELK_DOM_PREFIX:<domain name>'. In the response dict, the xlator will send the per domain count as values for each of these keys. Changes in AFR: Replaced afr_selfheal_locked_inspect() with afr_lockless_inspect(). Logic has been added to make the latter behave same as the former, thus not breaking the current heal info output behaviour. fixes: bz#1774011 Change-Id: I9ae08ce768b39aeb6ee230207b5b7fa744176952 Signed-off-by: Ravishankar N <ravishankar@redhat.com>
-rw-r--r--heal/src/glfs-heal.c17
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h2
-rw-r--r--xlators/cluster/afr/src/afr-common.c203
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c40
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h3
-rw-r--r--xlators/features/locks/src/common.h4
-rw-r--r--xlators/features/locks/src/locks.h8
-rw-r--r--xlators/features/locks/src/posix.c104
8 files changed, 293 insertions, 88 deletions
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
index 3ebf79eee14..20372316edd 100644
--- a/heal/src/glfs-heal.c
+++ b/heal/src/glfs-heal.c
@@ -773,7 +773,8 @@ static int
glfsh_process_entries(xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
uint64_t *offset, num_entries_t *num_entries,
print_status glfsh_print_status,
- gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode)
+ gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode,
+ dict_t *xattr_req)
{
gf_dirent_t *entry = NULL;
gf_dirent_t *tmp = NULL;
@@ -805,7 +806,7 @@ glfsh_process_entries(xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
gf_uuid_parse(entry->d_name, gfid);
gf_uuid_copy(loc.gfid, gfid);
- ret = syncop_getxattr(this, &loc, &dict, GF_HEAL_INFO, NULL, NULL);
+ ret = syncop_getxattr(this, &loc, &dict, GF_HEAL_INFO, xattr_req, NULL);
if (ret) {
if ((mode != GLFSH_MODE_CONTINUE_ON_ERROR) && (ret == -ENOTCONN))
goto out;
@@ -874,19 +875,19 @@ glfsh_crawl_directory(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
if (heal_op == GF_SHD_OP_INDEX_SUMMARY) {
ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
num_entries, glfsh_print_heal_status,
- ignore, mode);
+ ignore, mode, xattr_req);
if (ret < 0)
goto out;
} else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) {
ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
num_entries, glfsh_print_spb_status,
- ignore, mode);
+ ignore, mode, xattr_req);
if (ret < 0)
goto out;
} else if (heal_op == GF_SHD_OP_HEAL_SUMMARY) {
ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
num_entries, glfsh_print_summary_status,
- ignore, mode);
+ ignore, mode, xattr_req);
if (ret < 0)
goto out;
} else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
@@ -895,7 +896,7 @@ glfsh_crawl_directory(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
} else if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) {
ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
num_entries, glfsh_heal_status_boolean,
- ignore, mode);
+ ignore, mode, xattr_req);
if (ret < 0)
goto out;
}
@@ -949,6 +950,10 @@ glfsh_print_pending_heals_type(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
int32_t op_errno = 0;
gf_boolean_t ignore = _gf_false;
+ ret = dict_set_str(xattr_req, "index-vgfid", vgfid);
+ if (ret)
+ return ret;
+
if (!strcmp(vgfid, GF_XATTROP_DIRTY_GFID))
ignore = _gf_true;
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
index ea024a02a30..fb91806393e 100644
--- a/libglusterfs/src/glusterfs/glusterfs.h
+++ b/libglusterfs/src/glusterfs/glusterfs.h
@@ -203,6 +203,8 @@ enum gf_internal_fop_indicator {
#define GLUSTERFS_POSIXLK_COUNT "glusterfs.posixlk-count"
#define GLUSTERFS_PARENT_ENTRYLK "glusterfs.parent-entrylk"
#define GLUSTERFS_INODELK_DOM_COUNT "glusterfs.inodelk-dom-count"
+#define GLUSTERFS_INODELK_DOM_PREFIX "glusterfs.inodelk-dom-prefix"
+#define GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS "glusterfs.multi-dom-lk-cnt-req"
#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
#define GF_XATTR_STIME_PATTERN "trusted.glusterfs.*.stime"
#define GF_XATTR_XTIME_PATTERN "trusted.glusterfs.*.xtime"
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index bc34a023d2f..7913dfe58bf 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -6882,68 +6882,6 @@ out:
return ret;
}
-int
-afr_selfheal_locked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid,
- inode_t **inode, gf_boolean_t *entry_selfheal,
- gf_boolean_t *data_selfheal,
- gf_boolean_t *metadata_selfheal,
- unsigned char *pending)
-
-{
- int ret = -1;
- fd_t *fd = NULL;
- gf_boolean_t dsh = _gf_false;
- gf_boolean_t msh = _gf_false;
- gf_boolean_t esh = _gf_false;
-
- ret = afr_selfheal_unlocked_inspect(frame, this, gfid, inode, &dsh, &msh,
- &esh);
- if (ret)
- goto out;
-
- /* For every heal type hold locks and check if it indeed needs heal */
-
- /* Heal-info does an open() on the file being examined so that the
- * current eager-lock holding client, if present, at some point sees
- * open-fd count being > 1 and releases the eager-lock so that heal-info
- * doesn't remain blocked forever until IO completes.
- */
- if ((*inode)->ia_type == IA_IFREG) {
- ret = afr_selfheal_data_open(this, *inode, &fd);
- if (ret < 0) {
- gf_msg_debug(this->name, -ret, "%s: Failed to open",
- uuid_utoa((*inode)->gfid));
- goto out;
- }
- }
-
- if (msh) {
- ret = afr_selfheal_locked_metadata_inspect(frame, this, *inode, &msh,
- pending);
- if (ret == -EIO)
- goto out;
- }
-
- if (dsh) {
- ret = afr_selfheal_locked_data_inspect(frame, this, fd, &dsh, pending);
- if (ret == -EIO || (ret == -EAGAIN))
- goto out;
- }
-
- if (esh) {
- ret = afr_selfheal_locked_entry_inspect(frame, this, *inode, &esh,
- pending);
- }
-
-out:
- *data_selfheal = dsh;
- *entry_selfheal = esh;
- *metadata_selfheal = msh;
- if (fd)
- fd_unref(fd);
- return ret;
-}
-
static dict_t *
afr_set_heal_info(char *status)
{
@@ -6975,6 +6913,132 @@ out:
return dict;
}
+static int
+afr_update_heal_status(xlator_t *this, struct afr_reply *replies,
+ char *index_vgfid, gf_boolean_t *esh, gf_boolean_t *dsh,
+ gf_boolean_t *msh)
+{
+ int ret = -1;
+ int i = 0;
+ int io_domain_lk_count = 0;
+ int shd_domain_lk_count = 0;
+ afr_private_t *priv = NULL;
+ char *key1 = NULL;
+ char *key2 = NULL;
+
+ priv = this->private;
+ key1 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 +
+ strlen(priv->sh_domain));
+ key2 = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 +
+ strlen(priv->sh_domain));
+ sprintf(key1, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, this->name);
+ sprintf(key2, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, priv->sh_domain);
+
+ for (i = 0; i < priv->child_count; i++) {
+ if ((replies[i].valid != 1) || (replies[i].op_ret != 0))
+ continue;
+ if (!io_domain_lk_count) {
+ ret = dict_get_int32(replies[i].xdata, key1, &io_domain_lk_count);
+ }
+ if (!shd_domain_lk_count) {
+ ret = dict_get_int32(replies[i].xdata, key2, &shd_domain_lk_count);
+ }
+ }
+
+ if (!strcmp(index_vgfid, GF_XATTROP_INDEX_GFID)) {
+ if (shd_domain_lk_count) {
+ ret = -EAGAIN; /*For 'possibly-healing'. */
+ } else {
+ ret = 0; /*needs heal. Just set a non -ve value so that it is
+ assumed as the source index.*/
+ }
+ } else if (!strcmp(index_vgfid, GF_XATTROP_DIRTY_GFID)) {
+ if ((!shd_domain_lk_count && !io_domain_lk_count) ||
+ (!io_domain_lk_count && shd_domain_lk_count)) {
+ /* Needs heal. */
+ ret = 0;
+ } else {
+ GF_ASSERT(io_domain_lk_count && !shd_domain_lk_count);
+ /* No heal needed. */
+ *dsh = *esh = *msh = 0;
+ }
+ }
+ return ret;
+}
+
+/*return EIO, EAGAIN or pending*/
+int
+afr_lockless_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid,
+ inode_t **inode, char *index_vgfid,
+ gf_boolean_t *entry_selfheal, gf_boolean_t *data_selfheal,
+ gf_boolean_t *metadata_selfheal, unsigned char *pending)
+{
+ int ret = -1;
+ int i = 0;
+ afr_private_t *priv = NULL;
+ struct afr_reply *replies = NULL;
+ gf_boolean_t dsh = _gf_false;
+ gf_boolean_t msh = _gf_false;
+ gf_boolean_t esh = _gf_false;
+ unsigned char *sources = NULL;
+ unsigned char *sinks = NULL;
+ unsigned char *valid_on = NULL;
+ uint64_t *witness = NULL;
+
+ priv = this->private;
+ replies = alloca0(sizeof(*replies) * priv->child_count);
+ sources = alloca0(sizeof(*sources) * priv->child_count);
+ sinks = alloca0(sizeof(*sinks) * priv->child_count);
+ witness = alloca0(sizeof(*witness) * priv->child_count);
+ valid_on = alloca0(sizeof(*valid_on) * priv->child_count);
+
+ ret = afr_selfheal_unlocked_inspect(frame, this, gfid, inode, &dsh, &msh,
+ &esh, replies);
+ if (ret)
+ goto out;
+ for (i = 0; i < priv->child_count; i++) {
+ if (replies[i].valid && replies[i].op_ret == 0) {
+ valid_on[i] = 1;
+ }
+ }
+ if (msh) {
+ ret = afr_selfheal_find_direction(frame, this, replies,
+ AFR_METADATA_TRANSACTION, valid_on,
+ sources, sinks, witness, pending);
+ if (*pending & PFLAG_SBRAIN)
+ ret = -EIO;
+ if (ret)
+ goto out;
+ }
+ if (dsh) {
+ ret = afr_selfheal_find_direction(frame, this, replies,
+ AFR_DATA_TRANSACTION, valid_on,
+ sources, sinks, witness, pending);
+ if (*pending & PFLAG_SBRAIN)
+ ret = -EIO;
+ if (ret)
+ goto out;
+ }
+ if (esh) {
+ ret = afr_selfheal_find_direction(frame, this, replies,
+ AFR_ENTRY_TRANSACTION, valid_on,
+ sources, sinks, witness, pending);
+ if (*pending & PFLAG_SBRAIN)
+ ret = -EIO;
+ if (ret)
+ goto out;
+ }
+
+ ret = afr_update_heal_status(this, replies, index_vgfid, &esh, &dsh, &msh);
+out:
+ *data_selfheal = dsh;
+ *entry_selfheal = esh;
+ *metadata_selfheal = msh;
+ if (replies)
+ afr_replies_wipe(replies, priv->child_count);
+ return ret;
+}
+
int
afr_get_heal_info(call_frame_t *frame, xlator_t *this, loc_t *loc)
{
@@ -6990,6 +7054,14 @@ afr_get_heal_info(call_frame_t *frame, xlator_t *this, loc_t *loc)
char *status = NULL;
call_frame_t *heal_frame = NULL;
afr_local_t *heal_local = NULL;
+ afr_local_t *local = NULL;
+ char *index_vgfid = NULL;
+
+ local = frame->local;
+ if (dict_get_str(local->xdata_req, "index-vgfid", &index_vgfid)) {
+ ret = -1;
+ goto out;
+ }
/*Use frame with lk-owner set*/
heal_frame = afr_frame_create(frame->this, &op_errno);
@@ -6999,9 +7071,10 @@ afr_get_heal_info(call_frame_t *frame, xlator_t *this, loc_t *loc)
}
heal_local = heal_frame->local;
heal_frame->local = frame->local;
- ret = afr_selfheal_locked_inspect(heal_frame, this, loc->gfid, &inode,
- &entry_selfheal, &data_selfheal,
- &metadata_selfheal, &pending);
+
+ ret = afr_lockless_inspect(heal_frame, this, loc->gfid, &inode, index_vgfid,
+ &entry_selfheal, &data_selfheal,
+ &metadata_selfheal, &pending);
if (ret == -ENOMEM) {
ret = -1;
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index f06f7e603a0..781437bf74e 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -1831,6 +1831,34 @@ afr_selfheal_unlocked_lookup_on(call_frame_t *frame, inode_t *parent,
return inode;
}
+static int
+afr_set_multi_dom_lock_count_request(xlator_t *this, dict_t *dict)
+{
+ int ret = 0;
+ afr_private_t *priv = NULL;
+ char *key = NULL;
+
+ priv = this->private;
+ key = alloca0(strlen(GLUSTERFS_INODELK_DOM_PREFIX) + 2 +
+ strlen(priv->sh_domain));
+
+ ret = dict_set_uint32(dict, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS, 1);
+ if (ret)
+ return ret;
+
+ sprintf(key, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, this->name);
+ ret = dict_set_uint32(dict, key, 1);
+ if (ret)
+ return ret;
+
+ sprintf(key, "%s:%s", GLUSTERFS_INODELK_DOM_PREFIX, priv->sh_domain);
+ ret = dict_set_uint32(dict, key, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
int
afr_selfheal_unlocked_discover_on(call_frame_t *frame, inode_t *inode,
uuid_t gfid, struct afr_reply *replies,
@@ -1857,6 +1885,11 @@ afr_selfheal_unlocked_discover_on(call_frame_t *frame, inode_t *inode,
return -ENOMEM;
}
+ if (afr_set_multi_dom_lock_count_request(frame->this, xattr_req)) {
+ dict_unref(xattr_req);
+ return -1;
+ }
+
loc.inode = inode_ref(inode);
gf_uuid_copy(loc.gfid, gfid);
@@ -2252,7 +2285,8 @@ int
afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid,
inode_t **link_inode, gf_boolean_t *data_selfheal,
gf_boolean_t *metadata_selfheal,
- gf_boolean_t *entry_selfheal)
+ gf_boolean_t *entry_selfheal,
+ struct afr_reply *replies_dst)
{
afr_private_t *priv = NULL;
inode_t *inode = NULL;
@@ -2388,6 +2422,8 @@ afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid,
ret = 0;
out:
+ if (replies && replies_dst)
+ afr_replies_copy(replies_dst, replies, priv->child_count);
if (inode)
inode_unref(inode);
if (replies)
@@ -2507,7 +2543,7 @@ afr_selfheal_do(call_frame_t *frame, xlator_t *this, uuid_t gfid)
ret = afr_selfheal_unlocked_inspect(frame, this, gfid, &inode,
&data_selfheal, &metadata_selfheal,
- &entry_selfheal);
+ &entry_selfheal, NULL);
if (ret)
goto out;
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
index 55d94e20cea..5e7bde8689d 100644
--- a/xlators/cluster/afr/src/afr-self-heal.h
+++ b/xlators/cluster/afr/src/afr-self-heal.h
@@ -325,7 +325,8 @@ int
afr_selfheal_unlocked_inspect(call_frame_t *frame, xlator_t *this, uuid_t gfid,
inode_t **link_inode, gf_boolean_t *data_selfheal,
gf_boolean_t *metadata_selfheal,
- gf_boolean_t *entry_selfheal);
+ gf_boolean_t *entry_selfheal,
+ struct afr_reply *replies);
int
afr_selfheal_do(call_frame_t *frame, xlator_t *this, uuid_t gfid);
diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h
index 4006062606e..0916c299e84 100644
--- a/xlators/features/locks/src/common.h
+++ b/xlators/features/locks/src/common.h
@@ -44,6 +44,10 @@
fd_unref(__local->fd); \
if (__local->inode) \
inode_unref(__local->inode); \
+ if (__local->xdata) { \
+ dict_unref(__local->xdata); \
+ __local->xdata = NULL; \
+ } \
mem_put(__local); \
} \
} while (0)
diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h
index 0ab2aa6cbae..3305350afb1 100644
--- a/xlators/features/locks/src/locks.h
+++ b/xlators/features/locks/src/locks.h
@@ -240,6 +240,7 @@ typedef struct {
gf_boolean_t inodelk_count_req;
gf_boolean_t posixlk_count_req;
gf_boolean_t parent_entrylk_req;
+ gf_boolean_t multiple_dom_lk_requests;
int update_mlock_enforced_flag;
} pl_local_t;
@@ -261,6 +262,13 @@ typedef struct _locks_ctx {
struct list_head metalk_list;
} pl_ctx_t;
+typedef struct _multi_dom_lk_data {
+ xlator_t *this;
+ inode_t *inode;
+ dict_t *xdata_rsp;
+ gf_boolean_t keep_max;
+} multi_dom_lk_data;
+
typedef enum { DECREMENT, INCREMENT } pl_count_op_t;
pl_ctx_t *
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index d2f5db5116b..e03a6063128 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -151,13 +151,20 @@ fetch_pathinfo(xlator_t *, inode_t *, int32_t *, char **);
gf_boolean_t
pl_has_xdata_requests(dict_t *xdata)
{
- static char *reqs[] = {GLUSTERFS_ENTRYLK_COUNT, GLUSTERFS_INODELK_COUNT,
- GLUSTERFS_INODELK_DOM_COUNT, GLUSTERFS_POSIXLK_COUNT,
- GLUSTERFS_PARENT_ENTRYLK, NULL};
- static int reqs_size[] = {
- SLEN(GLUSTERFS_ENTRYLK_COUNT), SLEN(GLUSTERFS_INODELK_COUNT),
- SLEN(GLUSTERFS_INODELK_DOM_COUNT), SLEN(GLUSTERFS_POSIXLK_COUNT),
- SLEN(GLUSTERFS_PARENT_ENTRYLK), 0};
+ static char *reqs[] = {GLUSTERFS_ENTRYLK_COUNT,
+ GLUSTERFS_INODELK_COUNT,
+ GLUSTERFS_INODELK_DOM_COUNT,
+ GLUSTERFS_POSIXLK_COUNT,
+ GLUSTERFS_PARENT_ENTRYLK,
+ GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS,
+ NULL};
+ static int reqs_size[] = {SLEN(GLUSTERFS_ENTRYLK_COUNT),
+ SLEN(GLUSTERFS_INODELK_COUNT),
+ SLEN(GLUSTERFS_INODELK_DOM_COUNT),
+ SLEN(GLUSTERFS_POSIXLK_COUNT),
+ SLEN(GLUSTERFS_PARENT_ENTRYLK),
+ SLEN(GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS),
+ 0};
int i = 0;
if (!xdata)
@@ -176,6 +183,9 @@ pl_get_xdata_requests(pl_local_t *local, dict_t *xdata)
if (!local || !xdata)
return;
+ GF_ASSERT(local->xdata == NULL);
+ local->xdata = dict_ref(xdata);
+
if (dict_get_sizen(xdata, GLUSTERFS_ENTRYLK_COUNT)) {
local->entrylk_count_req = 1;
dict_del_sizen(xdata, GLUSTERFS_ENTRYLK_COUNT);
@@ -184,6 +194,10 @@ pl_get_xdata_requests(pl_local_t *local, dict_t *xdata)
local->inodelk_count_req = 1;
dict_del_sizen(xdata, GLUSTERFS_INODELK_COUNT);
}
+ if (dict_get_sizen(xdata, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS)) {
+ local->multiple_dom_lk_requests = 1;
+ dict_del_sizen(xdata, GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS);
+ }
local->inodelk_dom_count_req = dict_get_sizen(xdata,
GLUSTERFS_INODELK_DOM_COUNT);
@@ -211,7 +225,7 @@ pl_needs_xdata_response(pl_local_t *local)
if (local->parent_entrylk_req || local->entrylk_count_req ||
local->inodelk_dom_count_req || local->inodelk_count_req ||
- local->posixlk_count_req)
+ local->posixlk_count_req || local->multiple_dom_lk_requests)
return _gf_true;
return _gf_false;
@@ -411,6 +425,71 @@ pl_posixlk_xattr_fill(xlator_t *this, inode_t *inode, dict_t *dict,
}
void
+pl_inodelk_xattr_fill_each(xlator_t *this, inode_t *inode, dict_t *dict,
+ char *domname, gf_boolean_t keep_max, char *key)
+{
+ int32_t count = 0;
+ int32_t maxcount = -1;
+ int ret = -1;
+
+ if (keep_max) {
+ ret = dict_get_int32(dict, key, &maxcount);
+ if (ret < 0)
+ gf_msg_debug(this->name, 0, " Failed to fetch the value for key %s",
+ GLUSTERFS_INODELK_COUNT);
+ }
+ count = get_inodelk_count(this, inode, domname);
+ if (maxcount >= count)
+ return;
+
+ ret = dict_set_int32(dict, key, count);
+ if (ret < 0) {
+ gf_msg_debug(this->name, 0,
+ "Failed to set count for "
+ "key %s",
+ key);
+ }
+
+ return;
+}
+
+static int
+pl_inodelk_xattr_fill_multiple(dict_t *this, char *key, data_t *value,
+ void *data)
+{
+ multi_dom_lk_data *d = data;
+ char *tmp_key = NULL;
+ char *save_ptr = NULL;
+
+ tmp_key = gf_strdup(key);
+ strtok_r(tmp_key, ":", &save_ptr);
+ GF_ASSERT(*save_ptr); // Should contain the domain string.
+
+ pl_inodelk_xattr_fill_each(d->this, d->inode, d->xdata_rsp, save_ptr,
+ d->keep_max, key);
+ if (tmp_key)
+ GF_FREE(tmp_key);
+
+ return 0;
+}
+
+void
+pl_fill_multiple_dom_lk_requests(xlator_t *this, pl_local_t *local,
+ inode_t *inode, dict_t *dict,
+ gf_boolean_t keep_max)
+{
+ multi_dom_lk_data data;
+
+ data.this = this;
+ data.inode = inode;
+ data.xdata_rsp = dict;
+ data.keep_max = keep_max;
+
+ dict_foreach_fnmatch(local->xdata, GLUSTERFS_INODELK_DOM_PREFIX "*",
+ pl_inodelk_xattr_fill_multiple, &data);
+}
+
+void
pl_set_xdata_response(xlator_t *this, pl_local_t *local, inode_t *parent,
inode_t *inode, char *name, dict_t *xdata,
gf_boolean_t max_lock)
@@ -437,6 +516,9 @@ pl_set_xdata_response(xlator_t *this, pl_local_t *local, inode_t *parent,
if (local->posixlk_count_req)
pl_posixlk_xattr_fill(this, inode, xdata, max_lock);
+
+ if (local->multiple_dom_lk_requests)
+ pl_fill_multiple_dom_lk_requests(this, local, inode, xdata, max_lock);
}
/* Checks whether the region where fop is acting upon conflicts
@@ -775,9 +857,6 @@ pl_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
{
pl_local_t *local = frame->local;
- if (local->xdata)
- dict_unref(local->xdata);
-
pl_track_io_fop_count(local, this, DECREMENT);
if (local->op == GF_FOP_TRUNCATE)
@@ -935,9 +1014,6 @@ unwind:
"ret: %d, error: %s",
op_ret, strerror(op_errno));
- if (local->xdata)
- dict_unref(local->xdata);
-
switch (local->op) {
case GF_FOP_TRUNCATE:
PL_STACK_UNWIND(truncate, xdata, frame, op_ret, op_errno, buf,