summaryrefslogtreecommitdiffstats
path: root/xlators/features/thin-arbiter
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/thin-arbiter')
-rw-r--r--xlators/features/thin-arbiter/Makefile.am3
-rw-r--r--xlators/features/thin-arbiter/src/Makefile.am22
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h19
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter-messages.h28
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter.c661
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter.h59
6 files changed, 792 insertions, 0 deletions
diff --git a/xlators/features/thin-arbiter/Makefile.am b/xlators/features/thin-arbiter/Makefile.am
new file mode 100644
index 00000000000..a985f42a877
--- /dev/null
+++ b/xlators/features/thin-arbiter/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/features/thin-arbiter/src/Makefile.am b/xlators/features/thin-arbiter/src/Makefile.am
new file mode 100644
index 00000000000..a3c133e7798
--- /dev/null
+++ b/xlators/features/thin-arbiter/src/Makefile.am
@@ -0,0 +1,22 @@
+xlator_LTLIBRARIES = thin-arbiter.la
+
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
+
+thin_arbiter_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
+
+thin_arbiter_la_SOURCES = thin-arbiter.c \
+ $(top_builddir)/xlators/lib/src/libxlator.c
+
+thin_arbiter_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = thin-arbiter.h thin-arbiter-mem-types.h thin-arbiter-messages.h \
+ $(top_builddir)/xlators/lib/src/libxlator.h
+
+AM_CPPFLAGS = $(GF_CPPFLAGS) \
+ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h b/xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h
new file mode 100644
index 00000000000..69562d2febc
--- /dev/null
+++ b/xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h
@@ -0,0 +1,19 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef __THIN_ARBITER_MEM_TYPES_H__
+#define __THIN_ARBITER_MEM_TYPES_H__
+#include <glusterfs/mem-types.h>
+
+typedef enum gf_ta_mem_types_ {
+ gf_ta_mt_local_t = gf_common_mt_end + 1,
+ gf_ta_mt_char,
+ gf_ta_mt_end
+} gf_ta_mem_types_t;
+#endif
diff --git a/xlators/features/thin-arbiter/src/thin-arbiter-messages.h b/xlators/features/thin-arbiter/src/thin-arbiter-messages.h
new file mode 100644
index 00000000000..81d7491577a
--- /dev/null
+++ b/xlators/features/thin-arbiter/src/thin-arbiter-messages.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _TA_MESSAGES_H_
+#define _TA_MESSAGES_H_
+
+#include <glusterfs/glfs-message-id.h>
+
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
+ */
+
+GLFS_MSGID(TA, TA_MSG_INVALID_FOP);
+
+#endif /* !_TA_MESSAGES_H_ */
diff --git a/xlators/features/thin-arbiter/src/thin-arbiter.c b/xlators/features/thin-arbiter/src/thin-arbiter.c
new file mode 100644
index 00000000000..ce3008636f1
--- /dev/null
+++ b/xlators/features/thin-arbiter/src/thin-arbiter.c
@@ -0,0 +1,661 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#include "thin-arbiter.h"
+#include "thin-arbiter-messages.h"
+#include "thin-arbiter-mem-types.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/xlator.h>
+#include <glusterfs/logging.h>
+#include <glusterfs/byte-order.h>
+#include <glusterfs/common-utils.h>
+
+int
+ta_set_incoming_values(dict_t *dict, char *key, data_t *value, void *data)
+{
+ int32_t ret = 0;
+ ta_fop_t *fop = (ta_fop_t *)data;
+ int32_t *pending = NULL;
+
+ pending = GF_CALLOC(1, value->len, gf_ta_mt_char);
+ if (!pending) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = dict_set_bin(fop->brick_xattr, key, pending, value->len);
+out:
+ return ret;
+}
+
+int
+ta_get_incoming_and_brick_values(dict_t *dict, char *key, data_t *value,
+ void *data)
+{
+ ta_fop_t *fop = data;
+ char *source = NULL;
+ char *in_coming = NULL;
+ int32_t len = 0, ret = 0;
+
+ source = GF_CALLOC(1, value->len, gf_ta_mt_char);
+ if (!source) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = dict_get_ptr_and_len(fop->dict, key, (void **)&in_coming, &len);
+
+ if (!in_coming || value->len != len) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!memcmp(value->data, source, value->len) &&
+ (!memcmp(in_coming, source, len))) {
+ fop->on_disk[fop->idx] = 0;
+ } else {
+ fop->on_disk[fop->idx] = 1;
+ }
+
+ fop->idx++;
+out:
+ GF_FREE(source);
+ return ret;
+}
+
+void
+ta_release_fop(ta_fop_t *fop)
+{
+ if (!fop) {
+ return;
+ }
+ if (fop->fd) {
+ fd_unref(fop->fd);
+ }
+ loc_wipe(&fop->loc);
+ if (fop->dict) {
+ dict_unref(fop->dict);
+ }
+ if (fop->brick_xattr) {
+ dict_unref(fop->brick_xattr);
+ }
+
+ GF_FREE(fop);
+ return;
+}
+
+int32_t
+ta_set_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ TA_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+/*
+case 1 - If brick value is 0 and incoming value is also 0, fine
+case 2 - If brick value is 0 and incoming value is non 0, fine
+case 3 - If brick value is non 0 and incoming value is also 0, fine
+case 4 - If brick value is non 0 and incoming value is non 0, fine
+case 5 - If incoming value is non zero on both brick, it is wrong
+case 6 - If incoming value is non zero but brick value for other
+brick is also non zero, wrong
+*/
+
+int32_t
+ta_verify_on_disk_source(ta_fop_t *fop, dict_t *dict)
+{
+ int ret = 0;
+
+ if (!fop) {
+ return -EINVAL;
+ }
+
+ ret = dict_foreach(dict, ta_get_incoming_and_brick_values, (void *)fop);
+ if (ret < 0) {
+ return ret;
+ }
+ if (fop->on_disk[0] && fop->on_disk[1]) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int32_t
+ta_get_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ ta_fop_t *fop = NULL;
+ int ret = 0;
+
+ fop = frame->local;
+ if (op_ret) {
+ goto unwind;
+ }
+
+ ret = ta_verify_on_disk_source(fop, dict);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto unwind;
+ }
+
+ if (fop->fd) {
+ STACK_WIND(frame, ta_set_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fxattrop, fop->fd,
+ fop->xattrop_flags, fop->dict, NULL);
+ } else {
+ STACK_WIND(frame, ta_set_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, &fop->loc,
+ fop->xattrop_flags, fop->dict, NULL);
+ }
+ return 0;
+
+unwind:
+
+ TA_STACK_UNWIND(xattrop, frame, -1, op_errno, NULL, NULL);
+ return -1;
+}
+
+ta_fop_t *
+ta_prepare_fop(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ ta_fop_t *fop = NULL;
+ int ret = 0;
+
+ fop = GF_CALLOC(1, sizeof(*fop), gf_ta_mt_local_t);
+ if (!fop) {
+ goto out;
+ }
+
+ if (loc) {
+ loc_copy(&fop->loc, loc);
+ }
+
+ if (fd) {
+ fop->fd = fd_ref(fd);
+ }
+
+ fop->xattrop_flags = flags;
+ fop->idx = 0;
+
+ if (dict != NULL) {
+ fop->dict = dict_ref(dict);
+ }
+ fop->brick_xattr = dict_new();
+ if (fop->brick_xattr == NULL) {
+ goto out;
+ }
+ ret = dict_foreach(dict, ta_set_incoming_values, (void *)fop);
+ if (ret < 0) {
+ goto out;
+ }
+ frame->local = fop;
+ return fop;
+
+out:
+ ta_release_fop(fop);
+ return NULL;
+}
+
+int32_t
+ta_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ int ret = 0;
+ ta_fop_t *fop = NULL;
+
+ fop = ta_prepare_fop(frame, this, NULL, fd, flags, dict, xdata);
+ if (!fop) {
+ ret = -ENOMEM;
+ goto unwind;
+ }
+
+ STACK_WIND(frame, ta_get_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, fop->brick_xattr,
+ xdata);
+ return 0;
+
+unwind:
+
+ TA_STACK_UNWIND(xattrop, frame, -1, -ret, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ta_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ int ret = 0;
+ ta_fop_t *fop = NULL;
+
+ fop = ta_prepare_fop(frame, this, loc, NULL, flags, dict, xdata);
+ if (!fop) {
+ ret = -ENOMEM;
+ goto unwind;
+ }
+
+ STACK_WIND(frame, ta_get_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, fop->brick_xattr,
+ xdata);
+ return 0;
+
+unwind:
+
+ TA_STACK_UNWIND(xattrop, frame, -1, -ret, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ta_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, uint32_t flags, struct iobref *iobref,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(writev, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ TA_FAILED_FOP(fsetxattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ TA_FAILED_FOP(setxattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size,
+ off_t offset, size_t len, dict_t *xdata)
+{
+ TA_FAILED_FOP(fallocate, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(access, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ TA_FAILED_FOP(discard, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_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)
+{
+ TA_FAILED_FOP(entrylk, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_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)
+{
+ TA_FAILED_FOP(fentrylk, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ TA_FAILED_FOP(flush, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(fsync, frame, EINVAL);
+ return 0;
+}
+int32_t
+ta_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(fsyncdir, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(getxattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(fgetxattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(link, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *flock, dict_t *xdata)
+{
+ TA_FAILED_FOP(lk, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
+{
+ TA_FAILED_FOP(mkdir, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
+{
+ TA_FAILED_FOP(mknod, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
+{
+ TA_FAILED_FOP(open, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(opendir, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, dict_t *xdata)
+{
+ TA_FAILED_FOP(readdir, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, dict_t *xdata)
+{
+ TA_FAILED_FOP(readdirp, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(readlink, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
+{
+ TA_FAILED_FOP(readv, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ TA_FAILED_FOP(removexattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(fremovexattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(rename, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(rmdir, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ TA_FAILED_FOP(setattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ TA_FAILED_FOP(fsetattr, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ TA_FAILED_FOP(stat, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ TA_FAILED_FOP(fstat, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ TA_FAILED_FOP(statfs, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_symlink(call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, mode_t umask, dict_t *xdata)
+{
+ TA_FAILED_FOP(symlink, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(truncate, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(ftruncate, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflags,
+ dict_t *xdata)
+{
+ TA_FAILED_FOP(unlink, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ off_t len, dict_t *xdata)
+{
+ TA_FAILED_FOP(zerofill, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+ta_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata)
+{
+ TA_FAILED_FOP(seek, frame, EINVAL);
+ return 0;
+}
+
+int32_t
+mem_acct_init(xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init(this, gf_ta_mt_end + 1);
+ if (ret)
+ gf_log(this->name, GF_LOG_ERROR,
+ "Memory accounting "
+ "initialization failed.");
+ return ret;
+}
+
+int
+reconfigure(xlator_t *this, dict_t *options)
+{
+ return 0;
+}
+
+int32_t
+init(xlator_t *this)
+{
+ if (!this->children || this->children->next) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "'thin_arbiter' not configured with exactly one child");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log(this->name, GF_LOG_ERROR, "dangling volume. check volfile ");
+ }
+ return 0;
+}
+
+void
+fini(xlator_t *this)
+{
+ return;
+}
+
+struct xlator_fops fops = {
+ /*Passed fop*/
+ .xattrop = ta_xattrop,
+ .fxattrop = ta_fxattrop,
+ /*Failed fop*/
+ .writev = ta_writev,
+ .stat = ta_stat,
+ .fstat = ta_fstat,
+ .truncate = ta_truncate,
+ .ftruncate = ta_ftruncate,
+ .access = ta_access,
+ .readlink = ta_readlink,
+ .mknod = ta_mknod,
+ .mkdir = ta_mkdir,
+ .unlink = ta_unlink,
+ .rmdir = ta_rmdir,
+ .symlink = ta_symlink,
+ .rename = ta_rename,
+ .link = ta_link,
+ .open = ta_open,
+ .readv = ta_readv,
+ .flush = ta_flush,
+ .fsync = ta_fsync,
+ .opendir = ta_opendir,
+ .readdir = ta_readdir,
+ .readdirp = ta_readdirp,
+ .fsyncdir = ta_fsyncdir,
+ .statfs = ta_statfs,
+ .setxattr = ta_setxattr,
+ .getxattr = ta_getxattr,
+ .fsetxattr = ta_fsetxattr,
+ .fgetxattr = ta_fgetxattr,
+ .removexattr = ta_removexattr,
+ .fremovexattr = ta_fremovexattr,
+ .lk = ta_lk,
+ .entrylk = ta_entrylk,
+ .fentrylk = ta_fentrylk,
+ .setattr = ta_setattr,
+ .fsetattr = ta_fsetattr,
+ .fallocate = ta_fallocate,
+ .discard = ta_discard,
+ .zerofill = ta_zerofill,
+ .seek = ta_seek,
+};
+
+struct xlator_cbks cbks = {};
+
+struct volume_options options[] = {
+ {.key = {NULL}},
+};
+
+xlator_api_t xlator_api = {
+ .init = init,
+ .fini = fini,
+ .reconfigure = reconfigure,
+ .mem_acct_init = mem_acct_init,
+ .op_version = {GD_OP_VERSION_6_0},
+ .fops = &fops,
+ .cbks = &cbks,
+ .options = options,
+ .identifier = "thin-arbiter",
+ .category = GF_MAINTAINED,
+};
diff --git a/xlators/features/thin-arbiter/src/thin-arbiter.h b/xlators/features/thin-arbiter/src/thin-arbiter.h
new file mode 100644
index 00000000000..e5f914b84bf
--- /dev/null
+++ b/xlators/features/thin-arbiter/src/thin-arbiter.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _THIN_ARBITER_H
+#define _THIN_ARBITER_H
+
+#include <glusterfs/locking.h>
+#include <glusterfs/common-utils.h>
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/xlator.h>
+#include <glusterfs/defaults.h>
+#include <glusterfs/list.h>
+
+#define THIN_ARBITER_SOURCE_XATTR "trusted.ta.source"
+#define THIN_ARBITER_SOURCE_SIZE 2
+
+#define TA_FAILED_FOP(fop, frame, op_errno) \
+ do { \
+ default_##fop##_failure_cbk(frame, op_errno); \
+ } while (0)
+
+#define TA_STACK_UNWIND(fop, frame, op_ret, op_errno, params...) \
+ do { \
+ ta_fop_t *__local = NULL; \
+ int32_t __op_ret = 0; \
+ int32_t __op_errno = 0; \
+ \
+ __local = frame->local; \
+ __op_ret = op_ret; \
+ __op_errno = op_errno; \
+ if (__local) { \
+ ta_release_fop(__local); \
+ frame->local = NULL; \
+ } \
+ STACK_UNWIND_STRICT(fop, frame, __op_ret, __op_errno, params); \
+ \
+ } while (0)
+
+struct _ta_fop;
+typedef struct _ta_fop ta_fop_t;
+
+struct _ta_fop {
+ gf_xattrop_flags_t xattrop_flags;
+ loc_t loc;
+ fd_t *fd;
+ dict_t *dict;
+ dict_t *brick_xattr;
+ int32_t on_disk[2];
+ int32_t idx;
+};
+
+#endif /* _THIN_ARBITER_H */