summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShyamsundarR <srangana@redhat.com>2018-03-10 23:08:04 -0500
committerRaghavendra G <rgowdapp@redhat.com>2018-03-11 15:52:22 +0530
commit03b31d91bad7a694cff863a20843fcf3b1df82f7 (patch)
tree62da23b8230028b1c0ec4c9dd8d13d4d7d68245e
parent95ae89504e302426e96b044c57ec07e81095c4dc (diff)
protocol: Fix 4.0 client, parsing older iatt in dict
In a mixed mode cluster involving 4.0 and older 3.x bricks, if clients are newer, then the iatt encoded in the dictionary can be of the older iatt format, which a newer client will map incorrectly to the newer structure. This causes failures in FOPs that depend on this iatt for some functionality (seen in mkdir operations failing as EIO, when DHT hits its internal setxattr call). The fix provided is to convert the iatt in the dict, based on which RPC version is used to communicate with the server. IOW, this is the reverse of change in commit "b966c7790e" Tested using a mixed mode cluster (i.e bricks in 3.12 and 4.0 versions) and a mixed set of clients, 3.12 and 4.0 clients. There is no regression test provided, as this needs a mixed mode cluster to test and validate. >Change-Id: I454e54651ca836b9f7c28f45f51d5956106aefa9 >BUG: 1554053 >Signed-off-by: ShyamsundarR <srangana@redhat.com> Change-Id: I454e54651ca836b9f7c28f45f51d5956106aefa9 BUG: 1554077 Signed-off-by: ShyamsundarR <srangana@redhat.com> Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--libglusterfs/src/common-utils.c64
-rw-r--r--libglusterfs/src/common-utils.h6
-rw-r--r--libglusterfs/src/iatt.h32
-rw-r--r--libglusterfs/src/libglusterfs.sym2
-rw-r--r--xlators/protocol/client/src/client-common.c10
-rw-r--r--xlators/protocol/server/src/server-helpers.c42
-rw-r--r--xlators/protocol/server/src/server-helpers.h2
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c10
8 files changed, 124 insertions, 44 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 5345924a41d..9ad93550941 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -4983,3 +4983,67 @@ gf_strncpy (char *dest, const char *src, const size_t dest_size)
dest[dest_size - 1] = '\0';
return dest;
}
+
+int
+gf_replace_old_iatt_in_dict (dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* current iatt */
+ int32_t len = sizeof(struct old_iatt);
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **)&c_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ o_iatt = GF_CALLOC (1, len, gf_common_mt_char);
+ if (!o_iatt) {
+ return -1;
+ }
+
+ oldiatt_from_iatt (o_iatt, c_iatt);
+
+ ret = dict_set_bin (xdata, DHT_IATT_IN_XDATA_KEY, o_iatt, len);
+ if (ret) {
+ GF_FREE (o_iatt);
+ }
+
+ return ret;
+}
+
+int
+gf_replace_new_iatt_in_dict (dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* new iatt */
+ int32_t len = sizeof(struct iatt);
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **)&o_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ c_iatt = GF_CALLOC (1, len, gf_common_mt_char);
+ if (!c_iatt) {
+ return -1;
+ }
+
+ iatt_from_oldiatt (c_iatt, o_iatt);
+
+ ret = dict_set_bin (xdata, DHT_IATT_IN_XDATA_KEY, c_iatt, len);
+ if (ret) {
+ GF_FREE (c_iatt);
+ }
+
+ return ret;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index c7f9fd58cc8..c6c82e2696a 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -954,4 +954,10 @@ gf_strncpy (char *dest, const char *src, const size_t dest_size);
void
gf_strTrim (char **s);
+int
+gf_replace_old_iatt_in_dict (struct _dict *);
+
+int
+gf_replace_new_iatt_in_dict (struct _dict *);
+
#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
index 68a81fa9cd0..500ccb01324 100644
--- a/libglusterfs/src/iatt.h
+++ b/libglusterfs/src/iatt.h
@@ -423,6 +423,38 @@ oldiatt_from_iatt (struct old_iatt *o_iatt, struct iatt *c_iatt)
return;
}
+static inline void
+iatt_from_oldiatt (struct iatt *c_iatt, struct old_iatt *o_iatt)
+{
+ c_iatt->ia_dev = o_iatt->ia_dev;
+ c_iatt->ia_ino = o_iatt->ia_ino;
+ c_iatt->ia_type = o_iatt->ia_type;
+ c_iatt->ia_prot = o_iatt->ia_prot;
+ c_iatt->ia_nlink = o_iatt->ia_nlink;
+ c_iatt->ia_uid = o_iatt->ia_uid;
+ c_iatt->ia_gid = o_iatt->ia_gid;
+ c_iatt->ia_rdev = o_iatt->ia_rdev;
+ c_iatt->ia_size = o_iatt->ia_size;
+ c_iatt->ia_blksize = o_iatt->ia_blksize;
+ c_iatt->ia_blocks = o_iatt->ia_blocks;
+ c_iatt->ia_atime = o_iatt->ia_atime;
+ c_iatt->ia_atime_nsec = o_iatt->ia_atime_nsec;
+ c_iatt->ia_mtime = o_iatt->ia_mtime;
+ c_iatt->ia_mtime_nsec = o_iatt->ia_mtime_nsec;
+ c_iatt->ia_ctime = o_iatt->ia_ctime;
+ c_iatt->ia_ctime_nsec = o_iatt->ia_ctime_nsec;
+
+ gf_uuid_copy (c_iatt->ia_gfid, o_iatt->ia_gfid);
+
+ c_iatt->ia_attributes = 0;
+
+ c_iatt->ia_flags = IATT_TYPE | IATT_MODE | IATT_NLINK | IATT_INO |
+ IATT_UID | IATT_GID | IATT_SIZE | IATT_BLOCKS |
+ IATT_ATIME | IATT_MTIME | IATT_CTIME | IATT_GFID;
+
+ return;
+}
+
static inline int
is_same_mode (ia_prot_t prot1, ia_prot_t prot2)
{
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
index 8d263c4cb5c..c2c498cdd7a 100644
--- a/libglusterfs/src/libglusterfs.sym
+++ b/libglusterfs/src/libglusterfs.sym
@@ -1098,3 +1098,5 @@ global_xlator
use_spinlocks
dump_options
glusterfs_leaseid_buf_get
+gf_replace_old_iatt_in_dict
+gf_replace_new_iatt_in_dict \ No newline at end of file
diff --git a/xlators/protocol/client/src/client-common.c b/xlators/protocol/client/src/client-common.c
index 3b4dea1aff1..1d9fbde7c86 100644
--- a/xlators/protocol/client/src/client-common.c
+++ b/xlators/protocol/client/src/client-common.c
@@ -1461,6 +1461,8 @@ client_post_unlink (xlator_t *this, gfs3_unlink_rsp *rsp,
GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),
(rsp->xdata.xdata_len), ret,
rsp->op_errno, out);
+
+ ret = gf_replace_new_iatt_in_dict (*xdata);
out:
return ret;
}
@@ -1679,6 +1681,8 @@ client_post_setxattr (xlator_t *this, gf_common_rsp *rsp, dict_t **xdata)
GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),
(rsp->xdata.xdata_len), ret,
rsp->op_errno, out);
+
+ ret = gf_replace_new_iatt_in_dict (*xdata);
out:
return ret;
}
@@ -1713,6 +1717,8 @@ client_post_removexattr (xlator_t *this, gf_common_rsp *rsp,
GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),
(rsp->xdata.xdata_len), ret,
rsp->op_errno, out);
+
+ ret = gf_replace_new_iatt_in_dict (*xdata);
out:
return ret;
}
@@ -1983,6 +1989,8 @@ client_post_fsetxattr (xlator_t *this, gf_common_rsp *rsp, dict_t **xdata)
GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),
(rsp->xdata.xdata_len), ret,
rsp->op_errno, out);
+
+ ret = gf_replace_new_iatt_in_dict (*xdata);
out:
return ret;
}
@@ -2062,6 +2070,8 @@ client_post_fremovexattr (xlator_t *this, gf_common_rsp *rsp,
GF_PROTOCOL_DICT_UNSERIALIZE (this, *xdata, (rsp->xdata.xdata_val),
(rsp->xdata.xdata_len), ret,
rsp->op_errno, out);
+
+ ret = gf_replace_new_iatt_in_dict (*xdata);
out:
return ret;
}
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 8d6a81fe1e2..84f99ad8945 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1221,38 +1221,6 @@ getactivelkinfo_rsp_cleanup_v2 (gfx_getactivelk_rsp *rsp)
}
int
-replace_old_iatt_in_dict (dict_t *xdata)
-{
- int ret;
- struct old_iatt *o_iatt; /* old iatt structure */
- struct iatt *c_iatt; /* current iatt */
- int32_t len = sizeof(struct old_iatt);
-
- if (!xdata) {
- return 0;
- }
-
- ret = dict_get_bin (xdata, DHT_IATT_IN_XDATA_KEY, (void **)&c_iatt);
- if (ret < 0) {
- return 0;
- }
-
- o_iatt = GF_CALLOC (1, len, gf_common_mt_char);
- if (!o_iatt) {
- return -1;
- }
-
- oldiatt_from_iatt (o_iatt, c_iatt);
-
- ret = dict_set_bin (xdata, DHT_IATT_IN_XDATA_KEY, o_iatt, len);
- if (ret) {
- GF_FREE (o_iatt);
- }
-
- return ret;
-}
-
-int
gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
{
@@ -2494,7 +2462,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
rsp_args = &this_rsp->compound_rsp_u.compound_unlink_rsp;
- if (replace_old_iatt_in_dict (this_args_cbk->xdata)) {
+ if (gf_replace_old_iatt_in_dict (this_args_cbk->xdata)) {
rsp_args->op_errno = errno;
rsp_args->op_ret = -1;
goto out;
@@ -2762,7 +2730,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
rsp_args = &this_rsp->compound_rsp_u.compound_setxattr_rsp;
- if (replace_old_iatt_in_dict (this_args_cbk->xdata)) {
+ if (gf_replace_old_iatt_in_dict (this_args_cbk->xdata)) {
rsp_args->op_errno = errno;
rsp_args->op_ret = -1;
goto out;
@@ -2806,7 +2774,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
rsp_args = &this_rsp->compound_rsp_u.compound_removexattr_rsp;
- if (replace_old_iatt_in_dict (this_args_cbk->xdata)) {
+ if (gf_replace_old_iatt_in_dict (this_args_cbk->xdata)) {
rsp_args->op_errno = errno;
rsp_args->op_ret = -1;
goto out;
@@ -3143,7 +3111,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
rsp_args = &this_rsp->compound_rsp_u.compound_setxattr_rsp;
- if (replace_old_iatt_in_dict (this_args_cbk->xdata)) {
+ if (gf_replace_old_iatt_in_dict (this_args_cbk->xdata)) {
rsp_args->op_errno = errno;
rsp_args->op_ret = -1;
goto out;
@@ -3253,7 +3221,7 @@ server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
rsp_args = &this_rsp->compound_rsp_u.compound_fremovexattr_rsp;
- if (replace_old_iatt_in_dict (this_args_cbk->xdata)) {
+ if (gf_replace_old_iatt_in_dict (this_args_cbk->xdata)) {
rsp_args->op_errno = errno;
rsp_args->op_ret = -1;
goto out;
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 73e2b89b21f..b89105a355f 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -74,8 +74,6 @@ getactivelkinfo_rsp_cleanup (gfs3_getactivelk_rsp *rsp);
int
getactivelkinfo_rsp_cleanup_v2 (gfx_getactivelk_rsp *rsp);
-int replace_old_iatt_in_dict (dict_t *);
-
int
server_populate_compound_response (xlator_t *this, gfs3_compound_rsp *rsp,
call_frame_t *frame,
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
index 45cd5b68048..64bb9f0f2b8 100644
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -724,7 +724,7 @@ server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
server_state_t *state = NULL;
gf_loglevel_t loglevel = GF_LOG_NONE;
- if (replace_old_iatt_in_dict (xdata)) {
+ if (gf_replace_old_iatt_in_dict (xdata)) {
op_errno = errno;
op_ret = -1;
goto out;
@@ -772,7 +772,7 @@ server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- if (replace_old_iatt_in_dict (xdata)) {
+ if (gf_replace_old_iatt_in_dict (xdata)) {
op_errno = errno;
op_ret = -1;
goto out;
@@ -921,7 +921,7 @@ server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- if (replace_old_iatt_in_dict (xdata)) {
+ if (gf_replace_old_iatt_in_dict (xdata)) {
op_errno = errno;
op_ret = -1;
goto out;
@@ -992,7 +992,7 @@ server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- if (replace_old_iatt_in_dict (xdata)) {
+ if (gf_replace_old_iatt_in_dict (xdata)) {
op_errno = errno;
op_ret = -1;
goto out;
@@ -1090,7 +1090,7 @@ server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- if (replace_old_iatt_in_dict (xdata)) {
+ if (gf_replace_old_iatt_in_dict (xdata)) {
op_errno = errno;
op_ret = -1;
goto out;