summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec/src/ec-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/ec/src/ec-helpers.c')
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c867
1 files changed, 867 insertions, 0 deletions
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c
new file mode 100644
index 00000000000..48f54475e01
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-helpers.c
@@ -0,0 +1,867 @@
+/*
+ Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#include <libgen.h>
+
+#include <glusterfs/byte-order.h>
+
+#include "ec.h"
+#include "ec-mem-types.h"
+#include "ec-messages.h"
+#include "ec-fops.h"
+#include "ec-method.h"
+#include "ec-helpers.h"
+
+static const char *ec_fop_list[] = {[-EC_FOP_HEAL] = "HEAL"};
+
+const char *
+ec_bin(char *str, size_t size, uint64_t value, int32_t digits)
+{
+ str += size;
+
+ if (size-- < 1) {
+ goto failed;
+ }
+ *--str = 0;
+
+ while ((value != 0) || (digits > 0)) {
+ if (size-- < 1) {
+ goto failed;
+ }
+ *--str = '0' + (value & 1);
+ digits--;
+ value >>= 1;
+ }
+
+ return str;
+
+failed:
+ return "<buffer too small>";
+}
+
+const char *
+ec_fop_name(int32_t id)
+{
+ if (id >= 0) {
+ return gf_fop_list[id];
+ }
+
+ return ec_fop_list[-id];
+}
+
+void
+ec_trace(const char *event, ec_fop_data_t *fop, const char *fmt, ...)
+{
+ char str1[32], str2[32], str3[32];
+ char *msg;
+ ec_t *ec = fop->xl->private;
+ va_list args;
+ int32_t ret;
+
+ va_start(args, fmt);
+ ret = vasprintf(&msg, fmt, args);
+ va_end(args);
+
+ if (ret < 0) {
+ msg = "<memory allocation error>";
+ }
+
+ gf_msg_trace("ec", 0,
+ "%s(%s) %p(%p) [refs=%d, winds=%d, jobs=%d] "
+ "frame=%p/%p, min/exp=%d/%d, err=%d state=%d "
+ "{%s:%s:%s} %s",
+ event, ec_fop_name(fop->id), fop, fop->parent, fop->refs,
+ fop->winds, fop->jobs, fop->req_frame, fop->frame,
+ fop->minimum, fop->expected, fop->error, fop->state,
+ ec_bin(str1, sizeof(str1), fop->mask, ec->nodes),
+ ec_bin(str2, sizeof(str2), fop->remaining, ec->nodes),
+ ec_bin(str3, sizeof(str3), fop->good, ec->nodes), msg);
+
+ if (ret >= 0) {
+ free(msg);
+ }
+}
+
+int32_t
+ec_bits_consume(uint64_t *n)
+{
+ uint64_t tmp;
+
+ tmp = *n;
+ tmp &= -tmp;
+ *n ^= tmp;
+
+ return gf_bits_index(tmp);
+}
+
+size_t
+ec_iov_copy_to(void *dst, struct iovec *vector, int32_t count, off_t offset,
+ size_t size)
+{
+ int32_t i = 0;
+ size_t total = 0, len = 0;
+
+ while (i < count) {
+ if (offset < vector[i].iov_len) {
+ while ((i < count) && (size > 0)) {
+ len = size;
+ if (len > vector[i].iov_len - offset) {
+ len = vector[i].iov_len - offset;
+ }
+ memcpy(dst, vector[i++].iov_base + offset, len);
+ offset = 0;
+ dst += len;
+ total += len;
+ size -= len;
+ }
+
+ break;
+ }
+
+ offset -= vector[i].iov_len;
+ i++;
+ }
+
+ return total;
+}
+
+int32_t
+ec_buffer_alloc(xlator_t *xl, size_t size, struct iobref **piobref, void **ptr)
+{
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ int32_t ret = -ENOMEM;
+
+ iobuf = iobuf_get_page_aligned(xl->ctx->iobuf_pool, size,
+ EC_METHOD_WORD_SIZE);
+ if (iobuf == NULL) {
+ goto out;
+ }
+
+ iobref = *piobref;
+ if (iobref == NULL) {
+ iobref = iobref_new();
+ if (iobref == NULL) {
+ goto out;
+ }
+ }
+
+ ret = iobref_add(iobref, iobuf);
+ if (ret != 0) {
+ if (iobref != *piobref) {
+ iobref_unref(iobref);
+ }
+ iobref = NULL;
+
+ goto out;
+ }
+
+ GF_ASSERT(EC_ALIGN_CHECK(iobuf->ptr, EC_METHOD_WORD_SIZE));
+
+ *ptr = iobuf->ptr;
+
+out:
+ if (iobuf != NULL) {
+ iobuf_unref(iobuf);
+ }
+
+ if (iobref != NULL) {
+ *piobref = iobref;
+ }
+
+ return ret;
+}
+
+int32_t
+ec_dict_set_array(dict_t *dict, char *key, uint64_t value[], int32_t size)
+{
+ int ret = -1;
+ uint64_t *ptr = NULL;
+ int32_t vindex;
+
+ if (value == NULL) {
+ return -EINVAL;
+ }
+
+ ptr = GF_MALLOC(sizeof(uint64_t) * size, gf_common_mt_char);
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+ for (vindex = 0; vindex < size; vindex++) {
+ ptr[vindex] = hton64(value[vindex]);
+ }
+ ret = dict_set_bin(dict, key, ptr, sizeof(uint64_t) * size);
+ if (ret)
+ GF_FREE(ptr);
+ return ret;
+}
+
+int32_t
+ec_dict_get_array(dict_t *dict, char *key, uint64_t value[], int32_t size)
+{
+ void *ptr;
+ int32_t len;
+ int32_t vindex;
+ int32_t old_size = 0;
+ int32_t err;
+
+ if (dict == NULL) {
+ return -EINVAL;
+ }
+ err = dict_get_ptr_and_len(dict, key, &ptr, &len);
+ if (err != 0) {
+ return err;
+ }
+
+ if (len > (size * sizeof(uint64_t)) || (len % sizeof(uint64_t))) {
+ return -EINVAL;
+ }
+
+ /* 3.6 version ec would have stored version in 64 bit. In that case treat
+ * metadata versions same as data*/
+ old_size = min(size, len / sizeof(uint64_t));
+ for (vindex = 0; vindex < old_size; vindex++) {
+ value[vindex] = ntoh64(*((uint64_t *)ptr + vindex));
+ }
+
+ if (old_size < size) {
+ for (vindex = old_size; vindex < size; vindex++) {
+ value[vindex] = value[old_size - 1];
+ }
+ }
+
+ return 0;
+}
+
+int32_t
+ec_dict_del_array(dict_t *dict, char *key, uint64_t value[], int32_t size)
+{
+ int ret = 0;
+
+ ret = ec_dict_get_array(dict, key, value, size);
+ if (ret == 0)
+ dict_del(dict, key);
+
+ return ret;
+}
+
+int32_t
+ec_dict_set_number(dict_t *dict, char *key, uint64_t value)
+{
+ int ret = -1;
+ uint64_t *ptr;
+
+ ptr = GF_MALLOC(sizeof(value), gf_common_mt_char);
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+
+ *ptr = hton64(value);
+
+ ret = dict_set_bin(dict, key, ptr, sizeof(value));
+ if (ret)
+ GF_FREE(ptr);
+
+ return ret;
+}
+
+int32_t
+ec_dict_del_number(dict_t *dict, char *key, uint64_t *value)
+{
+ void *ptr;
+ int32_t len, err;
+
+ if (dict == NULL) {
+ return -EINVAL;
+ }
+ err = dict_get_ptr_and_len(dict, key, &ptr, &len);
+ if (err != 0) {
+ return err;
+ }
+ if (len != sizeof(uint64_t)) {
+ return -EINVAL;
+ }
+
+ *value = ntoh64(*(uint64_t *)ptr);
+
+ dict_del(dict, key);
+
+ return 0;
+}
+
+int32_t
+ec_dict_set_config(dict_t *dict, char *key, ec_config_t *config)
+{
+ int ret = -1;
+ uint64_t *ptr, data;
+
+ if (config->version > EC_CONFIG_VERSION) {
+ gf_msg("ec", GF_LOG_ERROR, EINVAL, EC_MSG_UNSUPPORTED_VERSION,
+ "Trying to store an unsupported config "
+ "version (%u)",
+ config->version);
+
+ return -EINVAL;
+ }
+
+ ptr = GF_MALLOC(sizeof(uint64_t), gf_common_mt_char);
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+
+ data = ((uint64_t)config->version) << 56;
+ data |= ((uint64_t)config->algorithm) << 48;
+ data |= ((uint64_t)config->gf_word_size) << 40;
+ data |= ((uint64_t)config->bricks) << 32;
+ data |= ((uint64_t)config->redundancy) << 24;
+ data |= config->chunk_size;
+
+ *ptr = hton64(data);
+
+ ret = dict_set_bin(dict, key, ptr, sizeof(uint64_t));
+ if (ret)
+ GF_FREE(ptr);
+
+ return ret;
+}
+
+int32_t
+ec_dict_del_config(dict_t *dict, char *key, ec_config_t *config)
+{
+ void *ptr;
+ uint64_t data;
+ int32_t len, err;
+
+ if (dict == NULL) {
+ return -EINVAL;
+ }
+ err = dict_get_ptr_and_len(dict, key, &ptr, &len);
+ if (err != 0) {
+ return err;
+ }
+ if (len != sizeof(uint64_t)) {
+ return -EINVAL;
+ }
+
+ data = ntoh64(*(uint64_t *)ptr);
+ /* Currently we need to get the config xattr for entries of type IA_INVAL.
+ * These entries can later become IA_DIR entries (after inode_link()),
+ * which don't have a config xattr. However, since the xattr is requested
+ * using an xattrop() fop, it will always return a config full of 0's
+ * instead of saying that it doesn't exist.
+ *
+ * We need to filter out this case and consider that a config xattr == 0 is
+ * the same as a non-existent xattr. Otherwise ec_config_check() will fail.
+ */
+ if (data == 0) {
+ return -ENODATA;
+ }
+
+ config->version = (data >> 56) & 0xff;
+ if (config->version > EC_CONFIG_VERSION) {
+ gf_msg("ec", GF_LOG_ERROR, EINVAL, EC_MSG_UNSUPPORTED_VERSION,
+ "Found an unsupported config version (%u)", config->version);
+
+ return -EINVAL;
+ }
+
+ config->algorithm = (data >> 48) & 0xff;
+ config->gf_word_size = (data >> 40) & 0xff;
+ config->bricks = (data >> 32) & 0xff;
+ config->redundancy = (data >> 24) & 0xff;
+ config->chunk_size = data & 0xffffff;
+
+ dict_del(dict, key);
+
+ return 0;
+}
+
+gf_boolean_t
+ec_loc_gfid_check(xlator_t *xl, uuid_t dst, uuid_t src)
+{
+ if (gf_uuid_is_null(src)) {
+ return _gf_true;
+ }
+
+ if (gf_uuid_is_null(dst)) {
+ gf_uuid_copy(dst, src);
+
+ return _gf_true;
+ }
+
+ if (gf_uuid_compare(dst, src) != 0) {
+ gf_msg(xl->name, GF_LOG_WARNING, 0, EC_MSG_GFID_MISMATCH,
+ "Mismatching GFID's in loc");
+
+ return _gf_false;
+ }
+
+ return _gf_true;
+}
+
+int32_t
+ec_loc_setup_inode(xlator_t *xl, inode_table_t *table, loc_t *loc)
+{
+ int32_t ret = -EINVAL;
+
+ if (loc->inode != NULL) {
+ if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid)) {
+ goto out;
+ }
+ } else if (table != NULL) {
+ if (!gf_uuid_is_null(loc->gfid)) {
+ loc->inode = inode_find(table, loc->gfid);
+ } else if (loc->path && strchr(loc->path, '/')) {
+ loc->inode = inode_resolve(table, (char *)loc->path);
+ }
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int32_t
+ec_loc_setup_parent(xlator_t *xl, inode_table_t *table, loc_t *loc)
+{
+ char *path, *parent;
+ int32_t ret = -EINVAL;
+
+ if (loc->parent != NULL) {
+ if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid)) {
+ goto out;
+ }
+ } else if (table != NULL) {
+ if (!gf_uuid_is_null(loc->pargfid)) {
+ loc->parent = inode_find(table, loc->pargfid);
+ } else if (loc->path && strchr(loc->path, '/')) {
+ path = gf_strdup(loc->path);
+ if (path == NULL) {
+ gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY,
+ "Unable to duplicate path '%s'", loc->path);
+
+ ret = -ENOMEM;
+
+ goto out;
+ }
+ parent = dirname(path);
+ loc->parent = inode_resolve(table, parent);
+ if (loc->parent != NULL) {
+ gf_uuid_copy(loc->pargfid, loc->parent->gfid);
+ }
+ GF_FREE(path);
+ }
+ }
+
+ /* If 'pargfid' has not been determined, clear 'name' to avoid resolutions
+ based on <gfid:pargfid>/name. */
+ if (gf_uuid_is_null(loc->pargfid)) {
+ loc->name = NULL;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int32_t
+ec_loc_setup_path(xlator_t *xl, loc_t *loc)
+{
+ static uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ char *name;
+ int32_t ret = -EINVAL;
+
+ if (loc->path != NULL) {
+ name = strrchr(loc->path, '/');
+ if (name == NULL) {
+ /* Allow gfid paths: <gfid:...> */
+ if (strncmp(loc->path, "<gfid:", 6) == 0) {
+ ret = 0;
+ }
+ goto out;
+ }
+ if (name == loc->path) {
+ if (name[1] == 0) {
+ if (!ec_loc_gfid_check(xl, loc->gfid, root)) {
+ goto out;
+ }
+ } else {
+ if (!ec_loc_gfid_check(xl, loc->pargfid, root)) {
+ goto out;
+ }
+ }
+ }
+ name++;
+
+ if (loc->name != NULL) {
+ if (strcmp(loc->name, name) != 0) {
+ gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_INVALID_LOC_NAME,
+ "Invalid name '%s' in loc", loc->name);
+
+ goto out;
+ }
+ } else {
+ loc->name = name;
+ }
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int32_t
+ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent)
+{
+ inode_table_t *table = NULL;
+ char *str = NULL;
+ int32_t ret = -ENOMEM;
+
+ memset(parent, 0, sizeof(loc_t));
+
+ if (loc->parent != NULL) {
+ table = loc->parent->table;
+ parent->inode = inode_ref(loc->parent);
+ } else if (loc->inode != NULL) {
+ table = loc->inode->table;
+ }
+ if (!gf_uuid_is_null(loc->pargfid)) {
+ gf_uuid_copy(parent->gfid, loc->pargfid);
+ }
+ if (loc->path && strchr(loc->path, '/')) {
+ str = gf_strdup(loc->path);
+ if (str == NULL) {
+ gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY,
+ "Unable to duplicate path '%s'", loc->path);
+
+ goto out;
+ }
+ parent->path = gf_strdup(dirname(str));
+ if (parent->path == NULL) {
+ gf_msg(xl->name, GF_LOG_ERROR, ENOMEM, EC_MSG_NO_MEMORY,
+ "Unable to duplicate path '%s'", dirname(str));
+
+ goto out;
+ }
+ }
+
+ ret = ec_loc_setup_path(xl, parent);
+ if (ret == 0) {
+ ret = ec_loc_setup_inode(xl, table, parent);
+ }
+ if (ret == 0) {
+ ret = ec_loc_setup_parent(xl, table, parent);
+ }
+ if (ret != 0) {
+ goto out;
+ }
+
+ if ((parent->inode == NULL) && (parent->path == NULL) &&
+ gf_uuid_is_null(parent->gfid)) {
+ gf_msg(xl->name, GF_LOG_ERROR, EINVAL, EC_MSG_LOC_PARENT_INODE_MISSING,
+ "Parent inode missing for loc_t");
+
+ ret = -EINVAL;
+
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ GF_FREE(str);
+
+ if (ret != 0) {
+ loc_wipe(parent);
+ }
+
+ return ret;
+}
+
+int32_t
+ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode, struct iatt *iatt)
+{
+ inode_table_t *table = NULL;
+ int32_t ret = -EINVAL;
+
+ if (inode != NULL) {
+ table = inode->table;
+ if (loc->inode != inode) {
+ if (loc->inode != NULL) {
+ inode_unref(loc->inode);
+ }
+ loc->inode = inode_ref(inode);
+ gf_uuid_copy(loc->gfid, inode->gfid);
+ }
+ } else if (loc->inode != NULL) {
+ table = loc->inode->table;
+ } else if (loc->parent != NULL) {
+ table = loc->parent->table;
+ }
+
+ if (iatt != NULL) {
+ if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid)) {
+ goto out;
+ }
+ }
+
+ ret = ec_loc_setup_path(xl, loc);
+ if (ret == 0) {
+ ret = ec_loc_setup_inode(xl, table, loc);
+ }
+ if (ret == 0) {
+ ret = ec_loc_setup_parent(xl, table, loc);
+ }
+ if (ret != 0) {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+int32_t
+ec_loc_from_fd(xlator_t *xl, loc_t *loc, fd_t *fd)
+{
+ ec_fd_t *ctx;
+ int32_t ret = -ENOMEM;
+
+ memset(loc, 0, sizeof(*loc));
+
+ ctx = ec_fd_get(fd, xl);
+ if (ctx != NULL) {
+ if (loc_copy(loc, &ctx->loc) != 0) {
+ goto out;
+ }
+ }
+
+ ret = ec_loc_update(xl, loc, fd->inode, NULL);
+ if (ret != 0) {
+ goto out;
+ }
+
+out:
+ if (ret != 0) {
+ loc_wipe(loc);
+ }
+
+ return ret;
+}
+
+int32_t
+ec_loc_from_loc(xlator_t *xl, loc_t *dst, loc_t *src)
+{
+ int32_t ret = -ENOMEM;
+
+ memset(dst, 0, sizeof(*dst));
+
+ if (loc_copy(dst, src) != 0) {
+ goto out;
+ }
+
+ ret = ec_loc_update(xl, dst, NULL, NULL);
+ if (ret != 0) {
+ goto out;
+ }
+
+out:
+ if (ret != 0) {
+ loc_wipe(dst);
+ }
+
+ return ret;
+}
+
+void
+ec_owner_set(call_frame_t *frame, void *owner)
+{
+ set_lk_owner_from_ptr(&frame->root->lk_owner, owner);
+}
+
+void
+ec_owner_copy(call_frame_t *frame, gf_lkowner_t *owner)
+{
+ lk_owner_copy(&frame->root->lk_owner, owner);
+}
+
+static void
+ec_stripe_cache_init(ec_t *ec, ec_inode_t *ctx)
+{
+ ec_stripe_list_t *stripe_cache = NULL;
+
+ stripe_cache = &(ctx->stripe_cache);
+ if (stripe_cache->max == 0) {
+ stripe_cache->max = ec->stripe_cache;
+ }
+}
+
+ec_inode_t *
+__ec_inode_get(inode_t *inode, xlator_t *xl)
+{
+ ec_inode_t *ctx = NULL;
+ uint64_t value = 0;
+
+ if ((__inode_ctx_get(inode, xl, &value) != 0) || (value == 0)) {
+ ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_inode_t);
+ if (ctx != NULL) {
+ memset(ctx, 0, sizeof(*ctx));
+ INIT_LIST_HEAD(&ctx->heal);
+ INIT_LIST_HEAD(&ctx->stripe_cache.lru);
+ ctx->heal_count = 0;
+ value = (uint64_t)(uintptr_t)ctx;
+ if (__inode_ctx_set(inode, xl, &value) != 0) {
+ GF_FREE(ctx);
+
+ return NULL;
+ }
+ }
+ } else {
+ ctx = (ec_inode_t *)(uintptr_t)value;
+ }
+ if (ctx)
+ ec_stripe_cache_init(xl->private, ctx);
+
+ return ctx;
+}
+
+ec_inode_t *
+ec_inode_get(inode_t *inode, xlator_t *xl)
+{
+ ec_inode_t *ctx = NULL;
+
+ LOCK(&inode->lock);
+
+ ctx = __ec_inode_get(inode, xl);
+
+ UNLOCK(&inode->lock);
+
+ return ctx;
+}
+
+ec_fd_t *
+__ec_fd_get(fd_t *fd, xlator_t *xl)
+{
+ int i = 0;
+ ec_fd_t *ctx = NULL;
+ ec_inode_t *ictx = NULL;
+ uint64_t value = 0;
+ ec_t *ec = xl->private;
+
+ if ((__fd_ctx_get(fd, xl, &value) != 0) || (value == 0)) {
+ ctx = GF_MALLOC(sizeof(*ctx) + (sizeof(ec_fd_status_t) * ec->nodes),
+ ec_mt_ec_fd_t);
+ if (ctx != NULL) {
+ memset(ctx, 0, sizeof(*ctx));
+
+ for (i = 0; i < ec->nodes; i++) {
+ if (fd_is_anonymous(fd)) {
+ ctx->fd_status[i] = EC_FD_OPENED;
+ } else {
+ ctx->fd_status[i] = EC_FD_NOT_OPENED;
+ }
+ }
+
+ value = (uint64_t)(uintptr_t)ctx;
+ if (__fd_ctx_set(fd, xl, value) != 0) {
+ GF_FREE(ctx);
+ return NULL;
+ }
+ /* Only refering bad-version so no need for lock
+ * */
+ ictx = __ec_inode_get(fd->inode, xl);
+ if (ictx) {
+ ctx->bad_version = ictx->bad_version;
+ }
+ }
+ } else {
+ ctx = (ec_fd_t *)(uintptr_t)value;
+ }
+
+ /* Treat anonymous fd specially */
+ if (fd->anonymous && ctx) {
+ /* Mark the fd open for all subvolumes. */
+ ctx->open = -1;
+ /* Try to populate ctx->loc with fd->inode information. */
+ ec_loc_update(xl, &ctx->loc, fd->inode, NULL);
+ }
+
+ return ctx;
+}
+
+ec_fd_t *
+ec_fd_get(fd_t *fd, xlator_t *xl)
+{
+ ec_fd_t *ctx = NULL;
+
+ LOCK(&fd->lock);
+
+ ctx = __ec_fd_get(fd, xl);
+
+ UNLOCK(&fd->lock);
+
+ return ctx;
+}
+
+gf_boolean_t
+ec_is_internal_xattr(dict_t *dict, char *key, data_t *value, void *data)
+{
+ if (key && (strncmp(key, EC_XATTR_PREFIX, SLEN(EC_XATTR_PREFIX)) == 0))
+ return _gf_true;
+
+ return _gf_false;
+}
+
+void
+ec_filter_internal_xattrs(dict_t *xattr)
+{
+ dict_foreach_match(xattr, ec_is_internal_xattr, NULL,
+ dict_remove_foreach_fn, NULL);
+}
+
+gf_boolean_t
+ec_is_data_fop(glusterfs_fop_t fop)
+{
+ switch (fop) {
+ case GF_FOP_WRITE:
+ case GF_FOP_TRUNCATE:
+ case GF_FOP_FTRUNCATE:
+ case GF_FOP_FALLOCATE:
+ case GF_FOP_DISCARD:
+ case GF_FOP_ZEROFILL:
+ return _gf_true;
+ default:
+ return _gf_false;
+ }
+ return _gf_false;
+}
+/*
+gf_boolean_t
+ec_is_metadata_fop (int32_t lock_kind, glusterfs_fop_t fop)
+{
+ if (lock_kind == EC_LOCK_ENTRY) {
+ return _gf_false;
+ }
+
+ switch (fop) {
+ case GF_FOP_SETATTR:
+ case GF_FOP_FSETATTR:
+ case GF_FOP_SETXATTR:
+ case GF_FOP_FSETXATTR:
+ case GF_FOP_REMOVEXATTR:
+ case GF_FOP_FREMOVEXATTR:
+ return _gf_true;
+ default:
+ return _gf_false;
+ }
+ return _gf_false;
+}*/