diff options
Diffstat (limited to 'libglusterfs/src')
| -rw-r--r-- | libglusterfs/src/dict.c | 190 | ||||
| -rw-r--r-- | libglusterfs/src/dict.h | 11 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 27 | ||||
| -rw-r--r-- | libglusterfs/src/libglusterfs.sym | 3 | 
4 files changed, 229 insertions, 2 deletions
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index d1a64c4a3a2..0f9632160cc 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -2022,6 +2022,196 @@ err:          return ret;  } +/* + * dict_check_flag can be used to check a one bit flag in an array of flags + * The flag argument indicates the bit position (within the array of bits). + * Currently limited to max of 256 flags for a key. + * return value, + * 1 : flag is set + * 0 : flag is not set + * <0: Error + */ +int +dict_check_flag (dict_t *this, char *key, int flag) +{ +        data_t  *data = NULL; +        int     ret = -ENOENT; + +        ret = dict_get_with_ref (this, key, &data); +        if (ret < 0) { +                return ret; +        } + +        if (BIT_VALUE((unsigned char *)(data->data), flag)) +                ret = 1; +        else +                ret = 0; + +        data_unref(data); +        return ret; +} + +/* + * _dict_modify_flag can be used to set/clear a bit flag in an array of flags + * flag: indicates the bit position. limited to max of DICT_MAX_FLAGS. + * op: Indicates operation DICT_FLAG_SET / DICT_FLAG_CLEAR + */ +static int +_dict_modify_flag (dict_t *this, char *key, int flag, int op) +{ +        data_t          *data           = NULL; +        int             ret             = 0; +        uint32_t        hash            = 0; +        data_pair_t     *pair           = NULL; +        char            *ptr            = NULL; +        int             hashval         = 0; + +        if (!this || !key) { +                gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL, +                                  LG_MSG_INVALID_ARG, +                                  "dict OR key (%s) is NULL", key); +                ret = -EINVAL; +                goto err; +        } + +        /* +         * Using a size of 32 bytes to support max of 256 +         * flags in a single key. This should be suffcient. +         */ +        GF_ASSERT(flag >= 0 && flag < DICT_MAX_FLAGS); + +        hash = SuperFastHash (key, strlen (key)); +        LOCK (&this->lock); +        { +                pair = dict_lookup_common (this, key, hash); + +                if (pair) { +                        data = pair->value; +                        if (op == DICT_FLAG_SET) +                                BIT_SET((unsigned char *)(data->data), flag); +                        else +                                BIT_CLEAR((unsigned char *)(data->data), flag); +                        ret = 0; +                } else { +                        ptr = GF_CALLOC(1, DICT_MAX_FLAGS / 8, +                                        gf_common_mt_char); +                        if (!ptr) { +                                gf_msg("dict", GF_LOG_ERROR, ENOMEM, +                                       LG_MSG_NO_MEMORY, +                                       "unable to allocate flag bit array"); +                                ret = -ENOMEM; +                                goto err; +                        } + +                        data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8); + +                        if (!data) { +                                gf_msg("dict", GF_LOG_ERROR, ENOMEM, +                                       LG_MSG_NO_MEMORY, +                                       "unable to allocate data"); +                                GF_FREE(ptr); +                                ret = -ENOMEM; +                                goto err; +                        } + +                        if (op == DICT_FLAG_SET) +                                BIT_SET((unsigned char *)(data->data), flag); +                        else +                                BIT_CLEAR((unsigned char *)(data->data), flag); + +                        if (this->free_pair_in_use) { +                                pair = mem_get0 (THIS->ctx->dict_pair_pool); +                                if (!pair) { +                                        gf_msg("dict", GF_LOG_ERROR, ENOMEM, +                                               LG_MSG_NO_MEMORY, +                                               "unable to allocate dict pair"); +                                        ret = -ENOMEM; +                                        goto err; +                                } +                        } else { +                                pair = &this->free_pair; +                                this->free_pair_in_use = _gf_true; +                        } + +                        pair->key = (char *)GF_CALLOC(1, strlen (key) + 1, +                                                      gf_common_mt_char); +                        if (!pair->key) { +                                gf_msg("dict", GF_LOG_ERROR, ENOMEM, +                                       LG_MSG_NO_MEMORY, +                                       "unable to allocate dict pair"); +                                ret = -ENOMEM; +                                goto err; +                        } +                        strcpy (pair->key, key); +                        pair->key_hash = hash; +                        pair->value = data_ref (data); + +                        hashval = hash % this->hash_size; +                        pair->hash_next = this->members[hashval]; +                        this->members[hashval] = pair; + +                        pair->next = this->members_list; +                        pair->prev = NULL; +                        if (this->members_list) +                                this->members_list->prev = pair; +                        this->members_list = pair; +                        this->count++; + + +                        if (this->max_count < this->count) +                                this->max_count = this->count; +                } +        } + +        UNLOCK (&this->lock); +        return 0; + +err: +        UNLOCK (&this->lock); +        if (pair) { +                if (pair->key) +                        free(pair->key); + +                if (pair == &this->free_pair) { +                        this->free_pair_in_use = _gf_false; +                } else { +                        mem_put (pair); +                } +        } + +        if (data) +                data_destroy(data); + + +        gf_msg("dict", GF_LOG_ERROR, EINVAL, +               LG_MSG_DICT_SET_FAILED, +               "unable to set key (%s) in dict ", key); + +        return ret; +} + +/* + * Todo: + * Add below primitives as needed: + * dict_check_flags(this, key, flag...): variadic function to check + *                                       multiple flags at a time. + * dict_set_flags(this, key, flag...): set multiple flags + * dict_clear_flags(this, key, flag...): reset multiple flags + */ + +int +dict_set_flag (dict_t *this, char *key, int flag) +{ +        return _dict_modify_flag (this, key, flag, DICT_FLAG_SET); +} + +int +dict_clear_flag (dict_t *this, char *key, int flag) +{ +        return _dict_modify_flag (this, key, flag, DICT_FLAG_CLEAR); +} + +  int  dict_get_double (dict_t *this, char *key, double *val)  { diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h index e481330d6b5..d0b05172c2e 100644 --- a/libglusterfs/src/dict.h +++ b/libglusterfs/src/dict.h @@ -60,10 +60,13 @@ typedef struct _data_pair data_pair_t;                                                                          \          } while (0) -#define DICT_KEY_VALUE_MAX_SIZE                     1048576 -  #define dict_foreach_inline(d, c) for (c = d->members_list; c; c = c->next) +#define DICT_KEY_VALUE_MAX_SIZE                     1048576 +#define DICT_MAX_FLAGS                              256 +#define DICT_FLAG_SET          1 +#define DICT_FLAG_CLEAR        0 +  struct _data {          unsigned char  is_static:1;          unsigned char  is_const:1; @@ -227,6 +230,10 @@ GF_MUST_CHECK int dict_set_uint32 (dict_t *this, char *key, uint32_t val);  GF_MUST_CHECK int dict_get_uint64 (dict_t *this, char *key, uint64_t *val);  GF_MUST_CHECK int dict_set_uint64 (dict_t *this, char *key, uint64_t val); +GF_MUST_CHECK int dict_check_flag (dict_t *this, char *key, int flag); +GF_MUST_CHECK int dict_set_flag (dict_t *this, char *key, int flag); +GF_MUST_CHECK int dict_clear_flag (dict_t *this, char *key, int flag); +  GF_MUST_CHECK int dict_get_double (dict_t *this, char *key, double *val);  GF_MUST_CHECK int dict_set_double (dict_t *this, char *key, double val); diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 28666de3da4..84e33449dad 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -173,6 +173,33 @@  #define GLUSTERFS_VERSION_XCHG_KEY     "glusterfs.version.xchg"  #define GLUSTERFS_INTERNAL_FOP_KEY  "glusterfs-internal-fop" + +/* GlusterFS Internal FOP Indicator flags + * (To pass information on the context in which a paritcular + *  fop is performed between translators) + * The presence of a particular flag must be treated as an + * indicator of the context, however the flag is added only in + * a scenario where there is a need for such context across translators. + * So it cannot be an absolute information on context. + */ +#define GF_INTERNAL_CTX_KEY  "glusterfs.internal-ctx" + +/* + * Always append entries to end of the enum, do not delete entries. + * Currently dict_set_flag allows to set upto 256 flag, if the enum + * needs to grow beyond this dict_set_flag has to be changed accordingly + */ +enum gf_internal_fop_indicator { +        GF_DHT_HEAL_DIR       /* Index 0 in bit array*/ +}; + +/* Todo: + * Add GF_FOP_LINK_FILE         0x2ULL + * address GLUSTERFS_MARKER_DONT_ACCOUNT_KEY and + * GLUSTERFS_INTERNAL_FOP_KEY with this flag + */ + +  #define DHT_CHANGELOG_RENAME_OP_KEY   "changelog.rename-op"  #define ZR_FILE_CONTENT_STR     "glusterfs.file." diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 6340bc8a3a2..1d21cfa8465 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -411,6 +411,9 @@ dict_set_static_ptr  dict_set_str  dict_set_uint32  dict_set_uint64 +dict_set_flag +dict_clear_flag +dict_check_flag  dict_unref  dict_unserialize  drop_token  | 
