From 92430596d697381d5f49ff69eb24d9ff3e291da8 Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Wed, 27 Dec 2017 16:14:30 +0530 Subject: dict: add more types for values Added 2 more types which are present in gluster codebase, mainly IATT and UUID. Updates #203 Change-Id: Ib6d6d6aefb88c3494fbf93dcbe08d9979484968f Signed-off-by: Amar Tumballi --- libglusterfs/src/dict.c | 155 ++++++++++++++++++++++++++-- libglusterfs/src/dict.h | 9 ++ libglusterfs/src/libglusterfs.sym | 4 + rpc/xdr/src/glusterfs-fops.x | 2 + rpc/xdr/src/glusterfs4-xdr.x | 30 +++++- rpc/xdr/src/rpc-common-xdr.x | 22 ---- xlators/mount/fuse/src/fuse-bridge.c | 2 +- xlators/mount/fuse/src/fuse-resolve.c | 4 +- xlators/storage/posix/src/posix-entry-ops.c | 12 +-- xlators/storage/posix/src/posix-helpers.c | 8 +- xlators/storage/posix/src/posix.h | 4 +- 11 files changed, 208 insertions(+), 44 deletions(-) diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index 1ce176e381c..fec0371cad0 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -30,6 +30,7 @@ #include "glusterfs-fops.h" #include "rpc-common-xdr.h" +#include "glusterfs3.h" struct dict_cmp { dict_t *dict; @@ -989,7 +990,6 @@ bin_to_data (void *value, int32_t len) data->is_static = 1; data->len = len; data->data = value; - data->data_type = GF_DATA_TYPE_PTR; return data; } @@ -1001,6 +1001,8 @@ static char *data_type_name[GF_DATA_TYPE_MAX] = { [GF_DATA_TYPE_DOUBLE] = "float", [GF_DATA_TYPE_STR] = "string", [GF_DATA_TYPE_PTR] = "pointer", + [GF_DATA_TYPE_GFUUID] = "gf-uuid", + [GF_DATA_TYPE_IATT] = "iatt", }; int64_t @@ -2335,7 +2337,7 @@ err: *******************************************************************/ static int dict_set_bin_common (dict_t *this, char *key, void *ptr, size_t size, - gf_boolean_t is_static) + gf_boolean_t is_static, gf_dict_data_type_t type) { data_t * data = NULL; int ret = 0; @@ -2352,6 +2354,7 @@ dict_set_bin_common (dict_t *this, char *key, void *ptr, size_t size, } data->is_static = is_static; + data->data_type = type; ret = dict_set (this, key, data); if (ret < 0) { @@ -2374,7 +2377,8 @@ err: int dict_set_bin (dict_t *this, char *key, void *ptr, size_t size) { - return dict_set_bin_common (this, key, ptr, size, _gf_false); + return dict_set_bin_common (this, key, ptr, size, _gf_false, + GF_DATA_TYPE_PTR); } /******************************************************************** @@ -2387,7 +2391,73 @@ dict_set_bin (dict_t *this, char *key, void *ptr, size_t size) int dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size) { - return dict_set_bin_common (this, key, ptr, size, _gf_true); + return dict_set_bin_common (this, key, ptr, size, _gf_true, + GF_DATA_TYPE_PTR); +} + +/* */ +int +dict_set_gfuuid (dict_t *this, char *key, uuid_t gfid, bool is_static) +{ + return dict_set_bin_common (this, key, gfid, sizeof (uuid_t), + is_static, GF_DATA_TYPE_GFUUID); +} + +int +dict_get_gfuuid (dict_t *this, char *key, uuid_t *gfid) +{ + data_t *data = NULL; + int ret = -EINVAL; + + if (!this || !key || !gfid) { + goto err; + } + ret = dict_get_with_ref (this, key, &data); + if (ret < 0) { + goto err; + } + + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_GFUUID, -EINVAL); + + memcpy (*gfid, data->data, min(data->len, sizeof (uuid_t))); + +err: + if (data) + data_unref (data); + + return ret; +} + +int +dict_set_iatt (dict_t *this, char *key, struct iatt *iatt, bool is_static) +{ + return dict_set_bin_common (this, key, iatt, sizeof (struct iatt), + is_static, GF_DATA_TYPE_IATT); +} + +int +dict_get_iatt (dict_t *this, char *key, struct iatt *iatt) +{ + data_t *data = NULL; + int ret = -EINVAL; + + if (!this || !key || !iatt) { + goto err; + } + ret = dict_get_with_ref (this, key, &data); + if (ret < 0) { + goto err; + } + + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, -EINVAL); + + memcpy (iatt, data->data, min(data->len, sizeof (struct iatt))); + +err: + if (data) + data_unref (data); + + return ret; } @@ -3165,9 +3235,19 @@ dict_to_xdr (dict_t *this, gfx_dict *dict) data_pair_t *dpair = NULL; gfx_dict_pair *xpair = NULL; - if (!this || !dict) + /* This is a failure as we expect destination to be valid */ + if (!dict) goto out; + /* This is OK as dictionary can be null, in which case, destination + will be set as 0 sized dictionary */ + if (!this) { + ret = 0; + dict->count = 0; + dict->pairs.pairs_len = 0; + goto out; + } + dict->pairs.pairs_val = GF_CALLOC (1, (this->count * sizeof (gfx_dict_pair)), gf_common_mt_char); @@ -3202,9 +3282,41 @@ dict_to_xdr (dict_t *this, gfx_dict *dict) xpair->value.gfx_value_u.val_string.val_string_val = dpair->value->data; xpair->value.gfx_value_u.val_string.val_string_len = dpair->value->len; break; + case GF_DATA_TYPE_IATT: + index++; + gf_stat_from_iatt (&xpair->value.gfx_value_u.iatt, + (struct iatt *)dpair->value->data); + break; + case GF_DATA_TYPE_GFUUID: + index++; + memcpy (&xpair->value.gfx_value_u.uuid, + dpair->value->data, sizeof (uuid_t)); + break; + + case GF_DATA_TYPE_PTR: + index++; + /* Ideally, each type of data stored in dictionary + should have type. A pointer type shouldn't be + sent on wire */ + + /* This is done for backward compatibility as dict is + heavily used for transporting data over wire. + Ideally, whereever there is an issue, fix and move on */ + xpair->value.gfx_value_u.other.other_val = + dpair->value->data; + xpair->value.gfx_value_u.other.other_len = + dpair->value->len; + + /* Change this to INFO, after taking the above down */ + gf_msg ("dict", GF_LOG_INFO, EINVAL, + LG_MSG_DICT_SERIAL_FAILED, + "key '%s' is would not be sent on wire in future", + dpair->key); + break; default: /* Unknown type and ptr type is not sent on wire */ - gf_log ("", GF_LOG_INFO, "%s is not sent on wire", dpair->key); + gf_msg ("dict", GF_LOG_WARNING, EINVAL, LG_MSG_DICT_SERIAL_FAILED, + "key '%s' is not sent on wire", dpair->key); break; } @@ -3227,6 +3339,8 @@ xdr_to_dict (gfx_dict *dict, dict_t **to) char *value = NULL; gfx_dict_pair *xpair = NULL; dict_t *this = NULL; + unsigned char *uuid = NULL; + struct iatt *iatt = NULL; if (!to || !dict) goto out; @@ -3263,6 +3377,35 @@ xdr_to_dict (gfx_dict *dict, dict_t **to) free (xpair->value.gfx_value_u.val_string.val_string_val); ret = dict_set_dynstr (this, key, value); break; + case GF_DATA_TYPE_GFUUID: + uuid = GF_CALLOC (1, 20, gf_common_mt_uuid_t); + if (!uuid) { + errno = ENOMEM; + goto out; + } + memcpy (uuid, xpair->value.gfx_value_u.uuid, 16); + ret = dict_set_gfuuid (this, key, uuid, false); + break; + case GF_DATA_TYPE_IATT: + iatt = GF_CALLOC (1, sizeof (struct iatt), gf_common_mt_char); + if (!iatt) { + errno = ENOMEM; + goto out; + } + gf_stat_to_iatt (&xpair->value.gfx_value_u.iatt, iatt); + ret = dict_set_iatt (this, key, iatt, false); + break; + case GF_DATA_TYPE_PTR: + value = gf_memdup (xpair->value.gfx_value_u.other.other_val, + xpair->value.gfx_value_u.other.other_len); + if (!value) { + errno = ENOMEM; + goto out; + } + free (xpair->value.gfx_value_u.other.other_val); + ret = dict_set_dynptr (this, key, value, + xpair->value.gfx_value_u.other.other_len); + break; default: ret = 0; /* Unknown type and ptr type is not sent on wire */ diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h index fab609cd31b..dfd4baf25ab 100644 --- a/libglusterfs/src/dict.h +++ b/libglusterfs/src/dict.h @@ -248,6 +248,15 @@ GF_MUST_CHECK int dict_get_str_boolean (dict_t *this, char *key, int default_val GF_MUST_CHECK int dict_rename_key (dict_t *this, char *key, char *replace_key); GF_MUST_CHECK int dict_serialize_value_with_delim (dict_t *this, char *buf, int32_t *serz_len, char delimiter); + +GF_MUST_CHECK int dict_set_gfuuid (dict_t *this, char *key, uuid_t uuid, + bool is_static); +GF_MUST_CHECK int dict_get_gfuuid (dict_t *this, char *key, uuid_t *uuid); + +GF_MUST_CHECK int dict_set_iatt (dict_t *this, char *key, struct iatt *iatt, + bool is_static); +GF_MUST_CHECK int dict_get_iatt (dict_t *this, char *key, struct iatt *iatt); + void dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain); diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 433ac53538d..1efb2b18207 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -362,6 +362,8 @@ dict_for_key_value dict_get dict_get_bin dict_get_double +dict_get_gfuuid +dict_get_iatt dict_get_int16 dict_get_int32 dict_get_int64 @@ -392,6 +394,8 @@ dict_set_double dict_set_dynptr dict_set_dynstr dict_set_dynstr_with_alloc +dict_set_gfuuid +dict_set_iatt dict_set_int16 dict_set_int32 dict_set_int64 diff --git a/rpc/xdr/src/glusterfs-fops.x b/rpc/xdr/src/glusterfs-fops.x index 44e5d9191a2..1cb2d83c161 100644 --- a/rpc/xdr/src/glusterfs-fops.x +++ b/rpc/xdr/src/glusterfs-fops.x @@ -239,5 +239,7 @@ enum gf_dict_data_type_t { GF_DATA_TYPE_DOUBLE, GF_DATA_TYPE_STR, GF_DATA_TYPE_PTR, + GF_DATA_TYPE_GFUUID, + GF_DATA_TYPE_IATT, GF_DATA_TYPE_MAX }; diff --git a/rpc/xdr/src/glusterfs4-xdr.x b/rpc/xdr/src/glusterfs4-xdr.x index a4fc9b22850..7396b566fa7 100644 --- a/rpc/xdr/src/glusterfs4-xdr.x +++ b/rpc/xdr/src/glusterfs4-xdr.x @@ -12,10 +12,38 @@ %#include "rpc-pragmas.h" #endif %#include "compat.h" -%#include "rpc-common-xdr.h" %#include "glusterfs-fops.h" %#include "glusterfs3-xdr.h" + +union gfx_value switch (gf_dict_data_type_t type) { + case GF_DATA_TYPE_INT: + hyper value_int; + case GF_DATA_TYPE_UINT: + unsigned hyper value_uint; + case GF_DATA_TYPE_DOUBLE: + double value_dbl; + case GF_DATA_TYPE_STR: + opaque val_string<>; + case GF_DATA_TYPE_IATT: + gf_iatt iatt; + case GF_DATA_TYPE_GFUUID: + opaque uuid[20]; + case GF_DATA_TYPE_PTR: + opaque other<>; +}; + +struct gfx_dict_pair { + opaque key<>; + gfx_value value; +}; + +struct gfx_dict { + unsigned int count; + gfx_dict_pair pairs<>; +}; + +/* fops */ struct gfs3_fsetattr_req_v2 { opaque gfid[16]; hyper fd; diff --git a/rpc/xdr/src/rpc-common-xdr.x b/rpc/xdr/src/rpc-common-xdr.x index 1af7c8041ed..b01d282f368 100644 --- a/rpc/xdr/src/rpc-common-xdr.x +++ b/rpc/xdr/src/rpc-common-xdr.x @@ -65,25 +65,3 @@ struct gf_common_rsp { int op_errno; opaque xdata<>; /* Extra data */ } ; - - -union gfx_value switch (gf_dict_data_type_t type) { - case GF_DATA_TYPE_INT: - hyper value_int; - case GF_DATA_TYPE_UINT: - unsigned hyper value_uint; - case GF_DATA_TYPE_DOUBLE: - double value_dbl; - case GF_DATA_TYPE_STR: - opaque val_string<>; -}; - -struct gfx_dict_pair { - opaque key<>; - gfx_value value; -}; - -struct gfx_dict { - unsigned int count; - gfx_dict_pair pairs<>; -}; diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 4e075904936..ddf6d59eb3e 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -4257,7 +4257,7 @@ fuse_first_lookup (xlator_t *this) memset (gfid, 0, 16); gfid[15] = 1; - ret = dict_set_static_bin (dict, "gfid-req", gfid, 16); + ret = dict_set_gfuuid (dict, "gfid-req", gfid, true); if (ret) { gf_log (xl->name, GF_LOG_ERROR, "failed to set 'gfid-req'"); goto out; diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c index 7d3494f5419..ed25bf034b8 100644 --- a/xlators/mount/fuse/src/fuse-resolve.c +++ b/xlators/mount/fuse/src/fuse-resolve.c @@ -585,8 +585,8 @@ fuse_gfid_set (fuse_state_t *state) goto out; } - ret = dict_set_static_bin (state->xdata, "gfid-req", - state->gfid, sizeof (state->gfid)); + ret = dict_set_gfuuid (state->xdata, "gfid-req", + state->gfid, true); out: return ret; } diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c index 050fea4c255..5fb3a4b09c8 100644 --- a/xlators/storage/posix/src/posix-entry-ops.c +++ b/xlators/storage/posix/src/posix-entry-ops.c @@ -314,7 +314,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, gid_t gid = 0; struct iatt preparent = {0,}; struct iatt postparent = {0,}; - void * uuid_req = NULL; + uuid_t uuid_req = {0,}; int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; @@ -366,7 +366,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, linkfile may be for a hardlinked file */ if (dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) { dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY); - op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); + op_ret = dict_get_gfuuid (xdata, "gfid-req", &uuid_req); if (op_ret) { gf_msg_debug (this->name, 0, "failed to get the gfid from " "dict for %s", loc->path); @@ -523,7 +523,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, struct iatt preparent = {0,}; struct iatt postparent = {0,}; gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false; - void *uuid_req = NULL; + uuid_t uuid_req = {0,}; ssize_t size = 0; dict_t *xdata_rsp = NULL; void *disk_xattr = NULL; @@ -580,7 +580,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, mode = posix_override_umask (mode, mode_bit); if (xdata) { - op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req); + op_ret = dict_get_gfuuid (xdata, "gfid-req", &uuid_req); if (!op_ret && !gf_uuid_compare (stbuf.ia_gfid, uuid_req)) { op_ret = -1; op_errno = EEXIST; @@ -588,7 +588,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, } } - if (uuid_req && !gf_uuid_is_null (uuid_req)) { + if (!gf_uuid_is_null (uuid_req)) { op_ret = posix_istat (this, uuid_req, NULL, &stbuf); if ((op_ret == 0) && IA_ISDIR (stbuf.ia_type)) { size = posix_handle_path (this, uuid_req, NULL, NULL, @@ -624,7 +624,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, * new dir.*/ posix_handle_unset (this, stbuf.ia_gfid, NULL); } - } else if (!uuid_req && frame->root->pid != GF_SERVER_PID_TRASH) { + } else if (frame->root->pid != GF_SERVER_PID_TRASH) { op_ret = -1; op_errno = EPERM; gf_msg_callingfn (this->name, GF_LOG_WARNING, op_errno, diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index e299dcb837c..fa9a120ebcd 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -856,7 +856,7 @@ posix_gfid_unset (xlator_t *this, dict_t *xdata) if (xdata == NULL) goto out; - ret = dict_get_ptr (xdata, "gfid-req", (void **)&uuid); + ret = dict_get_gfuuid (xdata, "gfid-req", &uuid); if (ret) { goto out; } @@ -869,7 +869,7 @@ out: int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) { - void *uuid_req = NULL; + uuid_t uuid_req; uuid_t uuid_curr; int ret = 0; ssize_t size = 0; @@ -888,7 +888,7 @@ posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req) goto verify_handle; } - ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req); + ret = dict_get_gfuuid (xattr_req, "gfid-req", &uuid_req); if (ret) { gf_msg_debug (this->name, 0, "failed to get the gfid from dict for %s", @@ -2705,7 +2705,7 @@ posix_set_iatt_in_dict (dict_t *dict, struct iatt *in_stbuf) memcpy (stbuf, in_stbuf, len); - ret = dict_set_bin (dict, DHT_IATT_IN_XDATA_KEY, stbuf, len); + ret = dict_set_iatt (dict, DHT_IATT_IN_XDATA_KEY, stbuf, false); if (ret) GF_FREE (stbuf); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index c4c28d59977..330ed20b480 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -81,14 +81,14 @@ #define GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xattr_req, op_ret, \ op_errno, out) \ do { \ - void *_uuid_req = NULL; \ + uuid_t _uuid_req; \ int _ret = 0; \ /* TODO: Remove pid check once trash implements client side \ * logic to assign gfid for entry creations inside .trashcan \ */ \ if (frame->root->pid == GF_SERVER_PID_TRASH) \ break; \ - _ret = dict_get_ptr (xattr_req, "gfid-req", &_uuid_req); \ + _ret = dict_get_gfuuid (xattr_req, "gfid-req", &_uuid_req); \ if (_ret) { \ gf_msg (this->name, GF_LOG_ERROR, EINVAL, \ P_MSG_NULL_GFID, "failed to get the gfid from" \ -- cgit