summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/dict.c155
-rw-r--r--libglusterfs/src/dict.h9
-rw-r--r--libglusterfs/src/libglusterfs.sym4
-rw-r--r--rpc/xdr/src/glusterfs-fops.x2
-rw-r--r--rpc/xdr/src/glusterfs4-xdr.x30
-rw-r--r--rpc/xdr/src/rpc-common-xdr.x22
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c2
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c4
-rw-r--r--xlators/storage/posix/src/posix-entry-ops.c12
-rw-r--r--xlators/storage/posix/src/posix-helpers.c8
-rw-r--r--xlators/storage/posix/src/posix.h4
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" \