glusterfs  8.2
About: GlusterFS is a network/cluster filesystem. The storage server (or each in a cluster) runs glusterfsd and the clients use mount command or glusterfs client to mount the exported filesystem. Release series 8.x (latest version).
  Fossies Dox: glusterfs-8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

dict.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3  This file is part of GlusterFS.
4 
5  This file is licensed to you under your choice of the GNU Lesser
6  General Public License, version 3 or any later version (LGPLv3 or
7  later), or the GNU General Public License, version 2 (GPLv2), in all
8  cases as published by the Free Software Foundation.
9 */
10 
11 #include <unistd.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <inttypes.h>
16 #include <limits.h>
17 #include <fnmatch.h>
18 
19 #include "glusterfs/dict.h"
20 #define XXH_INLINE_ALL
21 #include "xxhash.h"
22 #include "glusterfs/compat.h"
23 #include "glusterfs/compat-errno.h"
24 #include "glusterfs/byte-order.h"
25 #include "glusterfs/statedump.h"
27 
28 struct dict_cmp {
31 };
32 
33 #define VALIDATE_DATA_AND_LOG(data, type, key, ret_val) \
34  do { \
35  if (!data || !data->data) { \
36  gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
37  "data is NULL"); \
38  return ret_val; \
39  } \
40  /* Not of the asked type, or old version */ \
41  if ((data->data_type != type) && \
42  (data->data_type != GF_DATA_TYPE_STR_OLD)) { \
43  gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
44  "key %s, %s type asked, has %s type", key, \
45  data_type_name[type], \
46  data_type_name[data->data_type]); \
47  } \
48  } while (0)
49 
50 static data_t *
52 {
53  data_t *data = mem_get(THIS->ctx->dict_data_pool);
54 
55  if (!data)
56  return NULL;
57 
58  GF_ATOMIC_INIT(data->refcount, 0);
59  data->is_static = _gf_false;
60 
61  return data;
62 }
63 
64 static dict_t *
65 get_new_dict_full(int size_hint)
66 {
67  dict_t *dict = mem_get0(THIS->ctx->dict_pool);
68 
69  if (!dict) {
70  return NULL;
71  }
72 
73  dict->hash_size = size_hint;
74  if (size_hint == 1) {
75  /*
76  * This is the only case we ever see currently. If we ever
77  * need to support resizing the hash table, the resize function
78  * will have to take into account the possibility that
79  * "members" is not separately allocated (i.e. don't just call
80  * realloc() blindly.
81  */
82  dict->members = &dict->members_internal;
83  } else {
84  /*
85  * We actually need to allocate space for size_hint *pointers*
86  * but we actually allocate space for one *structure*. Since
87  * a data_pair_t consists of five pointers, we're wasting four
88  * pointers' worth for N=1, and will overrun what we allocated
89  * for N>5. If anybody ever starts using size_hint, we'll need
90  * to fix this.
91  */
92  GF_ASSERT(size_hint <= (sizeof(data_pair_t) / sizeof(data_pair_t *)));
93  dict->members = mem_get0(THIS->ctx->dict_pair_pool);
94  if (!dict->members) {
95  mem_put(dict);
96  return NULL;
97  }
98  }
99 
100  dict->free_pair.key = NULL;
101  LOCK_INIT(&dict->lock);
102 
103  return dict;
104 }
105 
106 dict_t *
107 dict_new(void)
108 {
109  dict_t *dict = get_new_dict_full(1);
110 
111  if (dict)
112  dict_ref(dict);
113 
114  return dict;
115 }
116 
117 int32_t
119 {
120  struct iatt *iatt1, *iatt2;
121  struct mdata_iatt *mdata_iatt1, *mdata_iatt2;
122 
123  if (!one || !two || !one->data || !two->data) {
125  "input arguments are provided "
126  "with value data_t as NULL");
127  return -1;
128  }
129 
130  if (one == two)
131  return 1;
132 
133  if (one->data == two->data)
134  return 1;
135 
136  if (one->data_type != two->data_type) {
137  return 0;
138  }
139 
140  if (one->data_type == GF_DATA_TYPE_IATT) {
141  if ((one->len < sizeof(struct iatt)) ||
142  (two->len < sizeof(struct iatt))) {
143  return 0;
144  }
145 
146  iatt1 = (struct iatt *)one->data;
147  iatt2 = (struct iatt *)two->data;
148 
149  /* Two iatt structs are considered equal if main fields are
150  * equal, even if times differ.
151  * TODO: maybe when ctime if fully operational we could
152  * enforce time matching. */
153  if (iatt1->ia_ino != iatt2->ia_ino) {
154  return 0;
155  }
156  if (iatt1->ia_type != iatt2->ia_type) {
157  return 0;
158  }
159  if ((iatt1->ia_type == IA_IFBLK) || (iatt1->ia_type == IA_IFCHR)) {
160  if (iatt1->ia_rdev != iatt2->ia_rdev) {
161  return 0;
162  }
163  }
164  if (gf_uuid_compare(iatt1->ia_gfid, iatt2->ia_gfid) != 0) {
165  return 0;
166  }
167 
168  /* TODO: ia_uid, ia_gid, ia_prot and ia_size can be changed
169  * with some commands. Here we don't have enough
170  * information to decide if they should match or not. */
171  /*
172  if ((iatt1->ia_uid != iatt2->ia_uid) ||
173  (iatt1->ia_gid != iatt2->ia_gid) ||
174  (st_mode_from_ia(iatt1->ia_prot, iatt1->ia_type) !=
175  st_mode_from_ia(iatt2->ia_prot,
176  iatt2->ia_type))) { return 0;
177  }
178  if (iatt1->ia_type == IA_IFREG) {
179  if (iatt1->ia_size != iatt2->ia_size) {
180  return 0;
181  }
182  }
183  */
184  return 1;
185  }
186  if (one->data_type == GF_DATA_TYPE_MDATA) {
187  if ((one->len < sizeof(struct mdata_iatt)) ||
188  (two->len < sizeof(struct mdata_iatt))) {
189  return 0;
190  }
191  mdata_iatt1 = (struct mdata_iatt *)one->data;
192  mdata_iatt2 = (struct mdata_iatt *)two->data;
193 
194  if (mdata_iatt1->ia_atime != mdata_iatt2->ia_atime ||
195  mdata_iatt1->ia_mtime != mdata_iatt2->ia_mtime ||
196  mdata_iatt1->ia_ctime != mdata_iatt2->ia_ctime ||
197  mdata_iatt1->ia_atime_nsec != mdata_iatt2->ia_atime_nsec ||
198  mdata_iatt1->ia_mtime_nsec != mdata_iatt2->ia_mtime_nsec ||
199  mdata_iatt1->ia_ctime_nsec != mdata_iatt2->ia_ctime_nsec) {
200  return 0;
201  }
202  return 1;
203  }
204 
205  if (one->len != two->len)
206  return 0;
207 
208  if (memcmp(one->data, two->data, one->len) == 0)
209  return 1;
210 
211  return 0;
212 }
213 
214 static int
215 key_value_cmp(dict_t *one, char *key1, data_t *value1, void *data)
216 {
217  struct dict_cmp *cmp = data;
218  dict_t *two = cmp->dict;
219  data_t *value2 = dict_get(two, key1);
220 
221  if (value2) {
222  if (cmp->value_ignore && cmp->value_ignore(key1))
223  return 0;
224 
225  if (is_data_equal(value1, value2) == 1)
226  return 0;
227  }
228 
229  if (value2 == NULL) {
230  gf_msg_debug(THIS->name, 0, "'%s' found only on one dict", key1);
231  } else {
232  gf_msg_debug(THIS->name, 0,
233  "'%s' is different in two dicts "
234  "(%u, %u)",
235  key1, value1->len, value2->len);
236  }
237 
238  return -1;
239 }
240 
241 /* If both dicts are NULL then equal. If one of the dicts is NULL but the
242  * other has only ignorable keys then also they are equal. If both dicts are
243  * non-null then check if for each non-ignorable key, values are same or
244  * not. value_ignore function is used to skip comparing values for the keys
245  * which must be present in both the dictionaries but the value could be
246  * different.
247  */
250  gf_boolean_t (*match)(dict_t *d, char *k, data_t *v,
251  void *data),
252  gf_boolean_t (*value_ignore)(char *k))
253 {
254  int num_matches1 = 0;
255  int num_matches2 = 0;
256  struct dict_cmp cmp = {0};
257 
258  if (one == two)
259  return _gf_true;
260 
261  if (!match)
262  match = dict_match_everything;
263 
264  if ((one == NULL) || (two == NULL)) {
265  num_matches1 = dict_foreach_match(one ? one : two, match, NULL,
266  dict_null_foreach_fn, NULL);
267  goto done;
268  }
269 
270  cmp.dict = two;
272  num_matches1 = dict_foreach_match(one, match, NULL, key_value_cmp, &cmp);
273 
274  if (num_matches1 == -1)
275  return _gf_false;
276 
277  if ((num_matches1 == one->count) && (one->count == two->count))
278  return _gf_true;
279 
280  num_matches2 = dict_foreach_match(two, match, NULL, dict_null_foreach_fn,
281  NULL);
282 done:
283  /* If the number of matches is same in 'two' then for all the
284  * valid-keys that exist in 'one' the value matched and no extra valid
285  * keys exist in 'two' alone. Otherwise there exists at least one extra
286  * valid-key in 'two' which doesn't exist in 'one' */
287  if (num_matches1 == num_matches2)
288  return _gf_true;
289  return _gf_false;
290 }
291 
292 void
294 {
295  if (data) {
296  if (!data->is_static)
297  GF_FREE(data->data);
298 
299  data->len = 0xbabababa;
300  mem_put(data);
301  }
302 }
303 
304 data_t *
306 {
307  if (!old) {
309  "old is NULL");
310  return NULL;
311  }
312 
313  data_t *newdata = mem_get0(THIS->ctx->dict_data_pool);
314  if (!newdata) {
315  return NULL;
316  }
317 
318  newdata->len = old->len;
319  if (old->data) {
320  newdata->data = gf_memdup(old->data, old->len);
321  if (!newdata->data)
322  goto err_out;
323  }
324  newdata->data_type = old->data_type;
325 
326  return newdata;
327 
328 err_out:
329  mem_put(newdata);
330 
331  return NULL;
332 }
333 
334 /* Always need to be called under lock
335  * Always this and key variables are not null -
336  * checked by callers.
337  */
338 static data_pair_t *
339 dict_lookup_common(const dict_t *this, const char *key, const uint32_t hash)
340 {
341  int hashval = 0;
342  data_pair_t *pair;
343 
344  /* If the divisor is 1, the modulo is always 0,
345  * in such case avoid hash calculation.
346  */
347  if (this->hash_size != 1)
348  hashval = hash % this->hash_size;
349 
350  for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
351  if (pair->key && (hash == pair->key_hash) && !strcmp(pair->key, key))
352  return pair;
353  }
354 
355  return NULL;
356 }
357 
358 int32_t
359 dict_lookup(dict_t *this, char *key, data_t **data)
360 {
361  if (!this || !key || !data) {
363  "!this || !key || "
364  "!data");
365  return -1;
366  }
367 
368  data_pair_t *tmp = NULL;
369 
370  uint32_t hash = (uint32_t)XXH64(key, strlen(key), 0);
371 
372  LOCK(&this->lock);
373  {
374  tmp = dict_lookup_common(this, key, hash);
375  }
376  UNLOCK(&this->lock);
377 
378  if (!tmp)
379  return -1;
380 
381  *data = tmp->value;
382  return 0;
383 }
384 
385 static int32_t
386 dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value,
387  const uint32_t hash, gf_boolean_t replace)
388 {
389  int hashval = 0;
390  data_pair_t *pair;
391  int key_free = 0;
392  uint32_t key_hash;
393  int keylen;
394 
395  if (!key) {
396  keylen = gf_asprintf(&key, "ref:%p", value);
397  if (-1 == keylen) {
398  return -1;
399  }
400  key_free = 1;
401  key_hash = (uint32_t)XXH64(key, keylen, 0);
402  } else {
403  keylen = key_len;
404  key_hash = hash;
405  }
406 
407  /* Search for a existing key if 'replace' is asked for */
408  if (replace) {
409  pair = dict_lookup_common(this, key, key_hash);
410  if (pair) {
411  data_t *unref_data = pair->value;
412  pair->value = data_ref(value);
413  data_unref(unref_data);
414  if (key_free)
415  GF_FREE(key);
416  /* Indicates duplicate key */
417  return 0;
418  }
419  }
420 
421  if (this->free_pair.key) { /* the free_pair is used */
422  pair = mem_get(THIS->ctx->dict_pair_pool);
423  if (!pair) {
424  if (key_free)
425  GF_FREE(key);
426  return -1;
427  }
428  } else { /* assign the pair to the free pair */
429  pair = &this->free_pair;
430  }
431 
432  if (key_free) {
433  /* It's ours. Use it. */
434  pair->key = key;
435  key_free = 0;
436  } else {
437  pair->key = (char *)GF_MALLOC(keylen + 1, gf_common_mt_char);
438  if (!pair->key) {
439  if (pair != &this->free_pair) {
440  mem_put(pair);
441  }
442  return -1;
443  }
444  strcpy(pair->key, key);
445  }
446  pair->key_hash = key_hash;
447  pair->value = data_ref(value);
448 
449  /* If the divisor is 1, the modulo is always 0,
450  * in such case avoid hash calculation.
451  */
452  if (this->hash_size != 1) {
453  hashval = (key_hash % this->hash_size);
454  }
455  pair->hash_next = this->members[hashval];
456  this->members[hashval] = pair;
457 
458  pair->next = this->members_list;
459  pair->prev = NULL;
460  if (this->members_list)
461  this->members_list->prev = pair;
462  this->members_list = pair;
463  this->count++;
464 
465  if (key_free)
466  GF_FREE(key);
467 
468  if (this->max_count < this->count)
469  this->max_count = this->count;
470  return 0;
471 }
472 
473 int32_t
474 dict_set(dict_t *this, char *key, data_t *value)
475 {
476  if (key)
477  return dict_setn(this, key, strlen(key), value);
478  else
479  return dict_setn(this, NULL, 0, value);
480 }
481 
482 int32_t
483 dict_setn(dict_t *this, char *key, const int keylen, data_t *value)
484 {
485  int32_t ret;
486  uint32_t key_hash = 0;
487 
488  if (!this || !value) {
490  "!this || !value for "
491  "key=%s",
492  key);
493  return -1;
494  }
495 
496  if (key) {
497  key_hash = (uint32_t)XXH64(key, keylen, 0);
498  }
499 
500  LOCK(&this->lock);
501 
502  ret = dict_set_lk(this, key, keylen, value, key_hash, 1);
503 
504  UNLOCK(&this->lock);
505 
506  return ret;
507 }
508 
509 int32_t
510 dict_add(dict_t *this, char *key, data_t *value)
511 {
512  if (key)
513  return dict_addn(this, key, strlen(key), value);
514  else
515  return dict_addn(this, NULL, 0, value);
516 }
517 
518 int32_t
519 dict_addn(dict_t *this, char *key, const int keylen, data_t *value)
520 {
521  int32_t ret;
522  uint32_t key_hash = 0;
523 
524  if (!this || !value) {
526  "!this || !value for key=%s", key);
527  return -1;
528  }
529 
530  if (key) {
531  key_hash = (uint32_t)XXH64(key, keylen, 0);
532  }
533 
534  LOCK(&this->lock);
535 
536  ret = dict_set_lk(this, key, keylen, value, key_hash, 0);
537 
538  UNLOCK(&this->lock);
539 
540  return ret;
541 }
542 
543 data_t *
544 dict_get(dict_t *this, char *key)
545 {
546  if (!this || !key) {
548  "!this || key=%s", (key) ? key : "()");
549  return NULL;
550  }
551 
552  return dict_getn(this, key, strlen(key));
553 }
554 
555 data_t *
556 dict_getn(dict_t *this, char *key, const int keylen)
557 {
558  data_pair_t *pair;
559  uint32_t hash;
560 
561  if (!this || !key) {
563  "!this || key=%s", (key) ? key : "()");
564  return NULL;
565  }
566 
567  hash = (uint32_t)XXH64(key, keylen, 0);
568 
569  LOCK(&this->lock);
570  {
571  pair = dict_lookup_common(this, key, hash);
572  }
573  UNLOCK(&this->lock);
574 
575  if (pair)
576  return pair->value;
577 
578  return NULL;
579 }
580 
581 int
583 {
584  int ret = -1;
585 
586  if (!this) {
588  "dict passed is NULL");
589  return ret;
590  }
591 
592  LOCK(&this->lock);
593  {
594  ret = this->count;
595  }
596  UNLOCK(&this->lock);
597 
598  return ret;
599 }
600 
601 void
602 dict_del(dict_t *this, char *key)
603 {
604  if (!this || !key) {
606  "!this || key=%s", key);
607  return;
608  }
609 
610  return dict_deln(this, key, strlen(key));
611 }
612 
613 void
614 dict_deln(dict_t *this, char *key, const int keylen)
615 {
616  int hashval = 0;
617  uint32_t hash;
618 
619  if (!this || !key) {
621  "!this || key=%s", key);
622  return;
623  }
624 
625  hash = (uint32_t)XXH64(key, keylen, 0);
626 
627  LOCK(&this->lock);
628 
629  /* If the divisor is 1, the modulo is always 0,
630  * in such case avoid hash calculation.
631  */
632  if (this->hash_size != 1)
633  hashval = hash % this->hash_size;
634 
635  data_pair_t *pair = this->members[hashval];
636  data_pair_t *prev = NULL;
637 
638  while (pair) {
639  if ((hash == pair->key_hash) && strcmp(pair->key, key) == 0) {
640  if (prev)
641  prev->hash_next = pair->hash_next;
642  else
643  this->members[hashval] = pair->hash_next;
644 
645  data_unref(pair->value);
646 
647  if (pair->prev)
648  pair->prev->next = pair->next;
649  else
650  this->members_list = pair->next;
651 
652  if (pair->next)
653  pair->next->prev = pair->prev;
654 
655  GF_FREE(pair->key);
656  if (pair == &this->free_pair) {
657  this->free_pair.key = NULL;
658  } else {
659  mem_put(pair);
660  }
661  this->count--;
662  break;
663  }
664 
665  prev = pair;
666  pair = pair->hash_next;
667  }
668 
669  UNLOCK(&this->lock);
670 
671  return;
672 }
673 
674 void
676 {
677  if (!this) {
679  "dict is NULL");
680  return;
681  }
682 
683  data_pair_t *pair = this->members_list;
684  data_pair_t *prev = this->members_list;
685  glusterfs_ctx_t *ctx = NULL;
686  uint64_t current_max = 0;
687  uint32_t total_pairs = 0;
688 
689  LOCK_DESTROY(&this->lock);
690 
691  while (prev) {
692  pair = pair->next;
693  data_unref(prev->value);
694  GF_FREE(prev->key);
695  if (prev != &this->free_pair) {
696  mem_put(prev);
697  } else {
698  this->free_pair.key = NULL;
699  }
700  total_pairs++;
701  prev = pair;
702  }
703 
704  if (this->members != &this->members_internal) {
705  mem_put(this->members);
706  }
707 
708  free(this->extra_stdfree);
709 
710  /* update 'ctx->stats.dict.details' using max_count */
711  ctx = THIS->ctx;
712 
713  /* NOTE: below logic is not totaly race proof */
714  /* thread0 and thread1 gets current_max as 10 */
715  /* thread0 has 'this->max_count as 11 */
716  /* thread1 has 'this->max_count as 20 */
717  /* thread1 goes ahead and sets the max_dict_pairs to 20 */
718  /* thread0 then goes and sets it to 11 */
719  /* As it is for information purpose only, no functionality will be
720  broken by this, but a point to consider about ATOMIC macros. */
721  current_max = GF_ATOMIC_GET(ctx->stats.max_dict_pairs);
722  if (current_max < this->max_count)
723  GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, this->max_count);
724 
725  GF_ATOMIC_ADD(ctx->stats.total_pairs_used, total_pairs);
727 
728  mem_put(this);
729 
730  return;
731 }
732 
733 void
735 {
736  uint64_t ref = 0;
737 
738  if (!this) {
740  "dict is NULL");
741  return;
742  }
743 
744  ref = GF_ATOMIC_DEC(this->refcount);
745 
746  if (!ref)
747  dict_destroy(this);
748 }
749 
750 dict_t *
752 {
753  if (!this) {
755  "dict is NULL");
756  return NULL;
757  }
758 
759  GF_ATOMIC_INC(this->refcount);
760  return this;
761 }
762 
763 void
765 {
766  uint64_t ref;
767 
768  if (!this) {
770  "data is NULL");
771  return;
772  }
773 
774  ref = GF_ATOMIC_DEC(this->refcount);
775 
776  if (!ref)
777  data_destroy(this);
778 }
779 
780 data_t *
782 {
783  if (!this) {
785  "data is NULL");
786  return NULL;
787  }
788 
789  GF_ATOMIC_INC(this->refcount);
790 
791  return this;
792 }
793 
794 data_t *
795 int_to_data(int64_t value)
796 {
797  data_t *data = get_new_data();
798 
799  if (!data) {
800  return NULL;
801  }
802 
803  data->len = gf_asprintf(&data->data, "%" PRId64, value);
804  if (-1 == data->len) {
805  gf_msg_debug("dict", 0, "asprintf failed");
806  data_destroy(data);
807  return NULL;
808  }
809  data->len++; /* account for terminating NULL */
810  data->data_type = GF_DATA_TYPE_INT;
811 
812  return data;
813 }
814 
815 data_t *
816 data_from_int64(int64_t value)
817 {
818  data_t *data = get_new_data();
819 
820  if (!data) {
821  return NULL;
822  }
823  data->len = gf_asprintf(&data->data, "%" PRId64, value);
824  if (-1 == data->len) {
825  gf_msg_debug("dict", 0, "asprintf failed");
826  data_destroy(data);
827  return NULL;
828  }
829  data->len++; /* account for terminating NULL */
830  data->data_type = GF_DATA_TYPE_INT;
831 
832  return data;
833 }
834 
835 data_t *
836 data_from_int32(int32_t value)
837 {
838  data_t *data = get_new_data();
839 
840  if (!data) {
841  return NULL;
842  }
843  data->len = gf_asprintf(&data->data, "%" PRId32, value);
844  if (-1 == data->len) {
845  gf_msg_debug("dict", 0, "asprintf failed");
846  data_destroy(data);
847  return NULL;
848  }
849 
850  data->len++; /* account for terminating NULL */
851  data->data_type = GF_DATA_TYPE_INT;
852 
853  return data;
854 }
855 
856 data_t *
857 data_from_int16(int16_t value)
858 {
859  data_t *data = get_new_data();
860 
861  if (!data) {
862  return NULL;
863  }
864  data->len = gf_asprintf(&data->data, "%" PRId16, value);
865  if (-1 == data->len) {
866  gf_msg_debug("dict", 0, "asprintf failed");
867  data_destroy(data);
868  return NULL;
869  }
870 
871  data->len++; /* account for terminating NULL */
872  data->data_type = GF_DATA_TYPE_INT;
873 
874  return data;
875 }
876 
877 data_t *
878 data_from_int8(int8_t value)
879 {
880  data_t *data = get_new_data();
881 
882  if (!data) {
883  return NULL;
884  }
885  data->len = gf_asprintf(&data->data, "%d", value);
886  if (-1 == data->len) {
887  gf_msg_debug("dict", 0, "asprintf failed");
888  data_destroy(data);
889  return NULL;
890  }
891 
892  data->len++; /* account for terminating NULL */
893  data->data_type = GF_DATA_TYPE_INT;
894 
895  return data;
896 }
897 
898 data_t *
899 data_from_uint64(uint64_t value)
900 {
901  data_t *data = get_new_data();
902 
903  if (!data) {
904  return NULL;
905  }
906  data->len = gf_asprintf(&data->data, "%" PRIu64, value);
907  if (-1 == data->len) {
908  gf_msg_debug("dict", 0, "asprintf failed");
909  data_destroy(data);
910  return NULL;
911  }
912 
913  data->len++; /* account for terminating NULL */
915 
916  return data;
917 }
918 
919 data_t *
920 data_from_double(double value)
921 {
922  data_t *data = get_new_data();
923 
924  if (!data) {
925  return NULL;
926  }
927 
928  data->len = gf_asprintf(&data->data, "%f", value);
929  if (data->len == -1) {
930  gf_msg_debug("dict", 0, "asprintf failed");
931  data_destroy(data);
932  return NULL;
933  }
934  data->len++; /* account for terminating NULL */
936 
937  return data;
938 }
939 
940 data_t *
941 data_from_uint32(uint32_t value)
942 {
943  data_t *data = get_new_data();
944 
945  if (!data) {
946  return NULL;
947  }
948  data->len = gf_asprintf(&data->data, "%" PRIu32, value);
949  if (-1 == data->len) {
950  gf_msg_debug("dict", 0, "asprintf failed");
951  data_destroy(data);
952  return NULL;
953  }
954 
955  data->len++; /* account for terminating NULL */
957 
958  return data;
959 }
960 
961 data_t *
962 data_from_uint16(uint16_t value)
963 {
964  data_t *data = get_new_data();
965 
966  if (!data) {
967  return NULL;
968  }
969  data->len = gf_asprintf(&data->data, "%" PRIu16, value);
970  if (-1 == data->len) {
971  gf_msg_debug("dict", 0, "asprintf failed");
972  data_destroy(data);
973  return NULL;
974  }
975 
976  data->len++; /* account for terminating NULL */
978 
979  return data;
980 }
981 
982 static data_t *
983 data_from_ptr_common(void *value, gf_boolean_t is_static)
984 {
985  /* it is valid to set 0/NULL as a value, no need to check *value */
986 
987  data_t *data = get_new_data();
988  if (!data) {
989  return NULL;
990  }
991 
992  data->data = value;
993  data->len = 0;
994  data->is_static = is_static;
995 
996  data->data_type = GF_DATA_TYPE_PTR;
997  return data;
998 }
999 
1000 data_t *
1001 str_to_data(char *value)
1002 {
1003  if (!value) {
1005  "value is NULL");
1006  return NULL;
1007  }
1008 
1009  return strn_to_data(value, strlen(value));
1010 }
1011 
1012 data_t *
1013 strn_to_data(char *value, const int vallen)
1014 {
1015  if (!value) {
1017  "value is NULL");
1018  return NULL;
1019  }
1020  data_t *data = get_new_data();
1021 
1022  if (!data) {
1023  return NULL;
1024  }
1025  data->len = vallen + 1;
1026  data->data_type = GF_DATA_TYPE_STR;
1027 
1028  data->data = value;
1029  data->is_static = _gf_true;
1030 
1031  return data;
1032 }
1033 
1034 static data_t *
1035 data_from_dynstr(char *value)
1036 {
1037  if (!value) {
1039  "value is NULL");
1040  return NULL;
1041  }
1042 
1043  data_t *data = get_new_data();
1044 
1045  if (!data)
1046  return NULL;
1047  data->len = strlen(value) + 1;
1048  data->data = value;
1049  data->data_type = GF_DATA_TYPE_STR;
1050 
1051  return data;
1052 }
1053 
1054 data_t *
1055 data_from_dynptr(void *value, int32_t len)
1056 {
1057  data_t *data = get_new_data();
1058 
1059  if (!data)
1060  return NULL;
1061 
1062  data->len = len;
1063  data->data = value;
1064  data->data_type = GF_DATA_TYPE_PTR;
1065 
1066  return data;
1067 }
1068 
1069 data_t *
1070 bin_to_data(void *value, int32_t len)
1071 {
1072  if (!value) {
1074  "value is NULL");
1075  return NULL;
1076  }
1077 
1078  data_t *data = get_new_data();
1079 
1080  if (!data)
1081  return NULL;
1082 
1083  data->is_static = _gf_true;
1084  data->len = len;
1085  data->data = value;
1086 
1087  return data;
1088 }
1089 
1091  [GF_DATA_TYPE_UNKNOWN] = "unknown",
1092  [GF_DATA_TYPE_STR_OLD] = "string-old-version",
1093  [GF_DATA_TYPE_INT] = "integer",
1094  [GF_DATA_TYPE_UINT] = "unsigned integer",
1095  [GF_DATA_TYPE_DOUBLE] = "float",
1096  [GF_DATA_TYPE_STR] = "string",
1097  [GF_DATA_TYPE_PTR] = "pointer",
1098  [GF_DATA_TYPE_GFUUID] = "gf-uuid",
1099  [GF_DATA_TYPE_IATT] = "iatt",
1100  [GF_DATA_TYPE_MDATA] = "mdata",
1101 };
1102 
1103 int64_t
1105 {
1106  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
1107 
1108  return (int64_t)strtoull(data->data, NULL, 0);
1109 }
1110 
1111 int32_t
1113 {
1114  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
1115 
1116  return strtoul(data->data, NULL, 0);
1117 }
1118 
1119 int16_t
1121 {
1122  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
1123 
1124  int16_t value = 0;
1125 
1126  errno = 0;
1127  value = strtol(data->data, NULL, 0);
1128 
1129  if ((value > SHRT_MAX) || (value < SHRT_MIN)) {
1130  errno = ERANGE;
1131  gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
1133  "Error in data"
1134  " conversion: detected overflow");
1135  return -1;
1136  }
1137 
1138  return (int16_t)value;
1139 }
1140 
1141 int8_t
1143 {
1144  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
1145 
1146  int8_t value = 0;
1147 
1148  errno = 0;
1149  value = strtol(data->data, NULL, 0);
1150 
1151  if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) {
1152  errno = ERANGE;
1153  gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
1155  "Error in data"
1156  " conversion: detected overflow");
1157  return -1;
1158  }
1159 
1160  return (int8_t)value;
1161 }
1162 
1163 uint64_t
1165 {
1166  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
1167 
1168  return strtoll(data->data, NULL, 0);
1169 }
1170 
1171 uint32_t
1173 {
1174  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
1175 
1176  return strtol(data->data, NULL, 0);
1177 }
1178 
1179 uint16_t
1181 {
1182  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
1183 
1184  uint16_t value = 0;
1185 
1186  errno = 0;
1187  value = strtol(data->data, NULL, 0);
1188 
1189  if ((USHRT_MAX - value) < 0) {
1190  errno = ERANGE;
1191  gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
1193  "Error in data conversion: "
1194  "overflow detected");
1195  return -1;
1196  }
1197 
1198  return (uint16_t)value;
1199 }
1200 
1201 uint8_t
1203 {
1204  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
1205 
1206  errno = 0;
1207  uint32_t value = strtol(data->data, NULL, 0);
1208 
1209  if ((UCHAR_MAX - (uint8_t)value) < 0) {
1210  errno = ERANGE;
1211  gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
1213  "data "
1214  "conversion overflow detected");
1215  return -1;
1216  }
1217 
1218  return (uint8_t)value;
1219 }
1220 
1221 char *
1223 {
1224  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, "null", NULL);
1225  return data->data;
1226 }
1227 
1228 void *
1230 {
1231  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
1232  return data->data;
1233 }
1234 
1235 void *
1237 {
1238  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
1239  return data->data;
1240 }
1241 
1242 struct iatt *
1243 data_to_iatt(data_t *data, char *key)
1244 {
1245  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, NULL);
1246 
1247  /* We only check for smaller size. If it's bigger we simply ignore
1248  * the extra data. This way it's easy to do changes in the future that
1249  * pass more data but are backward compatible (if the initial contents
1250  * of the struct are maintained, of course). */
1251  if (data->len < sizeof(struct iatt)) {
1252  gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
1253  "key=%s", key, NULL);
1254  return NULL;
1255  }
1256 
1257  return (struct iatt *)data->data;
1258 }
1259 
1260 int
1261 dict_null_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp)
1262 {
1263  return 0;
1264 }
1265 
1266 int
1267 dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *_tmp)
1268 {
1269  if (!d || !k) {
1270  gf_smsg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_KEY_OR_VALUE_NULL,
1271  "d=%s", d ? "key" : "dictionary", NULL);
1272  return -1;
1273  }
1274 
1275  dict_del(d, k);
1276  return 0;
1277 }
1278 
1280 dict_match_everything(dict_t *d, char *k, data_t *v, void *data)
1281 {
1282  return _gf_true;
1283 }
1284 
1285 int
1287  int (*fn)(dict_t *this, char *key, data_t *value, void *data),
1288  void *data)
1289 {
1290  int ret = dict_foreach_match(dict, dict_match_everything, NULL, fn, data);
1291 
1292  if (ret > 0)
1293  ret = 0;
1294 
1295  return ret;
1296 }
1297 
1298 /* return values:
1299  -1 = failure,
1300  0 = no matches found,
1301  +n = n number of matches
1302 */
1303 int
1305  gf_boolean_t (*match)(dict_t *this, char *key, data_t *value,
1306  void *mdata),
1307  void *match_data,
1308  int (*action)(dict_t *this, char *key, data_t *value,
1309  void *adata),
1310  void *action_data)
1311 {
1312  if (!dict || !match || !action) {
1314  "dict|match|action is "
1315  "NULL");
1316  return -1;
1317  }
1318 
1319  int ret = -1;
1320  int count = 0;
1321  data_pair_t *pairs = dict->members_list;
1322  data_pair_t *next = NULL;
1323 
1324  while (pairs) {
1325  next = pairs->next;
1326  if (match(dict, pairs->key, pairs->value, match_data)) {
1327  ret = action(dict, pairs->key, pairs->value, action_data);
1328  if (ret < 0)
1329  return ret;
1330  count++;
1331  }
1332  pairs = next;
1333  }
1334 
1335  return count;
1336 }
1337 
1338 static gf_boolean_t
1339 dict_fnmatch(dict_t *d, char *k, data_t *val, void *match_data)
1340 {
1341  return (fnmatch(match_data, k, 0) == 0);
1342 }
1343 /* return values:
1344  -1 = failure,
1345  0 = no matches found,
1346  +n = n number of matches
1347 */
1348 int
1349 dict_foreach_fnmatch(dict_t *dict, char *pattern,
1350  int (*fn)(dict_t *this, char *key, data_t *value,
1351  void *data),
1352  void *data)
1353 {
1354  return dict_foreach_match(dict, dict_fnmatch, pattern, fn, data);
1355 }
1356 
1370 int
1371 dict_keys_join(void *value, int size, dict_t *dict, int (*filter_fn)(char *k))
1372 {
1373  int len = 0;
1374  data_pair_t *pairs = dict->members_list;
1375  data_pair_t *next = NULL;
1376 
1377  while (pairs) {
1378  next = pairs->next;
1379 
1380  if (filter_fn && filter_fn(pairs->key)) {
1381  pairs = next;
1382  continue;
1383  }
1384 
1385  if (value && (size > len))
1386  strncpy(value + len, pairs->key, size - len);
1387 
1388  len += (strlen(pairs->key) + 1);
1389 
1390  pairs = next;
1391  }
1392 
1393  return len;
1394 }
1395 
1396 static int
1397 dict_copy_one(dict_t *unused, char *key, data_t *value, void *newdict)
1398 {
1399  return dict_set((dict_t *)newdict, key, (value));
1400 }
1401 
1402 dict_t *
1404 {
1405  if (!dict) {
1407  "dict is NULL");
1408  return NULL;
1409  }
1410 
1411  if (!new)
1412  new = get_new_dict_full(dict->hash_size);
1413 
1414  dict_foreach(dict, dict_copy_one, new);
1415 
1416  return new;
1417 }
1418 
1419 int
1421 {
1422  int32_t ret = -1;
1423  if (!dict) {
1425  "dict is NULL");
1426  goto out;
1427  }
1428  dict_foreach(dict, dict_remove_foreach_fn, NULL);
1429  ret = 0;
1430 out:
1431  return ret;
1432 }
1433 
1434 dict_t *
1436 {
1437  dict_t *local_new = NULL;
1438 
1439  GF_VALIDATE_OR_GOTO("dict", dict, fail);
1440 
1441  if (new == NULL) {
1442  local_new = dict_new();
1443  GF_VALIDATE_OR_GOTO("dict", local_new, fail);
1444  new = local_new;
1445  }
1446 
1447  dict_foreach(dict, dict_copy_one, new);
1448 fail:
1449  return new;
1450 }
1451 
1452 /*
1453  * !!!!!!! CLEANED UP CODE !!!!!!!
1454  */
1455 
1463 int
1464 dict_get_with_ref(dict_t *this, char *key, data_t **data)
1465 {
1466  if (!this || !key || !data) {
1468  "dict OR key (%s) is NULL", key);
1469  return -EINVAL;
1470  }
1471 
1472  return dict_get_with_refn(this, key, strlen(key), data);
1473 }
1474 
1475 int
1476 dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data)
1477 {
1478  data_pair_t *pair = NULL;
1479  int ret = -ENOENT;
1480  uint32_t hash;
1481 
1482  if (!this || !key || !data) {
1484  "dict OR key (%s) is NULL", key);
1485  ret = -EINVAL;
1486  goto err;
1487  }
1488 
1489  hash = (uint32_t)XXH64(key, keylen, 0);
1490 
1491  LOCK(&this->lock);
1492  {
1493  pair = dict_lookup_common(this, key, hash);
1494 
1495  if (pair) {
1496  ret = 0;
1497  *data = data_ref(pair->value);
1498  }
1499  }
1500  UNLOCK(&this->lock);
1501 err:
1502  return ret;
1503 }
1504 
1505 static int
1506 data_to_ptr_common(data_t *data, void **val)
1507 {
1508  int ret = 0;
1509 
1510  if (!data) {
1511  ret = -EINVAL;
1512  goto err;
1513  }
1514 
1515  *val = data->data;
1516 err:
1517  return ret;
1518 }
1519 
1520 static int
1521 data_to_int8_ptr(data_t *data, int8_t *val)
1522 {
1523  int ret = 0;
1524 
1525  if (!data || !val) {
1526  ret = -EINVAL;
1527  goto err;
1528  }
1529 
1530  errno = 0;
1531  *val = strtol(data->data, NULL, 0);
1532  if (errno != 0)
1533  ret = -errno;
1534 
1535 err:
1536  return ret;
1537 }
1538 
1539 static int
1540 data_to_int16_ptr(data_t *data, int16_t *val)
1541 {
1542  int ret = 0;
1543 
1544  if (!data || !val) {
1545  ret = -EINVAL;
1546  goto err;
1547  }
1548 
1549  errno = 0;
1550  *val = strtol(data->data, NULL, 0);
1551  if (errno != 0)
1552  ret = -errno;
1553 
1554 err:
1555  return ret;
1556 }
1557 
1558 static int
1559 data_to_int32_ptr(data_t *data, int32_t *val)
1560 {
1561  int ret = 0;
1562 
1563  if (!data || !val) {
1564  ret = -EINVAL;
1565  goto err;
1566  }
1567 
1568  errno = 0;
1569  *val = strtol(data->data, NULL, 0);
1570  if (errno != 0)
1571  ret = -errno;
1572 
1573 err:
1574  return ret;
1575 }
1576 
1577 static int
1578 data_to_int64_ptr(data_t *data, int64_t *val)
1579 {
1580  int ret = 0;
1581 
1582  if (!data || !val) {
1583  ret = -EINVAL;
1584  goto err;
1585  }
1586 
1587  errno = 0;
1588  *val = strtoll(data->data, NULL, 0);
1589  if (errno != 0)
1590  ret = -errno;
1591 
1592 err:
1593  return ret;
1594 }
1595 
1596 static int
1597 data_to_uint16_ptr(data_t *data, uint16_t *val)
1598 {
1599  int ret = 0;
1600 
1601  if (!data || !val) {
1602  ret = -EINVAL;
1603  goto err;
1604  }
1605 
1606  errno = 0;
1607  *val = strtoul(data->data, NULL, 0);
1608  if (errno != 0)
1609  ret = -errno;
1610 
1611 err:
1612  return ret;
1613 }
1614 
1615 static int
1616 data_to_uint32_ptr(data_t *data, uint32_t *val)
1617 {
1618  int ret = 0;
1619 
1620  if (!data || !val) {
1621  ret = -EINVAL;
1622  goto err;
1623  }
1624 
1625  errno = 0;
1626  *val = strtoul(data->data, NULL, 0);
1627  if (errno != 0)
1628  ret = -errno;
1629 
1630 err:
1631  return ret;
1632 }
1633 
1634 static int
1635 data_to_uint64_ptr(data_t *data, uint64_t *val)
1636 {
1637  int ret = 0;
1638 
1639  if (!data || !val) {
1640  ret = -EINVAL;
1641  goto err;
1642  }
1643 
1644  errno = 0;
1645  *val = strtoull(data->data, NULL, 0);
1646  if (errno != 0)
1647  ret = -errno;
1648 
1649 err:
1650  return ret;
1651 }
1652 
1653 static int
1654 data_to_double_ptr(data_t *data, double *val)
1655 {
1656  int ret = 0;
1657 
1658  if (!data || !val) {
1659  ret = -EINVAL;
1660  goto err;
1661  }
1662 
1663  errno = 0;
1664  *val = strtod(data->data, NULL);
1665  if (errno != 0)
1666  ret = -errno;
1667 
1668 err:
1669  return ret;
1670 }
1671 
1672 int
1673 dict_get_int8(dict_t *this, char *key, int8_t *val)
1674 {
1675  data_t *data = NULL;
1676  int ret = 0;
1677 
1678  if (!this || !key || !val) {
1679  ret = -EINVAL;
1680  goto err;
1681  }
1682 
1683  ret = dict_get_with_ref(this, key, &data);
1684  if (ret != 0) {
1685  goto err;
1686  }
1687 
1688  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
1689 
1690  ret = data_to_int8_ptr(data, val);
1691 
1692 err:
1693  if (data)
1694  data_unref(data);
1695  return ret;
1696 }
1697 
1698 int
1699 dict_set_int8(dict_t *this, char *key, int8_t val)
1700 {
1701  data_t *data = NULL;
1702  int ret = 0;
1703 
1704  data = data_from_int8(val);
1705  if (!data) {
1706  ret = -EINVAL;
1707  goto err;
1708  }
1709 
1710  ret = dict_set(this, key, data);
1711  if (ret < 0)
1712  data_destroy(data);
1713 
1714 err:
1715  return ret;
1716 }
1717 
1718 int
1719 dict_get_int16(dict_t *this, char *key, int16_t *val)
1720 {
1721  data_t *data = NULL;
1722  int ret = 0;
1723 
1724  if (!this || !key || !val) {
1725  ret = -EINVAL;
1726  goto err;
1727  }
1728 
1729  ret = dict_get_with_ref(this, key, &data);
1730  if (ret != 0) {
1731  goto err;
1732  }
1733 
1734  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
1735 
1736  ret = data_to_int16_ptr(data, val);
1737 
1738 err:
1739  if (data)
1740  data_unref(data);
1741  return ret;
1742 }
1743 
1744 int
1745 dict_set_int16(dict_t *this, char *key, int16_t val)
1746 {
1747  data_t *data = NULL;
1748  int ret = 0;
1749 
1750  data = data_from_int16(val);
1751  if (!data) {
1752  ret = -EINVAL;
1753  goto err;
1754  }
1755 
1756  ret = dict_set(this, key, data);
1757  if (ret < 0)
1758  data_destroy(data);
1759 
1760 err:
1761  return ret;
1762 }
1763 
1764 int
1765 dict_get_int32n(dict_t *this, char *key, const int keylen, int32_t *val)
1766 {
1767  data_t *data = NULL;
1768  int ret = 0;
1769 
1770  if (!this || !key || !val) {
1771  ret = -EINVAL;
1772  goto err;
1773  }
1774 
1775  ret = dict_get_with_refn(this, key, keylen, &data);
1776  if (ret != 0) {
1777  goto err;
1778  }
1779 
1780  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
1781 
1782  ret = data_to_int32_ptr(data, val);
1783 
1784 err:
1785  if (data)
1786  data_unref(data);
1787  return ret;
1788 }
1789 
1790 int
1791 dict_get_int32(dict_t *this, char *key, int32_t *val)
1792 {
1793  data_t *data = NULL;
1794  int ret = 0;
1795 
1796  if (!this || !key || !val) {
1797  ret = -EINVAL;
1798  goto err;
1799  }
1800 
1801  ret = dict_get_with_ref(this, key, &data);
1802  if (ret != 0) {
1803  goto err;
1804  }
1805 
1806  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
1807 
1808  ret = data_to_int32_ptr(data, val);
1809 
1810 err:
1811  if (data)
1812  data_unref(data);
1813  return ret;
1814 }
1815 
1816 int
1817 dict_set_int32n(dict_t *this, char *key, const int keylen, int32_t val)
1818 {
1819  data_t *data = NULL;
1820  int ret = 0;
1821 
1822  data = data_from_int32(val);
1823  if (!data) {
1824  ret = -EINVAL;
1825  goto err;
1826  }
1827 
1828  ret = dict_setn(this, key, keylen, data);
1829  if (ret < 0)
1830  data_destroy(data);
1831 
1832 err:
1833  return ret;
1834 }
1835 
1836 int
1837 dict_set_int32(dict_t *this, char *key, int32_t val)
1838 {
1839  data_t *data = data_from_int32(val);
1840  int ret = 0;
1841 
1842  if (!data) {
1843  ret = -EINVAL;
1844  goto err;
1845  }
1846 
1847  ret = dict_set(this, key, data);
1848  if (ret < 0)
1849  data_destroy(data);
1850 
1851 err:
1852  return ret;
1853 }
1854 
1855 int
1856 dict_get_int64(dict_t *this, char *key, int64_t *val)
1857 {
1858  data_t *data = NULL;
1859  int ret = 0;
1860 
1861  if (!this || !key || !val) {
1862  ret = -EINVAL;
1863  goto err;
1864  }
1865 
1866  ret = dict_get_with_ref(this, key, &data);
1867  if (ret != 0) {
1868  goto err;
1869  }
1870 
1871  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
1872 
1873  ret = data_to_int64_ptr(data, val);
1874 
1875 err:
1876  if (data)
1877  data_unref(data);
1878  return ret;
1879 }
1880 
1881 int
1882 dict_set_int64(dict_t *this, char *key, int64_t val)
1883 {
1884  data_t *data = data_from_int64(val);
1885  int ret = 0;
1886 
1887  if (!data) {
1888  ret = -EINVAL;
1889  goto err;
1890  }
1891 
1892  ret = dict_set(this, key, data);
1893  if (ret < 0)
1894  data_destroy(data);
1895 
1896 err:
1897  return ret;
1898 }
1899 
1900 int
1901 dict_get_uint16(dict_t *this, char *key, uint16_t *val)
1902 {
1903  data_t *data = NULL;
1904  int ret = 0;
1905 
1906  if (!this || !key || !val) {
1907  ret = -EINVAL;
1908  goto err;
1909  }
1910 
1911  ret = dict_get_with_ref(this, key, &data);
1912  if (ret != 0) {
1913  goto err;
1914  }
1915 
1916  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
1917 
1918  ret = data_to_uint16_ptr(data, val);
1919 
1920 err:
1921  if (data)
1922  data_unref(data);
1923  return ret;
1924 }
1925 
1926 int
1927 dict_set_uint16(dict_t *this, char *key, uint16_t val)
1928 {
1929  data_t *data = data_from_uint16(val);
1930  int ret = 0;
1931 
1932  if (!data) {
1933  ret = -EINVAL;
1934  goto err;
1935  }
1936 
1937  ret = dict_set(this, key, data);
1938  if (ret < 0)
1939  data_destroy(data);
1940 
1941 err:
1942  return ret;
1943 }
1944 
1945 int
1946 dict_get_uint32(dict_t *this, char *key, uint32_t *val)
1947 {
1948  data_t *data = NULL;
1949  int ret = 0;
1950 
1951  if (!this || !key || !val) {
1952  ret = -EINVAL;
1953  goto err;
1954  }
1955 
1956  ret = dict_get_with_ref(this, key, &data);
1957  if (ret != 0) {
1958  goto err;
1959  }
1960 
1961  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
1962 
1963  ret = data_to_uint32_ptr(data, val);
1964 
1965 err:
1966  if (data)
1967  data_unref(data);
1968  return ret;
1969 }
1970 
1971 int
1972 dict_set_uint32(dict_t *this, char *key, uint32_t val)
1973 {
1974  data_t *data = data_from_uint32(val);
1975  int ret = 0;
1976 
1977  if (!data) {
1978  ret = -EINVAL;
1979  goto err;
1980  }
1981 
1982  ret = dict_set(this, key, data);
1983  if (ret < 0)
1984  data_destroy(data);
1985 
1986 err:
1987  return ret;
1988 }
1989 
1990 int
1991 dict_get_uint64(dict_t *this, char *key, uint64_t *val)
1992 {
1993  data_t *data = NULL;
1994  int ret = 0;
1995 
1996  if (!this || !key || !val) {
1997  ret = -EINVAL;
1998  goto err;
1999  }
2000 
2001  ret = dict_get_with_ref(this, key, &data);
2002  if (ret != 0) {
2003  goto err;
2004  }
2005 
2006  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
2007 
2008  ret = data_to_uint64_ptr(data, val);
2009 
2010 err:
2011  if (data)
2012  data_unref(data);
2013  return ret;
2014 }
2015 
2016 int
2017 dict_set_uint64(dict_t *this, char *key, uint64_t val)
2018 {
2019  data_t *data = data_from_uint64(val);
2020  int ret = 0;
2021 
2022  if (!data) {
2023  ret = -EINVAL;
2024  goto err;
2025  }
2026 
2027  ret = dict_set(this, key, data);
2028  if (ret < 0)
2029  data_destroy(data);
2030 
2031 err:
2032  return ret;
2033 }
2034 
2035 /*
2036  * dict_check_flag can be used to check a one bit flag in an array of flags
2037  * The flag argument indicates the bit position (within the array of bits).
2038  * Currently limited to max of 256 flags for a key.
2039  * return value,
2040  * 1 : flag is set
2041  * 0 : flag is not set
2042  * <0: Error
2043  */
2044 int
2045 dict_check_flag(dict_t *this, char *key, int flag)
2046 {
2047  data_t *data = NULL;
2048  int ret = -ENOENT;
2049 
2050  ret = dict_get_with_ref(this, key, &data);
2051  if (ret < 0) {
2052  return ret;
2053  }
2054 
2055  if (BIT_VALUE((unsigned char *)(data->data), flag))
2056  ret = 1;
2057  else
2058  ret = 0;
2059 
2060  data_unref(data);
2061  return ret;
2062 }
2063 
2064 /*
2065  * _dict_modify_flag can be used to set/clear a bit flag in an array of flags
2066  * flag: indicates the bit position. limited to max of DICT_MAX_FLAGS.
2067  * op: Indicates operation DICT_FLAG_SET / DICT_FLAG_CLEAR
2068  */
2069 static int
2070 _dict_modify_flag(dict_t *this, char *key, int flag, int op)
2071 {
2072  data_t *data = NULL;
2073  int ret = 0;
2074  data_pair_t *pair = NULL;
2075  char *ptr = NULL;
2076  int hashval = 0;
2077  uint32_t hash;
2078 
2079  if (!this || !key) {
2081  "dict OR key (%s) is NULL", key);
2082  ret = -EINVAL;
2083  goto err;
2084  }
2085 
2086  /*
2087  * Using a size of 32 bytes to support max of 256
2088  * flags in a single key. This should be suffcient.
2089  */
2090  GF_ASSERT(flag >= 0 && flag < DICT_MAX_FLAGS);
2091 
2092  hash = (uint32_t)XXH64(key, strlen(key), 0);
2093  LOCK(&this->lock);
2094  {
2095  pair = dict_lookup_common(this, key, hash);
2096 
2097  if (pair) {
2098  data = pair->value;
2099  if (op == DICT_FLAG_SET)
2100  BIT_SET((unsigned char *)(data->data), flag);
2101  else
2102  BIT_CLEAR((unsigned char *)(data->data), flag);
2103  } else {
2105  if (!ptr) {
2106  gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
2107  "flag bit array", NULL);
2108  ret = -ENOMEM;
2109  goto err;
2110  }
2111 
2112  data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8);
2113 
2114  if (!data) {
2115  gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, "data",
2116  NULL);
2117  GF_FREE(ptr);
2118  ret = -ENOMEM;
2119  goto err;
2120  }
2121 
2122  if (op == DICT_FLAG_SET)
2123  BIT_SET((unsigned char *)(data->data), flag);
2124  else
2125  BIT_CLEAR((unsigned char *)(data->data), flag);
2126 
2127  if (this->free_pair.key) { /* the free pair is in use */
2128  pair = mem_get0(THIS->ctx->dict_pair_pool);
2129  if (!pair) {
2130  gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
2131  "dict pair", NULL);
2132  ret = -ENOMEM;
2133  goto err;
2134  }
2135  } else { /* use the free pair */
2136  pair = &this->free_pair;
2137  }
2138 
2139  pair->key = (char *)GF_MALLOC(strlen(key) + 1, gf_common_mt_char);
2140  if (!pair->key) {
2141  gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
2142  "dict pair", NULL);
2143  ret = -ENOMEM;
2144  goto err;
2145  }
2146  strcpy(pair->key, key);
2147  pair->key_hash = hash;
2148  pair->value = data_ref(data);
2149 
2150  hashval = hash % this->hash_size;
2151  pair->hash_next = this->members[hashval];
2152  this->members[hashval] = pair;
2153 
2154  pair->next = this->members_list;
2155  pair->prev = NULL;
2156  if (this->members_list)
2157  this->members_list->prev = pair;
2158  this->members_list = pair;
2159  this->count++;
2160 
2161  if (this->max_count < this->count)
2162  this->max_count = this->count;
2163  }
2164  }
2165 
2166  UNLOCK(&this->lock);
2167  return 0;
2168 
2169 err:
2170  if (key && this)
2171  UNLOCK(&this->lock);
2172 
2173  if (pair) {
2174  if (pair->key) {
2175  GF_FREE(pair->key);
2176  pair->key = NULL;
2177  }
2178  if (pair != &this->free_pair) {
2179  mem_put(pair);
2180  }
2181  }
2182 
2183  if (data)
2184  data_destroy(data);
2185 
2186  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, "key=%s", key,
2187  NULL);
2188 
2189  return ret;
2190 }
2191 
2192 /*
2193  * Todo:
2194  * Add below primitives as needed:
2195  * dict_check_flags(this, key, flag...): variadic function to check
2196  * multiple flags at a time.
2197  * dict_set_flags(this, key, flag...): set multiple flags
2198  * dict_clear_flags(this, key, flag...): reset multiple flags
2199  */
2200 
2201 int
2202 dict_set_flag(dict_t *this, char *key, int flag)
2203 {
2204  return _dict_modify_flag(this, key, flag, DICT_FLAG_SET);
2205 }
2206 
2207 int
2208 dict_clear_flag(dict_t *this, char *key, int flag)
2209 {
2210  return _dict_modify_flag(this, key, flag, DICT_FLAG_CLEAR);
2211 }
2212 
2213 int
2214 dict_get_double(dict_t *this, char *key, double *val)
2215 {
2216  data_t *data = NULL;
2217  int ret = 0;
2218 
2219  if (!this || !key || !val) {
2220  ret = -EINVAL;
2221  goto err;
2222  }
2223 
2224  ret = dict_get_with_ref(this, key, &data);
2225  if (ret != 0) {
2226  goto err;
2227  }
2228 
2229  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_DOUBLE, key, -EINVAL);
2230 
2231  ret = data_to_double_ptr(data, val);
2232 
2233 err:
2234  if (data)
2235  data_unref(data);
2236  return ret;
2237 }
2238 
2239 int
2240 dict_set_double(dict_t *this, char *key, double val)
2241 {
2242  data_t *data = data_from_double(val);
2243  int ret = 0;
2244 
2245  if (!data) {
2246  ret = -EINVAL;
2247  goto err;
2248  }
2249 
2250  ret = dict_set(this, key, data);
2251  if (ret < 0)
2252  data_destroy(data);
2253 
2254 err:
2255  return ret;
2256 }
2257 
2258 int
2259 dict_set_static_ptr(dict_t *this, char *key, void *ptr)
2260 {
2261  data_t *data = data_from_ptr_common(ptr, _gf_true);
2262  int ret = 0;
2263 
2264  if (!data) {
2265  ret = -EINVAL;
2266  goto err;
2267  }
2268 
2269  ret = dict_set(this, key, data);
2270  if (ret < 0)
2271  data_destroy(data);
2272 
2273 err:
2274  return ret;
2275 }
2276 
2277 int
2278 dict_set_dynptr(dict_t *this, char *key, void *ptr, size_t len)
2279 {
2280  data_t *data = data_from_dynptr(ptr, len);
2281  int ret = 0;
2282 
2283  if (!data) {
2284  ret = -EINVAL;
2285  goto err;
2286  }
2287 
2288  ret = dict_set(this, key, data);
2289  if (ret < 0)
2290  data_destroy(data);
2291 
2292 err:
2293  return ret;
2294 }
2295 
2296 int
2297 dict_get_ptr(dict_t *this, char *key, void **ptr)
2298 {
2299  data_t *data = NULL;
2300  int ret = 0;
2301 
2302  if (!this || !key || !ptr) {
2303  ret = -EINVAL;
2304  goto err;
2305  }
2306 
2307  ret = dict_get_with_ref(this, key, &data);
2308  if (ret != 0) {
2309  goto err;
2310  }
2311 
2312  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
2313 
2314  ret = data_to_ptr_common(data, ptr);
2315  if (ret != 0) {
2316  goto err;
2317  }
2318 
2319 err:
2320  if (data)
2321  data_unref(data);
2322 
2323  return ret;
2324 }
2325 
2326 int
2327 dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len)
2328 {
2329  data_t *data = NULL;
2330  int ret = 0;
2331 
2332  if (!this || !key || !ptr) {
2333  ret = -EINVAL;
2334  goto err;
2335  }
2336 
2337  ret = dict_get_with_ref(this, key, &data);
2338  if (ret != 0) {
2339  goto err;
2340  }
2341 
2342  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
2343 
2344  *len = data->len;
2345 
2346  ret = data_to_ptr_common(data, ptr);
2347  if (ret != 0) {
2348  goto err;
2349  }
2350 
2351 err:
2352  if (data)
2353  data_unref(data);
2354 
2355  return ret;
2356 }
2357 
2358 /* Get string - with known key length */
2359 int
2360 dict_get_strn(dict_t *this, char *key, const int keylen, char **str)
2361 {
2362  data_t *data = NULL;
2363  int ret = -EINVAL;
2364 
2365  if (!this || !key || !str) {
2366  goto err;
2367  }
2368  ret = dict_get_with_refn(this, key, keylen, &data);
2369  if (ret < 0) {
2370  goto err;
2371  }
2372 
2373  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
2374 
2375  *str = data->data;
2376 
2377 err:
2378  if (data)
2379  data_unref(data);
2380 
2381  return ret;
2382 }
2383 
2384 int
2385 dict_get_str(dict_t *this, char *key, char **str)
2386 {
2387  data_t *data = NULL;
2388  int ret = -EINVAL;
2389 
2390  if (!this || !key || !str) {
2391  goto err;
2392  }
2393  ret = dict_get_with_ref(this, key, &data);
2394  if (ret < 0) {
2395  goto err;
2396  }
2397 
2398  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
2399 
2400  *str = data->data;
2401 
2402 err:
2403  if (data)
2404  data_unref(data);
2405 
2406  return ret;
2407 }
2408 
2409 int
2410 dict_set_str(dict_t *this, char *key, char *str)
2411 {
2412  data_t *data = str_to_data(str);
2413  int ret = 0;
2414 
2415  if (!data) {
2416  ret = -EINVAL;
2417  goto err;
2418  }
2419 
2420  ret = dict_set(this, key, data);
2421  if (ret < 0)
2422  data_destroy(data);
2423 
2424 err:
2425  return ret;
2426 }
2427 
2428 /* Set string - with known key length */
2429 int
2430 dict_set_strn(dict_t *this, char *key, const int keylen, char *str)
2431 {
2432  data_t *data = NULL;
2433  int ret = 0;
2434 
2435  data = str_to_data(str);
2436  if (!data) {
2437  ret = -EINVAL;
2438  goto err;
2439  }
2440 
2441  ret = dict_setn(this, key, keylen, data);
2442  if (ret < 0)
2443  data_destroy(data);
2444 
2445 err:
2446  return ret;
2447 }
2448 
2449 /* Set string - with known key length and known value length */
2450 int
2451 dict_set_nstrn(dict_t *this, char *key, const int keylen, char *str,
2452  const int vallen)
2453 {
2454  data_t *data = strn_to_data(str, vallen);
2455  int ret = 0;
2456 
2457  if (!data) {
2458  ret = -EINVAL;
2459  goto err;
2460  }
2461 
2462  ret = dict_setn(this, key, keylen, data);
2463  if (ret < 0)
2464  data_destroy(data);
2465 
2466 err:
2467  return ret;
2468 }
2469 
2470 int
2471 dict_set_dynstr_with_alloc(dict_t *this, char *key, const char *str)
2472 {
2473  char *alloc_str = gf_strdup(str);
2474  int ret = -1;
2475 
2476  if (!alloc_str)
2477  return ret;
2478 
2479  ret = dict_set_dynstr(this, key, alloc_str);
2480  if (ret == -EINVAL)
2481  GF_FREE(alloc_str);
2482 
2483  return ret;
2484 }
2485 
2486 int
2487 dict_set_dynstr(dict_t *this, char *key, char *str)
2488 {
2489  const int keylen = strlen(key);
2490  return dict_set_dynstrn(this, key, keylen, str);
2491 }
2492 
2493 int
2494 dict_set_dynstrn(dict_t *this, char *key, const int keylen, char *str)
2495 {
2496  data_t *data = data_from_dynstr(str);
2497  int ret = 0;
2498 
2499  if (!data) {
2500  ret = -EINVAL;
2501  goto err;
2502  }
2503 
2504  ret = dict_setn(this, key, keylen, data);
2505  if (ret < 0)
2506  data_destroy(data);
2507 
2508 err:
2509  return ret;
2510 }
2511 
2512 /* This function is called only by the volgen for now.
2513  Check how else you can handle it */
2514 int
2515 dict_set_option(dict_t *this, char *key, char *str)
2516 {
2517  data_t *data = data_from_dynstr(str);
2518  int ret = 0;
2519 
2520  if (!data) {
2521  ret = -EINVAL;
2522  goto err;
2523  }
2524 
2526  ret = dict_set(this, key, data);
2527  if (ret < 0)
2528  data_destroy(data);
2529 err:
2530  return ret;
2531 }
2532 
2533 int
2534 dict_add_dynstr_with_alloc(dict_t *this, char *key, char *str)
2535 {
2536  data_t *data = NULL;
2537  int ret = 0;
2538  char *alloc_str = gf_strdup(str);
2539 
2540  if (!alloc_str)
2541  goto out;
2542 
2543  data = data_from_dynstr(alloc_str);
2544  if (!data) {
2545  GF_FREE(alloc_str);
2546  ret = -EINVAL;
2547  goto out;
2548  }
2549 
2550  ret = dict_add(this, key, data);
2551  if (ret < 0)
2552  data_destroy(data);
2553 
2554 out:
2555  return ret;
2556 }
2557 
2558 int
2559 dict_get_bin(dict_t *this, char *key, void **bin)
2560 {
2561  data_t *data = NULL;
2562  int ret = -EINVAL;
2563 
2564  if (!this || !key || !bin) {
2565  goto err;
2566  }
2567 
2568  ret = dict_get_with_ref(this, key, &data);
2569  if (ret < 0) {
2570  goto err;
2571  }
2572 
2573  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, ret);
2574 
2575  *bin = data->data;
2576 
2577 err:
2578  if (data)
2579  data_unref(data);
2580 
2581  return ret;
2582 }
2583 
2584 
2593 static int
2594 dict_set_bin_common(dict_t *this, char *key, void *ptr, size_t size,
2596 {
2597  data_t *data = NULL;
2598  int ret = 0;
2599 
2600  if (!ptr || (size > DICT_KEY_VALUE_MAX_SIZE)) {
2601  ret = -EINVAL;
2602  goto err;
2603  }
2604 
2605  data = bin_to_data(ptr, size);
2606  if (!data) {
2607  ret = -EINVAL;
2608  goto err;
2609  }
2610 
2611  data->is_static = is_static;
2612  data->data_type = type;
2613 
2614  ret = dict_set(this, key, data);
2615  if (ret < 0) {
2616  /* don't free data->data, let callers handle it */
2617  data->data = NULL;
2618  data_destroy(data);
2619  }
2620 
2621 err:
2622  return ret;
2623 }
2624 
2625 
2632 int
2633 dict_set_bin(dict_t *this, char *key, void *ptr, size_t size)
2634 {
2635  return dict_set_bin_common(this, key, ptr, size, _gf_false,
2637 }
2638 
2639 
2646 int
2647 dict_set_static_bin(dict_t *this, char *key, void *ptr, size_t size)
2648 {
2649  return dict_set_bin_common(this, key, ptr, size, _gf_true,
2651 }
2652 
2653 /* */
2654 int
2655 dict_set_gfuuid(dict_t *this, char *key, uuid_t gfid, bool is_static)
2656 {
2657  return dict_set_bin_common(this, key, gfid, sizeof(uuid_t), is_static,
2659 }
2660 
2661 int
2662 dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid)
2663 {
2664  data_t *data = NULL;
2665  int ret = -EINVAL;
2666 
2667  if (!this || !key || !gfid) {
2668  goto err;
2669  }
2670  ret = dict_get_with_ref(this, key, &data);
2671  if (ret < 0) {
2672  goto err;
2673  }
2674 
2675  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_GFUUID, key, -EINVAL);
2676 
2677  memcpy(*gfid, data->data, min(data->len, sizeof(uuid_t)));
2678 
2679 err:
2680  if (data)
2681  data_unref(data);
2682 
2683  return ret;
2684 }
2685 
2686 int
2687 dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
2688  bool is_static)
2689 {
2690  return dict_set_bin_common(this, key, mdata, sizeof(struct mdata_iatt),
2691  is_static, GF_DATA_TYPE_MDATA);
2692 }
2693 
2694 int
2695 dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata)
2696 {
2697  data_t *data = NULL;
2698  int ret = -EINVAL;
2699 
2700  if (!this || !key || !mdata) {
2701  goto err;
2702  }
2703  ret = dict_get_with_ref(this, key, &data);
2704  if (ret < 0) {
2705  goto err;
2706  }
2707 
2708  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL);
2709  if (data->len < sizeof(struct mdata_iatt)) {
2710  gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
2711  "key=%s", key, NULL);
2712  ret = -ENOBUFS;
2713  goto err;
2714  }
2715 
2716  memcpy(mdata, data->data, min(data->len, sizeof(struct mdata_iatt)));
2717 
2718 err:
2719  if (data)
2720  data_unref(data);
2721 
2722  return ret;
2723 }
2724 
2725 int
2726 dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static)
2727 {
2728  return dict_set_bin_common(this, key, iatt, sizeof(struct iatt), is_static,
2730 }
2731 
2732 int
2733 dict_get_iatt(dict_t *this, char *key, struct iatt *iatt)
2734 {
2735  data_t *data = NULL;
2736  int ret = -EINVAL;
2737 
2738  if (!this || !key || !iatt) {
2739  goto err;
2740  }
2741  ret = dict_get_with_ref(this, key, &data);
2742  if (ret < 0) {
2743  goto err;
2744  }
2745 
2746  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, -EINVAL);
2747 
2748  memcpy(iatt, data->data, min(data->len, sizeof(struct iatt)));
2749 
2750 err:
2751  if (data)
2752  data_unref(data);
2753 
2754  return ret;
2755 }
2756 
2780 int
2781 dict_get_str_boolean(dict_t *this, char *key, int default_val)
2782 {
2783  data_t *data = NULL;
2784  gf_boolean_t boo = _gf_false;
2785  int ret = 0;
2786 
2787  ret = dict_get_with_ref(this, key, &data);
2788  if (ret < 0) {
2789  if (ret == -ENOENT)
2790  ret = default_val;
2791  else
2792  ret = -1;
2793  goto err;
2794  }
2795 
2796  VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
2797 
2798  ret = gf_strn2boolean(data->data, data->len - 1, &boo);
2799  if (ret == -1)
2800  goto err;
2801 
2802  ret = boo;
2803 
2804 err:
2805  if (data)
2806  data_unref(data);
2807 
2808  return ret;
2809 }
2810 
2811 int
2812 dict_rename_key(dict_t *this, char *key, char *replace_key)
2813 {
2814  data_pair_t *pair = NULL;
2815  int ret = -EINVAL;
2816  uint32_t hash;
2817  uint32_t replacekey_hash;
2818  int replacekey_len;
2819 
2820  /* replacing a key by itself is a NO-OP */
2821  if (strcmp(key, replace_key) == 0)
2822  return 0;
2823 
2824  if (!this) {
2826  "dict is NULL");
2827  return ret;
2828  }
2829 
2830  hash = (uint32_t)XXH64(key, strlen(key), 0);
2831  replacekey_len = strlen(replace_key);
2832  replacekey_hash = (uint32_t)XXH64(replace_key, replacekey_len, 0);
2833 
2834  LOCK(&this->lock);
2835  {
2836  /* no need to data_ref(pair->value), dict_set_lk() does it */
2837  pair = dict_lookup_common(this, key, hash);
2838  if (!pair)
2839  ret = -ENODATA;
2840  else
2841  ret = dict_set_lk(this, replace_key, replacekey_len, pair->value,
2842  replacekey_hash, 1);
2843  }
2844  UNLOCK(&this->lock);
2845 
2846  if (!ret)
2847  /* only delete the key on success */
2848  dict_del(this, key);
2849 
2850  return ret;
2851 }
2852 
2870 int
2872 {
2873  int ret = -EINVAL;
2874  int count = this->count;
2875  int len = DICT_HDR_LEN;
2876  data_pair_t *pair = this->members_list;
2877 
2878  if (count < 0) {
2880  "count=%d", count, NULL);
2881  goto out;
2882  }
2883 
2884  while (count) {
2885  if (!pair) {
2887  NULL);
2888  goto out;
2889  }
2890 
2892 
2893  if (!pair->key) {
2894  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, NULL);
2895  goto out;
2896  }
2897 
2898  len += strlen(pair->key) + 1 /* for '\0' */;
2899 
2900  if (!pair->value) {
2901  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_NULL_PTR, NULL);
2902  goto out;
2903  }
2904 
2905  if (pair->value->len < 0) {
2906  gf_smsg("dict", GF_LOG_ERROR, EINVAL,
2908  pair->value->len, NULL);
2909  goto out;
2910  }
2911 
2912  len += pair->value->len;
2913 
2914  pair = pair->next;
2915  count--;
2916  }
2917 
2918  ret = len;
2919 out:
2920  return ret;
2921 }
2922 
2935 static int
2936 dict_serialize_lk(dict_t *this, char *buf)
2937 {
2938  int ret = -1;
2939  data_pair_t *pair = this->members_list;
2940  int32_t count = this->count;
2941  int32_t keylen = 0;
2942  int32_t netword = 0;
2943 
2944  if (!buf) {
2945  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
2946  goto out;
2947  }
2948 
2949  if (count < 0) {
2951  "count=%d", count, NULL);
2952  goto out;
2953  }
2954 
2955  netword = hton32(count);
2956  memcpy(buf, &netword, sizeof(netword));
2957  buf += DICT_HDR_LEN;
2958 
2959  while (count) {
2960  if (!pair) {
2962  NULL);
2963  goto out;
2964  }
2965 
2966  if (!pair->key) {
2967  gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
2968  goto out;
2969  }
2970 
2971  keylen = strlen(pair->key);
2972  netword = hton32(keylen);
2973  memcpy(buf, &netword, sizeof(netword));
2974  buf += DICT_DATA_HDR_KEY_LEN;
2975 
2976  if (!pair->value) {
2977  gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
2978  goto out;
2979  }
2980 
2981  netword = hton32(pair->value->len);
2982  memcpy(buf, &netword, sizeof(netword));
2983  buf += DICT_DATA_HDR_VAL_LEN;
2984 
2985  memcpy(buf, pair->key, keylen);
2986  buf += keylen;
2987  *buf++ = '\0';
2988 
2989  if (pair->value->data) {
2990  memcpy(buf, pair->value->data, pair->value->len);
2991  buf += pair->value->len;
2992  }
2993 
2994  pair = pair->next;
2995  count--;
2996  }
2997 
2998  ret = 0;
2999 out:
3000  return ret;
3001 }
3002 
3011 int
3013 {
3014  int ret = -EINVAL;
3015 
3016  if (!this) {
3018  "dict is null!");
3019  goto out;
3020  }
3021 
3022  LOCK(&this->lock);
3023  {
3024  ret = dict_serialized_length_lk(this);
3025  }
3026  UNLOCK(&this->lock);
3027 
3028 out:
3029  return ret;
3030 }
3031 
3043 int
3044 dict_serialize(dict_t *this, char *buf)
3045 {
3046  int ret = -1;
3047 
3048  if (!this || !buf) {
3050  "dict is null!");
3051  goto out;
3052  }
3053 
3054  LOCK(&this->lock);
3055  {
3056  ret = dict_serialize_lk(this, buf);
3057  }
3058  UNLOCK(&this->lock);
3059 out:
3060  return ret;
3061 }
3062 
3074 int32_t
3075 dict_unserialize(char *orig_buf, int32_t size, dict_t **fill)
3076 {
3077  char *buf = orig_buf;
3078  int ret = -1;
3079  int32_t count = 0;
3080  int i = 0;
3081 
3082  data_t *value = NULL;
3083  char *key = NULL;
3084  int32_t keylen = 0;
3085  int32_t vallen = 0;
3086  int32_t hostord = 0;
3087 
3088  if (!buf) {
3090  "buf is null!");
3091  goto out;
3092  }
3093 
3094  if (size == 0) {
3096  "size is 0!");
3097  goto out;
3098  }
3099 
3100  if (!fill) {
3102  "fill is null!");
3103  goto out;
3104  }
3105 
3106  if (!*fill) {
3108  "*fill is null!");
3109  goto out;
3110  }
3111 
3112  if ((buf + DICT_HDR_LEN) > (orig_buf + size)) {
3114  "undersized buffer "
3115  "passed. available (%lu) < required (%lu)",
3116  (long)(orig_buf + size), (long)(buf + DICT_HDR_LEN));
3117  goto out;
3118  }
3119 
3120  memcpy(&hostord, buf, sizeof(hostord));
3121  count = ntoh32(hostord);
3122  buf += DICT_HDR_LEN;
3123 
3124  if (count < 0) {
3126  "count=%d", count, NULL);
3127  goto out;
3128  }
3129 
3130  /* count will be set by the dict_set's below */
3131  (*fill)->count = 0;
3132 
3133  for (i = 0; i < count; i++) {
3134  if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) {
3136  "undersized "
3137  "buffer passed. available (%lu) < "
3138  "required (%lu)",
3139  (long)(orig_buf + size),
3140  (long)(buf + DICT_DATA_HDR_KEY_LEN));
3141  goto out;
3142  }
3143  memcpy(&hostord, buf, sizeof(hostord));
3144  keylen = ntoh32(hostord);
3145  buf += DICT_DATA_HDR_KEY_LEN;
3146 
3147  if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) {
3149  "undersized "
3150  "buffer passed. available (%lu) < "
3151  "required (%lu)",
3152  (long)(orig_buf + size),
3153  (long)(buf + DICT_DATA_HDR_VAL_LEN));
3154  goto out;
3155  }
3156  memcpy(&hostord, buf, sizeof(hostord));
3157  vallen = ntoh32(hostord);
3158  buf += DICT_DATA_HDR_VAL_LEN;
3159 
3160  if ((keylen < 0) || (vallen < 0)) {
3162  "undersized length passed "
3163  "key:%d val:%d",
3164  keylen, vallen);
3165  goto out;
3166  }
3167  if ((buf + keylen) > (orig_buf + size)) {
3169  "undersized buffer passed. "
3170  "available (%lu) < required (%lu)",
3171  (long)(orig_buf + size), (long)(buf + keylen));
3172  goto out;
3173  }
3174  key = buf;
3175  buf += keylen + 1; /* for '\0' */
3176 
3177  if ((buf + vallen) > (orig_buf + size)) {
3179  "undersized buffer passed. "
3180  "available (%lu) < required (%lu)",
3181  (long)(orig_buf + size), (long)(buf + vallen));
3182  goto out;
3183  }
3184  value = get_new_data();
3185 
3186  if (!value) {
3187  ret = -1;
3188  goto out;
3189  }
3190  value->len = vallen;
3191  value->data = gf_memdup(buf, vallen);
3193  value->is_static = _gf_false;
3194  buf += vallen;
3195 
3196  ret = dict_addn(*fill, key, keylen, value);
3197  if (ret < 0)
3198  goto out;
3199  }
3200 
3201  ret = 0;
3202 out:
3203  return ret;
3204 }
3205 
3217 int32_t
3218 dict_allocate_and_serialize(dict_t *this, char **buf, u_int *length)
3219 {
3220  int ret = -EINVAL;
3221  ssize_t len = 0;
3222 
3223  if (!this || !buf) {
3224  gf_msg_debug("dict", 0, "dict OR buf is NULL");
3225  goto out;
3226  }
3227 
3228  LOCK(&this->lock);
3229  {
3230  len = dict_serialized_length_lk(this);
3231  if (len < 0) {
3232  ret = len;
3233  goto unlock;
3234  }
3235 
3236  *buf = GF_MALLOC(len, gf_common_mt_char);
3237  if (*buf == NULL) {
3238  ret = -ENOMEM;
3239  goto unlock;
3240  }
3241 
3242  ret = dict_serialize_lk(this, *buf);
3243  if (ret < 0) {
3244  GF_FREE(*buf);
3245  *buf = NULL;
3246  goto unlock;
3247  }
3248 
3249  if (length != NULL) {
3250  *length = len;
3251  }
3252  }
3253 unlock:
3254  UNLOCK(&this->lock);
3255 out:
3256  return ret;
3257 }
3258 
3271 int
3272 dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len,
3273  char delimiter)
3274 {
3275  int ret = -1;
3276  int32_t count = this->count;
3277  int32_t vallen = 0;
3278  int32_t total_len = 0;
3279  data_pair_t *pair = this->members_list;
3280 
3281  if (!buf) {
3282  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
3283  goto out;
3284  }
3285 
3286  if (count < 0) {
3287  gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "count=%d",
3288  count, NULL);
3289  goto out;
3290  }
3291 
3292  while (count) {
3293  if (!pair) {
3295  NULL);
3296  goto out;
3297  }
3298 
3299  if (!pair->key || !pair->value) {
3300  gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_KEY_OR_VALUE_NULL, NULL);
3301  goto out;
3302  }
3303 
3304  if (!pair->value->data) {
3305  gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, NULL);
3306  goto out;
3307  }
3308 
3309  vallen = pair->value->len - 1; // length includes \0
3310  memcpy(buf, pair->value->data, vallen);
3311  buf += vallen;
3312  *buf++ = delimiter;
3313 
3314  total_len += (vallen + 1);
3315 
3316  pair = pair->next;
3317  count--;
3318  }
3319 
3320  *--buf = '\0'; // remove the last delimiter
3321  total_len--; // adjust the length
3322  ret = 0;
3323 
3324  if (serz_len)
3325  *serz_len = total_len;
3326 
3327 out:
3328  return ret;
3329 }
3330 
3331 int
3332 dict_serialize_value_with_delim(dict_t *this, char *buf, int32_t *serz_len,
3333  char delimiter)
3334 {
3335  int ret = -1;
3336 
3337  if (!this || !buf) {
3339  "dict is null!");
3340  goto out;
3341  }
3342 
3343  LOCK(&this->lock);
3344  {
3345  ret = dict_serialize_value_with_delim_lk(this, buf, serz_len,
3346  delimiter);
3347  }
3348  UNLOCK(&this->lock);
3349 out:
3350  return ret;
3351 }
3352 
3353 int
3354 dict_dump_to_str(dict_t *dict, char *dump, int dumpsize, char *format)
3355 {
3356  int ret = 0;
3357  int dumplen = 0;
3358  data_pair_t *trav = NULL;
3359 
3360  if (!dict)
3361  return 0;
3362 
3363  for (trav = dict->members_list; trav; trav = trav->next) {
3364  ret = snprintf(&dump[dumplen], dumpsize - dumplen, format, trav->key,
3365  trav->value->data);
3366  if ((ret == -1) || !ret)
3367  return ret;
3368 
3369  dumplen += ret;
3370  }
3371  return 0;
3372 }
3373 
3374 void
3376 {
3377  int ret = -1;
3378  char *dump = NULL;
3379  const int dump_size = 64 * 1024;
3380  char *format = "(%s:%s)";
3381 
3382  if (!dict) {
3384  "dict is NULL");
3385  goto out;
3386  }
3387 
3388  dump = GF_MALLOC(dump_size, gf_common_mt_char);
3389  if (!dump) {
3391  "dump buffer is NULL");
3392  goto out;
3393  }
3394 
3395  ret = dict_dump_to_str(dict, dump, dump_size, format);
3396  if (ret) {
3398  goto out;
3399  }
3400  gf_smsg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p", dict,
3401  "dump=%s", dump, NULL);
3402 out:
3403  GF_FREE(dump);
3404 
3405  return;
3406 }
3407 
3408 void
3409 dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain)
3410 {
3411  int ret = -1;
3412  char *dump = NULL;
3413  const int dump_size = 64 * 1024;
3414  char key[4096] = {
3415  0,
3416  };
3417  char *format = "\n\t%s:%s";
3418 
3419  if (!dict) {
3421  "dict is NULL");
3422  goto out;
3423  }
3424 
3425  dump = GF_MALLOC(dump_size, gf_common_mt_char);
3426  if (!dump) {
3428  "dump buffer is NULL");
3429  goto out;
3430  }
3431 
3432  ret = dict_dump_to_str(dict, dump, dump_size, format);
3433  if (ret) {
3434  gf_smsg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, "name=%s",
3435  dict_name, NULL);
3436  goto out;
3437  }
3438  gf_proc_dump_build_key(key, domain, "%s", dict_name);
3439  gf_proc_dump_write(key, "%s", dump);
3440 
3441 out:
3442  GF_FREE(dump);
3443 
3444  return;
3445 }
3446 
3447 dict_t *
3448 dict_for_key_value(const char *name, const char *value, size_t size,
3449  gf_boolean_t is_static)
3450 {
3451  dict_t *xattr = dict_new();
3452  int ret = 0;
3453 
3454  if (!xattr)
3455  return NULL;
3456 
3457  if (is_static)
3458  ret = dict_set_static_bin(xattr, (char *)name, (void *)value, size);
3459  else
3460  ret = dict_set_bin(xattr, (char *)name, (void *)value, size);
3461 
3462  if (ret) {
3463  dict_destroy(xattr);
3464  xattr = NULL;
3465  }
3466 
3467  return xattr;
3468 }
3469 
3470 /*
3471  * "strings" should be NULL terminated strings array.
3472  */
3473 int
3474 dict_has_key_from_array(dict_t *dict, char **strings, gf_boolean_t *result)
3475 {
3476  int i = 0;
3477  uint32_t hash = 0;
3478 
3479  if (!dict || !strings || !result)
3480  return -EINVAL;
3481 
3482  LOCK(&dict->lock);
3483  {
3484  for (i = 0; strings[i]; i++) {
3485  hash = (uint32_t)XXH64(strings[i], strlen(strings[i]), 0);
3486  if (dict_lookup_common(dict, strings[i], hash)) {
3487  *result = _gf_true;
3488  goto unlock;
3489  }
3490  }
3491  *result = _gf_false;
3492  }
3493 unlock:
3494  UNLOCK(&dict->lock);
3495  return 0;
3496 }
_gf_false
#define _gf_false
Definition: glusterfs.h:369
data_to_int64_ptr
static int data_to_int64_ptr(data_t *data, int64_t *val)
Definition: dict.c:1578
dict_get_uint64
int dict_get_uint64(dict_t *this, char *key, uint64_t *val)
Definition: dict.c:1991
out
#define out(x...)
Definition: gcrawler.c:35
data_from_uint16
data_t * data_from_uint16(uint16_t value)
Definition: dict.c:962
dict_remove_foreach_fn
int dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *_tmp)
Definition: dict.c:1267
lock
static glusterd_lock_t lock
Definition: glusterd-utils.c:220
dict_get_double
int dict_get_double(dict_t *this, char *key, double *val)
Definition: dict.c:2214
dict_get_bin
int dict_get_bin(dict_t *this, char *key, void **bin)
Definition: dict.c:2559
LG_MSG_FAILED_TO_LOG_DICT
@ LG_MSG_FAILED_TO_LOG_DICT
Definition: libglusterfs-messages.h:123
data_to_uint16
uint16_t data_to_uint16(data_t *data)
Definition: dict.c:1180
data_from_dynptr
data_t * data_from_dynptr(void *value, int32_t len)
Definition: dict.c:1055
GF_DATA_TYPE_GFUUID
@ GF_DATA_TYPE_GFUUID
Definition: glusterfs-fops.h:234
bin_to_data
data_t * bin_to_data(void *value, int32_t len)
Definition: dict.c:1070
mdata_iatt::ia_atime
int64_t ia_atime
Definition: iatt.h:96
_glusterfs_ctx
Definition: glusterfs.h:618
mem_get0
void * mem_get0(struct mem_pool *pool)
Definition: mem-pool.c:703
LG_MSG_UNDERSIZED_BUF
@ LG_MSG_UNDERSIZED_BUF
Definition: libglusterfs-messages.h:123
LG_MSG_INVALID_ARG
@ LG_MSG_INVALID_ARG
Definition: libglusterfs-messages.h:123
data_to_uint64
uint64_t data_to_uint64(data_t *data)
Definition: dict.c:1164
dict_get_int32
int dict_get_int32(dict_t *this, char *key, int32_t *val)
Definition: dict.c:1791
dict_dump_to_log
void dict_dump_to_log(dict_t *dict)
Definition: dict.c:3375
DICT_DATA_HDR_VAL_LEN
#define DICT_DATA_HDR_VAL_LEN
Definition: dict.h:95
data_copy
data_t * data_copy(data_t *old)
Definition: dict.c:305
dict_for_key_value
dict_t * dict_for_key_value(const char *name, const char *value, size_t size, bool is_static)
Definition: dict.c:3448
dict_reset
int dict_reset(dict_t *dict)
Definition: dict.c:1420
_data::is_static
bool is_static
Definition: dict.h:102
data_to_int8
int8_t data_to_int8(data_t *data)
Definition: dict.c:1142
iatt
Definition: iatt.h:46
GF_DATA_TYPE_UNKNOWN
@ GF_DATA_TYPE_UNKNOWN
Definition: glusterfs-fops.h:227
dict_set_int32n
int dict_set_int32n(dict_t *this, char *key, const int keylen, int32_t val)
Definition: dict.c:1817
GF_VALIDATE_OR_GOTO
#define GF_VALIDATE_OR_GOTO(name, arg, label)
Definition: common-utils.h:319
dict_get_ptr_and_len
int dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len)
Definition: dict.c:2327
_data_pair::prev
struct _data_pair * prev
Definition: dict.h:107
_glusterfs_ctx::stats
struct _glusterfs_ctx::@15 stats
THIS
#define THIS
Definition: globals.h:126
dict_set_lk
static int32_t dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value, const uint32_t hash, bool replace)
Definition: dict.c:386
dict_set_uint64
int dict_set_uint64(dict_t *this, char *key, uint64_t val)
Definition: dict.c:2017
data_destroy
void data_destroy(data_t *data)
Definition: dict.c:293
dict_add_dynstr_with_alloc
int dict_add_dynstr_with_alloc(dict_t *this, char *key, char *str)
Definition: dict.c:2534
_dict::members_list
data_pair_t * members_list
Definition: dict.h:120
str_to_data
data_t * str_to_data(char *value)
Definition: dict.c:1001
dict_match_everything
bool dict_match_everything(dict_t *d, char *k, data_t *v, void *data)
Definition: dict.c:1280
dict_set_static_bin
int dict_set_static_bin(dict_t *this, char *key, void *ptr, size_t size)
Definition: dict.c:2647
dict_get_with_ref
int dict_get_with_ref(dict_t *this, char *key, data_t **data)
Definition: dict.c:1464
gf_common_mt_char
@ gf_common_mt_char
Definition: mem-types.h:43
GF_FREE
#define GF_FREE(free_ptr)
Definition: mem-pool.h:159
DICT_DATA_HDR_KEY_LEN
#define DICT_DATA_HDR_KEY_LEN
Definition: dict.h:94
_dict::lock
gf_lock_t lock
Definition: dict.h:122
data_from_uint64
data_t * data_from_uint64(uint64_t value)
Definition: dict.c:899
LG_MSG_DATA_CONVERSION_ERROR
@ LG_MSG_DATA_CONVERSION_ERROR
Definition: libglusterfs-messages.h:123
data_from_dynstr
static data_t * data_from_dynstr(char *value)
Definition: dict.c:1035
dict_unserialize
int32_t dict_unserialize(char *orig_buf, int32_t size, dict_t **fill)
Definition: dict.c:3075
dict_get
data_t * dict_get(dict_t *this, char *key)
Definition: dict.c:544
dict_keys_join
int dict_keys_join(void *value, int size, dict_t *dict, int(*filter_fn)(char *k))
Definition: dict.c:1371
dict_set_int32
int dict_set_int32(dict_t *this, char *key, int32_t val)
Definition: dict.c:1837
done
int done
Definition: gf_attach.c:22
dict_set_mdata
int dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata, bool is_static)
Definition: dict.c:2687
dict_set_bin_common
static int dict_set_bin_common(dict_t *this, char *key, void *ptr, size_t size, bool is_static, gf_dict_data_type_t type)
Definition: dict.c:2594
data_to_int32
int32_t data_to_int32(data_t *data)
Definition: dict.c:1112
min
#define min(a, b)
Definition: common-utils.h:57
dict_serialized_length
int dict_serialized_length(dict_t *this)
Definition: dict.c:3012
dict_key_count
int dict_key_count(dict_t *this)
Definition: dict.c:582
gf_memdup
static void * gf_memdup(const void *src, size_t size)
Definition: mem-pool.h:191
data_from_int16
data_t * data_from_int16(int16_t value)
Definition: dict.c:857
GF_DATA_TYPE_IATT
@ GF_DATA_TYPE_IATT
Definition: glusterfs-fops.h:235
data_to_int64
int64_t data_to_int64(data_t *data)
Definition: dict.c:1104
dict_dump_to_str
int dict_dump_to_str(dict_t *dict, char *dump, int dumpsize, char *format)
Definition: dict.c:3354
LG_MSG_NULL_PTR
@ LG_MSG_NULL_PTR
Definition: libglusterfs-messages.h:123
dict_ref
dict_t * dict_ref(dict_t *this)
Definition: dict.c:751
get_new_data
static data_t * get_new_data()
Definition: dict.c:51
GF_ATOMIC_DEC
#define GF_ATOMIC_DEC(_atomic)
Definition: atomic.h:455
_data_pair::next
struct _data_pair * next
Definition: dict.h:108
BIT_CLEAR
static void BIT_CLEAR(unsigned char *array, unsigned int index)
Definition: common-utils.h:287
dict_set_bin
int dict_set_bin(dict_t *this, char *key, void *ptr, size_t size)
Definition: dict.c:2633
dict_set_dynstr_with_alloc
int dict_set_dynstr_with_alloc(dict_t *this, char *key, const char *str)
Definition: dict.c:2471
get_new_dict_full
static dict_t * get_new_dict_full(int size_hint)
Definition: dict.c:65
dict_get_ptr
int dict_get_ptr(dict_t *this, char *key, void **ptr)
Definition: dict.c:2297
data_to_int16_ptr
static int data_to_int16_ptr(data_t *data, int16_t *val)
Definition: dict.c:1540
dict_set_int16
int dict_set_int16(dict_t *this, char *key, int16_t val)
Definition: dict.c:1745
LG_MSG_DICT_ERROR
@ LG_MSG_DICT_ERROR
Definition: libglusterfs-messages.h:123
data_from_ptr_common
static data_t * data_from_ptr_common(void *value, bool is_static)
Definition: dict.c:983
_data::len
int32_t len
Definition: dict.h:101
_dict::members
data_pair_t ** members
Definition: dict.h:119
gf_asprintf
int gf_asprintf(char **string_ptr, const char *format,...)
Definition: mem-pool.c:237
DICT_FLAG_CLEAR
#define DICT_FLAG_CLEAR
Definition: dict.h:92
dict_foreach
int dict_foreach(dict_t *dict, int(*fn)(dict_t *this, char *key, data_t *value, void *data), void *data)
Definition: dict.c:1286
GF_LOG_WARNING
@ GF_LOG_WARNING
Definition: logging.h:74
mdata_iatt
Definition: iatt.h:95
GF_DATA_TYPE_PTR
@ GF_DATA_TYPE_PTR
Definition: glusterfs-fops.h:233
dict_set_dynstr
int dict_set_dynstr(dict_t *this, char *key, char *str)
Definition: dict.c:2487
dict_destroy
void dict_destroy(dict_t *this)
Definition: dict.c:675
dict_set_flag
int dict_set_flag(dict_t *this, char *key, int flag)
Definition: dict.c:2202
dict_null_foreach_fn
int dict_null_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp)
Definition: dict.c:1261
_data
Definition: dict.h:97
data_to_int32_ptr
static int data_to_int32_ptr(data_t *data, int32_t *val)
Definition: dict.c:1559
gf_boolean_t
#define gf_boolean_t
Definition: glusterfs.h:368
dict_get_uint16
int dict_get_uint16(dict_t *this, char *key, uint16_t *val)
Definition: dict.c:1901
GF_LOG_DEBUG
@ GF_LOG_DEBUG
Definition: logging.h:77
dict_rename_key
int dict_rename_key(dict_t *this, char *key, char *replace_key)
Definition: dict.c:2812
src.utils.fail
def fail(msg, code=1, logger=None)
Definition: utils.py:154
_glusterfs_ctx::total_dicts_used
gf_atomic_int64_t total_dicts_used
Definition: glusterfs.h:723
_glusterfs_ctx::total_pairs_used
gf_atomic_int64_t total_pairs_used
Definition: glusterfs.h:722
dict_cmp::value_ignore
bool(* value_ignore)(char *k)
Definition: dict.c:30
LG_MSG_KEY_OR_VALUE_NULL
@ LG_MSG_KEY_OR_VALUE_NULL
Definition: libglusterfs-messages.h:123
IA_IFBLK
@ IA_IFBLK
Definition: iatt.h:29
UNLOCK
#define UNLOCK(x)
Definition: locking.h:79
gf_proc_dump_build_key
#define gf_proc_dump_build_key(key, key_prefix, fmt...)
Definition: statedump.h:56
_dict::hash_size
int32_t hash_size
Definition: dict.h:116
GF_DATA_TYPE_MAX
@ GF_DATA_TYPE_MAX
Definition: glusterfs-fops.h:237
XXH64
unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
Definition: xxhash.c:855
BIT_VALUE
static unsigned int BIT_VALUE(unsigned char *array, unsigned int index)
Definition: common-utils.h:296
gf_msg_callingfn
#define gf_msg_callingfn(dom, level, errnum, msgid, fmt...)
Definition: logging.h:256
_data::refcount
gf_atomic_int64_t refcount
Definition: dict.h:99
data_to_uint8
uint8_t data_to_uint8(data_t *data)
Definition: dict.c:1202
gf_msg_debug
#define gf_msg_debug(dom, errnum, fmt...)
Definition: logging.h:270
compat.h
data_from_uint32
data_t * data_from_uint32(uint32_t value)
Definition: dict.c:941
dict_new
dict_t * dict_new(void)
Definition: dict.c:107
_data_pair::key
char * key
Definition: dict.h:110
dict_unref
void dict_unref(dict_t *this)
Definition: dict.c:734
LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO
@ LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO
Definition: libglusterfs-messages.h:123
dict_set_dynptr
int dict_set_dynptr(dict_t *this, char *key, void *ptr, size_t len)
Definition: dict.c:2278
compat-errno.h
dict_get_iatt
int dict_get_iatt(dict_t *this, char *key, struct iatt *iatt)
Definition: dict.c:2733
LG_MSG_DICT_SET_FAILED
@ LG_MSG_DICT_SET_FAILED
Definition: libglusterfs-messages.h:123
mdata_iatt::ia_ctime_nsec
uint32_t ia_ctime_nsec
Definition: iatt.h:101
data_to_uint64_ptr
static int data_to_uint64_ptr(data_t *data, uint64_t *val)
Definition: dict.c:1635
dict_get_str
int dict_get_str(dict_t *this, char *key, char **str)
Definition: dict.c:2385
dict_serialize_value_with_delim_lk
int dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len, char delimiter)
Definition: dict.c:3272
dict_check_flag
int dict_check_flag(dict_t *this, char *key, int flag)
Definition: dict.c:2045
dict_get_int32n
int dict_get_int32n(dict_t *this, char *key, const int keylen, int32_t *val)
Definition: dict.c:1765
dict_copy
dict_t * dict_copy(dict_t *dict, dict_t *new)
Definition: dict.c:1403
data_to_str
char * data_to_str(data_t *data)
Definition: dict.c:1222
_data::data
char * data
Definition: dict.h:98
DICT_FLAG_SET
#define DICT_FLAG_SET
Definition: dict.h:91
dict_cmp::dict
dict_t * dict
Definition: dict.c:29
data_from_int8
data_t * data_from_int8(int8_t value)
Definition: dict.c:878
dict_set_strn
int dict_set_strn(dict_t *this, char *key, const int keylen, char *str)
Definition: dict.c:2430
GF_DATA_TYPE_INT
@ GF_DATA_TYPE_INT
Definition: glusterfs-fops.h:229
dict_clear_flag
int dict_clear_flag(dict_t *this, char *key, int flag)
Definition: dict.c:2208
iatt::ia_gfid
uuid_t ia_gfid
Definition: iatt.h:69
dict_get_with_refn
int dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data)
Definition: dict.c:1476
dict_lookup
int32_t dict_lookup(dict_t *this, char *key, data_t **data)
Definition: dict.c:359
dict_get_gfuuid
int dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid)
Definition: dict.c:2662
dict_copy_one
static int dict_copy_one(dict_t *unused, char *key, data_t *value, void *newdict)
Definition: dict.c:1397
DICT_MAX_FLAGS
#define DICT_MAX_FLAGS
Definition: dict.h:90
dict_serialize
int dict_serialize(dict_t *this, char *buf)
Definition: dict.c:3044
dict_set_iatt
int dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static)
Definition: dict.c:2726
dict_get_strn
int dict_get_strn(dict_t *this, char *key, const int keylen, char **str)
Definition: dict.c:2360
data_to_int8_ptr
static int data_to_int8_ptr(data_t *data, int8_t *val)
Definition: dict.c:1521
mem_put
void mem_put(void *ptr)
Definition: mem-pool.c:849
int_to_data
data_t * int_to_data(int64_t value)
Definition: dict.c:795
dict_deln
void dict_deln(dict_t *this, char *key, const int keylen)
Definition: dict.c:614
data_to_bin
void * data_to_bin(data_t *data)
Definition: dict.c:1236
DICT_KEY_VALUE_MAX_SIZE
#define DICT_KEY_VALUE_MAX_SIZE
Definition: dict.h:89
dict_set_int64
int dict_set_int64(dict_t *this, char *key, int64_t val)
Definition: dict.c:1882
_data_pair::value
data_t * value
Definition: dict.h:109
iatt::ia_type
ia_type_t ia_type
Definition: iatt.h:70
dict_get_int64
int dict_get_int64(dict_t *this, char *key, int64_t *val)
Definition: dict.c:1856
dict_cmp
Definition: dict.c:28
data_to_iatt
struct iatt * data_to_iatt(data_t *data, char *key)
Definition: dict.c:1243
dict_set_static_ptr
int dict_set_static_ptr(dict_t *this, char *key, void *ptr)
Definition: dict.c:2259
dict_allocate_and_serialize
int32_t dict_allocate_and_serialize(dict_t *this, char **buf, u_int *length)
Definition: dict.c:3218
BIT_SET
static void BIT_SET(unsigned char *array, unsigned int index)
Definition: common-utils.h:278
is_data_equal
int32_t is_data_equal(data_t *one, data_t *two)
Definition: dict.c:118
name
char * name
Definition: xdr-nfs3.h:948
dict_getn
data_t * dict_getn(dict_t *this, char *key, const int keylen)
Definition: dict.c:556
data_from_int32
data_t * data_from_int32(int32_t value)
Definition: dict.c:836
xxhash.h
LOCK_DESTROY
#define LOCK_DESTROY(x)
Definition: locking.h:80
dict_get_int8
int dict_get_int8(dict_t *this, char *key, int8_t *val)
Definition: dict.c:1673
_dict::members_internal
data_pair_t * members_internal
Definition: dict.h:123
data_from_int64
data_t * data_from_int64(int64_t value)
Definition: dict.c:816
dict_serialize_value_with_delim
int dict_serialize_value_with_delim(dict_t *this, char *buf, int32_t *serz_len, char delimiter)
Definition: dict.c:3332
dict_set
int32_t dict_set(dict_t *this, char *key, data_t *value)
Definition: dict.c:474
data_to_uint32_ptr
static int data_to_uint32_ptr(data_t *data, uint32_t *val)
Definition: dict.c:1616
ntoh32
#define ntoh32
Definition: byte-order.h:28
dict_addn
int32_t dict_addn(dict_t *this, char *key, const int keylen, data_t *value)
Definition: dict.c:519
GF_DATA_TYPE_STR
@ GF_DATA_TYPE_STR
Definition: glusterfs-fops.h:232
dict_has_key_from_array
int dict_has_key_from_array(dict_t *dict, char **strings, bool *result)
Definition: dict.c:3474
gf_strn2boolean
int gf_strn2boolean(const char *str, const int len, bool *b)
Definition: common-utils.c:1948
dict_dump_to_statedump
void dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain)
Definition: dict.c:3409
dict_fnmatch
static bool dict_fnmatch(dict_t *d, char *k, data_t *val, void *match_data)
Definition: dict.c:1339
_dict_modify_flag
static int _dict_modify_flag(dict_t *this, char *key, int flag, int op)
Definition: dict.c:2070
dict_get_mdata
int dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata)
Definition: dict.c:2695
LG_MSG_NULL_VALUE_IN_DICT
@ LG_MSG_NULL_VALUE_IN_DICT
Definition: libglusterfs-messages.h:123
hton32
static uint32_t(* hton32)(uint32_t)
Definition: byte-order.h:24
GF_ATOMIC_GET
#define GF_ATOMIC_GET(_atomic)
Definition: atomic.h:423
key_value_cmp
static int key_value_cmp(dict_t *one, char *key1, data_t *value1, void *data)
Definition: dict.c:215
data_to_ptr
void * data_to_ptr(data_t *data)
Definition: dict.c:1229
dict_set_double
int dict_set_double(dict_t *this, char *key, double val)
Definition: dict.c:2240
mdata_iatt::ia_mtime
int64_t ia_mtime
Definition: iatt.h:97
_data_pair::hash_next
struct _data_pair * hash_next
Definition: dict.h:106
_dict::free_pair
data_pair_t free_pair
Definition: dict.h:124
GF_LOG_ERROR
@ GF_LOG_ERROR
Definition: logging.h:73
dict_set_dynstrn
int dict_set_dynstrn(dict_t *this, char *key, const int keylen, char *str)
Definition: dict.c:2494
GF_ATOMIC_INC
#define GF_ATOMIC_INC(_atomic)
Definition: atomic.h:454
dict_foreach_match
int dict_foreach_match(dict_t *dict, bool(*match)(dict_t *this, char *key, data_t *value, void *mdata), void *match_data, int(*action)(dict_t *this, char *key, data_t *value, void *adata), void *action_data)
Definition: dict.c:1304
LOCK_INIT
#define LOCK_INIT(x)
Definition: locking.h:76
gf_dict_data_type_t
gf_dict_data_type_t
Definition: glusterfs-fops.h:226
mdata_iatt::ia_atime_nsec
uint32_t ia_atime_nsec
Definition: iatt.h:99
gf_proc_dump_write
int gf_proc_dump_write(char *key, char *value,...)
Definition: statedump.c:187
dict.h
dict_lookup_common
static data_pair_t * dict_lookup_common(const dict_t *this, const char *key, const uint32_t hash)
Definition: dict.c:339
GF_DATA_TYPE_UINT
@ GF_DATA_TYPE_UINT
Definition: glusterfs-fops.h:230
dict_del
void dict_del(dict_t *this, char *key)
Definition: dict.c:602
dict_set_str
int dict_set_str(dict_t *this, char *key, char *str)
Definition: dict.c:2410
_dict::count
int32_t count
Definition: dict.h:117
LG_MSG_NO_MEMORY
@ LG_MSG_NO_MEMORY
Definition: libglusterfs-messages.h:123
mdata_iatt::ia_ctime
int64_t ia_ctime
Definition: iatt.h:98
gf_smsg
#define gf_smsg(dom, level, errnum, msgid, event...)
Definition: logging.h:377
LG_MSG_PAIRS_LESS_THAN_COUNT
@ LG_MSG_PAIRS_LESS_THAN_COUNT
Definition: libglusterfs-messages.h:123
GF_DATA_TYPE_MDATA
@ GF_DATA_TYPE_MDATA
Definition: glusterfs-fops.h:236
byte-order.h
dict_set_gfuuid
int dict_set_gfuuid(dict_t *this, char *key, uuid_t gfid, bool is_static)
Definition: dict.c:2655
LOCK
#define LOCK(x)
Definition: locking.h:77
statedump.h
dict_add
int32_t dict_add(dict_t *this, char *key, data_t *value)
Definition: dict.c:510
data_to_uint16_ptr
static int data_to_uint16_ptr(data_t *data, uint16_t *val)
Definition: dict.c:1597
dict_set_int8
int dict_set_int8(dict_t *this, char *key, int8_t val)
Definition: dict.c:1699
VALIDATE_DATA_AND_LOG
#define VALIDATE_DATA_AND_LOG(data, type, key, ret_val)
Definition: dict.c:33
dict_set_option
int dict_set_option(dict_t *this, char *key, char *str)
Definition: dict.c:2515
dict_set_uint32
int dict_set_uint32(dict_t *this, char *key, uint32_t val)
Definition: dict.c:1972
GF_ATOMIC_ADD
#define GF_ATOMIC_ADD(_atomic, _value)
Definition: atomic.h:424
GF_ATOMIC_INIT
#define GF_ATOMIC_INIT(_atomic, _value)
Definition: atomic.h:422
data_to_double_ptr
static int data_to_double_ptr(data_t *data, double *val)
Definition: dict.c:1654
_data_pair::key_hash
uint32_t key_hash
Definition: dict.h:111
libglusterfs-messages.h
data_to_int16
int16_t data_to_int16(data_t *data)
Definition: dict.c:1120
data_from_double
data_t * data_from_double(double value)
Definition: dict.c:920
mdata_iatt::ia_mtime_nsec
uint32_t ia_mtime_nsec
Definition: iatt.h:100
data_to_ptr_common
static int data_to_ptr_common(data_t *data, void **val)
Definition: dict.c:1506
data_to_uint32
uint32_t data_to_uint32(data_t *data)
Definition: dict.c:1172
_dict
Definition: dict.h:114
_data_pair
Definition: dict.h:105
GF_CALLOC
#define GF_CALLOC(nmemb, size, type)
Definition: mem-pool.h:153
data_unref
void data_unref(data_t *this)
Definition: dict.c:764
DICT_HDR_LEN
#define DICT_HDR_LEN
Definition: dict.h:93
dict_get_str_boolean
int dict_get_str_boolean(dict_t *this, char *key, int default_val)
Definition: dict.c:2781
mem_get
void * mem_get(struct mem_pool *pool)
Definition: mem-pool.c:826
S40ufo-stop.op
op
Definition: S40ufo-stop.py:14
ENODATA
#define ENODATA
Definition: compat-errno.h:218
GF_ASSERT
#define GF_ASSERT(x)
Definition: common-utils.h:434
GF_DATA_TYPE_DOUBLE
@ GF_DATA_TYPE_DOUBLE
Definition: glusterfs-fops.h:231
GF_LOG_INFO
@ GF_LOG_INFO
Definition: logging.h:76
dict_copy_with_ref
dict_t * dict_copy_with_ref(dict_t *dict, dict_t *new)
Definition: dict.c:1435
data_type_name
static char * data_type_name[GF_DATA_TYPE_MAX]
Definition: dict.c:1090
dict_set_nstrn
int dict_set_nstrn(dict_t *this, char *key, const int keylen, char *str, const int vallen)
Definition: dict.c:2451
_gf_true
#define _gf_true
Definition: glusterfs.h:370
dict_get_uint32
int dict_get_uint32(dict_t *this, char *key, uint32_t *val)
Definition: dict.c:1946
LG_MSG_COUNT_LESS_THAN_ZERO
@ LG_MSG_COUNT_LESS_THAN_ZERO
Definition: libglusterfs-messages.h:123
dict_setn
int32_t dict_setn(dict_t *this, char *key, const int keylen, data_t *value)
Definition: dict.c:483
GF_DATA_TYPE_STR_OLD
@ GF_DATA_TYPE_STR_OLD
Definition: glusterfs-fops.h:228
gf_strdup
static char * gf_strdup(const char *src)
Definition: mem-pool.h:182
err
#define err(x...)
Definition: gcrawler.c:34
dict_set_uint16
int dict_set_uint16(dict_t *this, char *key, uint16_t val)
Definition: dict.c:1927
S40ufo-stop.type
type
Definition: S40ufo-stop.py:15
iatt::ia_ino
uint64_t ia_ino
Definition: iatt.h:48
gf_uuid_compare
static int gf_uuid_compare(uuid_t u1, uuid_t u2)
Definition: compat-uuid.h:23
are_dicts_equal
bool are_dicts_equal(dict_t *one, dict_t *two, bool(*match)(dict_t *d, char *k, data_t *v, void *data), bool(*value_ignore)(char *k))
Definition: dict.c:249
GF_MALLOC
#define GF_MALLOC(size, type)
Definition: mem-pool.h:155
_glusterfs_ctx::max_dict_pairs
gf_atomic_int64_t max_dict_pairs
Definition: glusterfs.h:721
dict_foreach_fnmatch
int dict_foreach_fnmatch(dict_t *dict, char *pattern, int(*fn)(dict_t *this, char *key, data_t *value, void *data), void *data)
Definition: dict.c:1349
strn_to_data
data_t * strn_to_data(char *value, const int vallen)
Definition: dict.c:1013
dict_get_int16
int dict_get_int16(dict_t *this, char *key, int16_t *val)
Definition: dict.c:1719
iatt::ia_rdev
uint64_t ia_rdev
Definition: iatt.h:50
dict_serialized_length_lk
int dict_serialized_length_lk(dict_t *this)
Definition: dict.c:2871
IA_IFCHR
@ IA_IFCHR
Definition: iatt.h:30
_data::data_type
gf_dict_data_type_t data_type
Definition: dict.h:100
dict_serialize_lk
static int dict_serialize_lk(dict_t *this, char *buf)
Definition: dict.c:2936
data_ref
data_t * data_ref(data_t *this)
Definition: dict.c:781