summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2014-05-05 12:57:34 +0200
committerVijay Bellur <vbellur@redhat.com>2014-07-11 10:33:40 -0700
commitad112305a1c7452b13c92238b40ded80361838f3 (patch)
tree82dbf9aa0b77eb76d43c8b1ccb3ba58e61bc4e2a /xlators/cluster/ec
parent6b4702897bd56e29db4db06f8cf896f89df1133c (diff)
cluster/ec: Added erasure code translator
Change-Id: I293917501d5c2ca4cdc6303df30cf0b568cea361 BUG: 1118629 Signed-off-by: Xavier Hernandez <xhernandez@datalab.es> Reviewed-on: http://review.gluster.org/7749 Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r--xlators/cluster/ec/Makefile.am3
-rw-r--r--xlators/cluster/ec/src/Makefile.am49
-rw-r--r--xlators/cluster/ec/src/ec-combine.c787
-rw-r--r--xlators/cluster/ec/src/ec-combine.h44
-rw-r--r--xlators/cluster/ec/src/ec-common.c1109
-rw-r--r--xlators/cluster/ec/src/ec-common.h105
-rw-r--r--xlators/cluster/ec/src/ec-data.c261
-rw-r--r--xlators/cluster/ec/src/ec-data.h260
-rw-r--r--xlators/cluster/ec/src/ec-dir-read.c571
-rw-r--r--xlators/cluster/ec/src/ec-dir-write.c2102
-rw-r--r--xlators/cluster/ec/src/ec-fops.h211
-rw-r--r--xlators/cluster/ec/src/ec-generic.c1660
-rw-r--r--xlators/cluster/ec/src/ec-gf.c10120
-rw-r--r--xlators/cluster/ec/src/ec-gf.h114
-rw-r--r--xlators/cluster/ec/src/ec-heal.c1470
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c594
-rw-r--r--xlators/cluster/ec/src/ec-helpers.h59
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c1764
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c2235
-rw-r--r--xlators/cluster/ec/src/ec-locks.c1292
-rw-r--r--xlators/cluster/ec/src/ec-mem-types.h39
-rw-r--r--xlators/cluster/ec/src/ec-method.c182
-rw-r--r--xlators/cluster/ec/src/ec-method.h42
-rw-r--r--xlators/cluster/ec/src/ec.c904
-rw-r--r--xlators/cluster/ec/src/ec.h54
25 files changed, 26031 insertions, 0 deletions
diff --git a/xlators/cluster/ec/Makefile.am b/xlators/cluster/ec/Makefile.am
new file mode 100644
index 00000000000..d471a3f9243
--- /dev/null
+++ b/xlators/cluster/ec/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/cluster/ec/src/Makefile.am b/xlators/cluster/ec/src/Makefile.am
new file mode 100644
index 00000000000..e2a9330a944
--- /dev/null
+++ b/xlators/cluster/ec/src/Makefile.am
@@ -0,0 +1,49 @@
+xlator_LTLIBRARIES = ec.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
+
+ec_sources := ec.c
+ec_sources += ec-data.c
+ec_sources += ec-helpers.c
+ec_sources += ec-common.c
+ec_sources += ec-generic.c
+ec_sources += ec-locks.c
+ec_sources += ec-dir-read.c
+ec_sources += ec-dir-write.c
+ec_sources += ec-inode-read.c
+ec_sources += ec-inode-write.c
+ec_sources += ec-combine.c
+ec_sources += ec-gf.c
+ec_sources += ec-method.c
+ec_sources += ec-heal.c
+
+ec_headers := ec.h
+ec_headers += ec-mem-types.h
+ec_headers += ec-helpers.h
+ec_headers += ec-data.h
+ec_headers += ec-fops.h
+ec_headers += ec-common.h
+ec_headers += ec-combine.h
+ec_headers += ec-gf.h
+ec_headers += ec-method.h
+
+ec_ext_sources = $(top_builddir)/xlators/lib/src/libxlator.c
+
+ec_ext_headers = $(top_builddir)/xlators/lib/src/libxlator.h
+
+ec_la_LDFLAGS = -module -avoid-version
+ec_la_SOURCES = $(ec_sources) $(ec_headers) $(ec_ext_sources) $(ec_ext_headers)
+ec_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+AM_CPPFLAGS = $(GF_CPPFLAGS)
+AM_CPPFLAGS += -I$(top_srcdir)/libglusterfs/src
+AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
+CLEANFILES =
+
+install-data-hook:
+ ln -sf ec.so $(DESTDIR)$(xlatordir)/disperse.so
+
+uninstall-local:
+ rm -f $(DESTDIR)$(xlatordir)/disperse.so
diff --git a/xlators/cluster/ec/src/ec-combine.c b/xlators/cluster/ec/src/ec-combine.c
new file mode 100644
index 00000000000..07d819a9a3d
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-combine.c
@@ -0,0 +1,787 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <fnmatch.h>
+
+#include "libxlator.h"
+
+#include "ec-data.h"
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+
+struct _ec_dict_info;
+typedef struct _ec_dict_info ec_dict_info_t;
+
+struct _ec_dict_combine;
+typedef struct _ec_dict_combine ec_dict_combine_t;
+
+struct _ec_dict_info
+{
+ dict_t * dict;
+ int32_t count;
+};
+
+struct _ec_dict_combine
+{
+ ec_cbk_data_t * cbk;
+ int32_t which;
+};
+
+void ec_iatt_time_merge(uint32_t * dst_sec, uint32_t * dst_nsec,
+ uint32_t src_sec, uint32_t src_nsec)
+{
+ if ((*dst_sec < src_sec) ||
+ ((*dst_sec == src_sec) && (*dst_nsec < src_nsec)))
+ {
+ *dst_sec = src_sec;
+ *dst_nsec = src_nsec;
+ }
+}
+
+int32_t ec_iatt_combine(struct iatt * dst, struct iatt * src, int32_t count)
+{
+ int32_t i;
+
+ for (i = 0; i < count; i++)
+ {
+ if ((dst->ia_ino != src->ia_ino) ||
+ (dst->ia_uid != src->ia_uid) ||
+ (dst->ia_gid != src->ia_gid) ||
+ (((dst->ia_type == IA_IFBLK) || (dst->ia_type == IA_IFCHR)) &&
+ (dst->ia_rdev != src->ia_rdev)) ||
+ ((dst->ia_type == IA_IFREG) && (dst->ia_size != src->ia_size)) ||
+ (st_mode_from_ia(dst->ia_prot, dst->ia_type) !=
+ st_mode_from_ia(src->ia_prot, src->ia_type)) ||
+ (uuid_compare(dst->ia_gfid, src->ia_gfid) != 0))
+ {
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "Failed to combine iatt (inode: %lu-%lu, links: %u-%u, "
+ "uid: %u-%u, gid: %u-%u, rdev: %lu-%lu, size: %lu-%lu, "
+ "mode: %o-%o)",
+ dst->ia_ino, src->ia_ino, dst->ia_nlink, src->ia_nlink,
+ dst->ia_uid, src->ia_uid, dst->ia_gid, src->ia_gid,
+ dst->ia_rdev, src->ia_rdev, dst->ia_size, src->ia_size,
+ st_mode_from_ia(dst->ia_prot, dst->ia_type),
+ st_mode_from_ia(src->ia_prot, dst->ia_type));
+
+ return 0;
+ }
+ }
+
+ while (count-- > 0)
+ {
+ dst->ia_blocks += src->ia_blocks;
+ if (dst->ia_blksize < src->ia_blksize)
+ {
+ dst->ia_blksize = src->ia_blksize;
+ }
+
+ ec_iatt_time_merge(&dst->ia_atime, &dst->ia_atime_nsec, src->ia_atime,
+ src->ia_atime_nsec);
+ ec_iatt_time_merge(&dst->ia_mtime, &dst->ia_mtime_nsec, src->ia_mtime,
+ src->ia_mtime_nsec);
+ ec_iatt_time_merge(&dst->ia_ctime, &dst->ia_ctime_nsec, src->ia_ctime,
+ src->ia_ctime_nsec);
+ }
+
+ return 1;
+}
+
+void ec_iatt_rebuild(ec_t * ec, struct iatt * iatt, int32_t count,
+ int32_t answers)
+{
+ size_t blocks;
+
+ while (count-- > 0)
+ {
+ blocks = iatt[count].ia_blocks * ec->fragments + answers - 1;
+ blocks /= answers;
+ iatt[count].ia_blocks = blocks;
+ }
+}
+
+int32_t ec_dict_data_compare(dict_t * dict, char * key, data_t * value,
+ void * arg)
+{
+ ec_dict_info_t * info = arg;
+ data_t * data;
+
+ data = dict_get(info->dict, key);
+ if (data == NULL)
+ {
+ gf_log("ec", GF_LOG_DEBUG, "key '%s' found only on one dict", key);
+
+ return -1;
+ }
+
+ info->count--;
+
+ if ((strcmp(key, GF_CONTENT_KEY) == 0) ||
+ (strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) ||
+ (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0) ||
+ (strcmp(key, GF_XATTR_LOCKINFO_KEY) == 0) ||
+ (strcmp(key, GF_XATTR_CLRLK_CMD) == 0) ||
+ (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0) ||
+ (fnmatch(GF_XATTR_STIME_PATTERN, key, 0) == 0) ||
+ (XATTR_IS_NODE_UUID(key)))
+ {
+ return 0;
+ }
+
+ if ((data->len != value->len) ||
+ (memcmp(data->data, value->data, data->len) != 0))
+ {
+ gf_log("ec", GF_LOG_DEBUG, "key '%s' is different (size: %u, %u)",
+ key, data->len, value->len);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_data_show(dict_t * dict, char * key, data_t * value,
+ void * arg)
+{
+ if (dict_get(arg, key) == NULL)
+ {
+ gf_log("ec", GF_LOG_DEBUG, "key '%s' found only on one dict", key);
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_compare(dict_t * dict1, dict_t * dict2)
+{
+ ec_dict_info_t info;
+ dict_t * dict;
+
+ if (dict1 != NULL)
+ {
+ info.dict = dict1;
+ info.count = dict1->count;
+ dict = dict2;
+ }
+ else if (dict2 != NULL)
+ {
+ info.dict = dict2;
+ info.count = dict2->count;
+ dict = dict1;
+ }
+ else
+ {
+ return 1;
+ }
+
+ if (dict != NULL)
+ {
+ if (dict_foreach(dict, ec_dict_data_compare, &info) != 0)
+ {
+ return 0;
+ }
+ }
+
+ if (info.count != 0)
+ {
+ dict_foreach(info.dict, ec_dict_data_show, dict);
+ }
+
+ return (info.count == 0);
+}
+
+int32_t ec_dict_list(data_t ** list, int32_t * count, ec_cbk_data_t * cbk,
+ int32_t which, char * key)
+{
+ ec_cbk_data_t * ans;
+ dict_t * dict;
+ int32_t i, max;
+
+ max = *count;
+ i = 0;
+ for (ans = cbk; ans != NULL; ans = ans->next)
+ {
+ if (i >= max)
+ {
+ gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Unexpected number of "
+ "dictionaries");
+
+ return 0;
+ }
+
+ dict = (which == EC_COMBINE_XDATA) ? ans->xdata : ans->dict;
+ list[i] = dict_get(dict, key);
+ if (list[i] == NULL)
+ {
+ gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Unexpected missing "
+ "dictionary entry");
+
+ return 0;
+ }
+
+ i++;
+ }
+
+ *count = i;
+
+ return 1;
+}
+
+char * ec_concat_prepare(xlator_t * xl, char ** sep, char ** post,
+ const char * fmt, va_list args)
+{
+ char * str, * tmp;
+ int32_t len;
+
+ len = gf_vasprintf(&str, fmt, args);
+ if (len < 0)
+ {
+ return NULL;
+ }
+
+ tmp = strchr(str, '{');
+ if (tmp == NULL)
+ {
+ goto out;
+ }
+ *tmp++ = 0;
+ *sep = tmp;
+ tmp = strchr(tmp, '}');
+ if (tmp == NULL)
+ {
+ goto out;
+ }
+ *tmp++ = 0;
+ *post = tmp;
+
+ return str;
+
+out:
+ gf_log(xl->name, GF_LOG_ERROR, "Invalid concat format");
+
+ GF_FREE(str);
+
+ return NULL;
+}
+
+int32_t ec_dict_data_concat(const char * fmt, ec_cbk_data_t * cbk,
+ int32_t which, char * key, ...)
+{
+ data_t * data[cbk->count];
+ size_t len, tmp;
+ char * str = NULL, * pre = NULL, * sep, * post;
+ dict_t * dict;
+ va_list args;
+ int32_t i, num, prelen, postlen, seplen;
+ int32_t ret = -1;
+
+ num = cbk->count;
+ if (!ec_dict_list(data, &num, cbk, which, key))
+ {
+ return -1;
+ }
+
+ va_start(args, key);
+ pre = ec_concat_prepare(cbk->fop->xl, &sep, &post, fmt, args);
+ va_end(args);
+
+ if (pre == NULL)
+ {
+ return -1;
+ }
+
+ prelen = strlen(pre);
+ seplen = strlen(sep);
+ postlen = strlen(post);
+
+ len = prelen + (num - 1) * seplen + postlen + 1;
+ for (i = 0; i < num; i++)
+ {
+ len += data[i]->len - 1;
+ }
+
+ str = GF_MALLOC(len, gf_common_mt_char);
+ if (str == NULL)
+ {
+ goto out;
+ }
+
+ memcpy(str, pre, prelen);
+ len = prelen;
+ for (i = 0; i < num; i++)
+ {
+ memcpy(str + len, sep, seplen);
+ len += seplen;
+ tmp = data[i]->len - 1;
+ memcpy(str + len, data[i]->data, tmp);
+ len += tmp;
+ }
+ memcpy(str + len, post, postlen + 1);
+
+ dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+ if (dict_set_dynstr(dict, key, str) != 0)
+ {
+ goto out;
+ }
+
+ str = NULL;
+
+ ret = 0;
+
+out:
+ GF_FREE(str);
+ GF_FREE(pre);
+
+ return ret;
+}
+
+int32_t ec_dict_data_merge(ec_cbk_data_t * cbk, int32_t which, char * key)
+{
+ data_t * data[cbk->count];
+ dict_t * dict, * lockinfo, * tmp;
+ char * ptr = NULL;
+ int32_t i, num, len;
+ int32_t ret = -1;
+
+ num = cbk->count;
+ if (!ec_dict_list(data, &num, cbk, which, key))
+ {
+ return -1;
+ }
+
+ if (dict_unserialize(data[0]->data, data[0]->len, &lockinfo) != 0)
+ {
+ return -1;
+ }
+
+ for (i = 1; i < num; i++)
+ {
+ if (dict_unserialize(data[i]->data, data[i]->len, &tmp) != 0)
+ {
+ goto out;
+ }
+ if (dict_copy(tmp, lockinfo) == NULL)
+ {
+ dict_unref(tmp);
+
+ goto out;
+ }
+
+ dict_unref(tmp);
+ }
+
+ len = dict_serialized_length(lockinfo);
+ if (len < 0)
+ {
+ goto out;
+ }
+ ptr = GF_MALLOC(len, gf_common_mt_char);
+ if (ptr == NULL)
+ {
+ goto out;
+ }
+ if (dict_serialize(lockinfo, ptr) != 0)
+ {
+ goto out;
+ }
+ dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+ if (dict_set_dynptr(dict, key, ptr, len) != 0)
+ {
+ goto out;
+ }
+
+ ptr = NULL;
+
+ ret = 0;
+
+out:
+ GF_FREE(ptr);
+ dict_unref(lockinfo);
+
+ return ret;
+}
+
+int32_t ec_dict_data_uuid(ec_cbk_data_t * cbk, int32_t which, char * key)
+{
+ ec_cbk_data_t * ans, * min;
+ dict_t * src, * dst;
+ data_t * data;
+
+ min = cbk;
+ for (ans = cbk->next; ans != NULL; ans = ans->next)
+ {
+ if (ans->idx < min->idx)
+ {
+ min = ans;
+ }
+ }
+
+ if (min != cbk)
+ {
+ src = (which == EC_COMBINE_XDATA) ? min->xdata : min->dict;
+ dst = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+
+ data = dict_get(src, key);
+ if (data == NULL)
+ {
+ return -1;
+ }
+ if (dict_set(dst, key, data) != 0)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_data_max(ec_cbk_data_t * cbk, int32_t which, char * key)
+{
+ data_t * data[cbk->count];
+ dict_t * dict;
+ int32_t i, num;
+ uint32_t max, tmp;
+
+ num = cbk->count;
+ if (!ec_dict_list(data, &num, cbk, which, key))
+ {
+ return -1;
+ }
+
+ if (num <= 1)
+ {
+ return 0;
+ }
+
+ max = data_to_uint32(data[0]);
+ for (i = 1; i < num; i++)
+ {
+ tmp = data_to_uint32(data[i]);
+ if (max < tmp)
+ {
+ max = tmp;
+ }
+ }
+
+ dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+ if (dict_set_uint32(dict, key, max) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_data_stime(ec_cbk_data_t * cbk, int32_t which, char * key)
+{
+ data_t * data[cbk->count];
+ dict_t * dict;
+ int32_t i, num;
+
+ num = cbk->count;
+ if (!ec_dict_list(data, &num, cbk, which, key))
+ {
+ return -1;
+ }
+
+ dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+ for (i = 1; i < num; i++)
+ {
+ if (gf_get_max_stime(cbk->fop->xl, dict, key, data[i]) != 0)
+ {
+ gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "STIME combination "
+ "failed");
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_data_combine(dict_t * dict, char * key, data_t * value,
+ void * arg)
+{
+ ec_dict_combine_t * data = arg;
+
+ if ((strcmp(key, GF_XATTR_PATHINFO_KEY) == 0) ||
+ (strcmp(key, GF_XATTR_USER_PATHINFO_KEY) == 0))
+ {
+ return ec_dict_data_concat("(<EC:%s> { })", data->cbk, data->which,
+ key, data->cbk->fop->xl->name);
+ }
+
+ if (strncmp(key, GF_XATTR_CLRLK_CMD, strlen(GF_XATTR_CLRLK_CMD)) == 0)
+ {
+ return ec_dict_data_concat("{\n}", data->cbk, data->which, key);
+ }
+
+ if (strncmp(key, GF_XATTR_LOCKINFO_KEY,
+ strlen(GF_XATTR_LOCKINFO_KEY)) == 0)
+ {
+ return ec_dict_data_merge(data->cbk, data->which, key);
+ }
+
+ if (strcmp(key, GLUSTERFS_OPEN_FD_COUNT) == 0)
+ {
+ return ec_dict_data_max(data->cbk, data->which, key);
+ }
+
+ if (XATTR_IS_NODE_UUID(key))
+ {
+ return ec_dict_data_uuid(data->cbk, data->which, key);
+ }
+
+ if (fnmatch(GF_XATTR_STIME_PATTERN, key, FNM_NOESCAPE) == 0)
+ {
+ return ec_dict_data_stime(data->cbk, data->which, key);
+ }
+
+ return 0;
+}
+
+int32_t ec_dict_combine(ec_cbk_data_t * cbk, int32_t which)
+{
+ dict_t * dict;
+ ec_dict_combine_t data;
+
+ data.cbk = cbk;
+ data.which = which;
+
+ dict = (which == EC_COMBINE_XDATA) ? cbk->xdata : cbk->dict;
+ if ((dict != NULL) &&
+ (dict_foreach(dict, ec_dict_data_combine, &data) != 0))
+ {
+ gf_log(cbk->fop->xl->name, GF_LOG_ERROR, "Dictionary combination "
+ "failed");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_vector_compare(struct iovec * dst_vector, int32_t dst_count,
+ struct iovec * src_vector, int32_t src_count)
+{
+ size_t dst_size = 0, src_size = 0;
+
+ if (dst_count > 0)
+ {
+ dst_size = iov_length(dst_vector, dst_count);
+ }
+ if (src_count > 0)
+ {
+ src_size = iov_length(src_vector, src_count);
+ }
+
+ return (dst_size == src_size);
+}
+
+int32_t ec_flock_compare(struct gf_flock * dst, struct gf_flock * src)
+{
+ if ((dst->l_type != src->l_type) ||
+ (dst->l_whence != src->l_whence) ||
+ (dst->l_start != src->l_start) ||
+ (dst->l_len != src->l_len) ||
+ (dst->l_pid != src->l_pid) ||
+ !is_same_lkowner(&dst->l_owner, &src->l_owner))
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+void ec_statvfs_combine(struct statvfs * dst, struct statvfs * src)
+{
+ if (dst->f_bsize < src->f_bsize)
+ {
+ dst->f_bsize = src->f_bsize;
+ }
+
+ if (dst->f_frsize < src->f_frsize)
+ {
+ dst->f_blocks *= dst->f_frsize;
+ dst->f_blocks /= src->f_frsize;
+
+ dst->f_bfree *= dst->f_frsize;
+ dst->f_bfree /= src->f_frsize;
+
+ dst->f_bavail *= dst->f_frsize;
+ dst->f_bavail /= src->f_frsize;
+
+ dst->f_frsize = src->f_frsize;
+ }
+ else if (dst->f_frsize > src->f_frsize)
+ {
+ src->f_blocks *= src->f_frsize;
+ src->f_blocks /= dst->f_frsize;
+
+ src->f_bfree *= src->f_frsize;
+ src->f_bfree /= dst->f_frsize;
+
+ src->f_bavail *= src->f_frsize;
+ src->f_bavail /= dst->f_frsize;
+ }
+ if (dst->f_blocks > src->f_blocks)
+ {
+ dst->f_blocks = src->f_blocks;
+ }
+ if (dst->f_bfree > src->f_bfree)
+ {
+ dst->f_bfree = src->f_bfree;
+ }
+ if (dst->f_bavail > src->f_bavail)
+ {
+ dst->f_bavail = src->f_bavail;
+ }
+
+ if (dst->f_files < src->f_files)
+ {
+ dst->f_files = src->f_files;
+ }
+ if (dst->f_ffree > src->f_ffree)
+ {
+ dst->f_ffree = src->f_ffree;
+ }
+ if (dst->f_favail > src->f_favail)
+ {
+ dst->f_favail = src->f_favail;
+ }
+ if (dst->f_namemax > src->f_namemax)
+ {
+ dst->f_namemax = src->f_namemax;
+ }
+
+ if (dst->f_flag != src->f_flag)
+ {
+ gf_log(THIS->name, GF_LOG_DEBUG, "Mismatching file system flags "
+ "(%lX, %lX)",
+ dst->f_flag, src->f_flag);
+ }
+ dst->f_flag &= src->f_flag;
+}
+
+int32_t ec_combine_check(ec_cbk_data_t * dst, ec_cbk_data_t * src,
+ ec_combine_f combine)
+{
+ ec_fop_data_t * fop = dst->fop;
+
+ if (dst->op_ret != src->op_ret)
+ {
+ gf_log(fop->xl->name, GF_LOG_DEBUG, "Mismatching return code in "
+ "answers of '%s': %d <-> %d",
+ ec_fop_name(fop->id), dst->op_ret, src->op_ret);
+
+ return 0;
+ }
+ if (dst->op_ret < 0)
+ {
+ if (dst->op_errno != src->op_errno)
+ {
+ gf_log(fop->xl->name, GF_LOG_DEBUG, "Mismatching errno code in "
+ "answers of '%s': %d <-> %d",
+ ec_fop_name(fop->id), dst->op_errno, src->op_errno);
+
+ return 0;
+ }
+ }
+
+ if (!ec_dict_compare(dst->xdata, src->xdata))
+ {
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Mismatching xdata in answers "
+ "of '%s'",
+ ec_fop_name(fop->id));
+
+ return 0;
+ }
+
+ if ((dst->op_ret >= 0) && (combine != NULL))
+ {
+ return combine(fop, dst, src);
+ }
+
+ return 1;
+}
+
+void ec_combine(ec_cbk_data_t * cbk, ec_combine_f combine)
+{
+ ec_fop_data_t * fop = cbk->fop;
+ ec_cbk_data_t * ans = NULL, * tmp = NULL;
+ struct list_head * item = NULL;
+ int32_t needed = 0, report = 0;
+ char str[32];
+
+ LOCK(&fop->lock);
+
+ item = fop->cbk_list.prev;
+ list_for_each_entry(ans, &fop->cbk_list, list)
+ {
+ if (ec_combine_check(cbk, ans, combine))
+ {
+ cbk->count += ans->count;
+ cbk->mask |= ans->mask;
+
+ item = ans->list.prev;
+ while (item != &fop->cbk_list)
+ {
+ tmp = list_entry(item, ec_cbk_data_t, list);
+ if (tmp->count >= cbk->count)
+ {
+ break;
+ }
+ item = item->prev;
+ }
+ list_del(&ans->list);
+
+ cbk->next = ans;
+
+ break;
+ }
+ }
+ list_add(&cbk->list, item);
+
+ ec_trace("ANSWER", fop, "combine=%s[%d]",
+ ec_bin(str, sizeof(str), cbk->mask, 0), cbk->count);
+
+ if ((cbk->count == fop->expected) && (fop->answer == NULL))
+ {
+ fop->answer = cbk;
+
+ ec_update_bad(fop, cbk->mask);
+
+ report = 1;
+ }
+
+ ans = list_entry(fop->cbk_list.next, ec_cbk_data_t, list);
+ needed = fop->minimum - ans->count - fop->winds + 1;
+
+ UNLOCK(&fop->lock);
+
+ if (needed > 0)
+ {
+ ec_dispatch_next(fop, cbk->idx);
+ }
+ else if (report)
+ {
+ ec_report(fop, 0);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-combine.h b/xlators/cluster/ec/src/ec-combine.h
new file mode 100644
index 00000000000..0cf5a91dc03
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-combine.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_COMBINE_H__
+#define __EC_COMBINE_H__
+
+#define EC_COMBINE_DICT 0
+#define EC_COMBINE_XDATA 1
+
+typedef int32_t (* ec_combine_f)(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src);
+
+void ec_iatt_rebuild(ec_t * ec, struct iatt * iatt, int32_t count,
+ int32_t answers);
+
+int32_t ec_iatt_combine(struct iatt * dst, struct iatt * src, int32_t count);
+int32_t ec_dict_compare(dict_t * dict1, dict_t * dict2);
+int32_t ec_vector_compare(struct iovec * dst_vector, int32_t dst_count,
+ struct iovec * src_vector, int32_t src_count);
+int32_t ec_flock_compare(struct gf_flock * dst, struct gf_flock * src);
+void ec_statvfs_combine(struct statvfs * dst, struct statvfs * src);
+
+int32_t ec_dict_combine(ec_cbk_data_t * cbk, int32_t which);
+
+void ec_combine(ec_cbk_data_t * cbk, ec_combine_f combine);
+
+#endif /* __EC_COMBINE_H__ */
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
new file mode 100644
index 00000000000..a4423d94aa9
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -0,0 +1,1109 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "byte-order.h"
+
+#include "ec-mem-types.h"
+#include "ec-data.h"
+#include "ec-helpers.h"
+#include "ec-combine.h"
+#include "ec-common.h"
+#include "ec-fops.h"
+#include "ec.h"
+
+int32_t ec_child_valid(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ return (idx < ec->nodes) && (((fop->remaining >> idx) & 1) == 1);
+}
+
+int32_t ec_child_next(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ while (!ec_child_valid(ec, fop, idx))
+ {
+ if (++idx >= ec->nodes)
+ {
+ idx = 0;
+ }
+ if (idx == fop->first)
+ {
+ return -1;
+ }
+ }
+
+ return idx;
+}
+
+uintptr_t ec_inode_good(inode_t * inode, xlator_t * xl)
+{
+ ec_inode_t * ctx;
+ uintptr_t bad = 0;
+
+ ctx = ec_inode_get(inode, xl);
+ if (ctx != NULL)
+ {
+ bad = ctx->bad;
+ }
+
+ return ~bad;
+}
+
+uintptr_t ec_fd_good(fd_t * fd, xlator_t * xl)
+{
+ ec_fd_t * ctx;
+ uintptr_t bad = 0;
+
+ ctx = ec_fd_get(fd, xl);
+ if ((ctx != NULL) && (ctx->loc.inode != NULL))
+ {
+ bad = ctx->bad;
+ }
+
+ return ~bad;
+}
+
+uintptr_t ec_update_inode(ec_fop_data_t * fop, inode_t * inode, uintptr_t good,
+ uintptr_t bad)
+{
+ ec_inode_t * ctx = NULL;
+
+ if (inode != NULL)
+ {
+ LOCK(&inode->lock);
+
+ ctx = __ec_inode_get(inode, fop->xl);
+ if (ctx != NULL)
+ {
+ ctx->bad &= ~good;
+ bad |= ctx->bad;
+ ctx->bad = bad;
+ }
+
+ UNLOCK(&inode->lock);
+ }
+
+ return bad;
+}
+
+uintptr_t ec_update_fd(ec_fop_data_t * fop, fd_t * fd, uintptr_t good,
+ uintptr_t bad)
+{
+ ec_fd_t * ctx = NULL;
+
+ LOCK(&fd->lock);
+
+ ctx = __ec_fd_get(fd, fop->xl);
+ if ((ctx != NULL) && (ctx->loc.inode != NULL))
+ {
+ ctx->bad &= ~good;
+ bad |= ctx->bad;
+ ctx->bad = bad;
+ }
+
+ UNLOCK(&fd->lock);
+
+ return bad;
+}
+
+int32_t ec_heal_report(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, uintptr_t mask,
+ uintptr_t good, uintptr_t bad, dict_t * xdata)
+{
+ if (op_ret < 0)
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Heal failed (error %d)", op_errno);
+ }
+ else
+ {
+ gf_log(this->name, GF_LOG_INFO, "Heal succeeded on %d/%d subvolumes",
+ ec_bits_count(mask & ~ (good | bad)),
+ ec_bits_count(mask & ~good));
+ }
+
+ return 0;
+}
+
+void ec_check_status(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+
+ if ((ec->xl_up & ~(fop->remaining | fop->good)) == 0)
+ {
+ return;
+ }
+
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Operation failed on some "
+ "subvolumes (up=%lX, mask=%lX, "
+ "remaining=%lX, good=%lX, bad=%lX)",
+ ec->xl_up, fop->mask, fop->remaining, fop->good, fop->bad);
+
+ if (fop->fd != NULL)
+ {
+ ec_fheal(fop->frame, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL,
+ fop->fd, NULL);
+ }
+ else
+ {
+ ec_heal(fop->frame, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report, NULL,
+ &fop->loc[0], NULL);
+
+ if (fop->loc[1].inode != NULL)
+ {
+ ec_heal(fop->frame, fop->xl, -1, EC_MINIMUM_ONE, ec_heal_report,
+ NULL, &fop->loc[1], NULL);
+ }
+ }
+}
+
+void ec_update_bad(ec_fop_data_t * fop, uintptr_t good)
+{
+ uintptr_t bad;
+ int32_t update = 0;
+
+ bad = fop->mask & ~(fop->remaining | good);
+ if ((fop->bad & bad) != bad)
+ {
+ fop->bad |= bad;
+ update = 1;
+ }
+ if ((fop->good & good) != good)
+ {
+ fop->good |= good;
+ update = 1;
+ }
+
+ if (update && (fop->parent == NULL))
+ {
+ if ((fop->flags & EC_FLAG_UPDATE_LOC_PARENT) != 0)
+ {
+ ec_update_inode(fop, fop->loc[0].parent, good, bad);
+ }
+ if ((fop->flags & EC_FLAG_UPDATE_LOC_INODE) != 0)
+ {
+ ec_update_inode(fop, fop->loc[0].inode, good, bad);
+ }
+ ec_update_inode(fop, fop->loc[1].inode, good, bad);
+ if ((fop->flags & EC_FLAG_UPDATE_FD_INODE) != 0)
+ {
+ ec_update_inode(fop, fop->fd->inode, good, bad);
+ }
+ if ((fop->flags & EC_FLAG_UPDATE_FD) != 0)
+ {
+ ec_update_fd(fop, fop->fd, good, bad);
+ }
+
+ ec_check_status(fop);
+ }
+}
+
+
+void __ec_fop_set_error(ec_fop_data_t * fop, int32_t error)
+{
+ if ((error != 0) && (fop->error == 0))
+ {
+ fop->error = error;
+ }
+}
+
+void ec_fop_set_error(ec_fop_data_t * fop, int32_t error)
+{
+ LOCK(&fop->lock);
+
+ __ec_fop_set_error(fop, error);
+
+ UNLOCK(&fop->lock);
+}
+
+int32_t ec_check_complete(ec_fop_data_t * fop, ec_resume_f resume)
+{
+ int32_t error = -1;
+
+ LOCK(&fop->lock);
+
+ GF_ASSERT(fop->resume == NULL);
+
+ if (fop->jobs != 0)
+ {
+ ec_trace("WAIT", fop, "resume=%p", resume);
+
+ fop->resume = resume;
+ }
+ else
+ {
+ error = fop->error;
+ fop->error = 0;
+ }
+
+ UNLOCK(&fop->lock);
+
+ return error;
+}
+
+void ec_wait_winds(ec_fop_data_t * fop)
+{
+ LOCK(&fop->lock);
+
+ if (fop->winds > 0)
+ {
+ fop->jobs++;
+ fop->refs++;
+
+ fop->flags |= EC_FLAG_WAITING_WINDS;
+ }
+
+ UNLOCK(&fop->lock);
+}
+
+void ec_resume(ec_fop_data_t * fop, int32_t error)
+{
+ ec_resume_f resume = NULL;
+
+ LOCK(&fop->lock);
+
+ __ec_fop_set_error(fop, error);
+
+ if (--fop->jobs == 0)
+ {
+ resume = fop->resume;
+ fop->resume = NULL;
+ if (resume != NULL)
+ {
+ ec_trace("RESUME", fop, "error=%d", error);
+
+ if (fop->error != 0)
+ {
+ error = fop->error;
+ }
+ fop->error = 0;
+ }
+ }
+
+ UNLOCK(&fop->lock);
+
+ if (resume != NULL)
+ {
+ resume(fop, error);
+ }
+
+ ec_fop_data_release(fop);
+}
+
+void ec_resume_parent(ec_fop_data_t * fop, int32_t error)
+{
+ ec_fop_data_t * parent;
+
+ parent = fop->parent;
+ if (parent != NULL)
+ {
+ fop->parent = NULL;
+ ec_resume(parent, error);
+ }
+}
+
+void ec_report(ec_fop_data_t * fop, int32_t error)
+{
+ if (!list_empty(&fop->lock_list))
+ {
+ ec_owner_set(fop->frame, fop->frame->root);
+ }
+
+ ec_resume(fop, error);
+}
+
+void ec_complete(ec_fop_data_t * fop)
+{
+ ec_cbk_data_t * cbk = NULL;
+ int32_t ready = 0, report = 0;
+
+ LOCK(&fop->lock);
+
+ ec_trace("COMPLETE", fop, "");
+
+ if (--fop->winds == 0)
+ {
+ if ((fop->answer == NULL) && (fop->expected != 1))
+ {
+ if (!list_empty(&fop->cbk_list))
+ {
+ cbk = list_entry(fop->cbk_list.next, ec_cbk_data_t, list);
+ if ((cbk->count >= fop->minimum) &&
+ ((cbk->op_ret >= 0) || (cbk->op_errno != ENOTCONN)))
+ {
+ fop->answer = cbk;
+
+ ec_update_bad(fop, cbk->mask);
+ }
+ }
+
+ report = 1;
+ }
+ else if ((fop->flags & EC_FLAG_WAITING_WINDS) != 0)
+ {
+ ready = 1;
+ }
+ }
+
+ UNLOCK(&fop->lock);
+
+ if (report)
+ {
+ ec_report(fop, 0);
+ }
+ if (ready)
+ {
+ ec_resume(fop, 0);
+ }
+
+ ec_fop_data_release(fop);
+}
+
+int32_t ec_child_select(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+ uintptr_t mask = 0;
+ int32_t first = 0, num = 0;
+
+ fop->mask &= ec->node_mask;
+
+ mask = ec->xl_up;
+ if (fop->loc[0].inode != NULL)
+ {
+ mask |= ec_inode_good(fop->loc[0].inode, fop->xl);
+ }
+ if (fop->loc[1].inode != NULL)
+ {
+ mask |= ec_inode_good(fop->loc[1].inode, fop->xl);
+ }
+ if (fop->fd != NULL)
+ {
+ if (fop->fd->inode != NULL)
+ {
+ mask |= ec_inode_good(fop->fd->inode, fop->xl);
+ }
+ mask |= ec_fd_good(fop->fd, fop->xl);
+ }
+ if ((fop->mask & ~mask) != 0)
+ {
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Executing operation with "
+ "some subvolumes unavailable "
+ "(%lX)", fop->mask & ~mask);
+
+ fop->mask &= mask;
+ }
+
+ switch (fop->minimum)
+ {
+ case EC_MINIMUM_ALL:
+ fop->minimum = ec_bits_count(fop->mask);
+ if (fop->minimum >= ec->fragments)
+ {
+ break;
+ }
+ case EC_MINIMUM_MIN:
+ fop->minimum = ec->fragments;
+ break;
+ case EC_MINIMUM_ONE:
+ fop->minimum = 1;
+ }
+
+ first = ec->idx;
+ if (++first >= ec->nodes)
+ {
+ first = 0;
+ }
+ ec->idx = first;
+
+ fop->remaining = fop->mask;
+
+ ec_trace("SELECT", fop, "");
+
+ num = ec_bits_count(fop->mask);
+ if ((num < fop->minimum) && (num < ec->fragments))
+ {
+ gf_log(ec->xl->name, GF_LOG_ERROR, "Insufficient available childs "
+ "for this request (have %d, need "
+ "%d)", num, fop->minimum);
+
+ return 0;
+ }
+
+ LOCK(&fop->lock);
+
+ fop->jobs++;
+ fop->refs++;
+
+ UNLOCK(&fop->lock);
+
+ return 1;
+}
+
+int32_t ec_dispatch_next(ec_fop_data_t * fop, int32_t idx)
+{
+ ec_t * ec = fop->xl->private;
+
+ LOCK(&fop->lock);
+
+ idx = ec_child_next(ec, fop, idx);
+ if (idx >= 0)
+ {
+ fop->remaining ^= 1ULL << idx;
+
+ ec_trace("EXECUTE", fop, "idx=%d", idx);
+
+ fop->winds++;
+ fop->refs++;
+ }
+
+ UNLOCK(&fop->lock);
+
+ if (idx >= 0)
+ {
+ fop->wind(ec, fop, idx);
+ }
+
+ return idx;
+}
+
+void ec_dispatch_mask(ec_fop_data_t * fop, uintptr_t mask)
+{
+ ec_t * ec = fop->xl->private;
+ int32_t count, idx;
+
+ count = ec_bits_count(mask);
+
+ LOCK(&fop->lock);
+
+ ec_trace("EXECUTE", fop, "mask=%lX", mask);
+
+ fop->remaining ^= mask;
+
+ fop->winds += count;
+ fop->refs += count;
+
+ UNLOCK(&fop->lock);
+
+ idx = 0;
+ while (mask != 0)
+ {
+ if ((mask & 1) != 0)
+ {
+ fop->wind(ec, fop, idx);
+ }
+ idx++;
+ mask >>= 1;
+ }
+}
+
+void ec_dispatch_start(ec_fop_data_t * fop)
+{
+ fop->answer = NULL;
+ fop->good = 0;
+ fop->bad = 0;
+
+ INIT_LIST_HEAD(&fop->cbk_list);
+
+ if (!list_empty(&fop->lock_list))
+ {
+ ec_owner_copy(fop->frame, &fop->req_frame->root->lk_owner);
+ }
+}
+
+void ec_dispatch_one(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+
+ ec_dispatch_start(fop);
+
+ if (ec_child_select(fop))
+ {
+ fop->expected = 1;
+ fop->first = ec->idx;
+
+ ec_dispatch_next(fop, fop->first);
+ }
+}
+
+int32_t ec_dispatch_one_retry(ec_fop_data_t * fop, int32_t idx, int32_t op_ret,
+ int32_t op_errno)
+{
+ if ((op_ret < 0) && (op_errno == ENOTCONN))
+ {
+ return (ec_dispatch_next(fop, idx) >= 0);
+ }
+
+ return 0;
+}
+
+void ec_dispatch_inc(ec_fop_data_t * fop)
+{
+ ec_dispatch_start(fop);
+
+ if (ec_child_select(fop))
+ {
+ fop->expected = ec_bits_count(fop->remaining);
+ fop->first = 0;
+
+ ec_dispatch_next(fop, 0);
+ }
+}
+
+void ec_dispatch_all(ec_fop_data_t * fop)
+{
+ ec_dispatch_start(fop);
+
+ if (ec_child_select(fop))
+ {
+ fop->expected = ec_bits_count(fop->remaining);
+ fop->first = 0;
+
+ ec_dispatch_mask(fop, fop->remaining);
+ }
+}
+
+void ec_dispatch_min(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+ uintptr_t mask;
+ int32_t idx, count;
+
+ ec_dispatch_start(fop);
+
+ if (ec_child_select(fop))
+ {
+ fop->expected = count = ec->fragments;
+ fop->first = ec->idx;
+ idx = fop->first - 1;
+ mask = 0;
+ while (count-- > 0)
+ {
+ idx = ec_child_next(ec, fop, idx + 1);
+ mask |= 1ULL << idx;
+ }
+
+ ec_dispatch_mask(fop, mask);
+ }
+}
+
+ec_lock_t * ec_lock_allocate(xlator_t * xl, int32_t kind, loc_t * loc)
+{
+ ec_lock_t * lock;
+
+ if ((loc->inode == NULL) ||
+ (uuid_is_null(loc->gfid) && uuid_is_null(loc->inode->gfid)))
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Trying to lock based on an invalid "
+ "inode");
+
+ return NULL;
+ }
+
+ lock = GF_MALLOC(sizeof(*lock), ec_mt_ec_lock_t);
+ if (lock != NULL)
+ {
+ memset(lock, 0, sizeof(*lock));
+
+ lock->kind = kind;
+ if (!ec_loc_from_loc(xl, &lock->loc, loc))
+ {
+ GF_FREE(lock);
+ lock = NULL;
+ }
+ }
+
+ return lock;
+}
+
+void ec_lock_destroy(ec_lock_t * lock)
+{
+ GF_FREE(lock->basename);
+ loc_wipe(&lock->loc);
+
+ GF_FREE(lock);
+}
+
+int32_t ec_locked(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+ ec_lock_t * lock = NULL;
+
+ if (op_ret >= 0)
+ {
+ lock = fop->data;
+ lock->mask = fop->good;
+ fop->parent->mask &= fop->good;
+
+ ec_trace("LOCKED", fop->parent, "lock=%p", lock);
+ }
+ else
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to complete preop lock");
+ }
+
+ return 0;
+}
+
+void ec_lock_entry(ec_fop_data_t * fop, loc_t * loc)
+{
+ ec_lock_t * lock = NULL;
+ char * name = NULL;
+ loc_t tmp;
+ int32_t error;
+
+ if ((fop->parent != NULL) || (fop->error != 0))
+ {
+ return;
+ }
+
+ error = ec_loc_parent(fop->xl, loc, &tmp, &name);
+ if (error != 0)
+ {
+ ec_fop_set_error(fop, error);
+
+ return;
+ }
+
+ LOCK(&fop->lock);
+
+ list_for_each_entry(lock, &fop->lock_list, list)
+ {
+ if ((lock->kind == EC_LOCK_ENTRY) &&
+ (lock->loc.inode == tmp.inode) &&
+ (strcmp(lock->basename, name) == 0))
+ {
+ ec_trace("LOCK_ENTRYLK", fop, "lock=%p, parent=%p, path=%s, "
+ "name=%s. Lock already acquired",
+ lock, loc->parent, loc->path, name);
+
+ lock = NULL;
+
+ goto unlock;
+ }
+ }
+
+ lock = ec_lock_allocate(fop->xl, EC_LOCK_ENTRY, &tmp);
+ if (lock != NULL)
+ {
+ lock->type = ENTRYLK_WRLCK;
+ lock->basename = name;
+
+ if (list_empty(&fop->lock_list))
+ {
+ ec_owner_set(fop->frame, fop->frame->root);
+ }
+ list_add_tail(&lock->list, &fop->lock_list);
+ }
+ else
+ {
+ __ec_fop_set_error(fop, EIO);
+ }
+
+unlock:
+ UNLOCK(&fop->lock);
+
+ loc_wipe(&tmp);
+
+ if (lock != NULL)
+ {
+ ec_trace("LOCK_ENTRYLK", fop, "lock=%p, parent=%p, path=%s, "
+ "basename=%s", lock, lock->loc.inode,
+ lock->loc.path, lock->basename);
+
+ ec_entrylk(fop->frame, fop->xl, -1, EC_MINIMUM_ALL, ec_locked, lock,
+ fop->xl->name, &lock->loc, lock->basename, ENTRYLK_LOCK,
+ lock->type, NULL);
+ }
+ else
+ {
+ GF_FREE(name);
+ }
+}
+
+void ec_lock_inode(ec_fop_data_t * fop, loc_t * loc)
+{
+ ec_lock_t * lock;
+
+ if ((fop->parent != NULL) || (fop->error != 0) || (loc->inode == NULL))
+ {
+ return;
+ }
+
+ LOCK(&fop->lock);
+
+ list_for_each_entry(lock, &fop->lock_list, list)
+ {
+ if ((lock->kind == EC_LOCK_INODE) && (lock->loc.inode == loc->inode))
+ {
+ UNLOCK(&fop->lock);
+
+ ec_trace("LOCK_INODELK", fop, "lock=%p, inode=%p. Lock already "
+ "acquired", lock, loc->inode);
+
+ return;
+ }
+ }
+
+ lock = ec_lock_allocate(fop->xl, EC_LOCK_INODE, loc);
+ if (lock != NULL)
+ {
+ lock->flock.l_type = F_WRLCK;
+ lock->flock.l_whence = SEEK_SET;
+
+ if (list_empty(&fop->lock_list))
+ {
+ ec_owner_set(fop->frame, fop->frame->root);
+ }
+ list_add_tail(&lock->list, &fop->lock_list);
+ }
+ else
+ {
+ __ec_fop_set_error(fop, EIO);
+ }
+
+ UNLOCK(&fop->lock);
+
+ if (lock != NULL)
+ {
+ ec_trace("LOCK_INODELK", fop, "lock=%p, inode=%p, owner=%p", lock,
+ lock->loc.inode, fop->frame->root);
+
+ ec_inodelk(fop->frame, fop->xl, -1, EC_MINIMUM_ALL, ec_locked, lock,
+ fop->xl->name, &lock->loc, F_SETLKW, &lock->flock, NULL);
+ }
+}
+
+void ec_lock_fd(ec_fop_data_t * fop, fd_t * fd)
+{
+ loc_t loc;
+
+ if ((fop->parent != NULL) || (fop->error != 0))
+ {
+ return;
+ }
+
+ if (ec_loc_from_fd(fop->xl, &loc, fd))
+ {
+ ec_lock_inode(fop, &loc);
+
+ loc_wipe(&loc);
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+}
+
+int32_t ec_unlocked(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+
+ if (op_ret < 0)
+ {
+ gf_log(this->name, GF_LOG_WARNING, "entry/inode unlocking failed (%s)",
+ ec_fop_name(fop->parent->id));
+ }
+ else
+ {
+ ec_trace("UNLOCKED", fop->parent, "lock=%p", fop->data);
+ }
+
+ return 0;
+}
+
+void ec_unlock(ec_fop_data_t * fop)
+{
+ ec_lock_t * lock, * item;
+
+ ec_trace("UNLOCK", fop, "");
+
+ list_for_each_entry_safe(lock, item, &fop->lock_list, list)
+ {
+ list_del(&lock->list);
+
+ if (lock->mask != 0)
+ {
+ switch (lock->kind)
+ {
+ case EC_LOCK_ENTRY:
+ ec_trace("UNLOCK_ENTRYLK", fop, "lock=%p, parent=%p, "
+ "path=%s, basename=%s",
+ lock, lock->loc.inode, lock->loc.path,
+ lock->basename);
+
+ ec_entrylk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ALL,
+ ec_unlocked, lock, fop->xl->name, &lock->loc,
+ lock->basename, ENTRYLK_UNLOCK, lock->type,
+ NULL);
+
+ break;
+
+ case EC_LOCK_INODE:
+ lock->flock.l_type = F_UNLCK;
+ ec_trace("UNLOCK_INODELK", fop, "lock=%p, inode=%p", lock,
+ lock->loc.inode);
+
+ ec_inodelk(fop->frame, fop->xl, lock->mask, EC_MINIMUM_ALL,
+ ec_unlocked, lock, fop->xl->name, &lock->loc,
+ F_SETLK, &lock->flock, NULL);
+
+ break;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Invalid lock type");
+ }
+ }
+
+ loc_wipe(&lock->loc);
+
+ GF_FREE(lock);
+ }
+}
+
+int32_t ec_get_size_version_set(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, inode_t * inode,
+ struct iatt * buf, dict_t * xdata,
+ struct iatt * postparent)
+{
+ ec_fop_data_t * fop = cookie;
+
+ if (op_ret >= 0)
+ {
+ fop->parent->mask &= fop->good;
+ fop->parent->pre_size = fop->parent->post_size = buf->ia_size;
+ }
+ else
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to get size and version "
+ "(error %d)", op_errno);
+ ec_fop_set_error(fop, op_errno);
+ }
+
+ return 0;
+}
+
+void ec_get_size_version(ec_fop_data_t * fop)
+{
+ loc_t loc;
+ dict_t * xdata;
+ uid_t uid;
+ gid_t gid;
+ int32_t error = ENOMEM;
+
+ if (fop->parent != NULL)
+ {
+ fop->pre_size = fop->parent->pre_size;
+ fop->post_size = fop->parent->post_size;
+
+ return;
+ }
+
+ memset(&loc, 0, sizeof(loc));
+
+ xdata = dict_new();
+ if (xdata == NULL)
+ {
+ goto out;
+ }
+ if ((dict_set_uint64(xdata, EC_XATTR_VERSION, 0) != 0) ||
+ (dict_set_uint64(xdata, EC_XATTR_SIZE, 0) != 0))
+ {
+ goto out;
+ }
+
+ uid = fop->frame->root->uid;
+ gid = fop->frame->root->gid;
+
+ fop->frame->root->uid = 0;
+ fop->frame->root->gid = 0;
+
+ error = EIO;
+
+ if (fop->fd == NULL)
+ {
+ if (!ec_loc_from_loc(fop->xl, &loc, &fop->loc[0]))
+ {
+ goto out;
+ }
+ if (uuid_is_null(loc.pargfid))
+ {
+ if (loc.parent != NULL)
+ {
+ inode_unref(loc.parent);
+ loc.parent = NULL;
+ }
+ GF_FREE((char *)loc.path);
+ loc.path = NULL;
+ loc.name = NULL;
+ }
+ }
+ else if (!ec_loc_from_fd(fop->xl, &loc, fop->fd))
+ {
+ goto out;
+ }
+
+ ec_lookup(fop->frame, fop->xl, fop->mask, EC_MINIMUM_MIN,
+ ec_get_size_version_set, NULL, &loc, xdata);
+
+ fop->frame->root->uid = uid;
+ fop->frame->root->gid = gid;
+
+ error = 0;
+
+out:
+ loc_wipe(&loc);
+
+ if (xdata != NULL)
+ {
+ dict_unref(xdata);
+ }
+
+ ec_fop_set_error(fop, error);
+}
+
+int32_t ec_update_size_version_done(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+
+ if (op_ret < 0)
+ {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Failed to update version and "
+ "size (error %d)", op_errno);
+ }
+ else
+ {
+ fop->parent->mask &= fop->good;
+ }
+
+ return 0;
+}
+
+void ec_update_size_version(ec_fop_data_t * fop)
+{
+ dict_t * dict;
+ size_t size;
+ uid_t uid;
+ gid_t gid;
+
+ if (fop->parent != NULL)
+ {
+ fop->parent->post_size = fop->post_size;
+
+ return;
+ }
+
+ dict = dict_new();
+ if (dict == NULL)
+ {
+ goto out;
+ }
+
+ if (ec_dict_set_number(dict, EC_XATTR_VERSION, 1) != 0)
+ {
+ goto out;
+ }
+ size = fop->post_size;
+ if (fop->pre_size != size)
+ {
+ size -= fop->pre_size;
+ if (ec_dict_set_number(dict, EC_XATTR_SIZE, size) != 0)
+ {
+ goto out;
+ }
+ }
+
+ uid = fop->frame->root->uid;
+ gid = fop->frame->root->gid;
+
+ fop->frame->root->uid = 0;
+ fop->frame->root->gid = 0;
+
+ if (fop->fd == NULL)
+ {
+ ec_xattrop(fop->frame, fop->xl, fop->mask, EC_MINIMUM_MIN,
+ ec_update_size_version_done, NULL, &fop->loc[0],
+ GF_XATTROP_ADD_ARRAY64, dict, NULL);
+ }
+ else
+ {
+ ec_fxattrop(fop->frame, fop->xl, fop->mask, EC_MINIMUM_MIN,
+ ec_update_size_version_done, NULL, fop->fd,
+ GF_XATTROP_ADD_ARRAY64, dict, NULL);
+ }
+
+ fop->frame->root->uid = uid;
+ fop->frame->root->gid = gid;
+
+ dict_unref(dict);
+
+ return;
+
+out:
+ if (dict != NULL)
+ {
+ dict_unref(dict);
+ }
+
+ ec_fop_set_error(fop, EIO);
+
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to update version and size");
+}
+
+void __ec_manager(ec_fop_data_t * fop, int32_t error)
+{
+ do
+ {
+ ec_trace("MANAGER", fop, "error=%d", error);
+
+ if (fop->state == EC_STATE_END)
+ {
+ ec_fop_data_release(fop);
+
+ break;
+ }
+
+ if (error != 0)
+ {
+ fop->error = error;
+ fop->state = -fop->state;
+ }
+
+ fop->state = fop->handler(fop, fop->state);
+
+ error = ec_check_complete(fop, __ec_manager);
+ } while (error >= 0);
+}
+
+void ec_manager(ec_fop_data_t * fop, int32_t error)
+{
+ GF_ASSERT(fop->jobs == 0);
+ GF_ASSERT(fop->winds == 0);
+ GF_ASSERT(fop->error == 0);
+
+ if (fop->state == EC_STATE_START)
+ {
+ fop->state = EC_STATE_INIT;
+ }
+
+ __ec_manager(fop, error);
+}
diff --git a/xlators/cluster/ec/src/ec-common.h b/xlators/cluster/ec/src/ec-common.h
new file mode 100644
index 00000000000..83f3ba9637e
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-common.h
@@ -0,0 +1,105 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_COMMON_H__
+#define __EC_COMMON_H__
+
+#include "xlator.h"
+
+#include "ec-data.h"
+
+#define EC_FLAG_UPDATE_LOC_PARENT 0x0001
+#define EC_FLAG_UPDATE_LOC_INODE 0x0002
+#define EC_FLAG_UPDATE_FD 0x0004
+#define EC_FLAG_UPDATE_FD_INODE 0x0008
+
+#define EC_FLAG_WAITING_WINDS 0x0010
+
+#define EC_MINIMUM_ONE -1
+#define EC_MINIMUM_MIN -2
+#define EC_MINIMUM_ALL -3
+
+#define EC_LOCK_ENTRY 0
+#define EC_LOCK_INODE 1
+
+#define EC_STATE_START 0
+#define EC_STATE_END 0
+#define EC_STATE_INIT 1
+#define EC_STATE_LOCK 2
+#define EC_STATE_GET_SIZE_AND_VERSION 3
+#define EC_STATE_DISPATCH 4
+#define EC_STATE_PREPARE_ANSWER 5
+#define EC_STATE_REPORT 6
+#define EC_STATE_UPDATE_SIZE_AND_VERSION 7
+#define EC_STATE_UNLOCK 8
+
+#define EC_STATE_WRITE_START 100
+
+#define EC_STATE_HEAL_ENTRY_LOOKUP 200
+#define EC_STATE_HEAL_ENTRY_PREPARE 201
+#define EC_STATE_HEAL_PRE_INODELK_LOCK 202
+#define EC_STATE_HEAL_PRE_INODE_LOOKUP 203
+#define EC_STATE_HEAL_XATTRIBUTES_REMOVE 204
+#define EC_STATE_HEAL_XATTRIBUTES_SET 205
+#define EC_STATE_HEAL_ATTRIBUTES 206
+#define EC_STATE_HEAL_OPEN 207
+#define EC_STATE_HEAL_REOPEN_FD 208
+#define EC_STATE_HEAL_UNLOCK 209
+#define EC_STATE_HEAL_DATA_LOCK 210
+#define EC_STATE_HEAL_DATA_COPY 211
+#define EC_STATE_HEAL_DATA_UNLOCK 212
+#define EC_STATE_HEAL_POST_INODELK_LOCK 213
+#define EC_STATE_HEAL_POST_INODE_LOOKUP 214
+#define EC_STATE_HEAL_SETATTR 215
+#define EC_STATE_HEAL_POST_INODELK_UNLOCK 216
+#define EC_STATE_HEAL_DISPATCH 217
+
+int32_t ec_dispatch_one_retry(ec_fop_data_t * fop, int32_t idx, int32_t op_ret,
+ int32_t op_errno);
+int32_t ec_dispatch_next(ec_fop_data_t * fop, int32_t idx);
+
+void ec_complete(ec_fop_data_t * fop);
+
+void ec_update_bad(ec_fop_data_t * fop, uintptr_t good);
+
+void ec_fop_set_error(ec_fop_data_t * fop, int32_t error);
+
+void ec_lock_inode(ec_fop_data_t * fop, loc_t * loc);
+void ec_lock_entry(ec_fop_data_t * fop, loc_t * loc);
+void ec_lock_fd(ec_fop_data_t * fop, fd_t * fd);
+
+void ec_unlock(ec_fop_data_t * fop);
+
+void ec_get_size_version(ec_fop_data_t * fop);
+void ec_update_size_version(ec_fop_data_t * fop);
+
+void ec_dispatch_all(ec_fop_data_t * fop);
+void ec_dispatch_inc(ec_fop_data_t * fop);
+void ec_dispatch_min(ec_fop_data_t * fop);
+void ec_dispatch_one(ec_fop_data_t * fop);
+
+void ec_wait_winds(ec_fop_data_t * fop);
+
+void ec_resume_parent(ec_fop_data_t * fop, int32_t error);
+void ec_report(ec_fop_data_t * fop, int32_t error);
+
+void ec_manager(ec_fop_data_t * fop, int32_t error);
+
+#endif /* __EC_COMMON_H__ */
diff --git a/xlators/cluster/ec/src/ec-data.c b/xlators/cluster/ec/src/ec-data.c
new file mode 100644
index 00000000000..0e72fbbd3b6
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-data.c
@@ -0,0 +1,261 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "ec-mem-types.h"
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-data.h"
+
+ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t * frame, xlator_t * this,
+ ec_fop_data_t * fop, int32_t id,
+ int32_t idx, int32_t op_ret,
+ int32_t op_errno)
+{
+ ec_cbk_data_t * cbk;
+ ec_t * ec = this->private;
+
+ if (fop->xl != this)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Mismatching xlators between request "
+ "and answer (req=%s, ans=%s).",
+ fop->xl->name, this->name);
+
+ return NULL;
+ }
+ if (fop->frame != frame)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Mismatching frames between request "
+ "and answer (req=%p, ans=%p).",
+ fop->frame, frame);
+
+ return NULL;
+ }
+ if (fop->id != id)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Mismatching fops between request "
+ "and answer (req=%d, ans=%d).",
+ fop->id, id);
+
+ return NULL;
+ }
+
+ cbk = mem_get0(ec->cbk_pool);
+ if (cbk == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to allocate memory for an "
+ "answer.");
+ }
+
+ cbk->fop = fop;
+ cbk->idx = idx;
+ cbk->mask = 1ULL << idx;
+ cbk->count = 1;
+ cbk->op_ret = op_ret;
+ cbk->op_errno = op_errno;
+
+ LOCK(&fop->lock);
+
+ list_add_tail(&cbk->answer_list, &fop->answer_list);
+
+ UNLOCK(&fop->lock);
+
+ return cbk;
+}
+
+void ec_cbk_data_destroy(ec_cbk_data_t * cbk)
+{
+ if (cbk->xdata != NULL)
+ {
+ dict_unref(cbk->xdata);
+ }
+ if (cbk->dict != NULL)
+ {
+ dict_unref(cbk->dict);
+ }
+ if (cbk->inode != NULL)
+ {
+ inode_unref(cbk->inode);
+ }
+ if (cbk->fd != NULL)
+ {
+ fd_unref(cbk->fd);
+ }
+ if (cbk->buffers != NULL)
+ {
+ iobref_unref(cbk->buffers);
+ }
+ GF_FREE(cbk->vector);
+
+ mem_put(cbk);
+}
+
+ec_fop_data_t * ec_fop_data_allocate(call_frame_t * frame, xlator_t * this,
+ int32_t id, uint32_t flags,
+ uintptr_t target, int32_t minimum,
+ ec_wind_f wind, ec_handler_f handler,
+ ec_cbk_t cbks, void * data)
+{
+ ec_fop_data_t * fop, * parent;
+ ec_t * ec = this->private;
+
+ fop = mem_get0(ec->fop_pool);
+ if (fop == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to allocate memory for a "
+ "request.");
+
+ return NULL;
+ }
+
+ fop->xl = this;
+ fop->req_frame = frame;
+
+ /* fops need a private frame to be able to execute some postop operations
+ * even if the original fop has completed and reported back to the upper
+ * xlator and it has destroyed the base frame.
+ *
+ * TODO: minimize usage of private frames. Reuse req_frame as much as
+ * possible.
+ */
+ if (frame != NULL)
+ {
+ fop->frame = copy_frame(frame);
+ }
+ else
+ {
+ fop->frame = create_frame(this, this->ctx->pool);
+ }
+ if (fop->frame == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to create a private frame "
+ "for a request");
+
+ mem_put(fop);
+
+ return NULL;
+ }
+ fop->id = id;
+ fop->refs = 1;
+
+ fop->flags = flags;
+ fop->minimum = minimum;
+ fop->mask = target;
+
+ INIT_LIST_HEAD(&fop->lock_list);
+ INIT_LIST_HEAD(&fop->cbk_list);
+ INIT_LIST_HEAD(&fop->answer_list);
+
+ fop->wind = wind;
+ fop->handler = handler;
+ fop->cbks = cbks;
+ fop->data = data;
+
+ LOCK_INIT(&fop->lock);
+
+ fop->frame->local = fop;
+
+ if (frame != NULL)
+ {
+ parent = frame->local;
+ if (parent != NULL)
+ {
+ LOCK(&parent->lock);
+
+ parent->jobs++;
+ parent->refs++;
+
+ UNLOCK(&parent->lock);
+ }
+
+ fop->parent = parent;
+ }
+
+ return fop;
+}
+
+void ec_fop_data_acquire(ec_fop_data_t * fop)
+{
+ LOCK(&fop->lock);
+
+ ec_trace("ACQUIRE", fop, "");
+
+ fop->refs++;
+
+ UNLOCK(&fop->lock);
+}
+
+void ec_fop_data_release(ec_fop_data_t * fop)
+{
+ ec_cbk_data_t * cbk, * tmp;
+ int32_t refs;
+
+ LOCK(&fop->lock);
+
+ ec_trace("RELEASE", fop, "");
+
+ refs = --fop->refs;
+
+ UNLOCK(&fop->lock);
+
+ if (refs == 0)
+ {
+ fop->frame->local = NULL;
+ STACK_DESTROY(fop->frame->root);
+
+ LOCK_DESTROY(&fop->lock);
+
+ if (fop->xdata != NULL)
+ {
+ dict_unref(fop->xdata);
+ }
+ if (fop->dict != NULL)
+ {
+ dict_unref(fop->dict);
+ }
+ if (fop->inode != NULL)
+ {
+ inode_unref(fop->inode);
+ }
+ if (fop->fd != NULL)
+ {
+ fd_unref(fop->fd);
+ }
+ if (fop->buffers != NULL)
+ {
+ iobref_unref(fop->buffers);
+ }
+ GF_FREE(fop->vector);
+ GF_FREE(fop->str[0]);
+ GF_FREE(fop->str[1]);
+ loc_wipe(&fop->loc[0]);
+ loc_wipe(&fop->loc[1]);
+
+ ec_resume_parent(fop, fop->error);
+
+ list_for_each_entry_safe(cbk, tmp, &fop->answer_list, answer_list)
+ {
+ list_del_init(&cbk->answer_list);
+
+ ec_cbk_data_destroy(cbk);
+ }
+
+ mem_put(fop);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h
new file mode 100644
index 00000000000..e83b6ad74eb
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-data.h
@@ -0,0 +1,260 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_DATA_H__
+#define __EC_DATA_H__
+
+#include "xlator.h"
+
+#include "ec.h"
+
+struct _ec_fd;
+typedef struct _ec_fd ec_fd_t;
+
+struct _ec_inode;
+typedef struct _ec_inode ec_inode_t;
+
+union _ec_cbk;
+typedef union _ec_cbk ec_cbk_t;
+
+struct _ec_lock;
+typedef struct _ec_lock ec_lock_t;
+
+struct _ec_fop_data;
+typedef struct _ec_fop_data ec_fop_data_t;
+
+struct _ec_cbk_data;
+typedef struct _ec_cbk_data ec_cbk_data_t;
+
+struct _ec_heal;
+typedef struct _ec_heal ec_heal_t;
+
+typedef void (* ec_wind_f)(ec_t *, ec_fop_data_t *, int32_t);
+typedef int32_t (* ec_handler_f)(ec_fop_data_t *, int32_t);
+typedef void (* ec_resume_f)(ec_fop_data_t *, int32_t);
+
+struct _ec_fd
+{
+ uintptr_t bad;
+ loc_t loc;
+ uintptr_t open;
+ int32_t flags;
+};
+
+struct _ec_inode
+{
+ uintptr_t bad;
+ ec_heal_t * heal;
+};
+
+typedef int32_t (* fop_heal_cbk_t)(call_frame_t *, void * cookie, xlator_t *,
+ int32_t, int32_t, uintptr_t, uintptr_t,
+ uintptr_t, dict_t *);
+typedef int32_t (* fop_fheal_cbk_t)(call_frame_t *, void * cookie, xlator_t *,
+ int32_t, int32_t, uintptr_t, uintptr_t,
+ uintptr_t, dict_t *);
+
+
+union _ec_cbk
+{
+ fop_access_cbk_t access;
+ fop_create_cbk_t create;
+ fop_discard_cbk_t discard;
+ fop_entrylk_cbk_t entrylk;
+ fop_fentrylk_cbk_t fentrylk;
+ fop_fallocate_cbk_t fallocate;
+ fop_flush_cbk_t flush;
+ fop_fsync_cbk_t fsync;
+ fop_fsyncdir_cbk_t fsyncdir;
+ fop_getxattr_cbk_t getxattr;
+ fop_fgetxattr_cbk_t fgetxattr;
+ fop_heal_cbk_t heal;
+ fop_fheal_cbk_t fheal;
+ fop_inodelk_cbk_t inodelk;
+ fop_finodelk_cbk_t finodelk;
+ fop_link_cbk_t link;
+ fop_lk_cbk_t lk;
+ fop_lookup_cbk_t lookup;
+ fop_mkdir_cbk_t mkdir;
+ fop_mknod_cbk_t mknod;
+ fop_open_cbk_t open;
+ fop_opendir_cbk_t opendir;
+ fop_readdir_cbk_t readdir;
+ fop_readdirp_cbk_t readdirp;
+ fop_readlink_cbk_t readlink;
+ fop_readv_cbk_t readv;
+ fop_removexattr_cbk_t removexattr;
+ fop_fremovexattr_cbk_t fremovexattr;
+ fop_rename_cbk_t rename;
+ fop_rmdir_cbk_t rmdir;
+ fop_setattr_cbk_t setattr;
+ fop_fsetattr_cbk_t fsetattr;
+ fop_setxattr_cbk_t setxattr;
+ fop_fsetxattr_cbk_t fsetxattr;
+ fop_stat_cbk_t stat;
+ fop_fstat_cbk_t fstat;
+ fop_statfs_cbk_t statfs;
+ fop_symlink_cbk_t symlink;
+ fop_truncate_cbk_t truncate;
+ fop_ftruncate_cbk_t ftruncate;
+ fop_unlink_cbk_t unlink;
+ fop_writev_cbk_t writev;
+ fop_xattrop_cbk_t xattrop;
+ fop_fxattrop_cbk_t fxattrop;
+ fop_zerofill_cbk_t zerofill;
+};
+
+struct _ec_lock
+{
+ struct list_head list;
+ uintptr_t mask;
+ int32_t kind;
+ loc_t loc;
+ union
+ {
+ struct
+ {
+ entrylk_type type;
+ char * basename;
+ };
+ struct gf_flock flock;
+ };
+};
+
+struct _ec_fop_data
+{
+ int32_t id;
+ int32_t refs;
+ int32_t state;
+ int32_t minimum;
+ int32_t expected;
+ int32_t winds;
+ int32_t jobs;
+ int32_t error;
+ ec_fop_data_t * parent;
+ xlator_t * xl;
+ call_frame_t * req_frame; // frame of the calling xlator
+ call_frame_t * frame; // frame used by this fop
+ struct list_head lock_list; // list locks held by this fop
+ struct list_head cbk_list; // sorted list of groups of answers
+ struct list_head answer_list; // list of answers
+ ec_cbk_data_t * answer; // accepted answer
+ size_t pre_size;
+ size_t post_size;
+ gf_lock_t lock;
+
+ uint32_t flags;
+ uint32_t first;
+ uintptr_t mask;
+ uintptr_t remaining;
+ uintptr_t good;
+ uintptr_t bad;
+
+ ec_wind_f wind;
+ ec_handler_f handler;
+ ec_resume_f resume;
+ ec_cbk_t cbks;
+ void * data;
+
+ size_t user_size;
+ size_t head;
+
+ dict_t * xdata;
+ dict_t * dict;
+ int32_t int32;
+ uint32_t uint32;
+ size_t size;
+ off_t offset;
+ mode_t mode[2];
+ entrylk_cmd entrylk_cmd;
+ entrylk_type entrylk_type;
+ gf_xattrop_flags_t xattrop_flags;
+ dev_t dev;
+ inode_t * inode;
+ fd_t * fd;
+ struct iatt iatt;
+ char * str[2];
+ loc_t loc[2];
+ struct gf_flock flock;
+ struct iovec * vector;
+ struct iobref * buffers;
+};
+
+struct _ec_cbk_data
+{
+ struct list_head list; // item in the sorted list of groups
+ struct list_head answer_list; // item in the list of answers
+ ec_fop_data_t * fop;
+ ec_cbk_data_t * next; // next answer in the same group
+ int32_t idx;
+ int32_t op_ret;
+ int32_t op_errno;
+ int32_t count;
+ uintptr_t mask;
+
+ dict_t * xdata;
+ dict_t * dict;
+ int32_t int32;
+ uintptr_t uintptr[3];
+ size_t size;
+ uint64_t version;
+ inode_t * inode;
+ fd_t * fd;
+ struct statvfs statvfs;
+ struct iatt iatt[5];
+ struct gf_flock flock;
+ struct iovec * vector;
+ struct iobref * buffers;
+};
+
+struct _ec_heal
+{
+ gf_lock_t lock;
+ xlator_t * xl;
+ ec_fop_data_t * fop;
+ ec_fop_data_t * lookup;
+ loc_t loc;
+ struct iatt iatt;
+ char * symlink;
+ fd_t * fd;
+ int32_t done;
+ uintptr_t available;
+ uintptr_t good;
+ uintptr_t bad;
+ uintptr_t open;
+ off_t offset;
+ size_t size;
+ uint64_t version;
+ size_t raw_size;
+};
+
+ec_cbk_data_t * ec_cbk_data_allocate(call_frame_t * frame, xlator_t * this,
+ ec_fop_data_t * fop, int32_t id,
+ int32_t idx, int32_t op_ret,
+ int32_t op_errno);
+ec_fop_data_t * ec_fop_data_allocate(call_frame_t * frame, xlator_t * this,
+ int32_t id, uint32_t flags,
+ uintptr_t target, int32_t minimum,
+ ec_wind_f wind, ec_handler_f handler,
+ ec_cbk_t cbks, void * data);
+void ec_fop_data_acquire(ec_fop_data_t * fop);
+void ec_fop_data_release(ec_fop_data_t * fop);
+
+#endif /* __EC_DATA_H__ */
diff --git a/xlators/cluster/ec/src/ec-dir-read.c b/xlators/cluster/ec/src/ec-dir-read.c
new file mode 100644
index 00000000000..1e7abc30d91
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-dir-read.c
@@ -0,0 +1,571 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+/* FOP: opendir */
+
+int32_t ec_combine_opendir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (dst->fd != src->fd)
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
+ "of 'GF_FOP_OPENDIR': %p <-> %p",
+ dst->fd, src->fd);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_opendir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPENDIR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (fd != NULL)
+ {
+ cbk->fd = fd_ref(fd);
+ if (cbk->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_opendir);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_opendir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_opendir_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->opendir,
+ &fop->loc[0], fop->fd, fop->xdata);
+}
+
+int32_t ec_manager_opendir(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.opendir != NULL)
+ {
+ fop->cbks.opendir(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->fd, cbk->xdata);
+ }
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.opendir != NULL)
+ {
+ fop->cbks.opendir(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL);
+ }
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_opendir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_opendir_cbk_t func, void * data,
+ loc_t * loc, fd_t * fd, dict_t * xdata)
+{
+ ec_cbk_t callback = { .opendir = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(OPENDIR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_OPENDIR, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_opendir,
+ ec_manager_opendir, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: readdir */
+
+void ec_adjust_readdir(ec_t * ec, int32_t idx, gf_dirent_t * entries)
+{
+ gf_dirent_t * entry;
+
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ entry->d_off = ec_itransform(ec, idx, entry->d_off);
+
+ if (entry->d_stat.ia_type == IA_IFREG)
+ {
+ if ((entry->dict == NULL) ||
+ (ec_dict_del_number(entry->dict, EC_XATTR_SIZE,
+ &entry->d_stat.ia_size) != 0))
+ {
+ gf_log(ec->xl->name, GF_LOG_WARNING, "Unable to get exact "
+ "file size.");
+
+ entry->d_stat.ia_size *= ec->fragments;
+ }
+
+ ec_iatt_rebuild(ec, &entry->d_stat, 1, 1);
+ }
+ }
+}
+
+int32_t ec_readdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t * entries,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ if (op_ret > 0)
+ {
+ ec_adjust_readdir(fop->xl->private, idx, entries);
+ }
+
+ if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
+ {
+ if (fop->cbks.readdir != NULL)
+ {
+ fop->cbks.readdir(fop->req_frame, fop, this, op_ret, op_errno,
+ entries, xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_readdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_readdir_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->readdir,
+ fop->fd, fop->size, fop->offset, fop->xdata);
+}
+
+int32_t ec_manager_readdir(ec_fop_data_t * fop, int32_t state)
+{
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ if (fop->xdata == NULL)
+ {
+ fop->xdata = dict_new();
+ if (fop->xdata == NULL)
+ {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
+ "readdirp request");
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+ }
+ if (dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0) != 0)
+ {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
+ "readdirp request");
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+
+ if (fop->offset != 0)
+ {
+ int32_t idx;
+
+ fop->offset = ec_deitransform(fop->xl->private, &idx,
+ fop->offset);
+ fop->mask &= 1ULL << idx;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_one(fop);
+
+ return EC_STATE_REPORT;
+
+ case -EC_STATE_REPORT:
+ if (fop->id == GF_FOP_READDIR)
+ {
+ if (fop->cbks.readdir != NULL)
+ {
+ fop->cbks.readdir(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.readdirp != NULL)
+ {
+ fop->cbks.readdirp(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+
+ case EC_STATE_REPORT:
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_readdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readdir_cbk_t func, void * data,
+ fd_t * fd, size_t size, off_t offset, dict_t * xdata)
+{
+ ec_cbk_t callback = { .readdir = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(READDIR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_READDIR, 0, target, minimum,
+ ec_wind_readdir, ec_manager_readdir, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->size = size;
+ fop->offset = offset;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: readdirp */
+
+int32_t ec_readdirp_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t * entries, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ if (op_ret > 0)
+ {
+ ec_adjust_readdir(fop->xl->private, idx, entries);
+ }
+
+ if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
+ {
+ if (fop->cbks.readdirp != NULL)
+ {
+ fop->cbks.readdirp(fop->req_frame, fop, this, op_ret, op_errno,
+ entries, xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_readdirp(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_readdirp_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->readdirp,
+ fop->fd, fop->size, fop->offset, fop->xdata);
+}
+
+void ec_readdirp(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readdirp_cbk_t func, void * data,
+ fd_t * fd, size_t size, off_t offset, dict_t * xdata)
+{
+ ec_cbk_t callback = { .readdirp = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(READDIRP) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_READDIRP, 0, target,
+ minimum, ec_wind_readdirp, ec_manager_readdir,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->size = size;
+ fop->offset = offset;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-dir-write.c b/xlators/cluster/ec/src/ec-dir-write.c
new file mode 100644
index 00000000000..da89e34ba25
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-dir-write.c
@@ -0,0 +1,2102 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+/* FOP: create */
+
+int32_t ec_combine_create(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (dst->fd != src->fd)
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
+ "of 'GF_FOP_CREATE': %p <-> %p",
+ dst->fd, src->fd);
+
+ return 0;
+ }
+
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_CREATE'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_create_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, fd_t * fd,
+ inode_t * inode, struct iatt * buf,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_CREATE, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (fd != NULL)
+ {
+ cbk->fd = fd_ref(fd);
+ if (cbk->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preparent != NULL)
+ {
+ cbk->iatt[1] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[2] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_create);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_create(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_create_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->create,
+ &fop->loc[0], fop->int32, fop->mode[0], fop->mode[1],
+ fop->fd, fop->xdata);
+}
+
+int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+ ec_fd_t * ctx;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ LOCK(&fop->fd->lock);
+
+ ctx = __ec_fd_get(fop->fd, fop->xl);
+ if ((ctx == NULL) || !ec_loc_from_loc(fop->xl, &ctx->loc,
+ &fop->loc[0]))
+ {
+ UNLOCK(&fop->fd->lock);
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+
+ if (ctx->flags == 0)
+ {
+ ctx->flags = fop->int32;
+ }
+
+ UNLOCK(&fop->fd->lock);
+
+ fop->int32 &= ~O_ACCMODE;
+ fop->int32 |= O_RDWR;
+
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
+ cbk->count);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode,
+ &cbk->iatt[0]);
+
+ LOCK(&fop->fd->lock);
+
+ ctx = __ec_fd_get(fop->fd, fop->xl);
+ if (ctx != NULL)
+ {
+ ctx->open |= cbk->mask;
+ }
+
+ UNLOCK(&fop->fd->lock);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.create != NULL)
+ {
+ fop->cbks.create(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->fd, cbk->inode,
+ &cbk->iatt[0], &cbk->iatt[1], &cbk->iatt[2],
+ cbk->xdata);
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.create != NULL)
+ {
+ fop->cbks.create(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_create(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_create_cbk_t func, void * data,
+ loc_t * loc, int32_t flags, mode_t mode, mode_t umask,
+ fd_t * fd, dict_t * xdata)
+{
+ ec_cbk_t callback = { .create = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(CREATE) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_CREATE,
+ EC_FLAG_UPDATE_LOC_PARENT |
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_create, ec_manager_create, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = flags;
+ fop->mode[0] = mode;
+ fop->mode[1] = umask;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: link */
+
+int32_t ec_combine_link(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_LINK'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_link_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LINK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preparent != NULL)
+ {
+ cbk->iatt[1] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[2] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_link);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_link(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_link_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->link,
+ &fop->loc[0], &fop->loc[1], fop->xdata);
+}
+
+int32_t ec_manager_link(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ // Parent entry of fop->loc[0] should be locked, but I don't
+ // receive enough information to do it (fop->loc[0].parent is
+ // NULL).
+ ec_lock_entry(fop, &fop->loc[1]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
+ cbk->count);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode,
+ &cbk->iatt[0]);
+
+ if (cbk->iatt[0].ia_type == IA_IFREG)
+ {
+ cbk->iatt[0].ia_size = fop->pre_size;
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.link != NULL)
+ {
+ fop->cbks.link(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->inode, &cbk->iatt[0],
+ &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.link != NULL)
+ {
+ fop->cbks.link(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_link(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_link_cbk_t func, void * data, loc_t * oldloc,
+ loc_t * newloc, dict_t * xdata)
+{
+ ec_cbk_t callback = { .link = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(LINK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_LINK, 0, target, minimum,
+ ec_wind_link, ec_manager_link, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (oldloc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], oldloc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (newloc != NULL)
+ {
+ if (loc_copy(&fop->loc[1], newloc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: mkdir */
+
+int32_t ec_combine_mkdir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_MKDIR'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_mkdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_MKDIR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preparent != NULL)
+ {
+ cbk->iatt[1] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[2] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_mkdir);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_mkdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_mkdir_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->mkdir,
+ &fop->loc[0], fop->mode[0], fop->mode[1], fop->xdata);
+}
+
+int32_t ec_manager_mkdir(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
+ cbk->count);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode,
+ &cbk->iatt[0]);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.mkdir != NULL)
+ {
+ fop->cbks.mkdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->inode, &cbk->iatt[0],
+ &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.mkdir != NULL)
+ {
+ fop->cbks.mkdir(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_mkdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_mkdir_cbk_t func, void * data, loc_t * loc,
+ mode_t mode, mode_t umask, dict_t * xdata)
+{
+ ec_cbk_t callback = { .mkdir = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(MKDIR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_MKDIR,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_mkdir, ec_manager_mkdir, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->mode[0] = mode;
+ fop->mode[1] = umask;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: mknod */
+
+int32_t ec_combine_mknod(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_MKNOD'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_mknod_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_MKNOD, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preparent != NULL)
+ {
+ cbk->iatt[1] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[2] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_mknod);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_mknod(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_mknod_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->mknod,
+ &fop->loc[0], fop->mode[0], fop->dev, fop->mode[1],
+ fop->xdata);
+}
+
+int32_t ec_manager_mknod(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
+ cbk->count);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode,
+ &cbk->iatt[0]);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.mknod != NULL)
+ {
+ fop->cbks.mknod(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->inode, &cbk->iatt[0],
+ &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.mknod != NULL)
+ {
+ fop->cbks.mknod(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_mknod(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_mknod_cbk_t func, void * data, loc_t * loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata)
+{
+ ec_cbk_t callback = { .mknod = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(MKNOD) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_MKNOD,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_mknod, ec_manager_mknod, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->mode[0] = mode;
+ fop->dev = rdev;
+ fop->mode[1] = umask;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: rename */
+
+int32_t ec_combine_rename(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 5))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_RENAME'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_rename_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * buf,
+ struct iatt * preoldparent, struct iatt * postoldparent,
+ struct iatt * prenewparent, struct iatt * postnewparent,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_RENAME, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preoldparent != NULL)
+ {
+ cbk->iatt[1] = *preoldparent;
+ }
+ if (postoldparent != NULL)
+ {
+ cbk->iatt[2] = *postoldparent;
+ }
+ if (prenewparent != NULL)
+ {
+ cbk->iatt[3] = *prenewparent;
+ }
+ if (postnewparent != NULL)
+ {
+ cbk->iatt[4] = *postnewparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_rename);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_rename(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_rename_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->rename,
+ &fop->loc[0], &fop->loc[1], fop->xdata);
+}
+
+int32_t ec_manager_rename(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+ ec_lock_entry(fop, &fop->loc[1]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 5,
+ cbk->count);
+
+ if (cbk->iatt[0].ia_type == IA_IFREG)
+ {
+ cbk->iatt[0].ia_size = fop->pre_size;
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.rename != NULL)
+ {
+ fop->cbks.rename(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
+ &cbk->iatt[2], &cbk->iatt[3], &cbk->iatt[4],
+ cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.rename != NULL)
+ {
+ fop->cbks.rename(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_rename(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_rename_cbk_t func, void * data,
+ loc_t * oldloc, loc_t * newloc, dict_t * xdata)
+{
+ ec_cbk_t callback = { .rename = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(RENAME) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_RENAME,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_rename, ec_manager_rename, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (oldloc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], oldloc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (newloc != NULL)
+ {
+ if (loc_copy(&fop->loc[1], newloc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: rmdir */
+
+int32_t ec_combine_rmdir(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_RMDIR'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_rmdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_RMDIR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (preparent != NULL)
+ {
+ cbk->iatt[0] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[1] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_rmdir);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_rmdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_rmdir_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->rmdir,
+ &fop->loc[0], fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_rmdir(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.rmdir != NULL)
+ {
+ fop->cbks.rmdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.rmdir != NULL)
+ {
+ fop->cbks.rmdir(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_rmdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_rmdir_cbk_t func, void * data, loc_t * loc,
+ int xflags, dict_t * xdata)
+{
+ ec_cbk_t callback = { .rmdir = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(RMDIR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_RMDIR,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_rmdir, ec_manager_rmdir, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = xflags;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: symlink */
+
+int32_t ec_combine_symlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 3))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_SYMLINK'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_symlink_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SYMLINK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (preparent != NULL)
+ {
+ cbk->iatt[1] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[2] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_symlink);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_symlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_symlink_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->symlink,
+ fop->str[0], &fop->loc[0], fop->mode[0], fop->xdata);
+}
+
+int32_t ec_manager_symlink(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 3,
+ cbk->count);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode,
+ &cbk->iatt[0]);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.symlink != NULL)
+ {
+ fop->cbks.symlink(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->inode, &cbk->iatt[0],
+ &cbk->iatt[1], &cbk->iatt[2], cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.symlink != NULL)
+ {
+ fop->cbks.symlink(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_symlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_symlink_cbk_t func, void * data,
+ const char * linkname, loc_t * loc, mode_t umask,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .symlink = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(SYMLINK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_SYMLINK,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_symlink, ec_manager_symlink, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->mode[0] = umask;
+
+ if (linkname != NULL)
+ {
+ fop->str[0] = gf_strdup(linkname);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: unlink */
+
+int32_t ec_combine_unlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_UNLINK'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_unlink_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_UNLINK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (preparent != NULL)
+ {
+ cbk->iatt[0] = *preparent;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[1] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_unlink);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_unlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_unlink_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->unlink,
+ &fop->loc[0], fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_unlink(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_entry(fop, &fop->loc[0]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.unlink != NULL)
+ {
+ fop->cbks.unlink(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.unlink != NULL)
+ {
+ fop->cbks.unlink(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_unlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_unlink_cbk_t func, void * data,
+ loc_t * loc, int xflags, dict_t * xdata)
+{
+ ec_cbk_t callback = { .unlink = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(UNLINK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_UNLINK,
+ EC_FLAG_UPDATE_LOC_PARENT, target, minimum,
+ ec_wind_unlink, ec_manager_unlink, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = xflags;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-fops.h b/xlators/cluster/ec/src/ec-fops.h
new file mode 100644
index 00000000000..2b6e03f723f
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-fops.h
@@ -0,0 +1,211 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_FOPS_H__
+#define __EC_FOPS_H__
+
+#include "xlator.h"
+
+#include "ec-data.h"
+#include "ec-common.h"
+
+#define EC_FOP_HEAL -1
+#define EC_FOP_FHEAL -2
+
+void ec_access(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_access_cbk_t func, void *data, loc_t * loc,
+ int32_t mask, dict_t * xdata);
+
+void ec_create(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_create_cbk_t func, void *data, loc_t * loc,
+ int32_t flags, mode_t mode, mode_t umask, fd_t * fd,
+ dict_t * xdata);
+
+void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_entrylk_cbk_t func, void *data,
+ const char * volume, loc_t * loc, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata);
+
+void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fentrylk_cbk_t func, void *data,
+ const char * volume, fd_t * fd, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata);
+
+void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_flush_cbk_t func, void *data, fd_t * fd,
+ dict_t * xdata);
+
+void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsync_cbk_t func, void *data, fd_t * fd,
+ int32_t datasync, dict_t * xdata);
+
+void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsyncdir_cbk_t func, void *data,
+ fd_t * fd, int32_t datasync, dict_t * xdata);
+
+void ec_getxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_getxattr_cbk_t func, void *data,
+ loc_t * loc, const char * name, dict_t * xdata);
+
+void ec_fgetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fgetxattr_cbk_t func, void *data,
+ fd_t * fd, const char * name, dict_t * xdata);
+
+void ec_heal(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_heal_cbk_t func, void *data, loc_t * loc,
+ dict_t * xdata);
+
+void ec_fheal(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fheal_cbk_t func, void *data, fd_t * fd,
+ dict_t * xdata);
+
+void ec_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_inodelk_cbk_t func, void *data,
+ const char * volume, loc_t * loc, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata);
+
+void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_finodelk_cbk_t func, void *data,
+ const char * volume, fd_t * fd, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata);
+
+void ec_link(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_link_cbk_t func, void *data, loc_t * oldloc,
+ loc_t * newloc, dict_t * xdata);
+
+void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_lk_cbk_t func, void *data, fd_t * fd,
+ int32_t cmd, struct gf_flock * flock, dict_t * xdata);
+
+void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_lookup_cbk_t func, void *data, loc_t * loc,
+ dict_t * xdata);
+
+void ec_mkdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_mkdir_cbk_t func, void *data, loc_t * loc,
+ mode_t mode, mode_t umask, dict_t * xdata);
+
+void ec_mknod(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_mknod_cbk_t func, void *data, loc_t * loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata);
+
+void ec_open(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_open_cbk_t func, void *data, loc_t * loc,
+ int32_t flags, fd_t * fd, dict_t * xdata);
+
+void ec_opendir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_opendir_cbk_t func, void *data,
+ loc_t * loc, fd_t * fd, dict_t * xdata);
+
+void ec_readdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readdir_cbk_t func, void *data, fd_t * fd,
+ size_t size, off_t offset, dict_t * xdata);
+
+void ec_readdirp(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readdirp_cbk_t func, void *data,
+ fd_t * fd, size_t size, off_t offset, dict_t * xdata);
+
+void ec_readlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readlink_cbk_t func, void *data,
+ loc_t * loc, size_t size, dict_t * xdata);
+
+void ec_readv(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readv_cbk_t func, void *data, fd_t * fd,
+ size_t size, off_t offset, uint32_t flags, dict_t * xdata);
+
+void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_removexattr_cbk_t func, void *data,
+ loc_t * loc, const char * name, dict_t * xdata);
+
+void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fremovexattr_cbk_t func, void *data,
+ fd_t * fd, const char * name, dict_t * xdata);
+
+void ec_rename(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_rename_cbk_t func, void *data,
+ loc_t * oldloc, loc_t * newloc, dict_t * xdata);
+
+void ec_rmdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_rmdir_cbk_t func, void *data, loc_t * loc,
+ int xflags, dict_t * xdata);
+
+void ec_setattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_setattr_cbk_t func, void *data,
+ loc_t * loc, struct iatt * stbuf, int32_t valid,
+ dict_t * xdata);
+
+void ec_fsetattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsetattr_cbk_t func, void *data,
+ fd_t * fd, struct iatt * stbuf, int32_t valid,
+ dict_t * xdata);
+
+void ec_setxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_setxattr_cbk_t func, void *data,
+ loc_t * loc, dict_t * dict, int32_t flags, dict_t * xdata);
+
+void ec_fsetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsetxattr_cbk_t func, void *data,
+ fd_t * fd, dict_t * dict, int32_t flags, dict_t * xdata);
+
+void ec_stat(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_stat_cbk_t func, void *data, loc_t * loc,
+ dict_t * xdata);
+
+void ec_fstat(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fstat_cbk_t func, void *data, fd_t * fd,
+ dict_t * xdata);
+
+void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_statfs_cbk_t func, void *data, loc_t * loc,
+ dict_t * xdata);
+
+void ec_symlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_symlink_cbk_t func, void *data,
+ const char * linkname, loc_t * loc, mode_t umask,
+ dict_t * xdata);
+
+void ec_truncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_truncate_cbk_t func, void *data,
+ loc_t * loc, off_t offset, dict_t * xdata);
+
+void ec_ftruncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_ftruncate_cbk_t func, void *data,
+ fd_t * fd, off_t offset, dict_t * xdata);
+
+void ec_unlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_unlink_cbk_t func, void *data, loc_t * loc,
+ int xflags, dict_t * xdata);
+
+void ec_writev(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_writev_cbk_t func, void *data, fd_t * fd,
+ struct iovec * vector, int32_t count, off_t offset,
+ uint32_t flags, struct iobref * iobref, dict_t * xdata);
+
+void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_xattrop_cbk_t func, void *data,
+ loc_t * loc, gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata);
+
+void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fxattrop_cbk_t func, void *data,
+ fd_t * fd, gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata);
+
+#endif /* __EC_FOPS_H__ */
diff --git a/xlators/cluster/ec/src/ec-generic.c b/xlators/cluster/ec/src/ec-generic.c
new file mode 100644
index 00000000000..49343388934
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-generic.c
@@ -0,0 +1,1660 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+/* FOP: flush */
+
+int32_t ec_flush_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FLUSH, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_flush(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_flush_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->flush, fop->fd,
+ fop->xdata);
+}
+
+int32_t ec_manager_flush(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_fd(fop, fop->fd);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.flush != NULL)
+ {
+ fop->cbks.flush(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.flush != NULL)
+ {
+ fop->cbks.flush(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_flush(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_flush_cbk_t func, void * data, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .flush = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FLUSH) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FLUSH, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_flush,
+ ec_manager_flush, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: fsync */
+
+int32_t ec_combine_fsync(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_FSYNC'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_fsync_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * prebuf,
+ struct iatt * postbuf, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNC, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (prebuf != NULL)
+ {
+ cbk->iatt[0] = *prebuf;
+ }
+ if (postbuf != NULL)
+ {
+ cbk->iatt[1] = *postbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_fsync);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fsync(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fsync_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fsync, fop->fd,
+ fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_fsync(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_fd(fop, fop->fd);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
+ cbk->count);
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+ cbk->iatt[1].ia_size = fop->post_size;
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.fsync != NULL)
+ {
+ fop->cbks.fsync(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.fsync != NULL)
+ {
+ fop->cbks.fsync(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_fsync(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsync_cbk_t func, void * data, fd_t * fd,
+ int32_t datasync, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fsync = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FSYNC) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNC, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_fsync,
+ ec_manager_fsync, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = datasync;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: fsyncdir */
+
+int32_t ec_fsyncdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSYNCDIR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fsyncdir(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fsyncdir_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fsyncdir,
+ fop->fd, fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_fsyncdir(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_fd(fop, fop->fd);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.fsyncdir != NULL)
+ {
+ fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.fsyncdir != NULL)
+ {
+ fop->cbks.fsyncdir(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_fsyncdir(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsyncdir_cbk_t func, void * data,
+ fd_t * fd, int32_t datasync, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fsyncdir = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FSYNCDIR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FSYNCDIR, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_fsyncdir,
+ ec_manager_fsyncdir, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = datasync;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: lookup */
+
+void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
+{
+ ec_cbk_data_t * ans = NULL;
+ data_t * data = NULL;
+ uint8_t * ptr = NULL, * buff = NULL, * tmp = NULL;
+ size_t size = 0;
+ int32_t i = 0;
+
+ if (cbk->op_ret < 0)
+ {
+ return;
+ }
+
+ ec_dict_del_number(cbk->xdata, EC_XATTR_VERSION, &cbk->version);
+
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->inode, &cbk->iatt[0]);
+
+ if (cbk->iatt[0].ia_type == IA_IFREG)
+ {
+ uint8_t * blocks[cbk->count];
+ uint8_t * ptrs[cbk->count];
+ uint32_t values[cbk->count];
+
+ cbk->size = cbk->iatt[0].ia_size;
+ ec_dict_del_number(cbk->xdata, EC_XATTR_SIZE, &cbk->iatt[0].ia_size);
+
+ size = SIZE_MAX;
+ for (i = 0, ans = cbk; (ans != NULL) && (i < ec->fragments);
+ ans = ans->next)
+ {
+ data = dict_get(ans->xdata, GF_CONTENT_KEY);
+ if (data != NULL)
+ {
+ values[i] = ans->idx;
+ ptrs[i] = GF_MALLOC(data->len + EC_BUFFER_ALIGN_SIZE - 1,
+ gf_common_mt_char);
+ if (ptrs[i] == NULL)
+ {
+ continue;
+ }
+
+ if (size > data->len)
+ {
+ size = data->len;
+ }
+ blocks[i] = GF_ALIGN_BUF(ptrs[i], EC_BUFFER_ALIGN_SIZE);
+ memcpy(blocks[i], data->data, size);
+
+ i++;
+ }
+ }
+
+ dict_del(cbk->xdata, GF_CONTENT_KEY);
+
+ if (i >= ec->fragments)
+ {
+ size -= size % ec->fragment_size;
+ if (size > 0)
+ {
+ ptr = GF_MALLOC(size * ec->fragments +
+ EC_BUFFER_ALIGN_SIZE - 1,
+ gf_common_mt_char);
+ if (ptr != NULL)
+ {
+ buff = GF_ALIGN_BUF(ptr, EC_BUFFER_ALIGN_SIZE);
+
+ size = ec_method_decode(size, ec->fragments, values,
+ blocks, buff);
+ if (size > fop->size)
+ {
+ size = fop->size;
+ }
+ if (size > cbk->iatt[0].ia_size)
+ {
+ size = cbk->iatt[0].ia_size;
+ }
+
+ tmp = GF_MALLOC(size, gf_common_mt_char);
+ if (tmp != NULL)
+ {
+ memcpy(tmp, buff, size);
+ if (dict_set_bin(cbk->xdata, GF_CONTENT_KEY, tmp,
+ size) != 0)
+ {
+ GF_FREE(tmp);
+
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Lookup "
+ "read-ahead "
+ "failed");
+ }
+ }
+
+ GF_FREE(ptr);
+ }
+ else
+ {
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Lookup read-ahead "
+ "failed");
+ }
+ }
+ }
+ while (--i > 0)
+ {
+ GF_FREE(ptrs[i]);
+ }
+ }
+}
+
+int32_t ec_combine_lookup(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_LOOKUP'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_lookup_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, dict_t * xdata,
+ struct iatt * postparent)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LOOKUP, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (inode != NULL)
+ {
+ cbk->inode = inode_ref(inode);
+ if (cbk->inode == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Failed to reference an inode.");
+
+ goto out;
+ }
+ }
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ if (postparent != NULL)
+ {
+ cbk->iatt[1] = *postparent;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_lookup);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_lookup(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_lookup_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->lookup,
+ &fop->loc[0], fop->xdata);
+}
+
+int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ if (fop->xdata == NULL)
+ {
+ fop->xdata = dict_new();
+ if (fop->xdata == NULL)
+ {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare "
+ "lookup request");
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+ }
+ else
+ {
+ uint64_t size;
+
+ if (dict_get_uint64(fop->xdata, GF_CONTENT_KEY, &size) == 0)
+ {
+ fop->size = size;
+ size = ec_adjust_size(fop->xl->private, size, 1);
+ if (dict_set_uint64(fop->xdata, GF_CONTENT_KEY, size) != 0)
+ {
+ gf_log("ec", GF_LOG_DEBUG, "Unable to update lookup "
+ "content size");
+ }
+ }
+ }
+ if ((dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0) != 0) ||
+ (dict_set_uint64(fop->xdata, EC_XATTR_VERSION, 0) != 0))
+ {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare lookup "
+ "request");
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
+ cbk->count);
+
+ ec_lookup_rebuild(fop->xl->private, fop, cbk);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.lookup != NULL)
+ {
+ fop->cbks.lookup(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->inode, &cbk->iatt[0],
+ cbk->xdata, &cbk->iatt[1]);
+ }
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.lookup != NULL)
+ {
+ fop->cbks.lookup(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_lookup(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_lookup_cbk_t func, void * data,
+ loc_t * loc, dict_t * xdata)
+{
+ ec_cbk_t callback = { .lookup = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(LOOKUP) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_LOOKUP, 0, target, minimum,
+ ec_wind_lookup, ec_manager_lookup, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: statfs */
+
+int32_t ec_combine_statfs(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ ec_statvfs_combine(&dst->statvfs, &src->statvfs);
+
+ return 1;
+}
+
+int32_t ec_statfs_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct statvfs * buf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STATFS, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (buf != NULL)
+ {
+ cbk->statvfs = *buf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_statfs);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_statfs(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_statfs_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->statfs,
+ &fop->loc[0], fop->xdata);
+}
+
+int32_t ec_manager_statfs(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_t * ec = fop->xl->private;
+
+ cbk->statvfs.f_blocks *= ec->fragments;
+ cbk->statvfs.f_bfree *= ec->fragments;
+ cbk->statvfs.f_bavail *= ec->fragments;
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.statfs != NULL)
+ {
+ fop->cbks.statfs(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->statvfs, cbk->xdata);
+ }
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.statfs != NULL)
+ {
+ fop->cbks.statfs(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL);
+ }
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_statfs(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_statfs_cbk_t func, void * data,
+ loc_t * loc, dict_t * xdata)
+{
+ ec_cbk_t callback = { .statfs = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(STATFS) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_STATFS, 0, target, minimum,
+ ec_wind_statfs, ec_manager_statfs, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: xattrop */
+
+int32_t ec_combine_xattrop(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_dict_compare(dst->dict, src->dict))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching dictionary in "
+ "answers of 'GF_FOP_XATTROP'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_xattrop_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_XATTROP, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (xattr != NULL)
+ {
+ cbk->dict = dict_ref(xattr);
+ if (cbk->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_xattrop);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_xattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_xattrop_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->xattrop,
+ &fop->loc[0], fop->xattrop_flags, fop->dict, fop->xdata);
+}
+
+int32_t ec_manager_xattrop(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA) ||
+ ((cbk->op_ret >= 0) && !ec_dict_combine(cbk,
+ EC_COMBINE_DICT)))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.xattrop != NULL)
+ {
+ fop->cbks.xattrop(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->dict,
+ cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fxattrop != NULL)
+ {
+ fop->cbks.fxattrop(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->dict,
+ cbk->xdata);
+ }
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.xattrop != NULL)
+ {
+ fop->cbks.xattrop(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fxattrop != NULL)
+ {
+ fop->cbks.fxattrop(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_xattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_xattrop_cbk_t func, void * data,
+ loc_t * loc, gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .xattrop = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(XATTROP) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_XATTROP,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_xattrop, ec_manager_xattrop, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->xattrop_flags = optype;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xattr != NULL)
+ {
+ fop->dict = dict_ref(xattr);
+ if (fop->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: fxattrop */
+
+int32_t ec_fxattrop_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FXATTROP, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (xattr != NULL)
+ {
+ cbk->dict = dict_ref(xattr);
+ if (cbk->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_xattrop);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fxattrop(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fxattrop_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fxattrop,
+ fop->fd, fop->xattrop_flags, fop->dict, fop->xdata);
+}
+
+void ec_fxattrop(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fxattrop_cbk_t func, void * data,
+ fd_t * fd, gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .fxattrop = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FXATTROP) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FXATTROP,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fxattrop, ec_manager_xattrop, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->xattrop_flags = optype;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xattr != NULL)
+ {
+ fop->dict = dict_ref(xattr);
+ if (fop->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-gf.c b/xlators/cluster/ec/src/ec-gf.c
new file mode 100644
index 00000000000..03c4818c0cc
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-gf.c
@@ -0,0 +1,10120 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File automatically generated on Thu Jan 26 12:08:19 2012
+ *
+ * DO NOT MODIFY
+ *
+ * Multiplications in a GF(2^8) with modulus 0x11D using XOR's
+ *
+ * 7994 total xor's
+ * 31.3 average xor's per number
+ * 0 xor's for the best case (01)
+ * 43 xor's for the worst case (F4)
+ *
+ * 0 xor's: 01
+ * 10 xor's: 03
+ * 12 xor's: F5
+ * 16 xor's: 04 05
+ * 17 xor's: 9C A6
+ * 18 xor's: 02 73
+ * 19 xor's: 10 39
+ * 20 xor's: 0B
+ * 21 xor's: 0D 59 D2 E9 EC
+ * 22 xor's: 12 28 61
+ * 23 xor's: 08 09 44
+ * 24 xor's: 0A 1D 25 55 B4
+ * 25 xor's: 07 11 21 51 63 C4
+ * 26 xor's: 0C 0F 13 45 54 5E 64 BD F2
+ * 27 xor's: 06 1F 22 41 6B B9 C7 D1 F7
+ * 28 xor's: 19 31 8C 95 B5 C1 F3
+ * 29 xor's: 26 30 42 4A 4B 50 6A 88 90 A3 D8 E0 E8 F0 FD
+ * 30 xor's: 14 15 20 2E 34 5D 89 99 A2 A9 B0 E5 F9
+ * 31 xor's: 16 17 18 1A 1B 24 29 2B 2D 3B 57 84 85 87 8F 97 A5 EB F1 FB
+ * 32 xor's: 33 36 43 47 65 67 72 75 78 79 81 83 8D 9B A8 AF B8 BB C5 CB CC CE E6 ED
+ * 33 xor's: 0E 35 3D 49 4C 4D 6E 70 94 98 A0 AB B1 B2 B6 C8 C9 CD D0 D6 DC DD E3 EA F8
+ * 34 xor's: 1C 1E 23 27 2C 32 40 46 5C 60 68 6F 71 7F 8A 9A AA AC B3 C2 D3 FC FF
+ * 35 xor's: 3A 53 58 6D 74 7C 7D 8B 91 93 96 A1 AE C0 CA D5 DB E4 F6
+ * 36 xor's: 2A 2F 38 48 4F 5B 66 6C 82 86 92 9F AD BC CF D4 DA DE E2 FA FE
+ * 37 xor's: 37 3E 52 69 7B 9D B7 BE C3 C6 EE
+ * 38 xor's: 3C 5A 7E 80 9E A7 BA BF D7 E7 EF
+ * 39 xor's: 3F 4E 77 8E A4 D9 E1
+ * 40 xor's: 76 7A
+ * 41 xor's: 62
+ * 42 xor's: 56 5F DF
+ * 43 xor's: F4
+ *
+ */
+
+#include <xmmintrin.h>
+
+#include "ec-gf.h"
+
+static void gf8mul_00000000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm0, %xmm0\n"
+ "\tpxor %xmm1, %xmm1\n"
+ "\tpxor %xmm2, %xmm2\n"
+ "\tpxor %xmm3, %xmm3\n"
+ "\tpxor %xmm4, %xmm4\n"
+ "\tpxor %xmm5, %xmm5\n"
+ "\tpxor %xmm6, %xmm6\n"
+ "\tpxor %xmm7, %xmm7\n"
+ );
+}
+
+static void gf8mul_00000001(void)
+{
+}
+
+static void gf8mul_00000010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00000011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00000100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00000101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00000110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00000111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00001000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_00001001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_00001010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00001011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00001100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00001101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00001110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00001111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00010000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_00010001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_00010010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00010011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00010100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00010101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00010110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00010111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00011000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_00011001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_00011010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00011011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00011100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00011101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00011110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00011111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00100000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm5, %xmm0\n"
+ );
+}
+
+static void gf8mul_00100001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ );
+}
+
+static void gf8mul_00100010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00100011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00100100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00100101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00100110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00100111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00101000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_00101001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00101010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00101011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00101100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00101101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00101110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00101111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00110000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00110001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_00110010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00110011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00110100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00110101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00110110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00110111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00111000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_00111001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_00111010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_00111011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_00111100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_00111101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_00111110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ );
+}
+
+static void gf8mul_00111111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01000000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm6, %xmm0\n"
+ );
+}
+
+static void gf8mul_01000001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ );
+}
+
+static void gf8mul_01000010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01000011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01000100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01000101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01000110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01000111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01001000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_01001001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_01001010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01001011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01001100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01001101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01001110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01001111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01010000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_01010001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_01010010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01010011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01010100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01010101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01010110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01010111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01011000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_01011001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_01011010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01011011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01011100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01011101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01011110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01011111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01100000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm5, %xmm0\n"
+ );
+}
+
+static void gf8mul_01100001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ );
+}
+
+static void gf8mul_01100010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01100011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01100100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01100101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01100110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01100111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01101000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_01101001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_01101010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01101011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01101100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01101101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01101110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_01101111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01110000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_01110001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_01110010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01110011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01110100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01110101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01110110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01110111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_01111000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_01111001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_01111010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01111011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01111100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_01111101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_01111110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_01111111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10000000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm7, %xmm0\n"
+ );
+}
+
+static void gf8mul_10000001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ );
+}
+
+static void gf8mul_10000010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10000011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10000100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10000101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10000110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10000111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10001000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_10001001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_10001010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10001011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10001100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10001101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10001110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10001111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10010000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_10010001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_10010010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10010011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10010100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10010101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10010110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10010111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10011000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_10011001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_10011010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10011011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10011100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10011101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10011110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10011111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10100000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm5, %xmm0\n"
+ );
+}
+
+static void gf8mul_10100001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ );
+}
+
+static void gf8mul_10100010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10100011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10100100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10100101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10100110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10100111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10101000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_10101001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10101010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10101011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10101100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10101101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10101110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10101111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10110000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_10110001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_10110010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10110011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10110100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10110101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10110110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10110111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10111000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_10111001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10111010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10111011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_10111100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_10111101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_10111110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_10111111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_11000000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm6, %xmm0\n"
+ );
+}
+
+static void gf8mul_11000001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ );
+}
+
+static void gf8mul_11000010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11000011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11000100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11000101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11000110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11000111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11001000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_11001001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_11001010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11001011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11001100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11001101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11001110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11001111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11010000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_11010001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_11010010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11010011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11010100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11010101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11010110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11010111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11011000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_11011001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_11011010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11011011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11011100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11011101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11011110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11011111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11100000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm5, %xmm0\n"
+ );
+}
+
+static void gf8mul_11100001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11100010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11100011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11100100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11100101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11100110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11100111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11101000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11101001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_11101010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11101011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11101100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11101101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11101110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11101111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11110000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm4, %xmm0\n"
+ );
+}
+
+static void gf8mul_11110001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ );
+}
+
+static void gf8mul_11110010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11110011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11110100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11110101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11110110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11110111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11111000(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm3, %xmm0\n"
+ );
+}
+
+static void gf8mul_11111001(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ );
+}
+
+static void gf8mul_11111010(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11111011(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm5, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+static void gf8mul_11111100(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm3, %xmm7\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm3, %xmm0\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm6\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm2, %xmm0\n"
+ );
+}
+
+static void gf8mul_11111101(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm2\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm4\n"
+ "\tpxor %xmm5, %xmm0\n"
+ "\tpxor %xmm6, %xmm5\n"
+ "\tpxor %xmm4, %xmm7\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm3\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm5\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ );
+}
+
+static void gf8mul_11111110(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm6\n"
+ "\tpxor %xmm7, %xmm5\n"
+ "\tpxor %xmm7, %xmm4\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm5, %xmm1\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm1\n"
+ "\tpxor %xmm4, %xmm0\n"
+ "\tpxor %xmm6, %xmm4\n"
+ "\tpxor %xmm3, %xmm6\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm2\n"
+ "\tpxor %xmm2, %xmm7\n"
+ "\tpxor %xmm2, %xmm6\n"
+ "\tpxor %xmm2, %xmm1\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm1, %xmm4\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm1, %xmm0\n"
+ "\tpxor %xmm0, %xmm7\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm5\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm3\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ "\tpxor %xmm1, %xmm0\n"
+ );
+}
+
+static void gf8mul_11111111(void)
+{
+ __asm__ __volatile__
+ (
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm6, %xmm3\n"
+ "\tpxor %xmm6, %xmm2\n"
+ "\tpxor %xmm6, %xmm1\n"
+ "\tpxor %xmm6, %xmm0\n"
+ "\tpxor %xmm5, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm5, %xmm3\n"
+ "\tpxor %xmm4, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm4, %xmm2\n"
+ "\tpxor %xmm3, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm3, %xmm1\n"
+ "\tpxor %xmm2, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm2, %xmm0\n"
+ "\tpxor %xmm1, %xmm7\n"
+ "\tpxor %xmm1, %xmm5\n"
+ "\tpxor %xmm1, %xmm3\n"
+ "\tpxor %xmm0, %xmm6\n"
+ "\tpxor %xmm0, %xmm4\n"
+ "\tpxor %xmm0, %xmm2\n"
+ "\tpxor %xmm7, %xmm3\n"
+ "\tpxor %xmm7, %xmm1\n"
+ "\tpxor %xmm7, %xmm0\n"
+ "\tpxor %xmm6, %xmm7\n"
+ "\tpxor %xmm5, %xmm6\n"
+ "\tpxor %xmm4, %xmm5\n"
+ "\tpxor %xmm3, %xmm4\n"
+ "\tpxor %xmm2, %xmm3\n"
+ "\tpxor %xmm1, %xmm2\n"
+ "\tpxor %xmm0, %xmm1\n"
+ );
+}
+
+void (* ec_gf_mul_table[256])(void) =
+{
+ gf8mul_00000000,
+ gf8mul_00000001,
+ gf8mul_00000010,
+ gf8mul_00000011,
+ gf8mul_00000100,
+ gf8mul_00000101,
+ gf8mul_00000110,
+ gf8mul_00000111,
+ gf8mul_00001000,
+ gf8mul_00001001,
+ gf8mul_00001010,
+ gf8mul_00001011,
+ gf8mul_00001100,
+ gf8mul_00001101,
+ gf8mul_00001110,
+ gf8mul_00001111,
+ gf8mul_00010000,
+ gf8mul_00010001,
+ gf8mul_00010010,
+ gf8mul_00010011,
+ gf8mul_00010100,
+ gf8mul_00010101,
+ gf8mul_00010110,
+ gf8mul_00010111,
+ gf8mul_00011000,
+ gf8mul_00011001,
+ gf8mul_00011010,
+ gf8mul_00011011,
+ gf8mul_00011100,
+ gf8mul_00011101,
+ gf8mul_00011110,
+ gf8mul_00011111,
+ gf8mul_00100000,
+ gf8mul_00100001,
+ gf8mul_00100010,
+ gf8mul_00100011,
+ gf8mul_00100100,
+ gf8mul_00100101,
+ gf8mul_00100110,
+ gf8mul_00100111,
+ gf8mul_00101000,
+ gf8mul_00101001,
+ gf8mul_00101010,
+ gf8mul_00101011,
+ gf8mul_00101100,
+ gf8mul_00101101,
+ gf8mul_00101110,
+ gf8mul_00101111,
+ gf8mul_00110000,
+ gf8mul_00110001,
+ gf8mul_00110010,
+ gf8mul_00110011,
+ gf8mul_00110100,
+ gf8mul_00110101,
+ gf8mul_00110110,
+ gf8mul_00110111,
+ gf8mul_00111000,
+ gf8mul_00111001,
+ gf8mul_00111010,
+ gf8mul_00111011,
+ gf8mul_00111100,
+ gf8mul_00111101,
+ gf8mul_00111110,
+ gf8mul_00111111,
+ gf8mul_01000000,
+ gf8mul_01000001,
+ gf8mul_01000010,
+ gf8mul_01000011,
+ gf8mul_01000100,
+ gf8mul_01000101,
+ gf8mul_01000110,
+ gf8mul_01000111,
+ gf8mul_01001000,
+ gf8mul_01001001,
+ gf8mul_01001010,
+ gf8mul_01001011,
+ gf8mul_01001100,
+ gf8mul_01001101,
+ gf8mul_01001110,
+ gf8mul_01001111,
+ gf8mul_01010000,
+ gf8mul_01010001,
+ gf8mul_01010010,
+ gf8mul_01010011,
+ gf8mul_01010100,
+ gf8mul_01010101,
+ gf8mul_01010110,
+ gf8mul_01010111,
+ gf8mul_01011000,
+ gf8mul_01011001,
+ gf8mul_01011010,
+ gf8mul_01011011,
+ gf8mul_01011100,
+ gf8mul_01011101,
+ gf8mul_01011110,
+ gf8mul_01011111,
+ gf8mul_01100000,
+ gf8mul_01100001,
+ gf8mul_01100010,
+ gf8mul_01100011,
+ gf8mul_01100100,
+ gf8mul_01100101,
+ gf8mul_01100110,
+ gf8mul_01100111,
+ gf8mul_01101000,
+ gf8mul_01101001,
+ gf8mul_01101010,
+ gf8mul_01101011,
+ gf8mul_01101100,
+ gf8mul_01101101,
+ gf8mul_01101110,
+ gf8mul_01101111,
+ gf8mul_01110000,
+ gf8mul_01110001,
+ gf8mul_01110010,
+ gf8mul_01110011,
+ gf8mul_01110100,
+ gf8mul_01110101,
+ gf8mul_01110110,
+ gf8mul_01110111,
+ gf8mul_01111000,
+ gf8mul_01111001,
+ gf8mul_01111010,
+ gf8mul_01111011,
+ gf8mul_01111100,
+ gf8mul_01111101,
+ gf8mul_01111110,
+ gf8mul_01111111,
+ gf8mul_10000000,
+ gf8mul_10000001,
+ gf8mul_10000010,
+ gf8mul_10000011,
+ gf8mul_10000100,
+ gf8mul_10000101,
+ gf8mul_10000110,
+ gf8mul_10000111,
+ gf8mul_10001000,
+ gf8mul_10001001,
+ gf8mul_10001010,
+ gf8mul_10001011,
+ gf8mul_10001100,
+ gf8mul_10001101,
+ gf8mul_10001110,
+ gf8mul_10001111,
+ gf8mul_10010000,
+ gf8mul_10010001,
+ gf8mul_10010010,
+ gf8mul_10010011,
+ gf8mul_10010100,
+ gf8mul_10010101,
+ gf8mul_10010110,
+ gf8mul_10010111,
+ gf8mul_10011000,
+ gf8mul_10011001,
+ gf8mul_10011010,
+ gf8mul_10011011,
+ gf8mul_10011100,
+ gf8mul_10011101,
+ gf8mul_10011110,
+ gf8mul_10011111,
+ gf8mul_10100000,
+ gf8mul_10100001,
+ gf8mul_10100010,
+ gf8mul_10100011,
+ gf8mul_10100100,
+ gf8mul_10100101,
+ gf8mul_10100110,
+ gf8mul_10100111,
+ gf8mul_10101000,
+ gf8mul_10101001,
+ gf8mul_10101010,
+ gf8mul_10101011,
+ gf8mul_10101100,
+ gf8mul_10101101,
+ gf8mul_10101110,
+ gf8mul_10101111,
+ gf8mul_10110000,
+ gf8mul_10110001,
+ gf8mul_10110010,
+ gf8mul_10110011,
+ gf8mul_10110100,
+ gf8mul_10110101,
+ gf8mul_10110110,
+ gf8mul_10110111,
+ gf8mul_10111000,
+ gf8mul_10111001,
+ gf8mul_10111010,
+ gf8mul_10111011,
+ gf8mul_10111100,
+ gf8mul_10111101,
+ gf8mul_10111110,
+ gf8mul_10111111,
+ gf8mul_11000000,
+ gf8mul_11000001,
+ gf8mul_11000010,
+ gf8mul_11000011,
+ gf8mul_11000100,
+ gf8mul_11000101,
+ gf8mul_11000110,
+ gf8mul_11000111,
+ gf8mul_11001000,
+ gf8mul_11001001,
+ gf8mul_11001010,
+ gf8mul_11001011,
+ gf8mul_11001100,
+ gf8mul_11001101,
+ gf8mul_11001110,
+ gf8mul_11001111,
+ gf8mul_11010000,
+ gf8mul_11010001,
+ gf8mul_11010010,
+ gf8mul_11010011,
+ gf8mul_11010100,
+ gf8mul_11010101,
+ gf8mul_11010110,
+ gf8mul_11010111,
+ gf8mul_11011000,
+ gf8mul_11011001,
+ gf8mul_11011010,
+ gf8mul_11011011,
+ gf8mul_11011100,
+ gf8mul_11011101,
+ gf8mul_11011110,
+ gf8mul_11011111,
+ gf8mul_11100000,
+ gf8mul_11100001,
+ gf8mul_11100010,
+ gf8mul_11100011,
+ gf8mul_11100100,
+ gf8mul_11100101,
+ gf8mul_11100110,
+ gf8mul_11100111,
+ gf8mul_11101000,
+ gf8mul_11101001,
+ gf8mul_11101010,
+ gf8mul_11101011,
+ gf8mul_11101100,
+ gf8mul_11101101,
+ gf8mul_11101110,
+ gf8mul_11101111,
+ gf8mul_11110000,
+ gf8mul_11110001,
+ gf8mul_11110010,
+ gf8mul_11110011,
+ gf8mul_11110100,
+ gf8mul_11110101,
+ gf8mul_11110110,
+ gf8mul_11110111,
+ gf8mul_11111000,
+ gf8mul_11111001,
+ gf8mul_11111010,
+ gf8mul_11111011,
+ gf8mul_11111100,
+ gf8mul_11111101,
+ gf8mul_11111110,
+ gf8mul_11111111
+};
diff --git a/xlators/cluster/ec/src/ec-gf.h b/xlators/cluster/ec/src/ec-gf.h
new file mode 100644
index 00000000000..664feb46ce5
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-gf.h
@@ -0,0 +1,114 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * File automatically generated on Thu Jan 26 12:08:19 2012
+ *
+ * DO NOT MODIFY
+ *
+ * Multiplications in a GF(2^8) with modulus 0x11D using XOR's
+ *
+ */
+
+#ifndef __EC_GF_H__
+#define __EC_GF_H__
+
+#define EC_GF_BITS 8
+#define EC_GF_MOD 0x11D
+
+#define ec_gf_load(addr) \
+ do \
+ { \
+ __asm__ __volatile__ \
+ ( \
+ "\tmovdqa 0*16(%0), %%xmm0\n" \
+ "\tmovdqa 1*16(%0), %%xmm1\n" \
+ "\tmovdqa 2*16(%0), %%xmm2\n" \
+ "\tmovdqa 3*16(%0), %%xmm3\n" \
+ "\tmovdqa 4*16(%0), %%xmm4\n" \
+ "\tmovdqa 5*16(%0), %%xmm5\n" \
+ "\tmovdqa 6*16(%0), %%xmm6\n" \
+ "\tmovdqa 7*16(%0), %%xmm7\n" \
+ : \
+ : "r" (addr) \
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" \
+ ); \
+ } while (0)
+
+#define ec_gf_store(addr) \
+ do \
+ { \
+ __asm__ __volatile__ \
+ ( \
+ "\tmovdqa %%xmm0, 0*16(%0)\n" \
+ "\tmovdqa %%xmm1, 1*16(%0)\n" \
+ "\tmovdqa %%xmm2, 2*16(%0)\n" \
+ "\tmovdqa %%xmm3, 3*16(%0)\n" \
+ "\tmovdqa %%xmm4, 4*16(%0)\n" \
+ "\tmovdqa %%xmm5, 5*16(%0)\n" \
+ "\tmovdqa %%xmm6, 6*16(%0)\n" \
+ "\tmovdqa %%xmm7, 7*16(%0)\n" \
+ : \
+ : "r" (addr) \
+ : "memory" \
+ ); \
+ } while (0)
+
+#define ec_gf_clear() \
+ do \
+ { \
+ __asm__ __volatile__ \
+ ( \
+ "\tpxor %xmm0, %xmm0\n" \
+ "\tpxor %xmm1, %xmm1\n" \
+ "\tpxor %xmm2, %xmm2\n" \
+ "\tpxor %xmm3, %xmm3\n" \
+ "\tpxor %xmm4, %xmm4\n" \
+ "\tpxor %xmm5, %xmm5\n" \
+ "\tpxor %xmm6, %xmm6\n" \
+ "\tpxor %xmm7, %xmm7\n" \
+ : \
+ : \
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" \
+ ); \
+ } while (0)
+
+#define ec_gf_xor(addr) \
+ do \
+ { \
+ __asm__ __volatile__ \
+ ( \
+ "\tpxor 0*16(%0), %%xmm0\n" \
+ "\tpxor 1*16(%0), %%xmm1\n" \
+ "\tpxor 2*16(%0), %%xmm2\n" \
+ "\tpxor 3*16(%0), %%xmm3\n" \
+ "\tpxor 4*16(%0), %%xmm4\n" \
+ "\tpxor 5*16(%0), %%xmm5\n" \
+ "\tpxor 6*16(%0), %%xmm6\n" \
+ "\tpxor 7*16(%0), %%xmm7\n" \
+ : \
+ : "r" (addr) \
+ : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" \
+ ); \
+ } while (0)
+
+extern void (* ec_gf_mul_table[])(void);
+
+#endif /* __EC_GF_H__ */
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
new file mode 100644
index 00000000000..37264f598b9
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-heal.c
@@ -0,0 +1,1470 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+#include "ec-mem-types.h"
+#include "ec-data.h"
+
+/* FOP: heal */
+
+void ec_heal_exclude(ec_heal_t * heal, uintptr_t mask)
+{
+ LOCK(&heal->lock);
+
+ heal->bad &= ~mask;
+
+ UNLOCK(&heal->lock);
+}
+
+void ec_heal_lookup_resume(ec_fop_data_t * fop)
+{
+ ec_heal_t * heal = fop->data;
+ ec_cbk_data_t * cbk;
+ uintptr_t good = 0, bad = 0;
+
+ if (heal->lookup != NULL)
+ {
+ ec_fop_data_release(heal->lookup);
+ }
+ ec_fop_data_acquire(fop);
+
+ list_for_each_entry(cbk, &fop->cbk_list, list)
+ {
+ if ((cbk->op_ret < 0) && (cbk->op_errno == ENOTCONN))
+ {
+ continue;
+ }
+
+ if (cbk == fop->answer)
+ {
+ if (cbk->op_ret >= 0)
+ {
+ heal->iatt = cbk->iatt[0];
+ heal->version = cbk->version;
+ heal->raw_size = cbk->size;
+ heal->fop->pre_size = cbk->iatt[0].ia_size;
+ heal->fop->post_size = cbk->iatt[0].ia_size;
+
+ if (!ec_loc_prepare(heal->xl, &heal->loc, cbk->inode,
+ &cbk->iatt[0]))
+ {
+ fop->answer = NULL;
+ fop->error = EIO;
+
+ bad |= cbk->mask;
+
+ continue;
+ }
+ }
+
+ good |= cbk->mask;
+ }
+ else
+ {
+ bad |= cbk->mask;
+ }
+ }
+
+ heal->good = good;
+ heal->bad = bad;
+
+ heal->lookup = fop;
+
+ ec_resume_parent(fop, fop->answer != NULL ? 0 : fop->error);
+}
+
+int32_t ec_heal_entry_lookup_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, inode_t * inode,
+ struct iatt * buf, dict_t * xdata,
+ struct iatt * postparent)
+{
+ ec_heal_lookup_resume(cookie);
+
+ return 0;
+}
+
+int32_t ec_heal_inode_lookup_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, inode_t * inode,
+ struct iatt * buf, dict_t * xdata,
+ struct iatt * postparent)
+{
+ ec_heal_lookup_resume(cookie);
+
+ return 0;
+}
+
+uintptr_t ec_heal_check(ec_fop_data_t * fop, uintptr_t * pgood)
+{
+ ec_cbk_data_t * cbk;
+ uintptr_t mask[2] = { 0, 0 };
+
+ list_for_each_entry(cbk, &fop->cbk_list, list)
+ {
+ mask[cbk->op_ret >= 0] |= cbk->mask;
+ }
+
+ if (pgood != NULL)
+ {
+ *pgood = mask[1];
+ }
+
+ return mask[0];
+}
+
+void ec_heal_update(ec_fop_data_t * fop, int32_t is_open)
+{
+ ec_heal_t * heal = fop->data;
+ uintptr_t good, bad;
+
+ bad = ec_heal_check(fop, &good);
+
+ LOCK(&heal->lock);
+
+ heal->bad &= ~bad;
+ if (is_open)
+ {
+ heal->open |= good;
+ }
+
+ UNLOCK(&heal->lock);
+
+ fop->error = 0;
+}
+
+void ec_heal_avoid(ec_fop_data_t * fop)
+{
+ ec_heal_t * heal = fop->data;
+ uintptr_t bad;
+
+ bad = ec_heal_check(fop, NULL);
+
+ LOCK(&heal->lock);
+
+ heal->good &= ~bad;
+
+ UNLOCK(&heal->lock);
+}
+
+int32_t ec_heal_mkdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_mknod_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_symlink_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ inode_t * inode, struct iatt * buf,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_create_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ fd_t * fd, inode_t * inode, struct iatt * buf,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 1);
+
+ return 0;
+}
+
+int32_t ec_heal_setattr_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iatt * preop_stbuf,
+ struct iatt * postop_stbuf,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_setxattr_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_removexattr_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_link_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, inode_t * inode,
+ struct iatt * buf, struct iatt * preparent,
+ struct iatt * postparent, dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+ ec_heal_t * heal = fop->data;
+ uintptr_t good, bad;
+
+ bad = ec_heal_check(fop, &good);
+ ec_heal_exclude(heal, good);
+
+ if (bad != 0)
+ {
+ fop->error = 0;
+
+ xdata = fop->xdata;
+ fop = fop->parent;
+
+ ec_create(fop->frame, fop->xl, bad, EC_MINIMUM_ONE,
+ ec_heal_create_cbk, heal, &heal->loc, 0,
+ st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
+ 0, heal->fd, xdata);
+ }
+
+ return 0;
+}
+
+int32_t ec_heal_target_open_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, fd_t * fd, dict_t * xdata)
+{
+ ec_heal_update(cookie, 1);
+
+ return 0;
+}
+
+int32_t ec_heal_source_open_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, fd_t * fd, dict_t * xdata)
+{
+ ec_heal_avoid(cookie);
+
+ return 0;
+}
+
+int32_t ec_heal_reopen_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ fd_t * fd, dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+ ec_fd_t * ctx;
+ uintptr_t good;
+
+ ec_heal_check(fop, &good);
+
+ if (good != 0)
+ {
+ LOCK(&fd->lock);
+
+ ctx = __ec_fd_get(fd, fop->xl);
+ if ((ctx != NULL) && (ctx->loc.inode != NULL))
+ {
+ ctx->bad &= ~good;
+ ctx->open |= good;
+ }
+
+ UNLOCK(&fd->lock);
+ }
+
+ return 0;
+}
+
+int32_t ec_heal_create(ec_heal_t * heal, uintptr_t mask, int32_t try_link)
+{
+ loc_t loc;
+ dict_t * xdata;
+
+ xdata = dict_new();
+ if (xdata == NULL)
+ {
+ return ENOMEM;
+ }
+
+ if (dict_set_static_bin(xdata, "gfid-req", heal->iatt.ia_gfid,
+ sizeof(uuid_t)) != 0)
+ {
+ dict_unref(xdata);
+
+ return ENOMEM;
+ }
+
+ if ((heal->iatt.ia_type == IA_IFREG) && try_link)
+ {
+ memset(&loc, 0, sizeof(loc));
+ loc.inode = heal->loc.inode;
+ uuid_copy(loc.gfid, heal->iatt.ia_gfid);
+
+ ec_link(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_link_cbk, heal, &loc, &heal->loc, xdata);
+
+ dict_unref(xdata);
+
+ return 0;
+ }
+
+ switch (heal->iatt.ia_type)
+ {
+ case IA_IFDIR:
+ ec_mkdir(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_mkdir_cbk, heal, &heal->loc,
+ st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
+ 0, xdata);
+
+ break;
+
+ case IA_IFLNK:
+ ec_symlink(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_symlink_cbk, heal, heal->symlink, &heal->loc,
+ 0, xdata);
+
+ break;
+
+ case IA_IFREG:
+ ec_create(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_create_cbk, heal, &heal->loc, 0,
+ st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
+ 0, heal->fd, xdata);
+
+ break;
+
+ default:
+ ec_mknod(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_mknod_cbk, heal, &heal->loc,
+ st_mode_from_ia(heal->iatt.ia_prot, IA_INVAL),
+ heal->iatt.ia_rdev, 0, xdata);
+
+ break;
+ }
+
+ dict_unref(xdata);
+
+ return 0;
+}
+
+void ec_heal_recreate(ec_fop_data_t * fop)
+{
+ ec_cbk_data_t * cbk;
+ ec_heal_t * heal = fop->data;
+ uintptr_t mask = 0;
+
+ if (heal->iatt.ia_type == IA_INVAL)
+ {
+ return;
+ }
+
+ list_for_each_entry(cbk, &fop->cbk_list, list)
+ {
+ if ((cbk->op_ret >= 0) || (cbk->op_errno == ENOENT) ||
+ (cbk->op_errno == ENOTDIR))
+ {
+ mask |= cbk->mask;
+ }
+ }
+
+ if (mask != 0)
+ {
+ ec_heal_create(heal, mask, 0);
+ }
+}
+
+int32_t ec_heal_rmdir_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+ ec_heal_recreate(cookie);
+
+ return 0;
+}
+
+int32_t ec_heal_unlink_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iatt * preparent, struct iatt * postparent,
+ dict_t * xdata)
+{
+ ec_heal_update(cookie, 0);
+ ec_heal_recreate(cookie);
+
+ return 0;
+}
+
+int32_t ec_heal_init(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+ struct iobuf_pool * pool;
+ inode_t * inode;
+ ec_inode_t * ctx;
+ ec_heal_t * heal = NULL;
+ int32_t error = 0;
+
+ inode = fop->loc[0].inode;
+ if (inode == NULL)
+ {
+ gf_log(fop->xl->name, GF_LOG_WARNING, "Unable to start inode healing "
+ "because there is not enough "
+ "information");
+
+ return ENODATA;
+ }
+
+ LOCK(&inode->lock);
+
+ ctx = __ec_inode_get(inode, fop->xl);
+ if (ctx == NULL)
+ {
+ error = EIO;
+
+ goto out;
+ }
+
+ if (ctx->heal != NULL)
+ {
+ error = EEXIST;
+
+ goto out;
+ }
+
+ heal = GF_MALLOC(sizeof(ec_heal_t), ec_mt_ec_heal_t);
+ if (heal == NULL)
+ {
+ error = ENOMEM;
+
+ goto out;
+ }
+
+ memset(heal, 0, sizeof(ec_heal_t));
+
+ if (loc_copy(&heal->loc, &fop->loc[0]) != 0)
+ {
+ error = ENOMEM;
+
+ goto out;
+ }
+ if (uuid_is_null(heal->loc.gfid))
+ {
+ uuid_copy(heal->loc.gfid, heal->loc.inode->gfid);
+ }
+
+ LOCK_INIT(&heal->lock);
+
+ heal->xl = fop->xl;
+ heal->fop = fop;
+ pool = fop->xl->ctx->iobuf_pool;
+ heal->size = iobpool_default_pagesize(pool) * ec->fragments;
+
+ fop->data = heal;
+
+ ctx->heal = heal;
+ heal = NULL;
+
+out:
+ UNLOCK(&inode->lock);
+
+ GF_FREE(heal);
+
+ return error;
+}
+
+void ec_heal_entrylk(ec_heal_t * heal, entrylk_cmd cmd)
+{
+ loc_t loc;
+ char * name;
+ int32_t error;
+
+ error = ec_loc_parent(heal->xl, &heal->loc, &loc, &name);
+ if (error != 0)
+ {
+ ec_fop_set_error(heal->fop, error);
+
+ return;
+ }
+
+ ec_entrylk(heal->fop->frame, heal->xl, -1, EC_MINIMUM_ALL, NULL, NULL,
+ heal->xl->name, &loc, name, cmd, ENTRYLK_WRLCK, NULL);
+
+ loc_wipe(&loc);
+ GF_FREE(name);
+}
+
+void ec_heal_inodelk(ec_heal_t * heal, int32_t type, int32_t use_fd,
+ off_t offset, size_t size)
+{
+ struct gf_flock flock;
+
+ flock.l_type = type;
+ flock.l_whence = SEEK_SET;
+ flock.l_start = offset;
+ flock.l_len = size;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ if (use_fd)
+ {
+ ec_finodelk(heal->fop->frame, heal->xl, heal->fop->mask,
+ EC_MINIMUM_ALL, NULL, NULL, heal->xl->name, heal->fd,
+ F_SETLKW, &flock, NULL);
+ }
+ else
+ {
+ ec_inodelk(heal->fop->frame, heal->xl, heal->fop->mask, EC_MINIMUM_ALL,
+ NULL, NULL, heal->xl->name, &heal->loc, F_SETLKW, &flock,
+ NULL);
+ }
+}
+
+void ec_heal_lookup(ec_heal_t * heal)
+{
+ dict_t * xdata;
+ int32_t error = ENOMEM;
+
+ xdata = dict_new();
+ if (xdata == NULL)
+ {
+ goto out;
+ }
+ if (dict_set_uint64(xdata, "list-xattr", 0) != 0)
+ {
+ goto out;
+ }
+
+ ec_lookup(heal->fop->frame, heal->xl, heal->fop->mask, EC_MINIMUM_MIN,
+ ec_heal_inode_lookup_cbk, heal, &heal->loc, xdata);
+
+ error = 0;
+
+out:
+ if (xdata != NULL)
+ {
+ dict_unref(xdata);
+ }
+
+ ec_fop_set_error(heal->fop, error);
+}
+
+void ec_heal_remove(ec_heal_t * heal, ec_cbk_data_t * cbk)
+{
+ if (cbk->iatt[0].ia_type == IA_IFDIR)
+ {
+ // TODO: Remove directory recursively ?
+ ec_rmdir(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
+ ec_heal_rmdir_cbk, heal, &heal->loc, 0, NULL);
+ }
+ else
+ {
+ ec_unlink(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
+ ec_heal_unlink_cbk, heal, &heal->loc, 0, NULL);
+ }
+}
+
+void ec_heal_remove_others(ec_heal_t * heal)
+{
+ struct list_head * item;
+ ec_cbk_data_t * cbk;
+
+ item = heal->lookup->cbk_list.next;
+ do
+ {
+ item = item->next;
+ cbk = list_entry(item, ec_cbk_data_t, list);
+
+ if (cbk->op_ret < 0)
+ {
+ if ((cbk->op_errno != ENOENT) && (cbk->op_errno != ENOTDIR))
+ {
+ gf_log(heal->xl->name, GF_LOG_WARNING, "Don't know how to "
+ "remove inode with "
+ "error %d",
+ cbk->op_errno);
+ }
+
+ ec_heal_exclude(heal, cbk->mask);
+
+ continue;
+ }
+
+ ec_heal_remove(heal, cbk);
+ } while (item->next != &heal->lookup->cbk_list);
+}
+
+void ec_heal_prepare_others(ec_heal_t * heal)
+{
+ struct list_head * item;
+ ec_cbk_data_t * cbk;
+
+ item = heal->lookup->cbk_list.next;
+ while (item->next != &heal->lookup->cbk_list)
+ {
+ item = item->next;
+ cbk = list_entry(item, ec_cbk_data_t, list);
+
+ if (cbk->op_ret < 0)
+ {
+ if (cbk->op_errno == ENOENT)
+ {
+ ec_heal_create(heal, cbk->mask, 1);
+ }
+ else
+ {
+ gf_log(heal->xl->name, GF_LOG_ERROR, "Don't know how to "
+ "heal error %d",
+ cbk->op_errno);
+
+ ec_heal_exclude(heal, cbk->mask);
+ }
+ }
+ else
+ {
+ if ((heal->iatt.ia_type != cbk->iatt[0].ia_type) ||
+ (uuid_compare(heal->iatt.ia_gfid, cbk->iatt[0].ia_gfid) != 0))
+ {
+ ec_heal_remove(heal, cbk);
+ }
+ }
+ }
+}
+
+int32_t ec_heal_readlink_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ const char * path, struct iatt * buf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+ ec_heal_t * heal = fop->data;
+
+ if (op_ret >= 0)
+ {
+ heal->symlink = gf_strdup(path);
+ if (heal->symlink != NULL)
+ {
+ ec_heal_prepare_others(heal);
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+ }
+
+ return 0;
+}
+
+ec_cbk_data_t * ec_heal_lookup_check(ec_heal_t * heal, uintptr_t * pgood,
+ uintptr_t * pbad)
+{
+ ec_fop_data_t * fop = heal->lookup;
+ ec_cbk_data_t * cbk = NULL, * ans = NULL;
+ uintptr_t good = 0, bad = 0;
+
+ list_for_each_entry(ans, &fop->cbk_list, list)
+ {
+ if ((ans->op_ret < 0) && (ans->op_errno == ENOTCONN))
+ {
+ continue;
+ }
+
+ if (ans == fop->answer)
+ {
+ good |= ans->mask;
+ cbk = ans;
+ }
+ else
+ {
+ bad |= ans->mask;
+ }
+ }
+
+ *pgood = good;
+ *pbad = bad;
+
+ return cbk;
+}
+
+void ec_heal_prepare(ec_heal_t * heal)
+{
+ ec_cbk_data_t * cbk;
+ ec_fd_t * ctx;
+ int32_t error = ENOMEM;
+
+ heal->available = heal->good;
+
+ cbk = heal->lookup->answer;
+ if (cbk->op_ret < 0)
+ {
+ if ((cbk->op_errno == ENOENT) || (cbk->op_errno == ENOTDIR))
+ {
+ ec_heal_remove_others(heal);
+ }
+ else
+ {
+ gf_log(heal->xl->name, GF_LOG_ERROR, "Don't know how to heal "
+ "error %d",
+ cbk->op_errno);
+ }
+ }
+ else
+ {
+ if (heal->iatt.ia_type == IA_IFREG)
+ {
+ heal->fd = fd_create(heal->loc.inode, heal->fop->frame->root->pid);
+ if (heal->fd == NULL)
+ {
+ gf_log(heal->xl->name, GF_LOG_ERROR, "Unable to create a new "
+ "file descriptor");
+
+ goto out;
+ }
+ ctx = ec_fd_get(heal->fd, heal->xl);
+ if ((ctx == NULL) || (loc_copy(&ctx->loc, &heal->loc) != 0))
+ {
+ goto out;
+ }
+
+ ctx->flags = O_RDWR;
+ }
+
+ if (heal->iatt.ia_type == IA_IFLNK)
+ {
+ ec_readlink(heal->fop->frame, heal->xl, cbk->mask, EC_MINIMUM_ONE,
+ ec_heal_readlink_cbk, heal, &heal->loc,
+ heal->iatt.ia_size, NULL);
+ }
+ else
+ {
+ ec_heal_prepare_others(heal);
+ }
+ }
+
+ error = 0;
+
+out:
+ ec_fop_set_error(heal->fop, error);
+}
+
+int32_t ec_heal_open_others(ec_heal_t * heal)
+{
+ struct list_head * item;
+ ec_cbk_data_t * cbk;
+ uintptr_t mask = 0, open = heal->open;
+
+ item = heal->lookup->cbk_list.next;
+ while (item->next != &heal->lookup->cbk_list)
+ {
+ item = item->next;
+ cbk = list_entry(item, ec_cbk_data_t, list);
+
+ if ((cbk->op_ret < 0) || (cbk->iatt[0].ia_type != IA_IFREG) ||
+ (uuid_compare(heal->iatt.ia_gfid, cbk->iatt[0].ia_gfid) != 0))
+ {
+ ec_heal_exclude(heal, cbk->mask);
+ }
+ else
+ {
+ mask |= cbk->mask & ~heal->open;
+ }
+ }
+
+ if (mask != 0)
+ {
+ ec_open(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_target_open_cbk, heal, &heal->loc, O_RDWR | O_TRUNC,
+ heal->fd, NULL);
+
+ open |= mask;
+ }
+
+ return (open != 0);
+}
+
+void ec_heal_setxattr_others(ec_heal_t * heal)
+{
+ ec_cbk_data_t * cbk;
+ dict_t * xdata;
+ int32_t error = ENOMEM;
+
+ if ((heal->good != 0) && (heal->bad != 0))
+ {
+ cbk = heal->lookup->answer;
+ xdata = cbk->xdata;
+
+ if ((cbk->iatt[0].ia_type == IA_IFREG) ||
+ (cbk->iatt[0].ia_type == IA_IFDIR))
+ {
+ if (ec_dict_set_number(xdata, EC_XATTR_VERSION, cbk->version) != 0)
+ {
+ goto out;
+ }
+ if (cbk->iatt[0].ia_type == IA_IFREG)
+ {
+ if (ec_dict_set_number(xdata, EC_XATTR_SIZE,
+ cbk->iatt[0].ia_size) != 0)
+ {
+ goto out;
+ }
+ }
+ }
+
+ ec_setxattr(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
+ ec_heal_setxattr_cbk, heal, &heal->loc, xdata, 0, NULL);
+ }
+
+ error = 0;
+
+out:
+ ec_fop_set_error(heal->fop, error);
+}
+
+int32_t ec_heal_xattr_clean(dict_t * dict, char * key, data_t * data,
+ void * arg)
+{
+ dict_t * base = arg;
+
+ if (dict_get(base, key) == NULL)
+ {
+ if (dict_set_static_bin(dict, key, dict, 0) != 0)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ dict_del(dict, key);
+ }
+
+ return 0;
+}
+
+void ec_heal_removexattr_others(ec_heal_t * heal)
+{
+ struct list_head * item;
+ ec_cbk_data_t * cbk;
+ dict_t * xdata;
+
+ if ((heal->good == 0) || (heal->bad == 0))
+ {
+ return;
+ }
+
+ xdata = heal->lookup->answer->xdata;
+ item = heal->lookup->cbk_list.next;
+ while (item->next != &heal->lookup->cbk_list)
+ {
+ item = item->next;
+ cbk = list_entry(item, ec_cbk_data_t, list);
+
+ if (cbk->op_ret >= 0)
+ {
+ if (dict_foreach(cbk->xdata, ec_heal_xattr_clean, xdata) == 0)
+ {
+ ec_removexattr(heal->fop->frame, heal->xl, cbk->mask,
+ EC_MINIMUM_ONE, ec_heal_removexattr_cbk, heal,
+ &heal->loc, "", cbk->xdata);
+ }
+ }
+ }
+}
+
+void ec_heal_attr(ec_heal_t * heal)
+{
+ if ((heal->good != 0) && (heal->bad != 0))
+ {
+ ec_setattr(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
+ ec_heal_setattr_cbk, heal, &heal->loc, &heal->iatt,
+ GF_SET_ATTR_MODE | GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME, NULL);
+ }
+}
+
+int32_t ec_heal_needs_data_rebuild(ec_heal_t * heal)
+{
+ ec_fop_data_t * fop = heal->lookup;
+ ec_cbk_data_t * cbk = NULL;
+ uintptr_t bad = 0;
+
+ if ((heal->fop->error != 0) || (heal->good == 0) ||
+ (heal->iatt.ia_type != IA_IFREG))
+ {
+ return 0;
+ }
+
+ list_for_each_entry(cbk, &fop->cbk_list, list)
+ {
+ if ((cbk->op_ret >= 0) &&
+ ((cbk->size != heal->raw_size) || (cbk->version != heal->version)))
+ {
+ bad |= cbk->mask;
+ }
+ }
+
+ heal->bad = bad;
+
+ return (bad != 0);
+}
+
+void ec_heal_open(ec_heal_t * heal)
+{
+ if (!ec_heal_needs_data_rebuild(heal))
+ {
+ return;
+ }
+
+ if (ec_heal_open_others(heal))
+ {
+ ec_open(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN,
+ ec_heal_source_open_cbk, heal, &heal->loc, O_RDONLY, heal->fd,
+ NULL);
+ }
+}
+
+void ec_heal_reopen_fd(ec_heal_t * heal)
+{
+ inode_t * inode;
+ fd_t * fd;
+ ec_fd_t * ctx;
+ uintptr_t mask;
+ int32_t flags;
+
+ inode = heal->loc.inode;
+
+ LOCK(&inode->lock);
+
+ list_for_each_entry(fd, &inode->fd_list, inode_list)
+ {
+ ctx = ec_fd_get(fd, heal->xl);
+ if ((ctx != NULL) && (ctx->loc.inode != NULL))
+ {
+ mask = heal->bad & ~ctx->open;
+ if (mask != 0)
+ {
+ UNLOCK(&inode->lock);
+
+ if (heal->iatt.ia_type == IA_IFDIR)
+ {
+ ec_opendir(heal->fop->frame, heal->xl, mask,
+ EC_MINIMUM_ONE, ec_heal_reopen_cbk, NULL,
+ &heal->loc, fd, NULL);
+ }
+ else
+ {
+ flags = ctx->flags & ~O_TRUNC;
+ if ((flags & O_ACCMODE) == O_WRONLY)
+ {
+ flags &= ~O_ACCMODE;
+ flags |= O_RDWR;
+ }
+
+ ec_open(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE,
+ ec_heal_reopen_cbk, NULL, &heal->loc, flags, fd,
+ NULL);
+ }
+
+ LOCK(&inode->lock);
+ }
+ }
+ }
+
+ UNLOCK(&inode->lock);
+}
+
+int32_t ec_heal_writev_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iatt * prebuf, struct iatt * postbuf,
+ dict_t * xdata)
+{
+ ec_trace("WRITE_CBK", cookie, "ret=%d, errno=%d", op_ret, op_errno);
+
+ ec_heal_update(cookie, 0);
+
+ return 0;
+}
+
+int32_t ec_heal_readv_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iovec * vector, int32_t count,
+ struct iatt * stbuf, struct iobref * iobref,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+ ec_heal_t * heal = fop->data;
+
+ ec_trace("READ_CBK", fop, "ret=%d, errno=%d", op_ret, op_errno);
+
+ ec_heal_avoid(fop);
+
+ if (op_ret > 0)
+ {
+ ec_writev(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
+ ec_heal_writev_cbk, heal, heal->fd, vector, count,
+ heal->offset, 0, iobref, NULL);
+ }
+ else
+ {
+ heal->done = 1;
+ }
+
+ return 0;
+}
+
+void ec_heal_data(ec_heal_t * heal)
+{
+ ec_trace("DATA", heal->fop, "good=%lX, bad=%lX", heal->good, heal->bad);
+
+ if ((heal->good != 0) && (heal->bad != 0) &&
+ (heal->iatt.ia_type == IA_IFREG))
+ {
+ ec_readv(heal->fop->frame, heal->xl, heal->good, EC_MINIMUM_MIN,
+ ec_heal_readv_cbk, heal, heal->fd, heal->size, heal->offset,
+ 0, NULL);
+ }
+}
+
+void ec_heal_dispatch(ec_heal_t * heal)
+{
+ ec_fop_data_t * fop = heal->fop;
+ ec_cbk_data_t * cbk;
+ inode_t * inode;
+ ec_inode_t * ctx;
+ int32_t error;
+
+ inode = heal->loc.inode;
+
+ LOCK(&inode->lock);
+
+ ctx = __ec_inode_get(inode, heal->xl);
+ if (ctx != NULL)
+ {
+ ctx->bad &= ~heal->good;
+ ctx->heal = NULL;
+ }
+
+ fop->data = NULL;
+
+ UNLOCK(&inode->lock);
+
+ error = fop->error;
+
+ cbk = ec_cbk_data_allocate(fop->frame, heal->xl, fop, fop->id, 0,
+ error == 0 ? 0 : -1, error);
+ if (cbk != NULL)
+ {
+ cbk->uintptr[0] = heal->available;
+ cbk->uintptr[1] = heal->good;
+ cbk->uintptr[2] = heal->bad;
+
+ ec_combine(cbk, NULL);
+
+ fop->answer = cbk;
+ }
+ else if (error == 0)
+ {
+ error = ENOMEM;
+ }
+
+ if (heal->lookup != NULL)
+ {
+ ec_fop_data_release(heal->lookup);
+ }
+ if (heal->fd != NULL)
+ {
+ fd_unref(heal->fd);
+ }
+ GF_FREE(heal->symlink);
+ loc_wipe(&heal->loc);
+
+ LOCK_DESTROY(&heal->lock);
+
+ GF_FREE(heal);
+
+ ec_fop_set_error(heal->fop, error);
+}
+
+void ec_wind_heal(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_cbk_data_t * cbk;
+ ec_heal_t * heal = fop->data;
+
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ cbk = ec_cbk_data_allocate(fop->req_frame, fop->xl, fop, EC_FOP_HEAL, idx,
+ fop->error == 0 ? 0 : -1, fop->error);
+ if (cbk != NULL)
+ {
+ cbk->uintptr[0] = heal->available;
+ cbk->uintptr[1] = heal->good;
+ cbk->uintptr[2] = heal->bad;
+
+ ec_combine(cbk, NULL);
+ }
+
+ ec_complete(fop);
+}
+
+int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+ ec_heal_t * heal = fop->data;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ ec_owner_set(fop->frame, fop->frame->root);
+
+ fop->error = ec_heal_init(fop);
+ if (fop->error != 0)
+ {
+ return EC_STATE_REPORT;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_heal_entrylk(fop->data, ENTRYLK_LOCK);
+
+ return EC_STATE_HEAL_ENTRY_LOOKUP;
+
+ case EC_STATE_HEAL_ENTRY_LOOKUP:
+ ec_lookup(fop->frame, heal->xl, fop->mask, EC_MINIMUM_MIN,
+ ec_heal_entry_lookup_cbk, heal, &heal->loc, NULL);
+
+ return EC_STATE_HEAL_ENTRY_PREPARE;
+
+ case EC_STATE_HEAL_ENTRY_PREPARE:
+ ec_heal_prepare(heal);
+
+ return EC_STATE_HEAL_PRE_INODELK_LOCK;
+
+ case EC_STATE_HEAL_PRE_INODELK_LOCK:
+ ec_heal_inodelk(heal, F_WRLCK, 0, 0, 0);
+
+ return EC_STATE_HEAL_PRE_INODE_LOOKUP;
+
+ case EC_STATE_HEAL_PRE_INODE_LOOKUP:
+ ec_heal_lookup(heal);
+
+ return EC_STATE_HEAL_XATTRIBUTES_REMOVE;
+
+ case EC_STATE_HEAL_XATTRIBUTES_REMOVE:
+ ec_heal_removexattr_others(heal);
+
+ return EC_STATE_HEAL_XATTRIBUTES_SET;
+
+ case EC_STATE_HEAL_XATTRIBUTES_SET:
+ ec_heal_setxattr_others(heal);
+
+ return EC_STATE_HEAL_ATTRIBUTES;
+
+ case EC_STATE_HEAL_ATTRIBUTES:
+ ec_heal_attr(heal);
+
+ return EC_STATE_HEAL_OPEN;
+
+ case EC_STATE_HEAL_OPEN:
+ ec_heal_open(heal);
+
+ return EC_STATE_HEAL_REOPEN_FD;
+
+ case EC_STATE_HEAL_REOPEN_FD:
+ ec_heal_reopen_fd(heal);
+
+ return EC_STATE_HEAL_UNLOCK;
+
+ case -EC_STATE_HEAL_XATTRIBUTES_REMOVE:
+ case -EC_STATE_HEAL_XATTRIBUTES_SET:
+ case -EC_STATE_HEAL_ATTRIBUTES:
+ case -EC_STATE_HEAL_OPEN:
+ case -EC_STATE_HEAL_REOPEN_FD:
+ case -EC_STATE_HEAL_UNLOCK:
+ case EC_STATE_HEAL_UNLOCK:
+ ec_heal_inodelk(heal, F_UNLCK, 0, 0, 0);
+
+ case -EC_STATE_HEAL_ENTRY_PREPARE:
+ case -EC_STATE_HEAL_PRE_INODELK_LOCK:
+ case -EC_STATE_HEAL_PRE_INODE_LOOKUP:
+ ec_heal_entrylk(heal, ENTRYLK_UNLOCK);
+
+ if (ec_heal_needs_data_rebuild(heal))
+ {
+ return EC_STATE_HEAL_DATA_LOCK;
+ }
+
+ return EC_STATE_HEAL_DISPATCH;
+
+ case EC_STATE_HEAL_DATA_LOCK:
+ if (heal->done)
+ {
+ return EC_STATE_HEAL_POST_INODELK_LOCK;
+ }
+
+ ec_heal_inodelk(heal, F_WRLCK, 1, heal->offset, heal->size);
+
+ return EC_STATE_HEAL_DATA_COPY;
+
+ case EC_STATE_HEAL_DATA_COPY:
+ ec_heal_data(heal);
+
+ return EC_STATE_HEAL_DATA_UNLOCK;
+
+ case -EC_STATE_HEAL_DATA_COPY:
+ case -EC_STATE_HEAL_DATA_UNLOCK:
+ case EC_STATE_HEAL_DATA_UNLOCK:
+ ec_heal_inodelk(heal, F_UNLCK, 1, heal->offset, heal->size);
+
+ heal->offset += heal->size;
+
+ return EC_STATE_HEAL_DATA_LOCK;
+
+ case EC_STATE_HEAL_POST_INODELK_LOCK:
+ ec_heal_inodelk(heal, F_WRLCK, 1, 0, 0);
+
+ return EC_STATE_HEAL_POST_INODE_LOOKUP;
+
+ case EC_STATE_HEAL_POST_INODE_LOOKUP:
+ ec_heal_lookup(heal);
+
+ return EC_STATE_HEAL_SETATTR;
+
+ case EC_STATE_HEAL_SETATTR:
+ ec_setattr(heal->fop->frame, heal->xl, heal->bad, EC_MINIMUM_ONE,
+ ec_heal_setattr_cbk, heal, &heal->loc, &heal->iatt,
+ GF_SET_ATTR_MODE | GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME, NULL);
+
+ return EC_STATE_HEAL_POST_INODELK_UNLOCK;
+
+ case -EC_STATE_HEAL_SETATTR:
+ case -EC_STATE_HEAL_POST_INODELK_UNLOCK:
+ case EC_STATE_HEAL_POST_INODELK_UNLOCK:
+ ec_heal_inodelk(heal, F_UNLCK, 1, 0, 0);
+
+ return EC_STATE_HEAL_DISPATCH;
+
+ case -EC_STATE_HEAL_POST_INODELK_LOCK:
+ case -EC_STATE_HEAL_POST_INODE_LOOKUP:
+ case -EC_STATE_HEAL_ENTRY_LOOKUP:
+ case -EC_STATE_HEAL_DATA_LOCK:
+ case -EC_STATE_HEAL_DISPATCH:
+ case EC_STATE_HEAL_DISPATCH:
+ ec_heal_dispatch(heal);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.heal != NULL)
+ {
+ fop->cbks.heal(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->uintptr[0],
+ cbk->uintptr[1], cbk->uintptr[2],
+ cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fheal != NULL)
+ {
+ fop->cbks.fheal(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->uintptr[0],
+ cbk->uintptr[1], cbk->uintptr[2],
+ cbk->xdata);
+ }
+ }
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.heal != NULL)
+ {
+ fop->cbks.heal(fop->req_frame, fop, fop->xl, -1,
+ fop->error, 0, 0, 0, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fheal != NULL)
+ {
+ fop->cbks.fheal(fop->req_frame, fop, fop->xl, -1,
+ fop->error, 0, 0, 0, NULL);
+ }
+ }
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_heal(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_heal_cbk_t func, void * data, loc_t * loc,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .heal = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(HEAL) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(NULL, this, EC_FOP_HEAL,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_heal, ec_manager_heal, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, 0, 0, 0, NULL);
+ }
+}
+
+/* FOP: fheal */
+
+void ec_wind_fheal(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_cbk_data_t * cbk;
+ ec_heal_t * heal = fop->data;
+
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ cbk = ec_cbk_data_allocate(fop->req_frame, fop->xl, fop, EC_FOP_FHEAL, idx,
+ fop->error == 0 ? 0 : -1, fop->error);
+ if (cbk != NULL)
+ {
+ cbk->uintptr[0] = heal->available;
+ cbk->uintptr[1] = heal->good;
+ cbk->uintptr[2] = heal->bad;
+
+ ec_combine(cbk, NULL);
+ }
+
+ ec_complete(fop);
+}
+
+void ec_fheal(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fheal_cbk_t func, void * data, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_fd_t * ctx = ec_fd_get(fd, this);
+
+ if ((ctx != NULL) && (ctx->loc.inode != NULL))
+ {
+ gf_log("ec", GF_LOG_DEBUG, "FHEAL ctx: flags=%X, open=%lX, bad=%lX",
+ ctx->flags, ctx->open, ctx->bad);
+ ec_heal(frame, this, target, minimum, func, data, &ctx->loc, xdata);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c
new file mode 100644
index 00000000000..771faf5b013
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-helpers.c
@@ -0,0 +1,594 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <libgen.h>
+
+#include "byte-order.h"
+
+#include "ec-mem-types.h"
+#include "ec-fops.h"
+#include "ec-helpers.h"
+
+#define BACKEND_D_OFF_BITS 63
+#define PRESENT_D_OFF_BITS 63
+
+#define ONE 1ULL
+#define MASK (~0ULL)
+#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
+#define BACKEND_MASK (MASK >> (64 - BACKEND_D_OFF_BITS))
+
+#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
+#define SHIFT_BITS (max(0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
+
+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_log("ec", GF_LOG_TRACE, "%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->bad, ec->nodes), msg);
+
+ if (ret >= 0)
+ {
+ free(msg);
+ }
+}
+
+uint64_t ec_itransform(ec_t * ec, int32_t idx, uint64_t offset)
+{
+ int32_t bits;
+
+ if (offset == -1ULL)
+ {
+ return -1ULL;
+ }
+
+ bits = ec->bits_for_nodes;
+ if ((offset & ~(PRESENT_MASK >> (bits + 1))) != 0)
+ {
+ return TOP_BIT | ((offset >> SHIFT_BITS) & (MASK << bits)) | idx;
+ }
+
+ return (offset * ec->nodes) + idx;
+}
+
+uint64_t ec_deitransform(ec_t * ec, int32_t * idx, uint64_t offset)
+{
+ uint64_t mask = 0;
+
+ if ((offset & TOP_BIT) != 0)
+ {
+ mask = MASK << ec->bits_for_nodes;
+
+ *idx = offset & ~mask;
+ return ((offset & ~TOP_BIT) & mask) << SHIFT_BITS;
+ }
+
+ *idx = offset % ec->nodes;
+
+ return offset / ec->nodes;
+}
+
+int32_t ec_bits_count(uint64_t n)
+{
+ n -= (n >> 1) & 0x5555555555555555ULL;
+ n = ((n >> 2) & 0x3333333333333333ULL) + (n & 0x3333333333333333ULL);
+ n = (n + (n >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ n += n >> 8;
+ n += n >> 16;
+ n += n >> 32;
+
+ return n & 0xFF;
+}
+
+int32_t ec_bits_index(uint64_t n)
+{
+ return ffsll(n) - 1;
+}
+
+int32_t ec_bits_consume(uint64_t * n)
+{
+ uint64_t tmp;
+
+ tmp = *n;
+ tmp &= -tmp;
+ *n ^= tmp;
+
+ return ffsll(tmp) - 1;
+}
+
+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_dict_set_number(dict_t * dict, char * key, uint64_t value)
+{
+ uint64_t * ptr;
+
+ ptr = GF_MALLOC(sizeof(value), gf_common_mt_char);
+ if (ptr == NULL)
+ {
+ return -1;
+ }
+
+ *ptr = hton64(value);
+
+ return dict_set_bin(dict, key, ptr, sizeof(value));
+}
+
+int32_t ec_dict_del_number(dict_t * dict, char * key, uint64_t * value)
+{
+ void * ptr;
+ int32_t len;
+
+ if ((dict == NULL) || (dict_get_ptr_and_len(dict, key, &ptr, &len) != 0) ||
+ (len != sizeof(uint64_t)))
+ {
+ return -1;
+ }
+
+ *value = ntoh64(*(uint64_t *)ptr);
+
+ dict_del(dict, key);
+
+ return 0;
+}
+
+int32_t ec_loc_gfid_check(xlator_t * xl, uuid_t dst, uuid_t src)
+{
+ if (uuid_is_null(src))
+ {
+ return 1;
+ }
+
+ if (uuid_is_null(dst))
+ {
+ uuid_copy(dst, src);
+
+ return 1;
+ }
+
+ if (uuid_compare(dst, src) != 0)
+ {
+ gf_log(xl->name, GF_LOG_WARNING, "Mismatching GFID's in loc");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_loc_parent(xlator_t * xl, loc_t * loc, loc_t * parent, char ** name)
+{
+ char * str = NULL;
+ int32_t error = 0;
+
+ memset(parent, 0, sizeof(loc_t));
+
+ if (loc->path == NULL)
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "inode path missing in loc_t: %p", loc->parent);
+
+ return EINVAL;
+ }
+
+ if (loc->parent == NULL)
+ {
+ if ((loc->inode == NULL) || !__is_root_gfid(loc->inode->gfid) ||
+ (strcmp(loc->path, "/") != 0))
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Parent inode missing for "
+ "loc_t (path=%s, name=%s)",
+ loc->path, loc->name);
+
+ return EINVAL;
+ }
+
+ if (loc_copy(parent, loc) != 0)
+ {
+ return ENOMEM;
+ }
+
+ parent->name = NULL;
+
+ if (name != NULL)
+ {
+ *name = NULL;
+ }
+ }
+ else
+ {
+ if (uuid_is_null(loc->parent->gfid) && (uuid_is_null(loc->pargfid)))
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Invalid parent inode "
+ "(path=%s, name=%s)",
+ loc->path, loc->name);
+
+ return EINVAL;
+ }
+ uuid_copy(parent->gfid, loc->pargfid);
+
+ str = gf_strdup(loc->path);
+ if (str == NULL)
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Unable to duplicate path "
+ "'%s'", str);
+
+ return ENOMEM;
+ }
+ if (name != NULL)
+ {
+ *name = gf_strdup(basename(str));
+ if (*name == NULL)
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Unable to get basename "
+ "of '%s'", str);
+
+ error = ENOMEM;
+
+ goto out;
+ }
+ strcpy(str, loc->path);
+ }
+ parent->path = gf_strdup(dirname(str));
+ if (parent->path == NULL)
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Unable to get dirname of "
+ "'%s'", str);
+
+ error = ENOMEM;
+
+ goto out;
+ }
+ parent->name = strrchr(parent->path, '/');
+ if (parent->name == NULL)
+ {
+ gf_log(xl->name, GF_LOG_ERROR, "Invalid path name (%s)",
+ parent->path);
+
+ error = EINVAL;
+
+ goto out;
+ }
+ parent->name++;
+ parent->inode = inode_ref(loc->parent);
+ }
+
+ if ((loc->inode == NULL) ||
+ ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid))
+ {
+ parent = NULL;
+ }
+
+out:
+ GF_FREE(str);
+
+ if (parent != NULL)
+ {
+ loc_wipe(parent);
+ }
+
+ return error;
+}
+
+int32_t ec_loc_prepare(xlator_t * xl, loc_t * loc, inode_t * inode,
+ struct iatt * iatt)
+{
+ if ((inode != NULL) && (loc->inode != inode))
+ {
+ if (loc->inode != NULL)
+ {
+ inode_unref(loc->inode);
+ }
+ loc->inode = inode_ref(inode);
+
+ uuid_copy(loc->gfid, inode->gfid);
+ }
+ else if (loc->inode != NULL)
+ {
+ if (!ec_loc_gfid_check(xl, loc->gfid, loc->inode->gfid))
+ {
+ return 0;
+ }
+ }
+
+ if (iatt != NULL)
+ {
+ if (!ec_loc_gfid_check(xl, loc->gfid, iatt->ia_gfid))
+ {
+ return 0;
+ }
+ }
+
+ if (loc->parent != NULL)
+ {
+ if (!ec_loc_gfid_check(xl, loc->pargfid, loc->parent->gfid))
+ {
+ return 0;
+ }
+
+ }
+
+ if (uuid_is_null(loc->gfid))
+ {
+ gf_log(xl->name, GF_LOG_WARNING, "GFID not available for inode");
+ }
+
+ return 1;
+}
+
+int32_t ec_loc_from_fd(xlator_t * xl, loc_t * loc, fd_t * fd)
+{
+ ec_fd_t * ctx;
+
+ memset(loc, 0, sizeof(*loc));
+
+ ctx = ec_fd_get(fd, xl);
+ if (ctx != NULL)
+ {
+ if (loc_copy(loc, &ctx->loc) != 0)
+ {
+ return 0;
+ }
+ }
+
+ if (ec_loc_prepare(xl, loc, fd->inode, NULL))
+ {
+ return 1;
+ }
+
+ loc_wipe(loc);
+
+ return 0;
+}
+
+int32_t ec_loc_from_loc(xlator_t * xl, loc_t * dst, loc_t * src)
+{
+ memset(dst, 0, sizeof(*dst));
+
+ if (loc_copy(dst, src) != 0)
+ {
+ return 0;
+ }
+
+ if (ec_loc_prepare(xl, dst, NULL, NULL))
+ {
+ return 1;
+ }
+
+ loc_wipe(dst);
+
+ return 0;
+}
+
+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)
+{
+ frame->root->lk_owner.len = owner->len;
+ memcpy(frame->root->lk_owner.data, owner->data, owner->len);
+}
+
+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));
+
+ 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;
+ }
+
+ 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)
+{
+ ec_fd_t * ctx = NULL;
+ uint64_t value = 0;
+
+ if ((__fd_ctx_get(fd, xl, &value) != 0) || (value == 0))
+ {
+ ctx = GF_MALLOC(sizeof(*ctx), ec_mt_ec_fd_t);
+ if (ctx != NULL)
+ {
+ memset(ctx, 0, sizeof(*ctx));
+
+ value = (uint64_t)(uintptr_t)ctx;
+ if (__fd_ctx_set(fd, xl, value) != 0)
+ {
+ GF_FREE(ctx);
+
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ ctx = (ec_fd_t *)(uintptr_t)value;
+ }
+
+ 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;
+}
+
+size_t ec_adjust_offset(ec_t * ec, off_t * offset, int32_t scale)
+{
+ size_t head, tmp;
+
+ tmp = *offset;
+ head = tmp % ec->stripe_size;
+ tmp -= head;
+ if (scale)
+ {
+ tmp /= ec->fragments;
+ }
+
+ *offset = tmp;
+
+ return head;
+}
+
+size_t ec_adjust_size(ec_t * ec, size_t size, int32_t scale)
+{
+ size += ec->stripe_size - 1;
+ size -= size % ec->stripe_size;
+ if (scale)
+ {
+ size /= ec->fragments;
+ }
+
+ return size;
+}
diff --git a/xlators/cluster/ec/src/ec-helpers.h b/xlators/cluster/ec/src/ec-helpers.h
new file mode 100644
index 00000000000..6625ade4b08
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-helpers.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_HELPERS_H__
+#define __EC_HELPERS_H__
+
+#include "ec-data.h"
+
+const char * ec_bin(char * str, size_t size, uint64_t value, int32_t digits);
+const char * ec_fop_name(int32_t id);
+void ec_trace(const char * event, ec_fop_data_t * fop, const char * fmt, ...);
+uint64_t ec_itransform(ec_t * ec, int32_t idx, uint64_t offset);
+uint64_t ec_deitransform(ec_t * ec, int32_t * idx, uint64_t offset);
+int32_t ec_bits_count(uint64_t n);
+int32_t ec_bits_index(uint64_t n);
+int32_t ec_bits_consume(uint64_t * n);
+size_t ec_iov_copy_to(void * dst, struct iovec * vector, int32_t count,
+ off_t offset, size_t size);
+
+int32_t ec_dict_set_number(dict_t * dict, char * key, uint64_t value);
+int32_t ec_dict_del_number(dict_t * dict, char * key, uint64_t * value);
+
+int32_t ec_loc_parent(xlator_t * xl, loc_t * loc, loc_t * parent,
+ char ** name);
+int32_t ec_loc_prepare(xlator_t * xl, loc_t * loc, inode_t * inode,
+ struct iatt * iatt);
+
+int32_t ec_loc_from_fd(xlator_t * xl, loc_t * loc, fd_t * fd);
+int32_t ec_loc_from_loc(xlator_t * xl, loc_t * dst, loc_t * src);
+
+void ec_owner_set(call_frame_t * frame, void * owner);
+void ec_owner_copy(call_frame_t * frame, gf_lkowner_t * owner);
+
+ec_inode_t * __ec_inode_get(inode_t * inode, xlator_t * xl);
+ec_inode_t * ec_inode_get(inode_t * inode, xlator_t * xl);
+ec_fd_t * __ec_fd_get(fd_t * fd, xlator_t * xl);
+ec_fd_t * ec_fd_get(fd_t * fd, xlator_t * xl);
+
+size_t ec_adjust_offset(ec_t * ec, off_t * offset, int32_t scale);
+size_t ec_adjust_size(ec_t * ec, size_t size, int32_t scale);
+
+#endif /* __EC_HELPERS_H__ */
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
new file mode 100644
index 00000000000..b1db9c9fbb7
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-inode-read.c
@@ -0,0 +1,1764 @@
+
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+/* FOP: access */
+
+int32_t ec_access_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
+ {
+ if (fop->cbks.access != NULL)
+ {
+ fop->cbks.access(fop->req_frame, fop, this, op_ret, op_errno,
+ xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_access(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_access_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->access,
+ &fop->loc[0], fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_access(ec_fop_data_t * fop, int32_t state)
+{
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_DISPATCH:
+ ec_dispatch_one(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case -EC_STATE_REPORT:
+ if (fop->cbks.access != NULL)
+ {
+ fop->cbks.access(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL);
+ }
+
+ case EC_STATE_REPORT:
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_access(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_access_cbk_t func, void * data,
+ loc_t * loc, int32_t mask, dict_t * xdata)
+{
+ ec_cbk_t callback = { .access = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(ACCESS) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_ACCESS, 0, target, minimum,
+ ec_wind_access, ec_manager_access, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = mask;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: getxattr */
+
+int32_t ec_combine_getxattr(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_dict_compare(dst->dict, src->dict))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching dictionary in "
+ "answers of 'GF_FOP_GETXATTR'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_getxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * dict,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_GETXATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (dict != NULL)
+ {
+ cbk->dict = dict_ref(dict);
+ if (cbk->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_getxattr);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_getxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_getxattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->getxattr,
+ &fop->loc[0], fop->str[0], fop->xdata);
+}
+
+int32_t ec_manager_getxattr(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA) ||
+ ((cbk->op_ret >= 0) && !ec_dict_combine(cbk,
+ EC_COMBINE_DICT)))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ if (cbk->xdata != NULL)
+ {
+ dict_del(cbk->xdata, EC_XATTR_SIZE);
+ dict_del(cbk->xdata, EC_XATTR_VERSION);
+ }
+ if (cbk->dict != NULL)
+ {
+ dict_del(cbk->dict, EC_XATTR_SIZE);
+ dict_del(cbk->dict, EC_XATTR_VERSION);
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.getxattr != NULL)
+ {
+ fop->cbks.getxattr(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->dict, cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.getxattr != NULL)
+ {
+ fop->cbks.getxattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_getxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_getxattr_cbk_t func, void * data,
+ loc_t * loc, const char * name, dict_t * xdata)
+{
+ ec_cbk_t callback = { .getxattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(GETXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_GETXATTR,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_getxattr, ec_manager_getxattr, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (name != NULL)
+ {
+ fop->str[0] = gf_strdup(name);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: fgetxattr */
+
+int32_t ec_fgetxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * dict,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FGETXATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (dict != NULL)
+ {
+ cbk->dict = dict_ref(dict);
+ if (cbk->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_getxattr);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fgetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fgetxattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fgetxattr,
+ fop->fd, fop->str[0], fop->xdata);
+}
+
+void ec_fgetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fgetxattr_cbk_t func, void * data,
+ fd_t * fd, const char * name, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fgetxattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FGETXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FGETXATTR,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fgetxattr, ec_manager_getxattr,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (name != NULL)
+ {
+ fop->str[0] = gf_strdup(name);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: open */
+
+int32_t ec_combine_open(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (dst->fd != src->fd)
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching fd in answers "
+ "of 'GF_FOP_OPEN': %p <-> %p",
+ dst->fd, src->fd);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_open_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_OPEN, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (fd != NULL)
+ {
+ cbk->fd = fd_ref(fd);
+ if (cbk->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_open);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_open(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_open_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->open,
+ &fop->loc[0], fop->int32, fop->fd, fop->xdata);
+}
+
+int32_t ec_manager_open(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+ ec_fd_t * ctx;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ LOCK(&fop->fd->lock);
+
+ ctx = __ec_fd_get(fop->fd, fop->xl);
+ if ((ctx == NULL) || !ec_loc_from_loc(fop->xl, &ctx->loc,
+ &fop->loc[0]))
+ {
+ UNLOCK(&fop->fd->lock);
+
+ fop->error = EIO;
+
+ return EC_STATE_REPORT;
+ }
+
+ if (ctx->flags == 0)
+ {
+ ctx->flags = fop->int32;
+ }
+
+ UNLOCK(&fop->fd->lock);
+
+ if ((fop->int32 & O_ACCMODE) == O_WRONLY)
+ {
+ fop->int32 &= ~O_ACCMODE;
+ fop->int32 |= O_RDWR;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_loc_prepare(fop->xl, &fop->loc[0], cbk->fd->inode,
+ NULL);
+
+ LOCK(&fop->fd->lock);
+
+ ctx = __ec_fd_get(fop->fd, fop->xl);
+ if (ctx != NULL)
+ {
+ ctx->open |= cbk->mask;
+ }
+
+ UNLOCK(&fop->fd->lock);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.open != NULL)
+ {
+ fop->cbks.open(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->fd, cbk->xdata);
+ }
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.open != NULL)
+ {
+ fop->cbks.open(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL);
+ }
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_open(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_open_cbk_t func, void * data, loc_t * loc,
+ int32_t flags, fd_t * fd, dict_t * xdata)
+{
+ ec_cbk_t callback = { .open = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(OPEN) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_OPEN, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_open, ec_manager_open,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = flags;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: readlink */
+
+int32_t ec_combine_readlink(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_READLINK'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_readlink_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, const char * path,
+ struct iatt * buf, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ if (op_ret > 0)
+ {
+ ec_iatt_rebuild(fop->xl->private, buf, 1, 1);
+ }
+
+ if (!ec_dispatch_one_retry(fop, idx, op_ret, op_errno))
+ {
+ if (fop->cbks.readlink != NULL)
+ {
+ fop->cbks.readlink(fop->req_frame, fop, this, op_ret, op_errno,
+ path, buf, xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_readlink(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_readlink_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->readlink,
+ &fop->loc[0], fop->size, fop->xdata);
+}
+
+int32_t ec_manager_readlink(ec_fop_data_t * fop, int32_t state)
+{
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_DISPATCH:
+ ec_dispatch_one(fop);
+
+ return EC_STATE_REPORT;
+
+ case -EC_STATE_REPORT:
+ if (fop->cbks.readlink != NULL)
+ {
+ fop->cbks.readlink(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL, NULL);
+ }
+
+ case EC_STATE_REPORT:
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_readlink(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readlink_cbk_t func, void * data,
+ loc_t * loc, size_t size, dict_t * xdata)
+{
+ ec_cbk_t callback = { .readlink = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(READLINK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_READLINK, 0, target,
+ minimum, ec_wind_readlink, ec_manager_readlink,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->size = size;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: readv */
+
+int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
+{
+ ec_cbk_data_t * ans = NULL;
+ struct iobuf_pool * pool = NULL;
+ struct iobref * iobref = NULL;
+ struct iobuf * iobuf = NULL;
+ uint8_t * ptr = NULL, * buff = NULL;
+ size_t fsize = 0, size = 0, max = 0, slice = 0;
+ int32_t i = 0;
+
+ if (cbk->op_ret < 0)
+ {
+ goto out;
+ }
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+
+ if (cbk->op_ret > 0)
+ {
+ struct iovec vector[cbk->int32 * cbk->count];
+ uint8_t * blocks[cbk->count];
+ uint32_t values[cbk->count];
+
+ fsize = cbk->op_ret;
+ size = fsize * ec->fragments;
+ ptr = GF_MALLOC(size + EC_BUFFER_ALIGN_SIZE - 1, gf_common_mt_char);
+ if (ptr == NULL)
+ {
+ goto out;
+ }
+ buff = GF_ALIGN_BUF(ptr, EC_BUFFER_ALIGN_SIZE);
+
+ iobref = iobref_new();
+ if (iobref == NULL)
+ {
+ goto out;
+ }
+
+ for (i = 0, ans = cbk; ans != NULL; i++, ans = ans->next)
+ {
+ values[i] = ans->idx;
+ blocks[i] = buff;
+ buff += ec_iov_copy_to(buff, ans->vector, ans->int32, 0, fsize);
+ }
+
+ pool = fop->xl->ctx->iobuf_pool;
+ max = iobpool_default_pagesize(pool) / ec->stripe_size;
+ max *= ec->fragment_size;
+ i = 0;
+ do
+ {
+ iobuf = iobuf_get(pool);
+ if (iobuf == NULL)
+ {
+ goto out;
+ }
+ if (iobref_add(iobref, iobuf) != 0)
+ {
+ goto out;
+ }
+
+ slice = fsize;
+ if (slice > max)
+ {
+ slice = max;
+ }
+ fsize -= slice;
+
+ vector[i].iov_base = iobuf->ptr;
+ vector[i].iov_len = ec_method_decode(slice, ec->fragments, values,
+ blocks, iobuf->ptr);
+ i++;
+
+ iobuf_unref(iobuf);
+ } while (fsize > 0);
+
+ GF_FREE(ptr);
+ ptr = NULL;
+
+ vector[0].iov_base += fop->head;
+ vector[0].iov_len -= fop->head;
+
+ max = fop->offset * ec->fragments + size;
+ if (max > cbk->iatt[0].ia_size)
+ {
+ max = cbk->iatt[0].ia_size;
+ }
+ max -= fop->offset * ec->fragments + fop->head;
+ if (max > fop->user_size)
+ {
+ max = fop->user_size;
+ }
+ size -= fop->head;
+ while (size > max)
+ {
+ if (size - max >= vector[i - 1].iov_len)
+ {
+ size -= vector[--i].iov_len;
+ }
+ else
+ {
+ vector[i - 1].iov_len -= size - max;
+ size = max;
+ }
+ }
+
+ cbk->op_ret = size;
+ cbk->int32 = i;
+
+ iobref_unref(cbk->buffers);
+ cbk->buffers = iobref;
+
+ GF_FREE(cbk->vector);
+ cbk->vector = iov_dup(vector, i);
+ if (cbk->vector == NULL)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+
+ return 0;
+ }
+ }
+
+ return 1;
+
+out:
+ if (iobuf != NULL)
+ {
+ iobuf_unref(iobuf);
+ }
+ if (iobref != NULL)
+ {
+ iobref_unref(iobref);
+ }
+ GF_FREE(ptr);
+
+ return 0;
+}
+
+int32_t ec_combine_readv(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_vector_compare(dst->vector, dst->int32, src->vector, src->int32))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching vector in "
+ "answers of 'GF_FOP_READ'");
+
+ return 0;
+ }
+
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_READ'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_readv_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iovec * vector,
+ int32_t count, struct iatt * stbuf,
+ struct iobref * iobref, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ ec_t * ec = this->private;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_READ, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ cbk->int32 = count;
+
+ if (count > 0)
+ {
+ cbk->vector = iov_dup(vector, count);
+ if (cbk->vector == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a "
+ "vector list.");
+
+ goto out;
+ }
+ cbk->int32 = count;
+ }
+ if (stbuf != NULL)
+ {
+ cbk->iatt[0] = *stbuf;
+ }
+ if (iobref != NULL)
+ {
+ cbk->buffers = iobref_ref(iobref);
+ if (cbk->buffers == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "buffer.");
+
+ goto out;
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0))
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+
+ ec_combine(cbk, ec_combine_readv);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_readv(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_readv_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->readv, fop->fd,
+ fop->size, fop->offset, fop->uint32, fop->xdata);
+}
+
+int32_t ec_manager_readv(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ fop->user_size = fop->size;
+ fop->head = ec_adjust_offset(fop->xl->private, &fop->offset, 1);
+ fop->size = ec_adjust_size(fop->xl->private, fop->size + fop->head,
+ 1);
+
+ case EC_STATE_LOCK:
+ ec_lock_fd(fop, fop->fd);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_min(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1,
+ cbk->count);
+
+ if (!ec_readv_rebuild(fop->xl->private, fop, cbk))
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.readv != NULL)
+ {
+ fop->cbks.readv(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, cbk->vector, cbk->int32,
+ &cbk->iatt[0], cbk->buffers, cbk->xdata);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.readv != NULL)
+ {
+ fop->cbks.readv(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, 0, NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_readv(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_readv_cbk_t func, void * data, fd_t * fd,
+ size_t size, off_t offset, uint32_t flags, dict_t * xdata)
+{
+ ec_cbk_t callback = { .readv = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(READ) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_READ, EC_FLAG_UPDATE_FD,
+ target, minimum, ec_wind_readv,
+ ec_manager_readv, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->size = size;
+ fop->offset = offset;
+ fop->uint32 = flags;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, 0, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: stat */
+
+int32_t ec_combine_stat(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 1))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_STAT'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_stat_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * buf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_STAT, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_stat);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_stat(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_stat_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->stat,
+ &fop->loc[0], fop->xdata);
+}
+
+int32_t ec_manager_stat(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 1,
+ cbk->count);
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.stat != NULL)
+ {
+ fop->cbks.stat(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fstat != NULL)
+ {
+ fop->cbks.fstat(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], cbk->xdata);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.stat != NULL)
+ {
+ fop->cbks.stat(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fstat != NULL)
+ {
+ fop->cbks.fstat(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_stat(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_stat_cbk_t func, void * data, loc_t * loc,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .stat = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(STAT) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_STAT,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_stat, ec_manager_stat, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
+
+/* FOP: fstat */
+
+int32_t ec_fstat_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * buf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSTAT, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (buf != NULL)
+ {
+ cbk->iatt[0] = *buf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_stat);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fstat(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fstat_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fstat, fop->fd,
+ fop->xdata);
+}
+
+void ec_fstat(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fstat_cbk_t func, void * data, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .fstat = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FSTAT) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FSTAT,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fstat, ec_manager_stat, callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
new file mode 100644
index 00000000000..a3c4ae5d8f2
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-inode-write.c
@@ -0,0 +1,2235 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+/* FOP: removexattr */
+
+int32_t ec_removexattr_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_REMOVEXATTR, idx,
+ op_ret, op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_removexattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_removexattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->removexattr,
+ &fop->loc[0], fop->str[0], fop->xdata);
+}
+
+int32_t ec_manager_removexattr(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.removexattr != NULL)
+ {
+ fop->cbks.removexattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fremovexattr != NULL)
+ {
+ fop->cbks.fremovexattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ cbk->xdata);
+ }
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.removexattr != NULL)
+ {
+ fop->cbks.removexattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fremovexattr != NULL)
+ {
+ fop->cbks.fremovexattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_removexattr_cbk_t func, void * data,
+ loc_t * loc, const char * name, dict_t * xdata)
+{
+ ec_cbk_t callback = { .removexattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(REMOVEXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_REMOVEXATTR,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_removexattr, ec_manager_removexattr,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (name != NULL)
+ {
+ fop->str[0] = gf_strdup(name);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: fremovexattr */
+
+int32_t ec_fremovexattr_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FREMOVEXATTR, idx,
+ op_ret, op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fremovexattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fremovexattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fremovexattr,
+ fop->fd, fop->str[0], fop->xdata);
+}
+
+void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fremovexattr_cbk_t func, void * data,
+ fd_t * fd, const char * name, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fremovexattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FREMOVEXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FREMOVEXATTR,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fremovexattr, ec_manager_removexattr,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (name != NULL)
+ {
+ fop->str[0] = gf_strdup(name);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: setattr */
+
+int32_t ec_combine_setattr(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_SETATTR'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_setattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt * preop_stbuf, struct iatt * postop_stbuf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SETATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (preop_stbuf != NULL)
+ {
+ cbk->iatt[0] = *preop_stbuf;
+ }
+ if (postop_stbuf != NULL)
+ {
+ cbk->iatt[1] = *postop_stbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_setattr);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_setattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_setattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->setattr,
+ &fop->loc[0], &fop->iatt, fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_setattr(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
+ cbk->count);
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+ cbk->iatt[1].ia_size = fop->pre_size;
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.setattr != NULL)
+ {
+ fop->cbks.setattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fsetattr != NULL)
+ {
+ fop->cbks.fsetattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.setattr != NULL)
+ {
+ fop->cbks.setattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fsetattr != NULL)
+ {
+ fop->cbks.fsetattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_setattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_setattr_cbk_t func, void * data,
+ loc_t * loc, struct iatt * stbuf, int32_t valid,
+ dict_t * xdata)
+{
+ ec_cbk_t callback = { .setattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(SETATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_SETATTR,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_setattr, ec_manager_setattr, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = valid;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (stbuf != NULL)
+ {
+ fop->iatt = *stbuf;
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: fsetattr */
+
+int32_t ec_fsetattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt * preop_stbuf, struct iatt * postop_stbuf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSETATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (preop_stbuf != NULL)
+ {
+ cbk->iatt[0] = *preop_stbuf;
+ }
+ if (postop_stbuf != NULL)
+ {
+ cbk->iatt[1] = *postop_stbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_setattr);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fsetattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fsetattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fsetattr,
+ fop->fd, &fop->iatt, fop->int32, fop->xdata);
+}
+
+void ec_fsetattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsetattr_cbk_t func, void * data,
+ fd_t * fd, struct iatt * stbuf, int32_t valid, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fsetattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FSETATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETATTR,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fsetattr, ec_manager_setattr, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = valid;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (stbuf != NULL)
+ {
+ fop->iatt = *stbuf;
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: setxattr */
+
+int32_t ec_setxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_SETXATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_setxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_setxattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->setxattr,
+ &fop->loc[0], fop->dict, fop->int32, fop->xdata);
+}
+
+int32_t ec_manager_setxattr(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.setxattr != NULL)
+ {
+ fop->cbks.setxattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fsetxattr != NULL)
+ {
+ fop->cbks.fsetxattr(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ cbk->xdata);
+ }
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.setxattr != NULL)
+ {
+ fop->cbks.setxattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fsetxattr != NULL)
+ {
+ fop->cbks.fsetxattr(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_setxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_setxattr_cbk_t func, void * data,
+ loc_t * loc, dict_t * dict, int32_t flags, dict_t * xdata)
+{
+ ec_cbk_t callback = { .setxattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(SETXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_SETXATTR,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_setxattr, ec_manager_setxattr, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = flags;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (dict != NULL)
+ {
+ fop->dict = dict_ref(dict);
+ if (fop->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: fsetxattr */
+
+int32_t ec_fsetxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FSETXATTR, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, NULL);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fsetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fsetxattr_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fsetxattr,
+ fop->fd, fop->dict, fop->int32, fop->xdata);
+}
+
+void ec_fsetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fsetxattr_cbk_t func, void * data,
+ fd_t * fd, dict_t * dict, int32_t flags, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fsetxattr = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FSETXATTR) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FSETXATTR,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fsetxattr, ec_manager_setxattr,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = flags;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (dict != NULL)
+ {
+ fop->dict = dict_ref(dict);
+ if (fop->dict == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: truncate */
+
+int32_t ec_truncate_write(ec_fop_data_t * fop, uintptr_t mask)
+{
+ ec_t * ec = fop->xl->private;
+ struct iobref * iobref = NULL;
+ struct iobuf * iobuf = NULL;
+ struct iovec vector;
+ int32_t ret = 0;
+
+ iobref = iobref_new();
+ if (iobref == NULL)
+ {
+ goto out;
+ }
+ iobuf = iobuf_get(fop->xl->ctx->iobuf_pool);
+ if (iobuf == NULL)
+ {
+ goto out;
+ }
+ if (iobref_add(iobref, iobuf) != 0)
+ {
+ goto out;
+ }
+
+ vector.iov_base = iobuf->ptr;
+ vector.iov_len = fop->offset * ec->fragments - fop->user_size;
+
+ memset(iobuf->ptr, 0, vector.iov_len);
+
+ iobuf = NULL;
+
+ ec_writev(fop->frame, fop->xl, mask, fop->minimum, NULL, NULL, fop->fd,
+ &vector, 1, fop->user_size, 0, iobref, NULL);
+
+ ret = 1;
+
+out:
+ if (iobuf != NULL)
+ {
+ iobuf_unref(iobuf);
+ }
+ if (iobref != NULL)
+ {
+ iobref_unref(iobref);
+ }
+
+ return ret;
+}
+
+int32_t ec_truncate_open_cbk(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ fd_t * fd, dict_t * xdata)
+{
+ ec_fop_data_t * fop = cookie;
+
+ if (op_ret >= 0)
+ {
+ if (!ec_truncate_write(fop->parent, fop->answer->mask))
+ {
+ fop->error = EIO;
+ }
+ }
+
+ return 0;
+}
+
+int32_t ec_truncate_clean(ec_fop_data_t * fop)
+{
+ ec_fd_t * ctx;
+
+ if (fop->fd == NULL)
+ {
+ fop->fd = fd_create(fop->loc[0].inode, fop->frame->root->pid);
+ if (fop->fd == NULL)
+ {
+ return 0;
+ }
+ ctx = ec_fd_get(fop->fd, fop->xl);
+ if ((ctx == NULL) || (loc_copy(&ctx->loc, &fop->loc[0]) != 0))
+ {
+ return 0;
+ }
+
+ ctx->flags = O_RDWR;
+
+ ec_open(fop->frame, fop->xl, fop->answer->mask, fop->minimum,
+ ec_truncate_open_cbk, fop, &fop->loc[0], O_RDWR, fop->fd,
+ NULL);
+
+ return 1;
+ }
+ else
+ {
+ return ec_truncate_write(fop, fop->answer->mask);
+ }
+}
+
+int32_t ec_combine_truncate(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_TRUNCATE'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_truncate_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * prebuf,
+ struct iatt * postbuf, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_TRUNCATE, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (prebuf != NULL)
+ {
+ cbk->iatt[0] = *prebuf;
+ }
+ if (postbuf != NULL)
+ {
+ cbk->iatt[1] = *postbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_truncate);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_truncate(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_truncate_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->truncate,
+ &fop->loc[0], fop->offset, fop->xdata);
+}
+
+int32_t ec_manager_truncate(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ fop->user_size = fop->offset;
+ fop->offset = ec_adjust_size(fop->xl->private, fop->offset, 1);
+
+ case EC_STATE_LOCK:
+ ec_lock_inode(fop, &fop->loc[0]);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
+ cbk->count);
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+ cbk->iatt[1].ia_size = fop->user_size;
+ fop->post_size = fop->user_size;
+ if ((fop->pre_size > fop->post_size) &&
+ (fop->user_size != fop->offset))
+ {
+ if (!ec_truncate_clean(fop))
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.truncate != NULL)
+ {
+ fop->cbks.truncate(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.ftruncate != NULL)
+ {
+ fop->cbks.ftruncate(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno,
+ &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.truncate != NULL)
+ {
+ fop->cbks.truncate(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.ftruncate != NULL)
+ {
+ fop->cbks.ftruncate(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL, NULL, NULL);
+ }
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_truncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_truncate_cbk_t func, void * data,
+ loc_t * loc, off_t offset, dict_t * xdata)
+{
+ ec_cbk_t callback = { .truncate = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(TRUNCATE) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_TRUNCATE,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_truncate, ec_manager_truncate, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->offset = offset;
+
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: ftruncate */
+
+int32_t ec_ftruncate_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt * prebuf, struct iatt * postbuf,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FTRUNCATE, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (prebuf != NULL)
+ {
+ cbk->iatt[0] = *prebuf;
+ }
+ if (postbuf != NULL)
+ {
+ cbk->iatt[1] = *postbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ ec_combine(cbk, ec_combine_truncate);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_ftruncate(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_ftruncate_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->ftruncate,
+ fop->fd, fop->offset, fop->xdata);
+}
+
+void ec_ftruncate(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_ftruncate_cbk_t func, void * data,
+ fd_t * fd, off_t offset, dict_t * xdata)
+{
+ ec_cbk_t callback = { .ftruncate = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FTRUNCATE) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FTRUNCATE,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_ftruncate, ec_manager_truncate,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->offset = offset;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
+
+/* FOP: writev */
+
+int32_t ec_writev_init(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+ struct iobref * iobref = NULL;
+ struct iobuf * iobuf = NULL;
+ void * ptr = NULL;
+ ec_fd_t * ctx;
+
+ ctx = ec_fd_get(fop->fd, fop->xl);
+ if (ctx != NULL)
+ {
+ if ((ctx->flags & O_ACCMODE) == O_RDONLY)
+ {
+ return EBADF;
+ }
+ }
+
+ fop->user_size = iov_length(fop->vector, fop->int32);
+ fop->head = ec_adjust_offset(ec, &fop->offset, 0);
+ fop->size = ec_adjust_size(ec, fop->user_size + fop->head, 0);
+
+ iobref = iobref_new();
+ if (iobref == NULL)
+ {
+ goto out;
+ }
+ iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, fop->size);
+ if (iobuf == NULL)
+ {
+ goto out;
+ }
+ if (iobref_add(iobref, iobuf) != 0)
+ {
+ goto out;
+ }
+
+ ptr = iobuf->ptr + fop->head;
+ ec_iov_copy_to(ptr, fop->vector, fop->int32, 0, fop->user_size);
+
+ fop->vector[0].iov_base = iobuf->ptr;
+ fop->vector[0].iov_len = fop->size;
+
+ iobuf_unref(iobuf);
+
+ iobref_unref(fop->buffers);
+ fop->buffers = iobref;
+
+ return 0;
+
+out:
+ if (iobuf != NULL)
+ {
+ iobuf_unref(iobuf);
+ }
+ if (iobref != NULL)
+ {
+ iobref_unref(iobref);
+ }
+
+ return EIO;
+}
+
+int32_t ec_writev_merge_tail(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iovec * vector, int32_t count,
+ struct iatt * stbuf, struct iobref * iobref,
+ dict_t * xdata)
+{
+ ec_t * ec = this->private;
+ ec_fop_data_t * fop = frame->local;
+ size_t size, base, tmp;
+
+ if (op_ret >= 0)
+ {
+ tmp = 0;
+ size = fop->size - fop->user_size - fop->head;
+ base = ec->stripe_size - size;
+ if (op_ret > base)
+ {
+ tmp = min(op_ret - base, size);
+ ec_iov_copy_to(fop->vector[0].iov_base + fop->size - size, vector,
+ count, base, tmp);
+
+ size -= tmp;
+ }
+
+ if (size > 0)
+ {
+ memset(fop->vector[0].iov_base + fop->size - size, 0, size);
+ }
+ }
+
+ return 0;
+}
+
+int32_t ec_writev_merge_head(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iovec * vector, int32_t count,
+ struct iatt * stbuf, struct iobref * iobref,
+ dict_t * xdata)
+{
+ ec_t * ec = this->private;
+ ec_fop_data_t * fop = frame->local;
+ size_t size, base;
+
+ if (op_ret >= 0)
+ {
+ size = fop->head;
+ base = 0;
+
+ if (op_ret > 0)
+ {
+ base = min(op_ret, size);
+ ec_iov_copy_to(fop->vector[0].iov_base, vector, count, 0, base);
+
+ size -= base;
+ }
+
+ if (size > 0)
+ {
+ memset(fop->vector[0].iov_base + base, 0, size);
+ }
+
+ size = fop->size - fop->user_size - fop->head;
+ if ((size > 0) && (fop->size == ec->stripe_size))
+ {
+ ec_writev_merge_tail(frame, cookie, this, op_ret, op_errno, vector,
+ count, stbuf, iobref, xdata);
+ }
+ }
+
+ return 0;
+}
+
+void ec_writev_start(ec_fop_data_t * fop)
+{
+ ec_t * ec = fop->xl->private;
+ size_t tail;
+
+ if (fop->head > 0)
+ {
+ ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, ec_writev_merge_head,
+ NULL, fop->fd, ec->stripe_size, fop->offset, 0, NULL);
+ }
+ tail = fop->size - fop->user_size - fop->head;
+ if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size)))
+ {
+ if (fop->pre_size > fop->offset + fop->head + fop->user_size)
+ {
+ ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN,
+ ec_writev_merge_tail, NULL, fop->fd, ec->stripe_size,
+ fop->offset + fop->size - ec->stripe_size, 0, NULL);
+ }
+ else
+ {
+ memset(fop->vector[0].iov_base + fop->size - tail, 0, tail);
+ }
+ }
+}
+
+int32_t ec_combine_writev(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_iatt_combine(dst->iatt, src->iatt, 2))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching iatt in "
+ "answers of 'GF_FOP_WRITE'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_writev_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt * prebuf,
+ struct iatt * postbuf, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ ec_t * ec = this->private;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_WRITE, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ if (op_ret >= 0)
+ {
+ if (prebuf != NULL)
+ {
+ cbk->iatt[0] = *prebuf;
+ }
+ if (postbuf != NULL)
+ {
+ cbk->iatt[1] = *postbuf;
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ if ((op_ret > 0) && ((op_ret % ec->fragment_size) != 0))
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+
+ ec_combine(cbk, ec_combine_writev);
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_writev(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ struct iovec vector[fop->int32];
+ struct iobuf_pool * pool = NULL;
+ struct iobref * iobref = NULL;
+ struct iobuf * iobuf = NULL;
+ uint8_t * ptr = NULL;
+ ssize_t size = 0, slice = 0, pagesize = 0, maxsize = 0;
+ int32_t count = 0;
+
+ pool = fop->xl->ctx->iobuf_pool;
+
+ pagesize = iobpool_default_pagesize(pool);
+ maxsize = pagesize * ec->fragments;
+
+ iobref = iobref_new();
+ if (iobref == NULL)
+ {
+ goto out;
+ }
+
+ ptr = fop->vector[0].iov_base;
+ size = fop->vector[0].iov_len;
+
+ count = 0;
+ while (size > 0)
+ {
+ iobuf = iobuf_get(pool);
+ if (iobuf == NULL)
+ {
+ goto out;
+ }
+ if (iobref_add(iobref, iobuf) != 0)
+ {
+ goto out;
+ }
+
+ slice = size;
+ if (slice > maxsize)
+ {
+ slice = maxsize;
+ }
+
+ ec_method_encode(slice, ec->fragments, idx, ptr, iobuf->ptr);
+ ptr += slice;
+
+ vector[count].iov_base = iobuf->ptr;
+ vector[count].iov_len = slice / ec->fragments;
+ count++;
+
+ iobuf_unref(iobuf);
+
+ size -= slice;
+ }
+
+ STACK_WIND_COOKIE(fop->frame, ec_writev_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->writev,
+ fop->fd, vector, count, fop->offset / ec->fragments,
+ fop->uint32, iobref, fop->xdata);
+
+ iobref_unref(iobref);
+
+ return;
+
+out:
+ if (iobuf != NULL)
+ {
+ iobuf_unref(iobuf);
+ }
+ if (iobref != NULL)
+ {
+ iobref_unref(iobref);
+ }
+
+ ec_writev_cbk(fop->frame, (void *)(uintptr_t)idx, fop->xl, -1, EIO, NULL,
+ NULL, NULL);
+}
+
+int32_t ec_manager_writev(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ fop->error = ec_writev_init(fop);
+ if (fop->error != 0)
+ {
+ return EC_STATE_REPORT;
+ }
+
+ case EC_STATE_LOCK:
+ ec_lock_fd(fop, fop->fd);
+
+ return EC_STATE_GET_SIZE_AND_VERSION;
+
+ case EC_STATE_GET_SIZE_AND_VERSION:
+ ec_get_size_version(fop);
+
+ return EC_STATE_DISPATCH;
+
+ case EC_STATE_DISPATCH:
+ ec_writev_start(fop);
+
+ return EC_STATE_WRITE_START;
+
+ case EC_STATE_WRITE_START:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if (cbk != NULL)
+ {
+ if (!ec_dict_combine(cbk, EC_COMBINE_XDATA))
+ {
+ if (cbk->op_ret >= 0)
+ {
+ cbk->op_ret = -1;
+ cbk->op_errno = EIO;
+ }
+ }
+ if (cbk->op_ret < 0)
+ {
+ ec_fop_set_error(fop, cbk->op_errno);
+ }
+ else
+ {
+ ec_t * ec = fop->xl->private;
+ size_t size;
+
+ ec_iatt_rebuild(fop->xl->private, cbk->iatt, 2,
+ cbk->count);
+
+ size = fop->offset + fop->head + fop->user_size;
+ if (size > fop->pre_size)
+ {
+ fop->post_size = size;
+ }
+
+ cbk->iatt[0].ia_size = fop->pre_size;
+ cbk->iatt[1].ia_size = fop->post_size;
+
+ cbk->op_ret *= ec->fragments;
+ if (cbk->op_ret < fop->head)
+ {
+ cbk->op_ret = 0;
+ }
+ else
+ {
+ cbk->op_ret -= fop->head;
+ }
+ if (cbk->op_ret > fop->user_size)
+ {
+ cbk->op_ret = fop->user_size;
+ }
+ }
+ }
+ else
+ {
+ ec_fop_set_error(fop, EIO);
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.writev != NULL)
+ {
+ fop->cbks.writev(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->iatt[0], &cbk->iatt[1],
+ cbk->xdata);
+ }
+
+ if (cbk->op_ret >= 0)
+ {
+ return EC_STATE_UPDATE_SIZE_AND_VERSION;
+ }
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_LOCK:
+ case -EC_STATE_GET_SIZE_AND_VERSION:
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.writev != NULL)
+ {
+ fop->cbks.writev(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL, NULL);
+ }
+
+ return EC_STATE_UNLOCK;
+
+ case EC_STATE_UPDATE_SIZE_AND_VERSION:
+ ec_update_size_version(fop);
+
+ return EC_STATE_UNLOCK;
+
+ case -EC_STATE_UPDATE_SIZE_AND_VERSION:
+ case -EC_STATE_UNLOCK:
+ case EC_STATE_UNLOCK:
+ ec_unlock(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_writev(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_writev_cbk_t func, void * data, fd_t * fd,
+ struct iovec * vector, int32_t count, off_t offset,
+ uint32_t flags, struct iobref * iobref, dict_t * xdata)
+{
+ ec_cbk_t callback = { .writev = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(WRITE) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_WRITE,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_writev, ec_manager_writev, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = count;
+ fop->offset = offset;
+ fop->uint32 = flags;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (count > 0)
+ {
+ fop->vector = iov_dup(vector, count);
+ if (fop->vector == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a "
+ "vector list.");
+
+ goto out;
+ }
+ fop->int32 = count;
+ }
+ if (iobref != NULL)
+ {
+ fop->buffers = iobref_ref(iobref);
+ if (fop->buffers == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "buffer.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-locks.c b/xlators/cluster/ec/src/ec-locks.c
new file mode 100644
index 00000000000..96c1e03f8ec
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-locks.c
@@ -0,0 +1,1292 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xlator.h"
+#include "defaults.h"
+
+#include "ec-helpers.h"
+#include "ec-common.h"
+#include "ec-combine.h"
+#include "ec-method.h"
+#include "ec-fops.h"
+
+#define EC_LOCK_MODE_NONE 0
+#define EC_LOCK_MODE_INC 1
+#define EC_LOCK_MODE_ALL 2
+
+int32_t ec_lock_check(ec_fop_data_t * fop, ec_cbk_data_t ** cbk,
+ uintptr_t * mask)
+{
+ ec_t * ec = fop->xl->private;
+ ec_cbk_data_t * ans = NULL;
+ uintptr_t locked = 0, notlocked = 0;
+ int32_t error = -1;
+
+ list_for_each_entry(ans, &fop->cbk_list, list)
+ {
+ if (ans->op_ret >= 0)
+ {
+ if (locked != 0)
+ {
+ error = EIO;
+ }
+ locked |= ans->mask;
+ *cbk = ans;
+ }
+ else if (ans->op_errno == EAGAIN)
+ {
+ notlocked |= ans->mask;
+ }
+ }
+
+ if (error == -1)
+ {
+ if (ec_bits_count(locked | notlocked) >= ec->fragments)
+ {
+ if (notlocked == 0)
+ {
+ fop->answer = *cbk;
+
+ ec_update_bad(fop, locked);
+
+ error = 0;
+ }
+ else
+ {
+ if (fop->uint32 == EC_LOCK_MODE_NONE)
+ {
+ error = EAGAIN;
+ }
+ else
+ {
+ fop->uint32 = EC_LOCK_MODE_INC;
+ }
+ }
+ }
+ else
+ {
+ error = EIO;
+ }
+ }
+
+ *mask = locked;
+
+ return error;
+}
+
+uintptr_t ec_lock_handler(ec_fop_data_t * fop, ec_cbk_data_t * cbk,
+ ec_combine_f combine)
+{
+ uintptr_t mask = 0;
+
+ if (fop->uint32 == EC_LOCK_MODE_INC)
+ {
+ if (cbk->op_ret < 0)
+ {
+ if (cbk->op_errno != ENOTCONN)
+ {
+ mask = fop->mask & ~fop->remaining & ~cbk->mask;
+ fop->remaining = 0;
+ }
+ }
+ }
+
+ ec_combine(cbk, combine);
+
+ return mask;
+}
+
+int32_t ec_lock_unlocked(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata)
+{
+ if (op_ret < 0)
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an entry/inode");
+ }
+
+ return 0;
+}
+
+int32_t ec_lock_lk_unlocked(call_frame_t * frame, void * cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct gf_flock * flock, dict_t * xdata)
+{
+ if (op_ret < 0)
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Failed to unlock an lk");
+ }
+
+ return 0;
+}
+
+/* FOP: entrylk */
+
+int32_t ec_entrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_ENTRYLK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ uintptr_t mask;
+
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ mask = ec_lock_handler(fop, cbk, NULL);
+ if (mask != 0)
+ {
+ ec_entrylk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked,
+ NULL, fop->str[0], &fop->loc[0], fop->str[1],
+ ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_entrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_entrylk_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->entrylk,
+ fop->str[0], &fop->loc[0], fop->str[1], fop->entrylk_cmd,
+ fop->entrylk_type, fop->xdata);
+}
+
+int32_t ec_manager_entrylk(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ if (fop->entrylk_cmd == ENTRYLK_LOCK)
+ {
+ fop->uint32 = EC_LOCK_MODE_ALL;
+ fop->entrylk_cmd = ENTRYLK_LOCK_NB;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if ((cbk == NULL) ||
+ ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
+ {
+ uintptr_t mask;
+
+ fop->error = ec_lock_check(fop, &cbk, &mask);
+ if (fop->error != 0)
+ {
+ if (mask != 0)
+ {
+ if (fop->fd == NULL)
+ {
+ ec_entrylk(fop->req_frame, fop->xl, mask, 1,
+ ec_lock_unlocked, NULL, fop->str[0],
+ &fop->loc[0], fop->str[1],
+ ENTRYLK_UNLOCK, fop->entrylk_type,
+ fop->xdata);
+ }
+ else
+ {
+ ec_fentrylk(fop->req_frame, fop->xl, mask, 1,
+ ec_lock_unlocked, NULL, fop->str[0],
+ fop->fd, fop->str[1], ENTRYLK_UNLOCK,
+ fop->entrylk_type, fop->xdata);
+ }
+ }
+ if (fop->error > 0)
+ {
+ return EC_STATE_REPORT;
+ }
+
+ fop->error = 0;
+
+ fop->entrylk_cmd = ENTRYLK_LOCK;
+
+ ec_dispatch_inc(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+ }
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.entrylk != NULL)
+ {
+ fop->cbks.entrylk(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fentrylk != NULL)
+ {
+ fop->cbks.fentrylk(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->xdata);
+ }
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.entrylk != NULL)
+ {
+ fop->cbks.entrylk(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.fentrylk != NULL)
+ {
+ fop->cbks.fentrylk(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_entrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_entrylk_cbk_t func, void * data,
+ const char * volume, loc_t * loc, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
+{
+ ec_cbk_t callback = { .entrylk = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(ENTRYLK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_ENTRYLK,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_entrylk, ec_manager_entrylk, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->entrylk_cmd = cmd;
+ fop->entrylk_type = type;
+
+ if (volume != NULL)
+ {
+ fop->str[0] = gf_strdup(volume);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (basename != NULL)
+ {
+ fop->str[1] = gf_strdup(basename);
+ if (fop->str[1] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: fentrylk */
+
+int32_t ec_fentrylk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FENTRYLK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ uintptr_t mask;
+
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ mask = ec_lock_handler(fop, cbk, NULL);
+ if (mask != 0)
+ {
+ ec_fentrylk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked,
+ NULL, fop->str[0], fop->fd, fop->str[1],
+ ENTRYLK_UNLOCK, fop->entrylk_type, fop->xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_fentrylk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_fentrylk_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->fentrylk,
+ fop->str[0], fop->fd, fop->str[1], fop->entrylk_cmd,
+ fop->entrylk_type, fop->xdata);
+}
+
+void ec_fentrylk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_fentrylk_cbk_t func, void * data,
+ const char * volume, fd_t * fd, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
+{
+ ec_cbk_t callback = { .fentrylk = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FENTRYLK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FENTRYLK,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_fentrylk, ec_manager_entrylk, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->entrylk_cmd = cmd;
+ fop->entrylk_type = type;
+
+ if (volume != NULL)
+ {
+ fop->str[0] = gf_strdup(volume);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (basename != NULL)
+ {
+ fop->str[1] = gf_strdup(basename);
+ if (fop->str[1] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: inodelk */
+
+int32_t ec_inodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_INODELK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ uintptr_t mask;
+
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ mask = ec_lock_handler(fop, cbk, NULL);
+ if (mask != 0)
+ {
+ ec_t * ec = fop->xl->private;
+ struct gf_flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = fop->flock.l_whence;
+ flock.l_start = fop->flock.l_start * ec->fragments;
+ flock.l_len = fop->flock.l_len * ec->fragments;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ ec_inodelk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked,
+ NULL, fop->str[0], &fop->loc[0], F_SETLK, &flock,
+ fop->xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_inodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_inodelk_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->inodelk,
+ fop->str[0], &fop->loc[0], fop->int32, &fop->flock,
+ fop->xdata);
+}
+
+int32_t ec_manager_inodelk(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ fop->flock.l_len += ec_adjust_offset(fop->xl->private,
+ &fop->flock.l_start, 1);
+ fop->flock.l_len = ec_adjust_size(fop->xl->private,
+ fop->flock.l_len, 1);
+ if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK))
+ {
+ fop->uint32 = EC_LOCK_MODE_ALL;
+ fop->int32 = F_SETLK;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if ((cbk == NULL) ||
+ ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
+ {
+ uintptr_t mask;
+
+ fop->error = ec_lock_check(fop, &cbk, &mask);
+ if (fop->error != 0)
+ {
+ if (mask != 0)
+ {
+ ec_t * ec = fop->xl->private;
+ struct gf_flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = fop->flock.l_whence;
+ flock.l_start = fop->flock.l_start * ec->fragments;
+ flock.l_len = fop->flock.l_len * ec->fragments;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ if (fop->fd == NULL)
+ {
+ ec_inodelk(fop->req_frame, fop->xl, mask, 1,
+ ec_lock_unlocked, NULL, fop->str[0],
+ &fop->loc[0], F_SETLK, &flock,
+ fop->xdata);
+ }
+ else
+ {
+ ec_finodelk(fop->req_frame, fop->xl, mask, 1,
+ ec_lock_unlocked, NULL, fop->str[0],
+ fop->fd, F_SETLK, &flock, fop->xdata);
+ }
+ }
+ if (fop->error > 0)
+ {
+ return EC_STATE_REPORT;
+ }
+
+ fop->error = 0;
+
+ fop->int32 = F_SETLKW;
+
+ ec_dispatch_inc(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+ }
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.inodelk != NULL)
+ {
+ fop->cbks.inodelk(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->xdata);
+ }
+ }
+ else
+ {
+ if (fop->cbks.finodelk != NULL)
+ {
+ fop->cbks.finodelk(fop->req_frame, fop, fop->xl,
+ cbk->op_ret, cbk->op_errno, cbk->xdata);
+ }
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->fd == NULL)
+ {
+ if (fop->cbks.inodelk != NULL)
+ {
+ fop->cbks.inodelk(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+ else
+ {
+ if (fop->cbks.finodelk != NULL)
+ {
+ fop->cbks.finodelk(fop->req_frame, fop, fop->xl, -1,
+ fop->error, NULL);
+ }
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_inodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_inodelk_cbk_t func, void * data,
+ const char * volume, loc_t * loc, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata)
+{
+ ec_cbk_t callback = { .inodelk = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(INODELK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_INODELK,
+ EC_FLAG_UPDATE_LOC_INODE, target, minimum,
+ ec_wind_inodelk, ec_manager_inodelk, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = cmd;
+
+ if (volume != NULL)
+ {
+ fop->str[0] = gf_strdup(volume);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (loc != NULL)
+ {
+ if (loc_copy(&fop->loc[0], loc) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to copy a location.");
+
+ goto out;
+ }
+ }
+ if (flock != NULL)
+ {
+ fop->flock.l_type = flock->l_type;
+ fop->flock.l_whence = flock->l_whence;
+ fop->flock.l_start = flock->l_start;
+ fop->flock.l_len = flock->l_len;
+ fop->flock.l_pid = flock->l_pid;
+ fop->flock.l_owner.len = flock->l_owner.len;
+ if (flock->l_owner.len > 0)
+ {
+ memcpy(fop->flock.l_owner.data, flock->l_owner.data,
+ flock->l_owner.len);
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: finodelk */
+
+int32_t ec_finodelk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_FINODELK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ uintptr_t mask;
+
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ mask = ec_lock_handler(fop, cbk, NULL);
+ if (mask != 0)
+ {
+ ec_t * ec = fop->xl->private;
+ struct gf_flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = fop->flock.l_whence;
+ flock.l_start = fop->flock.l_start * ec->fragments;
+ flock.l_len = fop->flock.l_len * ec->fragments;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ ec_finodelk(fop->req_frame, fop->xl, mask, 1, ec_lock_unlocked,
+ NULL, fop->str[0], fop->fd, F_SETLK, &flock,
+ fop->xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_finodelk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_finodelk_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->finodelk,
+ fop->str[0], fop->fd, fop->int32, &fop->flock,
+ fop->xdata);
+}
+
+void ec_finodelk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_finodelk_cbk_t func, void * data,
+ const char * volume, fd_t * fd, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata)
+{
+ ec_cbk_t callback = { .finodelk = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(FINODELK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_FINODELK,
+ EC_FLAG_UPDATE_FD_INODE, target, minimum,
+ ec_wind_finodelk, ec_manager_inodelk, callback,
+ data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = cmd;
+
+ if (volume != NULL)
+ {
+ fop->str[0] = gf_strdup(volume);
+ if (fop->str[0] == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to duplicate a string.");
+
+ goto out;
+ }
+ }
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (flock != NULL)
+ {
+ fop->flock.l_type = flock->l_type;
+ fop->flock.l_whence = flock->l_whence;
+ fop->flock.l_start = flock->l_start;
+ fop->flock.l_len = flock->l_len;
+ fop->flock.l_pid = flock->l_pid;
+ fop->flock.l_owner.len = flock->l_owner.len;
+ if (flock->l_owner.len > 0)
+ {
+ memcpy(fop->flock.l_owner.data, flock->l_owner.data,
+ flock->l_owner.len);
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL);
+ }
+}
+
+/* FOP: lk */
+
+int32_t ec_combine_lk(ec_fop_data_t * fop, ec_cbk_data_t * dst,
+ ec_cbk_data_t * src)
+{
+ if (!ec_flock_compare(&dst->flock, &src->flock))
+ {
+ gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching lock in "
+ "answers of 'GF_FOP_LK'");
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int32_t ec_lk_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock * flock,
+ dict_t * xdata)
+{
+ ec_fop_data_t * fop = NULL;
+ ec_cbk_data_t * cbk = NULL;
+ int32_t idx = (int32_t)(uintptr_t)cookie;
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = frame->local;
+
+ ec_trace("CBK", fop, "idx=%d, frame=%p, op_ret=%d, op_errno=%d", idx,
+ frame, op_ret, op_errno);
+
+ cbk = ec_cbk_data_allocate(frame, this, fop, GF_FOP_LK, idx, op_ret,
+ op_errno);
+ if (cbk != NULL)
+ {
+ uintptr_t mask;
+
+ if (op_ret >= 0)
+ {
+ if (flock != NULL)
+ {
+ cbk->flock.l_type = flock->l_type;
+ cbk->flock.l_whence = flock->l_whence;
+ cbk->flock.l_start = flock->l_start;
+ cbk->flock.l_len = flock->l_len;
+ cbk->flock.l_pid = flock->l_pid;
+ cbk->flock.l_owner.len = flock->l_owner.len;
+ if (flock->l_owner.len > 0)
+ {
+ memcpy(cbk->flock.l_owner.data, flock->l_owner.data,
+ flock->l_owner.len);
+ }
+ }
+ }
+ if (xdata != NULL)
+ {
+ cbk->xdata = dict_ref(xdata);
+ if (cbk->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ mask = ec_lock_handler(fop, cbk, ec_combine_lk);
+ if (mask != 0)
+ {
+ ec_t * ec = fop->xl->private;
+ struct gf_flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = fop->flock.l_whence;
+ flock.l_start = fop->flock.l_start * ec->fragments;
+ flock.l_len = fop->flock.l_len * ec->fragments;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ ec_lk(fop->req_frame, fop->xl, mask, 1, ec_lock_lk_unlocked, NULL,
+ fop->fd, F_SETLK, &flock, fop->xdata);
+ }
+ }
+
+out:
+ if (fop != NULL)
+ {
+ ec_complete(fop);
+ }
+
+ return 0;
+}
+
+void ec_wind_lk(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+{
+ ec_trace("WIND", fop, "idx=%d", idx);
+
+ STACK_WIND_COOKIE(fop->frame, ec_lk_cbk, (void *)(uintptr_t)idx,
+ ec->xl_list[idx], ec->xl_list[idx]->fops->lk, fop->fd,
+ fop->int32, &fop->flock, fop->xdata);
+}
+
+int32_t ec_manager_lk(ec_fop_data_t * fop, int32_t state)
+{
+ ec_cbk_data_t * cbk;
+
+ switch (state)
+ {
+ case EC_STATE_INIT:
+ fop->flock.l_len += ec_adjust_offset(fop->xl->private,
+ &fop->flock.l_start, 1);
+ fop->flock.l_len = ec_adjust_size(fop->xl->private,
+ fop->flock.l_len, 1);
+ if ((fop->int32 == F_SETLKW) && (fop->flock.l_type != F_UNLCK))
+ {
+ fop->uint32 = EC_LOCK_MODE_ALL;
+ fop->int32 = F_SETLK;
+ }
+
+ case EC_STATE_DISPATCH:
+ ec_dispatch_all(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+
+ case EC_STATE_PREPARE_ANSWER:
+ cbk = fop->answer;
+ if ((cbk == NULL) ||
+ ((cbk->op_ret < 0) && (cbk->op_errno == EAGAIN)))
+ {
+ uintptr_t mask;
+
+ fop->error = ec_lock_check(fop, &cbk, &mask);
+ if (fop->error != 0)
+ {
+ if (mask != 0)
+ {
+ ec_t * ec = fop->xl->private;
+ struct gf_flock flock;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = fop->flock.l_whence;
+ flock.l_start = fop->flock.l_start * ec->fragments;
+ flock.l_len = fop->flock.l_len * ec->fragments;
+ flock.l_pid = 0;
+ flock.l_owner.len = 0;
+
+ ec_lk(fop->req_frame, fop->xl, mask, 1,
+ ec_lock_lk_unlocked, NULL, fop->fd, F_SETLK,
+ &flock, fop->xdata);
+ }
+ if (fop->error > 0)
+ {
+ return EC_STATE_REPORT;
+ }
+
+ fop->error = 0;
+
+ fop->int32 = F_SETLKW;
+
+ ec_dispatch_inc(fop);
+
+ return EC_STATE_PREPARE_ANSWER;
+ }
+ }
+
+ return EC_STATE_REPORT;
+
+ case EC_STATE_REPORT:
+ cbk = fop->answer;
+
+ GF_ASSERT(cbk != NULL);
+
+ if (fop->cbks.lk != NULL)
+ {
+ fop->cbks.lk(fop->req_frame, fop, fop->xl, cbk->op_ret,
+ cbk->op_errno, &cbk->flock, cbk->xdata);
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ case -EC_STATE_DISPATCH:
+ case -EC_STATE_PREPARE_ANSWER:
+ case -EC_STATE_REPORT:
+ GF_ASSERT(fop->error != 0);
+
+ if (fop->cbks.lk != NULL)
+ {
+ fop->cbks.lk(fop->req_frame, fop, fop->xl, -1, fop->error,
+ NULL, NULL);
+ }
+
+ ec_wait_winds(fop);
+
+ return EC_STATE_END;
+
+ default:
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Unhandled state %d for %s",
+ state, ec_fop_name(fop->id));
+
+ return EC_STATE_END;
+ }
+}
+
+void ec_lk(call_frame_t * frame, xlator_t * this, uintptr_t target,
+ int32_t minimum, fop_lk_cbk_t func, void * data, fd_t * fd,
+ int32_t cmd, struct gf_flock * flock, dict_t * xdata)
+{
+ ec_cbk_t callback = { .lk = func };
+ ec_fop_data_t * fop = NULL;
+ int32_t error = EIO;
+
+ gf_log("ec", GF_LOG_TRACE, "EC(LK) %p", frame);
+
+ VALIDATE_OR_GOTO(this, out);
+ GF_VALIDATE_OR_GOTO(this->name, frame, out);
+ GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+
+ fop = ec_fop_data_allocate(frame, this, GF_FOP_LK, EC_FLAG_UPDATE_FD_INODE,
+ target, minimum, ec_wind_lk, ec_manager_lk,
+ callback, data);
+ if (fop == NULL)
+ {
+ goto out;
+ }
+
+ fop->int32 = cmd;
+
+ if (fd != NULL)
+ {
+ fop->fd = fd_ref(fd);
+ if (fop->fd == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "file descriptor.");
+
+ goto out;
+ }
+ }
+ if (flock != NULL)
+ {
+ fop->flock.l_type = flock->l_type;
+ fop->flock.l_whence = flock->l_whence;
+ fop->flock.l_start = flock->l_start;
+ fop->flock.l_len = flock->l_len;
+ fop->flock.l_pid = flock->l_pid;
+ fop->flock.l_owner.len = flock->l_owner.len;
+ if (flock->l_owner.len > 0)
+ {
+ memcpy(fop->flock.l_owner.data, flock->l_owner.data,
+ flock->l_owner.len);
+ }
+ }
+ if (xdata != NULL)
+ {
+ fop->xdata = dict_ref(xdata);
+ if (fop->xdata == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to reference a "
+ "dictionary.");
+
+ goto out;
+ }
+ }
+
+ error = 0;
+
+out:
+ if (fop != NULL)
+ {
+ ec_manager(fop, error);
+ }
+ else
+ {
+ func(frame, NULL, this, -1, EIO, NULL, NULL);
+ }
+}
diff --git a/xlators/cluster/ec/src/ec-mem-types.h b/xlators/cluster/ec/src/ec-mem-types.h
new file mode 100644
index 00000000000..f312d1e333f
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-mem-types.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_MEM_TYPES_H__
+#define __EC_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_ec_mem_types_
+{
+ ec_mt_ec_t = gf_common_mt_end + 1,
+ ec_mt_xlator_t,
+ ec_mt_ec_fop_data_t,
+ ec_mt_ec_cbk_data_t,
+ ec_mt_ec_inode_t,
+ ec_mt_ec_fd_t,
+ ec_mt_ec_lock_t,
+ ec_mt_ec_heal_t,
+ ec_mt_end
+};
+
+#endif /* __EC_MEM_TYPES_H__ */
diff --git a/xlators/cluster/ec/src/ec-method.c b/xlators/cluster/ec/src/ec-method.c
new file mode 100644
index 00000000000..deedf2a21f2
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-method.c
@@ -0,0 +1,182 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "ec-method.h"
+
+#define EC_METHOD_WORD_SIZE 16
+
+static uint32_t GfPow[EC_METHOD_SIZE << 1];
+static uint32_t GfLog[EC_METHOD_SIZE << 1];
+
+void ec_method_initialize(void)
+{
+ uint32_t i;
+
+ GfPow[0] = 1;
+ GfLog[0] = EC_METHOD_SIZE;
+ for (i = 1; i < EC_METHOD_SIZE; i++)
+ {
+ GfPow[i] = GfPow[i - 1] << 1;
+ if (GfPow[i] >= EC_METHOD_SIZE)
+ {
+ GfPow[i] ^= EC_GF_MOD;
+ }
+ GfPow[i + EC_METHOD_SIZE - 1] = GfPow[i];
+ GfLog[GfPow[i] + EC_METHOD_SIZE - 1] = GfLog[GfPow[i]] = i;
+ }
+}
+
+static uint32_t ec_method_mul(uint32_t a, uint32_t b)
+{
+ if (a && b)
+ {
+ return GfPow[GfLog[a] + GfLog[b]];
+ }
+ return 0;
+}
+
+static uint32_t ec_method_div(uint32_t a, uint32_t b)
+{
+ if (b)
+ {
+ if (a)
+ {
+ return GfPow[EC_METHOD_SIZE - 1 + GfLog[a] - GfLog[b]];
+ }
+ return 0;
+ }
+ return EC_METHOD_SIZE;
+}
+
+size_t ec_method_encode(size_t size, uint32_t columns, uint32_t row,
+ uint8_t * in, uint8_t * out)
+{
+ uint32_t i, j;
+
+ size /= EC_METHOD_CHUNK_SIZE * columns;
+ row++;
+ for (j = 0; j < size; j++)
+ {
+ ec_gf_load(in);
+ in += EC_METHOD_CHUNK_SIZE;
+ for (i = 1; i < columns; i++)
+ {
+ ec_gf_mul_table[row]();
+ ec_gf_xor(in);
+ in += EC_METHOD_CHUNK_SIZE;
+ }
+ ec_gf_store(out);
+ out += EC_METHOD_CHUNK_SIZE;
+ }
+
+ return size * EC_METHOD_CHUNK_SIZE;
+}
+
+size_t ec_method_decode(size_t size, uint32_t columns, uint32_t * rows,
+ uint8_t ** in, uint8_t * out)
+{
+ uint32_t i, j, k;
+ uint32_t f, off, mask;
+ uint8_t inv[EC_METHOD_MAX_FRAGMENTS][EC_METHOD_MAX_FRAGMENTS + 1];
+ uint8_t mtx[EC_METHOD_MAX_FRAGMENTS][EC_METHOD_MAX_FRAGMENTS];
+ uint8_t * p[EC_METHOD_MAX_FRAGMENTS];
+
+ size /= EC_METHOD_CHUNK_SIZE;
+
+ memset(inv, 0, sizeof(inv));
+ memset(mtx, 0, sizeof(mtx));
+ mask = 0;
+ for (i = 0; i < columns; i++)
+ {
+ inv[i][i] = 1;
+ inv[i][columns] = 1;
+ }
+ k = 0;
+ for (i = 0; i < columns; i++)
+ {
+ while ((mask & 1) != 0)
+ {
+ k++;
+ mask >>= 1;
+ }
+ mtx[k][columns - 1] = 1;
+ for (j = columns - 1; j > 0; j--)
+ {
+ mtx[k][j - 1] = ec_method_mul(mtx[k][j], rows[i] + 1);
+ }
+ p[k] = in[i];
+ k++;
+ mask >>= 1;
+ }
+
+ for (i = 0; i < columns; i++)
+ {
+ f = mtx[i][i];
+ for (j = 0; j < columns; j++)
+ {
+ mtx[i][j] = ec_method_div(mtx[i][j], f);
+ inv[i][j] = ec_method_div(inv[i][j], f);
+ }
+ for (j = 0; j < columns; j++)
+ {
+ if (i != j)
+ {
+ f = mtx[j][i];
+ for (k = 0; k < columns; k++)
+ {
+ mtx[j][k] ^= ec_method_mul(mtx[i][k], f);
+ inv[j][k] ^= ec_method_mul(inv[i][k], f);
+ }
+ }
+ }
+ }
+ off = 0;
+ for (f = 0; f < size; f++)
+ {
+ for (i = 0; i < columns; i++)
+ {
+ ec_gf_load(p[0] + off);
+ j = 0;
+ while (j < columns)
+ {
+ k = j + 1;
+ while (inv[i][k] == 0)
+ {
+ k++;
+ }
+ ec_gf_mul_table[ec_method_div(inv[i][j], inv[i][k])]();
+ if (k < columns)
+ {
+ ec_gf_xor(p[k] + off);
+ }
+ j = k;
+ }
+ ec_gf_store(out);
+ out += EC_METHOD_CHUNK_SIZE;
+ in[i] += EC_METHOD_CHUNK_SIZE;
+ }
+ off += EC_METHOD_CHUNK_SIZE;
+ }
+
+ return size * EC_METHOD_CHUNK_SIZE * columns;
+}
diff --git a/xlators/cluster/ec/src/ec-method.h b/xlators/cluster/ec/src/ec-method.h
new file mode 100644
index 00000000000..64e724ff3f0
--- /dev/null
+++ b/xlators/cluster/ec/src/ec-method.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_METHOD_H__
+#define __EC_METHOD_H__
+
+#include "ec-gf.h"
+
+#define EC_METHOD_MAX_FRAGMENTS 16
+
+#define EC_METHOD_WORD_SIZE 16
+
+#define EC_BUFFER_ALIGN_SIZE EC_METHOD_WORD_SIZE
+
+#define EC_METHOD_BITS EC_GF_BITS
+#define EC_METHOD_SIZE (1 << (EC_METHOD_BITS))
+#define EC_METHOD_CHUNK_SIZE (EC_METHOD_WORD_SIZE * EC_METHOD_BITS)
+
+void ec_method_initialize(void);
+size_t ec_method_encode(size_t size, uint32_t columns, uint32_t row,
+ uint8_t * in, uint8_t * out);
+size_t ec_method_decode(size_t size, uint32_t columns, uint32_t * rows,
+ uint8_t ** in, uint8_t * out);
+
+#endif /* __EC_METHOD_H__ */
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
new file mode 100644
index 00000000000..3290df55732
--- /dev/null
+++ b/xlators/cluster/ec/src/ec.c
@@ -0,0 +1,904 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "defaults.h"
+
+#include "ec-mem-types.h"
+#include "ec-common.h"
+#include "ec-fops.h"
+#include "ec-method.h"
+#include "ec.h"
+
+#define EC_MAX_FRAGMENTS EC_METHOD_MAX_FRAGMENTS
+/* The maximum number of nodes is derived from the maximum allowed fragments
+ * using the rule that redundancy cannot be equal or greater than the number
+ * of fragments.
+ */
+#define EC_MAX_NODES (EC_MAX_FRAGMENTS + ((EC_MAX_FRAGMENTS - 1) / 2))
+
+int32_t ec_parse_options(xlator_t * this)
+{
+ ec_t * ec = this->private;
+ int32_t error = EINVAL;
+ uintptr_t mask;
+
+ GF_OPTION_INIT("redundancy", ec->redundancy, int32, out);
+ ec->fragments = ec->nodes - ec->redundancy;
+ if ((ec->redundancy < 1) || (ec->redundancy >= ec->fragments) ||
+ (ec->fragments > EC_MAX_FRAGMENTS))
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Invalid redundancy (must be between "
+ "1 and %d)", (ec->nodes - 1) / 2);
+
+ goto out;
+ }
+
+ ec->bits_for_nodes = 1;
+ mask = 2;
+ while (ec->nodes > mask)
+ {
+ ec->bits_for_nodes++;
+ mask <<= 1;
+ }
+ ec->node_mask = (1ULL << ec->nodes) - 1ULL;
+ ec->fragment_size = EC_METHOD_CHUNK_SIZE;
+ ec->stripe_size = ec->fragment_size * ec->fragments;
+
+ gf_log("ec", GF_LOG_DEBUG, "Initialized with: nodes=%u, fragments=%u, "
+ "stripe_size=%u, node_mask=%lX",
+ ec->nodes, ec->fragments, ec->stripe_size, ec->node_mask);
+
+ error = 0;
+
+out:
+ return error;
+}
+
+int32_t ec_prepare_childs(xlator_t * this)
+{
+ ec_t * ec = this->private;
+ xlator_list_t * child = NULL;
+ int32_t count = 0;
+
+ for (child = this->children; child != NULL; child = child->next)
+ {
+ count++;
+ }
+ if (count > EC_MAX_NODES)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Too many subvolumes");
+
+ return EINVAL;
+ }
+ ec->nodes = count;
+
+ ec->xl_list = GF_CALLOC(count, sizeof(ec->xl_list[0]), ec_mt_xlator_t);
+ if (ec->xl_list == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Allocation of xlator list failed");
+
+ return ENOMEM;
+ }
+ ec->xl_up = 0;
+ ec->xl_up_count = 0;
+
+ count = 0;
+ for (child = this->children; child != NULL; child = child->next)
+ {
+ ec->xl_list[count++] = child->xlator;
+ }
+
+ return 0;
+}
+
+void __ec_destroy_private(xlator_t * this)
+{
+ ec_t * ec = this->private;
+
+ if (ec != NULL)
+ {
+ LOCK(&ec->lock);
+
+ if (ec->timer != NULL)
+ {
+ gf_timer_call_cancel(this->ctx, ec->timer);
+ ec->timer = NULL;
+ }
+
+ UNLOCK(&ec->lock);
+
+ /* There is a race with timer because there is no way to know if
+ * timer callback has really been cancelled or it has been scheduled
+ * for execution. If it has been scheduled, it will crash if we
+ * destroy ec too fast.
+ *
+ * Not sure how this can be solved without using global variables or
+ * having support from gf_timer_call_cancel()
+ */
+ sleep(2);
+
+ this->private = NULL;
+ if (ec->xl_list != NULL)
+ {
+ GF_FREE(ec->xl_list);
+ ec->xl_list = NULL;
+ }
+
+ if (ec->fop_pool != NULL)
+ {
+ mem_pool_destroy(ec->fop_pool);
+ }
+
+ if (ec->cbk_pool != NULL)
+ {
+ mem_pool_destroy(ec->cbk_pool);
+ }
+
+ LOCK_DESTROY(&ec->lock);
+
+ GF_FREE(ec);
+ }
+}
+
+int32_t mem_acct_init(xlator_t * this)
+{
+ if (xlator_mem_acct_init(this, ec_mt_end + 1) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Memory accounting initialization "
+ "failed.");
+
+ return -1;
+ }
+
+ return 0;
+}
+
+int32_t reconfigure(xlator_t * this, dict_t * options)
+{
+ gf_log(this->name, GF_LOG_ERROR, "Online volume reconfiguration is not "
+ "supported.");
+
+ return -1;
+}
+
+void ec_up(xlator_t * this, ec_t * ec)
+{
+ if (ec->timer != NULL)
+ {
+ gf_timer_call_cancel(this->ctx, ec->timer);
+ ec->timer = NULL;
+ }
+
+ if (!ec->up && (ec->xl_up_count >= ec->fragments))
+ {
+ if (ec->xl_up_count < ec->nodes)
+ {
+ gf_log("ec", GF_LOG_WARNING, "Starting volume with only %d bricks",
+ ec->xl_up_count);
+ }
+
+ ec->up = 1;
+ gf_log(this->name, GF_LOG_INFO, "Going UP");
+
+ default_notify(this, GF_EVENT_CHILD_UP, NULL);
+ }
+}
+
+void ec_down(xlator_t * this, ec_t * ec)
+{
+ if (ec->timer != NULL)
+ {
+ gf_timer_call_cancel(this->ctx, ec->timer);
+ ec->timer = NULL;
+ }
+
+ if (ec->up)
+ {
+ ec->up = 0;
+ gf_log(this->name, GF_LOG_INFO, "Going DOWN");
+
+ default_notify(this, GF_EVENT_CHILD_DOWN, NULL);
+ }
+}
+
+void ec_notify_up_cbk(void * data)
+{
+ ec_t * ec = data;
+
+ LOCK(&ec->lock);
+
+ if (ec->timer != NULL)
+ {
+ ec_up(ec->xl, ec);
+ }
+
+ UNLOCK(&ec->lock);
+}
+
+int32_t ec_notify_up(xlator_t * this, ec_t * ec, int32_t idx)
+{
+ struct timespec delay = {0, };
+
+ if (((ec->xl_up >> idx) & 1) == 0)
+ {
+ ec->xl_up |= 1ULL << idx;
+ ec->xl_up_count++;
+
+ gf_log("ec", GF_LOG_DEBUG, "Child %d is UP (%lX, %u)", idx, ec->xl_up,
+ ec->xl_up_count);
+
+ if (ec->xl_up_count == ec->fragments)
+ {
+ gf_log("ec", GF_LOG_DEBUG, "Initiating up timer");
+
+ delay.tv_sec = 5;
+ delay.tv_nsec = 0;
+ ec->timer = gf_timer_call_after(this->ctx, delay, ec_notify_up_cbk,
+ ec);
+ if (ec->timer == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Cannot create timer for "
+ "delayed initialization");
+
+ return ENOMEM;
+ }
+ }
+ else if (ec->xl_up_count == ec->nodes)
+ {
+ ec_up(this, ec);
+ }
+ }
+
+ return EAGAIN;
+}
+
+int32_t ec_notify_down(xlator_t * this, ec_t * ec, int32_t idx)
+{
+ if (((ec->xl_up >> idx) & 1) != 0)
+ {
+ gf_log("ec", GF_LOG_DEBUG, "Child %d is DOWN", idx);
+
+ ec->xl_up ^= 1ULL << idx;
+ if (ec->xl_up_count-- == ec->fragments)
+ {
+ ec_down(this, ec);
+ }
+ }
+
+ return EAGAIN;
+}
+
+int32_t notify(xlator_t * this, int32_t event, void * data, ...)
+{
+ ec_t * ec = this->private;
+ int32_t idx = 0;
+ int32_t error = 0;
+
+ LOCK(&ec->lock);
+
+ for (idx = 0; idx < ec->nodes; idx++)
+ {
+ if (ec->xl_list[idx] == data)
+ {
+ break;
+ }
+ }
+
+ gf_log("ec", GF_LOG_TRACE, "NOTIFY(%d): %p, %d", event, data, idx);
+
+ if (idx < ec->nodes)
+ {
+ if (event == GF_EVENT_CHILD_UP)
+ {
+ error = ec_notify_up(this, ec, idx);
+ }
+ else if (event == GF_EVENT_CHILD_DOWN)
+ {
+ error = ec_notify_down(this, ec, idx);
+ }
+ }
+
+ UNLOCK(&ec->lock);
+
+ if (error == 0)
+ {
+ return default_notify(this, event, data);
+ }
+
+ return 0;
+}
+
+int32_t init(xlator_t * this)
+{
+ ec_t * ec;
+
+ if (this->parents == NULL)
+ {
+ gf_log(this->name, GF_LOG_WARNING, "Volume does not have parents.");
+ }
+
+ ec = GF_MALLOC(sizeof(*ec), ec_mt_ec_t);
+ if (ec == NULL)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to allocate private memory.");
+
+ return -1;
+ }
+ memset(ec, 0, sizeof(*ec));
+
+ this->private = ec;
+
+ ec->xl = this;
+ LOCK_INIT(&ec->lock);
+
+ ec->fop_pool = mem_pool_new(ec_fop_data_t, 1024);
+ ec->cbk_pool = mem_pool_new(ec_cbk_data_t, 4096);
+ if ((ec->fop_pool == NULL) || (ec->cbk_pool == NULL))
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to create memory pools.");
+
+ goto failed;
+ }
+
+ if (ec_prepare_childs(this) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to initialize xlator");
+
+ goto failed;
+ }
+
+ if (ec_parse_options(this) != 0)
+ {
+ gf_log(this->name, GF_LOG_ERROR, "Failed to parse xlator options");
+
+ goto failed;
+ }
+
+ ec_method_initialize();
+
+ gf_log(this->name, GF_LOG_DEBUG, "Disperse translator initialized.");
+
+ return 0;
+
+failed:
+ __ec_destroy_private(this);
+
+ return -1;
+}
+
+void fini(xlator_t * this)
+{
+ __ec_destroy_private(this);
+}
+
+int32_t ec_gf_access(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ int32_t mask, dict_t * xdata)
+{
+ ec_access(frame, this, -1, EC_MINIMUM_ONE, default_access_cbk, NULL, loc,
+ mask, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_create(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ int32_t flags, mode_t mode, mode_t umask, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_create(frame, this, -1, EC_MINIMUM_MIN, default_create_cbk, NULL, loc,
+ flags, mode, umask, fd, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_discard(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ off_t offset, size_t len, dict_t * xdata)
+{
+ default_discard_failure_cbk(frame, ENOTSUP);
+
+ return 0;
+}
+
+int32_t ec_gf_entrylk(call_frame_t * frame, xlator_t * this,
+ const char * volume, loc_t * loc, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
+{
+ ec_entrylk(frame, this, -1, EC_MINIMUM_ALL, default_entrylk_cbk, NULL,
+ volume, loc, basename, cmd, type, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fentrylk(call_frame_t * frame, xlator_t * this,
+ const char * volume, fd_t * fd, const char * basename,
+ entrylk_cmd cmd, entrylk_type type, dict_t * xdata)
+{
+ ec_fentrylk(frame, this, -1, EC_MINIMUM_ALL, default_fentrylk_cbk, NULL,
+ volume, fd, basename, cmd, type, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fallocate(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ int32_t keep_size, off_t offset, size_t len,
+ dict_t * xdata)
+{
+ default_fallocate_failure_cbk(frame, ENOTSUP);
+
+ return 0;
+}
+
+int32_t ec_gf_flush(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_flush(frame, this, -1, EC_MINIMUM_MIN, default_flush_cbk, NULL, fd,
+ xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fsync(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ int32_t datasync, dict_t * xdata)
+{
+ ec_fsync(frame, this, -1, EC_MINIMUM_MIN, default_fsync_cbk, NULL, fd,
+ datasync, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fsyncdir(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ int32_t datasync, dict_t * xdata)
+{
+ ec_fsyncdir(frame, this, -1, EC_MINIMUM_MIN, default_fsyncdir_cbk, NULL,
+ fd, datasync, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_getxattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ const char * name, dict_t * xdata)
+{
+ ec_getxattr(frame, this, -1, EC_MINIMUM_MIN, default_getxattr_cbk, NULL,
+ loc, name, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fgetxattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ const char * name, dict_t * xdata)
+{
+ ec_fgetxattr(frame, this, -1, EC_MINIMUM_MIN, default_fgetxattr_cbk, NULL,
+ fd, name, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_inodelk(call_frame_t * frame, xlator_t * this,
+ const char * volume, loc_t * loc, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata)
+{
+ ec_inodelk(frame, this, -1, EC_MINIMUM_ALL, default_inodelk_cbk, NULL,
+ volume, loc, cmd, flock, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_finodelk(call_frame_t * frame, xlator_t * this,
+ const char * volume, fd_t * fd, int32_t cmd,
+ struct gf_flock * flock, dict_t * xdata)
+{
+ ec_finodelk(frame, this, -1, EC_MINIMUM_ALL, default_finodelk_cbk, NULL,
+ volume, fd, cmd, flock, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_link(call_frame_t * frame, xlator_t * this, loc_t * oldloc,
+ loc_t * newloc, dict_t * xdata)
+{
+ ec_link(frame, this, -1, EC_MINIMUM_MIN, default_link_cbk, NULL, oldloc,
+ newloc, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_lk(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ int32_t cmd, struct gf_flock * flock, dict_t * xdata)
+{
+ ec_lk(frame, this, -1, EC_MINIMUM_ALL, default_lk_cbk, NULL, fd, cmd,
+ flock, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_lookup(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ dict_t * xdata)
+{
+ ec_lookup(frame, this, -1, EC_MINIMUM_MIN, default_lookup_cbk, NULL, loc,
+ xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_mkdir(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ mode_t mode, mode_t umask, dict_t * xdata)
+{
+ ec_mkdir(frame, this, -1, EC_MINIMUM_MIN, default_mkdir_cbk, NULL, loc,
+ mode, umask, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_mknod(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t * xdata)
+{
+ ec_mknod(frame, this, -1, EC_MINIMUM_MIN, default_mknod_cbk, NULL, loc,
+ mode, rdev, umask, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_open(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ int32_t flags, fd_t * fd, dict_t * xdata)
+{
+ ec_open(frame, this, -1, EC_MINIMUM_MIN, default_open_cbk, NULL, loc,
+ flags, fd, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_opendir(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ fd_t * fd, dict_t * xdata)
+{
+ ec_opendir(frame, this, -1, EC_MINIMUM_MIN, default_opendir_cbk, NULL, loc,
+ fd, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_readdir(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ size_t size, off_t offset, dict_t * xdata)
+{
+ ec_readdir(frame, this, -1, EC_MINIMUM_ONE, default_readdir_cbk, NULL, fd,
+ size, offset, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_readdirp(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ size_t size, off_t offset, dict_t * xdata)
+{
+ ec_readdirp(frame, this, -1, EC_MINIMUM_ONE, default_readdirp_cbk, NULL,
+ fd, size, offset, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_readlink(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ size_t size, dict_t * xdata)
+{
+ ec_readlink(frame, this, -1, EC_MINIMUM_ONE, default_readlink_cbk, NULL,
+ loc, size, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_readv(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ size_t size, off_t offset, uint32_t flags, dict_t * xdata)
+{
+ ec_readv(frame, this, -1, EC_MINIMUM_MIN, default_readv_cbk, NULL, fd,
+ size, offset, flags, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_removexattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ const char * name, dict_t * xdata)
+{
+ ec_removexattr(frame, this, -1, EC_MINIMUM_MIN, default_removexattr_cbk,
+ NULL, loc, name, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fremovexattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ const char * name, dict_t * xdata)
+{
+ ec_fremovexattr(frame, this, -1, EC_MINIMUM_MIN, default_fremovexattr_cbk,
+ NULL, fd, name, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_rename(call_frame_t * frame, xlator_t * this, loc_t * oldloc,
+ loc_t * newloc, dict_t * xdata)
+{
+ ec_rename(frame, this, -1, EC_MINIMUM_MIN, default_rename_cbk, NULL,
+ oldloc, newloc, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_rmdir(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ int xflags, dict_t * xdata)
+{
+ ec_rmdir(frame, this, -1, EC_MINIMUM_MIN, default_rmdir_cbk, NULL, loc,
+ xflags, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_setattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ struct iatt * stbuf, int32_t valid, dict_t * xdata)
+{
+ ec_setattr(frame, this, -1, EC_MINIMUM_MIN, default_setattr_cbk, NULL, loc,
+ stbuf, valid, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fsetattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ struct iatt * stbuf, int32_t valid, dict_t * xdata)
+{
+ ec_fsetattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetattr_cbk, NULL,
+ fd, stbuf, valid, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_setxattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ dict_t * dict, int32_t flags, dict_t * xdata)
+{
+ ec_setxattr(frame, this, -1, EC_MINIMUM_MIN, default_setxattr_cbk, NULL,
+ loc, dict, flags, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fsetxattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ dict_t * dict, int32_t flags, dict_t * xdata)
+{
+ ec_fsetxattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetxattr_cbk, NULL,
+ fd, dict, flags, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_stat(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ dict_t * xdata)
+{
+ ec_stat(frame, this, -1, EC_MINIMUM_MIN, default_stat_cbk, NULL, loc,
+ xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fstat(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ dict_t * xdata)
+{
+ ec_fstat(frame, this, -1, EC_MINIMUM_MIN, default_fstat_cbk, NULL, fd,
+ xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_statfs(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ dict_t * xdata)
+{
+ ec_statfs(frame, this, -1, EC_MINIMUM_MIN, default_statfs_cbk, NULL, loc,
+ xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_symlink(call_frame_t * frame, xlator_t * this,
+ const char * linkname, loc_t * loc, mode_t umask,
+ dict_t * xdata)
+{
+ ec_symlink(frame, this, -1, EC_MINIMUM_MIN, default_symlink_cbk, NULL,
+ linkname, loc, umask, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_truncate(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ off_t offset, dict_t * xdata)
+{
+ ec_truncate(frame, this, -1, EC_MINIMUM_MIN, default_truncate_cbk, NULL,
+ loc, offset, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_ftruncate(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ off_t offset, dict_t * xdata)
+{
+ ec_ftruncate(frame, this, -1, EC_MINIMUM_MIN, default_ftruncate_cbk, NULL,
+ fd, offset, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_unlink(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ int xflags, dict_t * xdata)
+{
+ ec_unlink(frame, this, -1, EC_MINIMUM_MIN, default_unlink_cbk, NULL, loc,
+ xflags, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_writev(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ struct iovec * vector, int32_t count, off_t offset,
+ uint32_t flags, struct iobref * iobref, dict_t * xdata)
+{
+ ec_writev(frame, this, -1, EC_MINIMUM_MIN, default_writev_cbk, NULL, fd,
+ vector, count, offset, flags, iobref, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_xattrop(call_frame_t * frame, xlator_t * this, loc_t * loc,
+ gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_xattrop(frame, this, -1, EC_MINIMUM_MIN, default_xattrop_cbk, NULL, loc,
+ optype, xattr, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_fxattrop(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ gf_xattrop_flags_t optype, dict_t * xattr,
+ dict_t * xdata)
+{
+ ec_fxattrop(frame, this, -1, EC_MINIMUM_MIN, default_fxattrop_cbk, NULL,
+ fd, optype, xattr, xdata);
+
+ return 0;
+}
+
+int32_t ec_gf_zerofill(call_frame_t * frame, xlator_t * this, fd_t * fd,
+ off_t offset, off_t len, dict_t * xdata)
+{
+ default_zerofill_failure_cbk(frame, ENOTSUP);
+
+ return 0;
+}
+
+void __ec_gf_release_fd(xlator_t * this, fd_t * fd)
+{
+ uint64_t value = 0;
+ ec_fd_t * ctx = NULL;
+
+ if ((fd_ctx_del(fd, this, &value) == 0) && (value != 0))
+ {
+ ctx = (ec_fd_t *)(uintptr_t)value;
+ loc_wipe(&ctx->loc);
+ GF_FREE(ctx);
+ }
+}
+
+void __ec_gf_release_inode(xlator_t * this, inode_t * inode)
+{
+ uint64_t value = 0;
+ ec_inode_t * ctx = NULL;
+
+ if ((inode_ctx_del(inode, this, &value) == 0) && (value != 0))
+ {
+ ctx = (ec_inode_t *)(uintptr_t)value;
+ GF_FREE(ctx);
+ }
+}
+
+int32_t ec_gf_forget(xlator_t * this, inode_t * inode)
+{
+ __ec_gf_release_inode(this, inode);
+
+ return 0;
+}
+
+int32_t ec_gf_invalidate(xlator_t * this, inode_t * inode)
+{
+ __ec_gf_release_inode(this, inode);
+
+ return 0;
+}
+
+int32_t ec_gf_release(xlator_t * this, fd_t * fd)
+{
+ __ec_gf_release_fd(this, fd);
+
+ return 0;
+}
+
+int32_t ec_gf_releasedir(xlator_t * this, fd_t * fd)
+{
+ __ec_gf_release_fd(this, fd);
+
+ return 0;
+}
+
+struct xlator_fops fops =
+{
+ .lookup = ec_gf_lookup,
+ .stat = ec_gf_stat,
+ .fstat = ec_gf_fstat,
+ .truncate = ec_gf_truncate,
+ .ftruncate = ec_gf_ftruncate,
+ .access = ec_gf_access,
+ .readlink = ec_gf_readlink,
+ .mknod = ec_gf_mknod,
+ .mkdir = ec_gf_mkdir,
+ .unlink = ec_gf_unlink,
+ .rmdir = ec_gf_rmdir,
+ .symlink = ec_gf_symlink,
+ .rename = ec_gf_rename,
+ .link = ec_gf_link,
+ .create = ec_gf_create,
+ .open = ec_gf_open,
+ .readv = ec_gf_readv,
+ .writev = ec_gf_writev,
+ .flush = ec_gf_flush,
+ .fsync = ec_gf_fsync,
+ .opendir = ec_gf_opendir,
+ .readdir = ec_gf_readdir,
+ .readdirp = ec_gf_readdirp,
+ .fsyncdir = ec_gf_fsyncdir,
+ .statfs = ec_gf_statfs,
+ .setxattr = ec_gf_setxattr,
+ .getxattr = ec_gf_getxattr,
+ .fsetxattr = ec_gf_fsetxattr,
+ .fgetxattr = ec_gf_fgetxattr,
+ .removexattr = ec_gf_removexattr,
+ .fremovexattr = ec_gf_fremovexattr,
+ .lk = ec_gf_lk,
+ .inodelk = ec_gf_inodelk,
+ .finodelk = ec_gf_finodelk,
+ .entrylk = ec_gf_entrylk,
+ .fentrylk = ec_gf_fentrylk,
+ .xattrop = ec_gf_xattrop,
+ .fxattrop = ec_gf_fxattrop,
+ .setattr = ec_gf_setattr,
+ .fsetattr = ec_gf_fsetattr,
+ .fallocate = ec_gf_fallocate,
+ .discard = ec_gf_discard,
+ .zerofill = ec_gf_zerofill
+};
+
+struct xlator_cbks cbks =
+{
+ .forget = ec_gf_forget,
+ .release = ec_gf_release,
+ .releasedir = ec_gf_releasedir,
+ .invalidate = ec_gf_invalidate,
+ .client_destroy = NULL,
+ .client_disconnect = NULL
+};
+
+struct volume_options options[] =
+{
+ {
+ .key = { "redundancy" },
+ .type = GF_OPTION_TYPE_INT,
+ .description = "Maximum number of bricks that can fail "
+ "simultaneously without losing data."
+ },
+ { }
+};
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
new file mode 100644
index 00000000000..85c430e2045
--- /dev/null
+++ b/xlators/cluster/ec/src/ec.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 2012 DataLab, s.l. <http://www.datalab.es>
+
+ This file is part of the cluster/ec translator for GlusterFS.
+
+ The cluster/ec translator for GlusterFS is free software: you can
+ redistribute it and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ The cluster/ec translator for GlusterFS is distributed in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the cluster/ec translator for GlusterFS. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __EC_H__
+#define __EC_H__
+
+#include "xlator.h"
+#include "timer.h"
+
+#define EC_XATTR_SIZE "trusted.ec.size"
+#define EC_XATTR_VERSION "trusted.ec.version"
+
+struct _ec;
+typedef struct _ec ec_t;
+
+struct _ec
+{
+ xlator_t * xl;
+ int32_t nodes;
+ int32_t bits_for_nodes;
+ int32_t fragments;
+ int32_t redundancy;
+ uint32_t fragment_size;
+ uint32_t stripe_size;
+ int32_t up;
+ uint32_t idx;
+ uint32_t xl_up_count;
+ uintptr_t xl_up;
+ uintptr_t node_mask;
+ xlator_t ** xl_list;
+ gf_lock_t lock;
+ gf_timer_t * timer;
+ struct mem_pool * fop_pool;
+ struct mem_pool * cbk_pool;
+};
+
+#endif /* __EC_H__ */