summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/aha/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/aha/src')
-rw-r--r--xlators/cluster/aha/src/Makefile.am18
-rw-r--r--xlators/cluster/aha/src/aha-fops.c952
-rw-r--r--xlators/cluster/aha/src/aha-fops.h360
-rw-r--r--xlators/cluster/aha/src/aha-helpers.c46
-rw-r--r--xlators/cluster/aha/src/aha-helpers.h23
-rw-r--r--xlators/cluster/aha/src/aha-mem-types.h22
-rw-r--r--xlators/cluster/aha/src/aha-retry.c524
-rw-r--r--xlators/cluster/aha/src/aha-retry.h12
-rw-r--r--xlators/cluster/aha/src/aha.c345
-rw-r--r--xlators/cluster/aha/src/aha.h46
10 files changed, 2348 insertions, 0 deletions
diff --git a/xlators/cluster/aha/src/Makefile.am b/xlators/cluster/aha/src/Makefile.am
new file mode 100644
index 00000000000..006db127d28
--- /dev/null
+++ b/xlators/cluster/aha/src/Makefile.am
@@ -0,0 +1,18 @@
+
+xlator_LTLIBRARIES = aha.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
+
+aha_la_LDFLAGS = -module -avoid-version
+
+aha_la_SOURCES = aha.c aha-fops.c aha-helpers.c aha-retry.c
+aha_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = aha-mem-types.h aha.h aha-helpers.h aha.h aha-retry.h aha-fops.h
+
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/cluster/aha/src/aha-fops.c b/xlators/cluster/aha/src/aha-fops.c
new file mode 100644
index 00000000000..3b2ca641de2
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-fops.c
@@ -0,0 +1,952 @@
+#include "aha-fops.h"
+
+static void
+__save_fop (struct aha_fop *fop, struct aha_conf *conf)
+{
+ list_add_tail (&fop->list, &conf->failed);
+}
+
+void
+save_fop (struct aha_fop *fop, struct aha_conf *conf)
+{
+ LOCK (&conf->lock);
+ {
+ __save_fop (fop, conf);
+ }
+ UNLOCK (&conf->lock);
+}
+
+#define AHA_HANDLE_FOP(frame, type, cbk, obj, fn, args ...) \
+ do { \
+ struct aha_fop *fop = aha_fop_new (); \
+ if (!fop) { \
+ gf_log (GF_AHA, GF_LOG_CRITICAL, \
+ "Allocation failed, terminating " \
+ "to prevent a hung mount."); \
+ assert (0); \
+ } \
+ fop->stub = fop_##type##_stub (frame, aha_##type, \
+ args); \
+ fop->frame = frame; \
+ frame->local = fop; \
+ STACK_WIND (frame, cbk, obj, fn, args); \
+ } while (0) \
+
+/*
+ * AHA_HANDLE_FOP_CBK
+ *
+ * 1) If the error returned is ENOTCONN *and* the timer that waits
+ * for the server to come back has not expired, store the fop to retry later.
+ * 2) If the timer waiting for the server has expired, just unwind.
+ * 3) If the error returned is something other than ENOTCONN, just unwind.
+ *
+ */
+#define AHA_HANDLE_FOP_CBK(type, frame, args ...) \
+ do { \
+ struct aha_conf *conf = frame->this->private; \
+ struct aha_fop *fop = frame->local; \
+ if (op_ret != 0 && op_errno == ENOTCONN && \
+ !aha_is_timer_expired (conf)) { \
+ gf_log (GF_AHA, GF_LOG_WARNING, \
+ "Got ENOTCONN from client, storing " \
+ "to retry later!"); \
+ save_fop (fop, conf); \
+ } else { \
+ AHA_DESTROY_LOCAL (frame); \
+ STACK_UNWIND_STRICT (type, frame, args); \
+ } \
+ } while (0) \
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (lookup, frame, op_ret, op_errno, inode,
+ buf, xdata, postparent);
+ return 0;
+}
+
+
+int
+aha_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, lookup, aha_lookup_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lookup,
+ loc, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (stat, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+int
+aha_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, stat, aha_stat_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat,
+ loc, xdata);
+ return 0;
+}
+
+
+int
+aha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop, struct iatt *postop,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (setattr, frame, op_ret, op_errno, preop,
+ postop, xdata);
+ return 0;
+}
+
+
+int
+aha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, setattr, aha_setattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr,
+ loc, stbuf, valid, xdata);
+ return 0;
+}
+
+
+int
+aha_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop, struct iatt *postop, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fsetattr, frame, op_ret, op_errno, preop,
+ postop, xdata);
+ return 0;
+}
+
+int
+aha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fsetattr, aha_fsetattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetattr,
+ fd, stbuf, valid, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (truncate, frame, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+ return 0;
+}
+
+
+int
+aha_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, truncate, aha_truncate_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->truncate,
+ loc, offset, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (ftruncate, frame, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+ return 0;
+}
+
+
+int
+aha_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, ftruncate, aha_ftruncate_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->ftruncate,
+ fd, offset, xdata);
+ return 0;
+}
+
+
+int
+aha_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (access, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t mask, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, access, aha_access_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->access,
+ loc, mask, xdata);
+ return 0;
+}
+
+
+int
+aha_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ const char *path, struct iatt *sbuf, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (readlink, frame, op_ret, op_errno,
+ path, sbuf, xdata);
+ return 0;
+}
+
+
+int
+aha_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ size_t size, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, readlink, aha_readlink_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readlink,
+ loc, size, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (mknod, frame, op_ret, op_errno,
+ inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, mknod, aha_mknod_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mknod,
+ loc, mode, rdev, umask, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (mkdir, frame, op_ret, op_errno,
+ inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+int
+aha_mkdir (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, mkdir, aha_mkdir_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->mkdir,
+ loc, mode, umask, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (unlink, frame, op_ret, op_errno,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, unlink, aha_unlink_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->unlink,
+ loc, xflag, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (rmdir, frame, op_ret, op_errno,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, rmdir, aha_rmdir_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rmdir,
+ loc, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (symlink, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, symlink, aha_symlink_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->symlink,
+ linkpath, loc, umask, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (rename, frame, op_ret, op_errno, buf,
+ preoldparent, postoldparent,
+ prenewparent, postnewparent, xdata);
+ return 0;
+}
+
+
+int
+aha_rename (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, rename, aha_rename_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rename,
+ oldloc, newloc, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (link, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_link (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, link, aha_link_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->link,
+ oldloc, newloc, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP (frame, create, aha_create_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->create,
+ loc, flags, mode, umask, fd, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (open, frame, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+
+int
+aha_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags, fd_t *fd, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, open, aha_open_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->open,
+ loc, flags, fd, xdata);
+ return 0;
+}
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (readv, frame, op_ret, op_errno,
+ vector, count, stbuf, iobref, xdata);
+ return 0;
+}
+
+int
+aha_readv (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset, uint32_t flags,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, readv, aha_readv_cbk,
+ FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,
+ fd, size, offset, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (writev, frame, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+ return 0;
+}
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP (frame, writev, aha_writev_cbk,
+ FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,
+ fd, vector, count, off, flags, iobref, xdata);
+ return 0;
+}
+
+
+int
+aha_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (flush, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, flush, aha_flush_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->flush,
+ fd, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (fsync, frame, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+ return 0;
+}
+
+
+int
+aha_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fsync, aha_fsync_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsync,
+ fd, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (fstat, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+
+int
+aha_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fstat, aha_fstat_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat,
+ fd, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (opendir, frame, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+
+int
+aha_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, opendir, aha_opendir_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->opendir,
+ loc, fd, xdata);
+ return 0;
+}
+
+int
+aha_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fsyncdir, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fsyncdir, aha_fsyncdir_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsyncdir,
+ fd, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (statfs, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+
+int
+aha_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, statfs, aha_statfs_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->statfs,
+ loc, xdata);
+ return 0;
+}
+
+
+
+int
+aha_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (setxattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, setxattr, aha_setxattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setxattr,
+ loc, dict, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (getxattr, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, getxattr, aha_getxattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->getxattr,
+ loc, name, xdata);
+ return 0;
+}
+
+int
+aha_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fsetxattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fsetxattr, aha_fsetxattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetxattr,
+ fd, dict, flags, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fgetxattr, aha_fgetxattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fgetxattr,
+ fd, name, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (xattrop, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, xattrop, aha_xattrop_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->xattrop,
+ loc, flags, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fxattrop, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fxattrop, aha_fxattrop_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fxattrop,
+ fd, flags, dict, xdata);
+ return 0;
+}
+
+
+int
+aha_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (removexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, removexattr, aha_removexattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->removexattr,
+ loc, name, xdata);
+ return 0;
+}
+
+int
+aha_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fremovexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, fremovexattr, aha_fremovexattr_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fremovexattr,
+ fd, name, xdata);
+ return 0;
+}
+
+
+int
+aha_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (lk, frame, op_ret, op_errno, lock, xdata);
+ return 0;
+}
+
+
+int
+aha_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, lk, aha_lk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lk,
+ fd, cmd, lock, xdata);
+ return 0;
+}
+
+
+int
+aha_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (inodelk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, inodelk, aha_inodelk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->inodelk,
+ volume, loc, cmd, lock, xdata);
+ return 0;
+}
+
+
+int
+aha_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (finodelk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, finodelk, aha_finodelk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->finodelk,
+ volume, fd, cmd, lock, xdata);
+ return 0;
+}
+
+
+int
+aha_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (entrylk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP (frame, entrylk, aha_entrylk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->entrylk,
+ volume, loc, basename, cmd, type, xdata);
+ return 0;
+}
+
+
+int
+aha_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ AHA_HANDLE_FOP_CBK (fentrylk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP (frame, fentrylk, aha_fentrylk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fentrylk,
+ volume, fd, basename, cmd, type, xdata);
+ return 0;
+}
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (readdir, frame, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+
+int
+aha_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ size_t size, off_t off, dict_t *xdata)
+{
+ AHA_HANDLE_FOP (frame, readdir, aha_readdir_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdir,
+ fd, size, off, xdata);
+ return 0;
+}
+
+
+int
+aha_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)
+{
+ AHA_HANDLE_FOP_CBK (readdirp, frame, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+
+int
+aha_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *dict)
+{
+ AHA_HANDLE_FOP (frame, readdirp, aha_readdirp_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readdirp,
+ fd, size, off, dict);
+ return 0;
+}
diff --git a/xlators/cluster/aha/src/aha-fops.h b/xlators/cluster/aha/src/aha-fops.h
new file mode 100644
index 00000000000..b1fb9d38a80
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-fops.h
@@ -0,0 +1,360 @@
+#ifndef _AHA_FOPS_H
+#define _AHA_FOPS_H
+
+#include "aha.h"
+#include "aha-helpers.h"
+
+/* FOP functions */
+int
+aha_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+
+int
+aha_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+
+int
+aha_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+
+int
+aha_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+
+int
+aha_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset, dict_t *xdata);
+
+int
+aha_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, dict_t *xdata);
+
+int
+aha_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata);
+
+int
+aha_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata);
+
+int
+aha_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata);
+
+int
+aha_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata);
+
+int
+aha_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata);
+
+int
+aha_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata);
+
+int
+aha_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata);
+
+int
+aha_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata);
+
+int
+aha_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata);
+
+int
+aha_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);
+
+int
+aha_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata);
+
+int
+aha_readv (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset, uint32_t flags,
+ dict_t *xdata);
+
+int
+aha_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);
+
+int
+aha_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
+
+int
+aha_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dict_t *xdata);
+
+int
+aha_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
+
+int
+aha_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata);
+
+int
+aha_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata);
+
+int
+aha_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+
+int
+aha_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata);
+
+int
+aha_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata);
+
+int
+aha_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata);
+
+int
+aha_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata);
+
+int
+aha_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
+
+int
+aha_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
+
+int
+aha_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata);
+
+int
+aha_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata);
+
+int
+aha_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata);
+
+int
+aha_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock,
+ dict_t *xdata);
+
+int
+aha_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata);
+
+int
+aha_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);
+
+int
+aha_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);
+int
+aha_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata);
+
+int
+aha_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *dict);
+
+/* Callback functions */
+
+int
+aha_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);
+
+int
+aha_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);
+
+int
+aha_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop, struct iatt *postop, dict_t *xdata);
+
+int
+aha_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop, struct iatt *postop, dict_t *xdata);
+
+int
+aha_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);
+
+
+int
+aha_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);
+
+
+int
+aha_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+
+int
+aha_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ const char *path, struct iatt *sbuf, dict_t *xdata);
+
+
+int
+aha_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);
+
+
+int
+aha_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);
+
+int
+aha_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);
+
+int
+aha_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);
+int
+aha_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);
+int
+aha_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);
+
+int
+aha_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);
+int
+aha_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);
+int
+aha_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);
+int
+aha_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);
+
+int
+aha_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);
+int
+aha_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+aha_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);
+int
+aha_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);
+
+int
+aha_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);
+int
+aha_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_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);
+int
+aha_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_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);
+
+int
+aha_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+aha_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);
+
+int
+aha_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);
+
+int
+aha_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int
+aha_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+aha_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata);
+
+int
+aha_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+aha_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+int
+aha_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);
+int
+aha_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);
+
+#endif /* _AHA_FOPS_H */
diff --git a/xlators/cluster/aha/src/aha-helpers.c b/xlators/cluster/aha/src/aha-helpers.c
new file mode 100644
index 00000000000..e3b713688d3
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-helpers.c
@@ -0,0 +1,46 @@
+#include "aha-helpers.h"
+
+struct aha_conf *aha_conf_new ()
+{
+ struct aha_conf *conf = NULL;
+
+ conf = GF_CALLOC (1, sizeof (*conf), gf_aha_mt_conf);
+ if (!conf)
+ goto err;
+
+ INIT_LIST_HEAD (&conf->failed);
+
+ LOCK_INIT (&conf->lock);
+err:
+ return conf;
+}
+
+void aha_conf_destroy (struct aha_conf *conf)
+{
+ LOCK_DESTROY (&conf->lock);
+ GF_FREE (conf);
+}
+
+struct aha_fop *aha_fop_new ()
+{
+ struct aha_fop *fop = NULL;
+
+ fop = GF_CALLOC (1, sizeof (*fop), gf_aha_mt_fop);
+ if (!fop)
+ goto err;
+
+ INIT_LIST_HEAD (&fop->list);
+
+err:
+ return fop;
+}
+
+void aha_fop_destroy (struct aha_fop *fop)
+{
+ if (!fop)
+ return;
+
+ call_stub_destroy (fop->stub);
+ fop->stub = NULL;
+ GF_FREE (fop);
+}
diff --git a/xlators/cluster/aha/src/aha-helpers.h b/xlators/cluster/aha/src/aha-helpers.h
new file mode 100644
index 00000000000..d9cf9b3295d
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-helpers.h
@@ -0,0 +1,23 @@
+#ifndef _AHA_HELPERS_H
+#define _AHA_HELPERS_H
+
+#include "aha.h"
+
+#define GF_AHA "aha"
+
+struct aha_conf *aha_conf_new ();
+
+void aha_conf_destroy (struct aha_conf *conf);
+
+struct aha_fop *aha_fop_new ();
+
+void aha_fop_destroy (struct aha_fop *fop);
+
+#define AHA_DESTROY_LOCAL(frame) \
+ do { \
+ struct aha_fop *fop = frame->local; \
+ aha_fop_destroy (fop); \
+ frame->local = NULL; \
+ } while (0) \
+
+#endif /* _AHA_HELPERS_H */
diff --git a/xlators/cluster/aha/src/aha-mem-types.h b/xlators/cluster/aha/src/aha-mem-types.h
new file mode 100644
index 00000000000..117dda27e8b
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-mem-types.h
@@ -0,0 +1,22 @@
+/*
+ Copyright (c) 2008-2012 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 __AHA_MEM_TYPES_H__
+#define __AHA_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_aha_mem_types_ {
+ gf_aha_mt_begin_t = gf_common_mt_end + 1,
+ gf_aha_mt_conf,
+ gf_aha_mt_fop,
+ gf_aha_mt_end
+};
+#endif
diff --git a/xlators/cluster/aha/src/aha-retry.c b/xlators/cluster/aha/src/aha-retry.c
new file mode 100644
index 00000000000..8810f913f42
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-retry.c
@@ -0,0 +1,524 @@
+#include "aha.h"
+#include "aha-helpers.h"
+#include "aha-retry.h"
+#include "aha-fops.h"
+
+/*
+ * AHA_RETRY_FOP:
+ *
+ * - We STACK_WIND the fop using the arguments in the call_stub.
+ * We use STACK_WIND because we need a *new* frame, since we already
+ * exhausted the existing frame with the original STACK_WIND.
+ *
+ * - After STACK_WIND completes, we can destroy this frame's local (which
+ * should be struct aha_fop *). The frame itself will get destroyed higher in
+ * the xlator graph, since its still part of the call stack.
+ */
+#define AHA_RETRY_FOP(fop, type, args ...) \
+ do { \
+ call_stub_t *stub = fop->stub; \
+ call_frame_t *frame = fop->frame; \
+ xlator_t *this = frame->this; \
+ STACK_WIND (frame, aha_##type##_cbk, this, \
+ this->fops->type, args); \
+ AHA_DESTROY_LOCAL (frame); \
+ } while (0) \
+
+#define AHA_UNWIND_FOP(fop, type) \
+ do { \
+ call_frame_t *frame = fop->frame; \
+ AHA_DESTROY_LOCAL (frame); \
+ default_##type##_failure_cbk (frame, ETIMEDOUT); \
+ } while (0) \
+
+void
+__aha_retry_force_unwind_fops (struct aha_conf *conf)
+{
+ struct aha_fop *fop = NULL;
+ struct aha_fop *tmp = NULL;
+ size_t ndrained = 0;
+
+ /*
+ * Drain the queue. After we finish the loop, the list
+ * must be empty.
+ */
+ list_for_each_entry_safe (fop, tmp, &conf->failed, list) {
+ list_del (&fop->list);
+ aha_force_unwind_fop (fop);
+ ndrained++;
+ }
+
+ gf_log (GF_AHA, GF_LOG_WARNING,
+ "Force-unwound %"GF_PRI_SIZET" fops!", ndrained);
+
+ assert (list_empty (&conf->failed));
+}
+
+void
+aha_force_unwind_fops (struct aha_conf *conf)
+{
+ LOCK (&conf->lock);
+ {
+ __aha_retry_force_unwind_fops (conf);
+ }
+ UNLOCK (&conf->lock);
+}
+
+void
+__aha_retry_failed_fops (struct aha_conf *conf)
+{
+ struct aha_fop *fop = NULL;
+ struct aha_fop *tmp = NULL;
+ size_t ndrained = 0;
+
+ /*
+ * Skip if the child is not up
+ */
+ if (!conf->child_up) {
+ gf_log (GF_AHA, GF_LOG_WARNING,
+ "Waiting for child to come up before retrying.");
+ return;
+ }
+
+ /*
+ * Skip if the the queue is empty.
+ */
+ if (list_empty (&conf->failed)) {
+ gf_log (GF_AHA, GF_LOG_WARNING, "No FOPs to retry.");
+ }
+
+ /*
+ * Drain the queue. After we finish the loop, the list
+ * must be empty.
+ */
+ list_for_each_entry_safe (fop, tmp, &conf->failed, list) {
+ list_del (&fop->list);
+ aha_retry_fop (fop);
+ ndrained++;
+ }
+
+ gf_log (GF_AHA, GF_LOG_WARNING,
+ "Drained %"GF_PRI_SIZET" fops!", ndrained);
+
+ assert (list_empty (&conf->failed));
+}
+
+
+void
+aha_retry_failed_fops (struct aha_conf *conf)
+{
+ LOCK (&conf->lock);
+ {
+ __aha_retry_failed_fops (conf);
+ }
+ UNLOCK (&conf->lock);
+}
+
+void aha_retry_fop (struct aha_fop *fop)
+{
+ call_stub_t *stub = fop->stub;
+
+ switch (stub->fop) {
+ case GF_FOP_OPEN:
+ AHA_RETRY_FOP (fop, open, &stub->args.loc, stub->args.flags,
+ stub->args.fd, stub->args.xdata);
+ break;
+
+ case GF_FOP_CREATE:
+ AHA_RETRY_FOP (fop, create, &stub->args.loc, stub->args.flags,
+ stub->args.mode, stub->args.umask,
+ stub->args.fd,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_STAT:
+ AHA_RETRY_FOP (fop, stat, &stub->args.loc, stub->args.xdata);
+ break;
+
+ case GF_FOP_READLINK:
+ AHA_RETRY_FOP (fop, readlink, &stub->args.loc,
+ stub->args.size, stub->args.xdata);
+ break;
+
+ case GF_FOP_MKNOD:
+ AHA_RETRY_FOP (fop, mknod, &stub->args.loc, stub->args.mode,
+ stub->args.rdev, stub->args.umask,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_MKDIR:
+ AHA_RETRY_FOP (fop, mkdir, &stub->args.loc, stub->args.mode,
+ stub->args.umask, stub->args.xdata);
+ break;
+
+ case GF_FOP_UNLINK:
+ AHA_RETRY_FOP (fop, unlink, &stub->args.loc, stub->args.xflag,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_RMDIR:
+ AHA_RETRY_FOP (fop, rmdir, &stub->args.loc,
+ stub->args.flags, stub->args.xdata);
+ break;
+
+ case GF_FOP_SYMLINK:
+ AHA_RETRY_FOP (fop, symlink, stub->args.linkname,
+ &stub->args.loc, stub->args.umask,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_RENAME:
+ AHA_RETRY_FOP (fop, rename, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
+
+ case GF_FOP_LINK:
+ AHA_RETRY_FOP (fop, link, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
+
+ case GF_FOP_TRUNCATE:
+ AHA_RETRY_FOP (fop, truncate, &stub->args.loc,
+ stub->args.offset, stub->args.xdata);
+ break;
+
+ case GF_FOP_READ:
+ AHA_RETRY_FOP (fop, readv, stub->args.fd, stub->args.size,
+ stub->args.offset, stub->args.flags,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_WRITE:
+ AHA_RETRY_FOP (fop, writev, stub->args.fd, stub->args.vector,
+ stub->args.count, stub->args.offset,
+ stub->args.flags, stub->args.iobref,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_STATFS:
+ AHA_RETRY_FOP (fop, statfs, &stub->args.loc, stub->args.xdata);
+ break;
+
+ case GF_FOP_FLUSH:
+ AHA_RETRY_FOP (fop, flush, stub->args.fd, stub->args.xdata);
+ break;
+
+ case GF_FOP_FSYNC:
+ AHA_RETRY_FOP (fop, fsync, stub->args.fd, stub->args.datasync,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_SETXATTR:
+ AHA_RETRY_FOP (fop, setxattr, &stub->args.loc, stub->args.xattr,
+ stub->args.flags, stub->args.xdata);
+ break;
+
+ case GF_FOP_GETXATTR:
+ AHA_RETRY_FOP (fop, getxattr, &stub->args.loc,
+ stub->args.name, stub->args.xdata);
+ break;
+
+ case GF_FOP_FSETXATTR:
+ AHA_RETRY_FOP (fop, fsetxattr, stub->args.fd,
+ stub->args.xattr, stub->args.flags,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_FGETXATTR:
+ AHA_RETRY_FOP (fop, fgetxattr, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
+
+ case GF_FOP_REMOVEXATTR:
+ AHA_RETRY_FOP (fop, removexattr, &stub->args.loc,
+ stub->args.name, stub->args.xdata);
+ break;
+
+ case GF_FOP_FREMOVEXATTR:
+ AHA_RETRY_FOP (fop, fremovexattr, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
+
+ case GF_FOP_OPENDIR:
+ AHA_RETRY_FOP (fop, opendir, &stub->args.loc,
+ stub->args.fd, stub->args.xdata);
+ break;
+
+ case GF_FOP_FSYNCDIR:
+ AHA_RETRY_FOP (fop, fsyncdir, stub->args.fd,
+ stub->args.datasync, stub->args.xdata);
+ break;
+
+ case GF_FOP_ACCESS:
+ AHA_RETRY_FOP (fop, access, &stub->args.loc,
+ stub->args.mask, stub->args.xdata);
+ break;
+
+ case GF_FOP_FTRUNCATE:
+ AHA_RETRY_FOP (fop, ftruncate, stub->args.fd,
+ stub->args.offset, stub->args.xdata);
+ break;
+
+ case GF_FOP_FSTAT:
+ AHA_RETRY_FOP (fop, fstat, stub->args.fd, stub->args.xdata);
+ break;
+
+ case GF_FOP_LK:
+ AHA_RETRY_FOP (fop, lk, stub->args.fd, stub->args.cmd,
+ &stub->args.lock, stub->args.xdata);
+ break;
+
+ case GF_FOP_INODELK:
+ AHA_RETRY_FOP (fop, inodelk, stub->args.volume,
+ &stub->args.loc, stub->args.cmd,
+ &stub->args.lock, stub->args.xdata);
+ break;
+
+ case GF_FOP_FINODELK:
+ AHA_RETRY_FOP (fop, finodelk, stub->args.volume,
+ stub->args.fd, stub->args.cmd,
+ &stub->args.lock, stub->args.xdata);
+ break;
+
+ case GF_FOP_ENTRYLK:
+ AHA_RETRY_FOP (fop, entrylk, stub->args.volume, &stub->args.loc,
+ stub->args.name, stub->args.entrylkcmd,
+ stub->args.entrylktype, stub->args.xdata);
+ break;
+
+ case GF_FOP_FENTRYLK:
+ AHA_RETRY_FOP (fop, fentrylk, stub->args.volume, stub->args.fd,
+ stub->args.name, stub->args.entrylkcmd,
+ stub->args.entrylktype, stub->args.xdata);
+ break;
+
+ case GF_FOP_LOOKUP:
+ AHA_RETRY_FOP (fop, lookup, &stub->args.loc, stub->args.xdata);
+ break;
+
+ case GF_FOP_READDIR:
+ AHA_RETRY_FOP (fop, readdir, stub->args.fd, stub->args.size,
+ stub->args.offset, stub->args.xdata);
+ break;
+
+ case GF_FOP_READDIRP:
+ AHA_RETRY_FOP (fop, readdirp, stub->args.fd, stub->args.size,
+ stub->args.offset, stub->args.xdata);
+ break;
+
+ case GF_FOP_XATTROP:
+ AHA_RETRY_FOP (fop, xattrop, &stub->args.loc, stub->args.optype,
+ stub->args.xattr, stub->args.xdata);
+ break;
+
+ case GF_FOP_FXATTROP:
+ AHA_RETRY_FOP (fop, fxattrop, stub->args.fd, stub->args.optype,
+ stub->args.xattr, stub->args.xdata);
+ break;
+
+ case GF_FOP_SETATTR:
+ AHA_RETRY_FOP (fop, setattr, &stub->args.loc, &stub->args.stat,
+ stub->args.valid, stub->args.xdata);
+ break;
+
+ case GF_FOP_FSETATTR:
+ AHA_RETRY_FOP (fop, fsetattr, stub->args.fd, &stub->args.stat,
+ stub->args.valid, stub->args.xdata);
+ break;
+
+ default:
+ /* Some fops are not implemented yet:
+ *
+ * GF_FOP_NULL
+ * GF_FOP_RCHECKSUM
+ * GF_FOP_FORGET
+ * GF_FOP_RELEASE
+ * GF_FOP_RELEASEDIR
+ * GF_FOP_GETSPEC
+ * GF_FOP_FALLOCATE
+ * GF_FOP_DISCARD
+ * GF_FOP_ZEROFILL
+ * GF_FOP_MAXVALUE
+ *
+ */
+ gf_log (GF_AHA, GF_LOG_CRITICAL, "Got unexpected FOP %s",
+ gf_fop_list[stub->fop]);
+ assert (0);
+ break;
+ }
+}
+
+void
+aha_force_unwind_fop (struct aha_fop *fop)
+{
+ call_stub_t *stub = fop->stub;
+
+ switch (stub->fop) {
+ case GF_FOP_OPEN:
+ AHA_UNWIND_FOP (fop, open);
+ break;
+
+ case GF_FOP_CREATE:
+ AHA_UNWIND_FOP (fop, create);
+ break;
+
+ case GF_FOP_STAT:
+ AHA_UNWIND_FOP (fop, stat);
+ break;
+
+ case GF_FOP_READLINK:
+ AHA_UNWIND_FOP (fop, readlink);
+ break;
+
+ case GF_FOP_MKNOD:
+ AHA_UNWIND_FOP (fop, mknod);
+ break;
+
+ case GF_FOP_MKDIR:
+ AHA_UNWIND_FOP (fop, mkdir);
+ break;
+
+ case GF_FOP_UNLINK:
+ AHA_UNWIND_FOP (fop, unlink);
+ break;
+
+ case GF_FOP_RMDIR:
+ AHA_UNWIND_FOP (fop, rmdir);
+ break;
+
+ case GF_FOP_SYMLINK:
+ AHA_UNWIND_FOP (fop, symlink);
+ break;
+
+ case GF_FOP_RENAME:
+ AHA_UNWIND_FOP (fop, rename);
+ break;
+
+ case GF_FOP_LINK:
+ AHA_UNWIND_FOP (fop, link);
+ break;
+
+ case GF_FOP_TRUNCATE:
+ AHA_UNWIND_FOP (fop, truncate);
+ break;
+
+ case GF_FOP_READ:
+ AHA_UNWIND_FOP (fop, readv);
+ break;
+
+ case GF_FOP_WRITE:
+ AHA_UNWIND_FOP (fop, writev);
+ break;
+
+ case GF_FOP_STATFS:
+ AHA_UNWIND_FOP (fop, statfs);
+ break;
+
+ case GF_FOP_FLUSH:
+ AHA_UNWIND_FOP (fop, flush);
+ break;
+
+ case GF_FOP_FSYNC:
+ AHA_UNWIND_FOP (fop, fsync);
+ break;
+
+ case GF_FOP_SETXATTR:
+ AHA_UNWIND_FOP (fop, setxattr);
+ break;
+
+ case GF_FOP_GETXATTR:
+ AHA_UNWIND_FOP (fop, getxattr);
+ break;
+
+ case GF_FOP_FSETXATTR:
+ AHA_UNWIND_FOP (fop, fsetxattr);
+ break;
+
+ case GF_FOP_FGETXATTR:
+ AHA_UNWIND_FOP (fop, fgetxattr);
+ break;
+
+ case GF_FOP_REMOVEXATTR:
+ AHA_UNWIND_FOP (fop, removexattr);
+ break;
+
+ case GF_FOP_FREMOVEXATTR:
+ AHA_UNWIND_FOP (fop, fremovexattr);
+ break;
+
+ case GF_FOP_OPENDIR:
+ AHA_UNWIND_FOP (fop, opendir);
+ break;
+
+ case GF_FOP_FSYNCDIR:
+ AHA_UNWIND_FOP (fop, fsyncdir);
+ break;
+
+ case GF_FOP_ACCESS:
+ AHA_UNWIND_FOP (fop, access);
+ break;
+
+ case GF_FOP_FTRUNCATE:
+ AHA_UNWIND_FOP (fop, ftruncate);
+ break;
+
+ case GF_FOP_FSTAT:
+ AHA_UNWIND_FOP (fop, fstat);
+ break;
+
+ case GF_FOP_LK:
+ AHA_UNWIND_FOP (fop, lk);
+ break;
+
+ case GF_FOP_INODELK:
+ AHA_UNWIND_FOP (fop, inodelk);
+ break;
+
+ case GF_FOP_FINODELK:
+ AHA_UNWIND_FOP (fop, finodelk);
+ break;
+
+ case GF_FOP_ENTRYLK:
+ AHA_UNWIND_FOP (fop, entrylk);
+ break;
+
+ case GF_FOP_FENTRYLK:
+ AHA_UNWIND_FOP (fop, fentrylk);
+ break;
+
+ case GF_FOP_LOOKUP:
+ AHA_UNWIND_FOP (fop, lookup);
+ break;
+
+ case GF_FOP_READDIR:
+ AHA_UNWIND_FOP (fop, readdir);
+ break;
+
+ case GF_FOP_READDIRP:
+ AHA_UNWIND_FOP (fop, readdirp);
+ break;
+
+ case GF_FOP_XATTROP:
+ AHA_UNWIND_FOP (fop, xattrop);
+ break;
+
+ case GF_FOP_FXATTROP:
+ AHA_UNWIND_FOP (fop, fxattrop);
+ break;
+
+ case GF_FOP_SETATTR:
+ AHA_UNWIND_FOP (fop, setattr);
+ break;
+
+ case GF_FOP_FSETATTR:
+ AHA_UNWIND_FOP (fop, fsetattr);
+ break;
+
+ default:
+ /* Some fops are not implemented yet,
+ * and this would never happen cause we wouldn't
+ * queue them (see the assert statement in aha_retry_fop())
+ */
+ break;
+ }
+}
diff --git a/xlators/cluster/aha/src/aha-retry.h b/xlators/cluster/aha/src/aha-retry.h
new file mode 100644
index 00000000000..5c8f56bca97
--- /dev/null
+++ b/xlators/cluster/aha/src/aha-retry.h
@@ -0,0 +1,12 @@
+#ifndef _AHA_RETRY_H
+#define _AHA_RETRY_H
+
+void aha_retry_failed_fops (struct aha_conf *conf);
+
+void aha_retry_fop (struct aha_fop *fop);
+
+void aha_force_unwind_fops (struct aha_conf *conf);
+
+void aha_force_unwind_fop (struct aha_fop *fop);
+
+#endif /* _AHA_RETRY_H */
diff --git a/xlators/cluster/aha/src/aha.c b/xlators/cluster/aha/src/aha.c
new file mode 100644
index 00000000000..2135e47f37f
--- /dev/null
+++ b/xlators/cluster/aha/src/aha.c
@@ -0,0 +1,345 @@
+#include "aha-helpers.h"
+#include "aha-retry.h"
+#include "aha-fops.h"
+#include "aha.h"
+
+#include "syncop.h"
+
+
+int
+retry_failed_fops_cbk (int ret, call_frame_t *frame, void *arg)
+{
+ /* Nothing to do here ... */
+ return 0;
+}
+
+int
+retry_failed_fops (void *arg)
+{
+ xlator_t *this = NULL;
+
+ struct aha_conf *conf = NULL;
+
+ this = arg;
+ conf = this->private;
+
+ aha_retry_failed_fops (conf);
+
+ return 0;
+}
+
+void
+dispatch_fop_queue_drain (xlator_t *this)
+{
+ struct syncenv *env = NULL;
+ int ret = 0;
+
+ env = this->ctx->env;
+
+ ret = synctask_new (env, retry_failed_fops,
+ retry_failed_fops_cbk, NULL, this);
+ if (ret != 0) {
+ gf_log (GF_AHA, GF_LOG_CRITICAL,
+ "Failed to dispatch synctask "
+ "to drain fop queue!");
+ }
+}
+
+inline void
+__aha_set_timer_status (struct aha_conf *conf, gf_boolean_t expired)
+{
+ conf->timer_expired = expired;
+}
+
+inline gf_boolean_t
+__aha_is_timer_expired (struct aha_conf *conf)
+{
+ return conf->timer_expired;
+}
+
+gf_boolean_t
+aha_is_timer_expired (struct aha_conf *conf)
+{
+ gf_boolean_t expired = _gf_false;
+
+ LOCK (&conf->lock);
+ {
+ expired = __aha_is_timer_expired (conf);
+ }
+ UNLOCK (&conf->lock);
+
+ return expired;
+}
+
+void
+aha_child_down_timer_expired (void *data)
+{
+ struct aha_conf *conf = NULL;
+
+ conf = data;
+
+ gf_log (GF_AHA, GF_LOG_INFO, "Timer expired!");
+
+ LOCK (&conf->lock);
+ {
+ __aha_set_timer_status (conf, _gf_true);
+ }
+ UNLOCK (&conf->lock);
+
+ aha_force_unwind_fops ((struct aha_conf *)data);
+}
+
+void
+__aha_start_timer (struct aha_conf *conf)
+{
+ struct timespec child_down_timeout = {
+ .tv_sec = conf->server_wait_timeout,
+ .tv_nsec = 0
+ };
+
+ __aha_set_timer_status (conf, _gf_false);
+
+ conf->timer = gf_timer_call_after (conf->this->ctx, child_down_timeout,
+ aha_child_down_timer_expired, conf);
+ if (!conf->timer) {
+ gf_log (GF_AHA, GF_LOG_CRITICAL, "Failed to start the timer!");
+ }
+
+ gf_log (GF_AHA, GF_LOG_INFO,
+ "Registered timer for %lu seconds.",
+ conf->server_wait_timeout);
+}
+
+void
+__aha_cancel_timer (struct aha_conf *conf)
+{
+ if (!conf->timer)
+ goto out;
+
+ gf_timer_call_cancel (conf->this->ctx, conf->timer);
+ conf->timer = NULL;
+ gf_log (GF_AHA, GF_LOG_INFO, "Timer cancelled!");
+out:
+ return;
+}
+
+void
+__aha_update_child_status (struct aha_conf *conf, int status)
+{
+ conf->child_up = status;
+}
+
+void
+aha_handle_child_up (xlator_t *this)
+{
+ struct aha_conf *conf = this->private;
+
+ LOCK (&conf->lock);
+ {
+ __aha_update_child_status (
+ conf, AHA_CHILD_STATUS_UP); /* Mark the child as up */
+ __aha_set_timer_status (
+ conf, _gf_false); /* Timer is no longer expired */
+ __aha_cancel_timer (conf); /* Cancel the timer */
+ }
+ UNLOCK (&conf->lock);
+}
+
+void
+aha_handle_child_down (xlator_t *this)
+{
+ struct aha_conf *conf = this->private;
+
+ LOCK (&conf->lock);
+ {
+ __aha_update_child_status (conf, AHA_CHILD_STATUS_DOWN);
+ __aha_set_timer_status (conf, _gf_true);
+ __aha_start_timer (conf);
+ }
+ UNLOCK (&conf->lock);
+}
+
+int32_t
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ switch (event) {
+ case GF_EVENT_CHILD_DOWN:
+ gf_log (this->name, GF_LOG_WARNING, "Got child-down event!");
+ aha_handle_child_down (this);
+ break;
+ case GF_EVENT_CHILD_UP:
+ gf_log (this->name, GF_LOG_WARNING, "Got child-up event!");
+ aha_handle_child_up (this);
+ dispatch_fop_queue_drain (this);
+ break;
+ default:
+ break;
+ }
+
+ default_notify (this, event, data);
+
+ return 0;
+}
+
+int32_t
+aha_priv_dump (xlator_t *this)
+{
+ return 0;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_aha_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Memory accounting init failed!");
+ return ret;
+ }
+
+ return ret;
+}
+
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ struct aha_conf *conf = NULL;
+
+ conf = this->private;
+
+ GF_OPTION_RECONF ("server-wait-timeout-seconds",
+ conf->server_wait_timeout,
+ options, size_uint64, err);
+
+ return 0;
+err:
+ return -1;
+}
+
+int
+aha_init_options (xlator_t *this)
+{
+ struct aha_conf *conf = NULL;
+
+ conf = this->private;
+
+ GF_OPTION_INIT ("server-wait-timeout-seconds",
+ conf->server_wait_timeout,
+ size_uint64, err);
+
+ return 0;
+err:
+ return -1;
+}
+
+
+int
+init (xlator_t *this)
+{
+ int ret = 0;
+ struct aha_conf *conf = NULL;
+
+ conf = aha_conf_new ();
+ if (!conf) {
+ ret = -(ENOMEM);
+ goto err;
+ }
+
+ conf->this = this;
+ this->private = conf;
+
+ aha_init_options (this);
+
+ /* init() completed successfully */
+ goto done;
+err:
+ gf_log (GF_AHA, GF_LOG_ERROR,
+ "init() failed, please see "
+ "logs for details.");
+
+ /* Free all allocated memory */
+ aha_conf_destroy (conf);
+done:
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ struct aha_conf *conf = this->private;
+
+ aha_conf_destroy (conf);
+
+ this->private = NULL;
+}
+
+struct xlator_dumpops dumpops = {
+ .priv = aha_priv_dump,
+};
+
+struct xlator_fops cbks;
+
+struct xlator_fops fops = {
+ .lookup = aha_lookup,
+ .stat = aha_stat,
+ .readlink = aha_readlink,
+ .mknod = aha_mknod,
+ .mkdir = aha_mkdir,
+ .unlink = aha_unlink,
+ .rmdir = aha_rmdir,
+ .symlink = aha_symlink,
+ .rename = aha_rename,
+ .link = aha_link,
+ .truncate = aha_truncate,
+ .create = aha_create,
+ .open = aha_open,
+ .readv = aha_readv,
+ .writev = aha_writev,
+ .statfs = aha_statfs,
+ .flush = aha_flush,
+ .fsync = aha_fsync,
+ .setxattr = aha_setxattr,
+ .getxattr = aha_getxattr,
+ .removexattr = aha_removexattr,
+ .fsetxattr = aha_fsetxattr,
+ .fgetxattr = aha_fgetxattr,
+ .fremovexattr = aha_fremovexattr,
+ .opendir = aha_opendir,
+ .readdir = aha_readdir,
+ .readdirp = aha_readdirp,
+ .fsyncdir = aha_fsyncdir,
+ .access = aha_access,
+ .ftruncate = aha_ftruncate,
+ .fstat = aha_fstat,
+ .lk = aha_lk,
+ .lookup_cbk = aha_lookup_cbk,
+ .xattrop = aha_xattrop,
+ .fxattrop = aha_fxattrop,
+ .inodelk = aha_inodelk,
+ .finodelk = aha_finodelk,
+ .entrylk = aha_entrylk,
+ .fentrylk = aha_fentrylk,
+ .setattr = aha_setattr,
+ .fsetattr = aha_fsetattr,
+};
+
+struct volume_options options[] = {
+ { .key = {"server-wait-timeout-seconds"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 10,
+ .max = 20 * 60,
+ .default_value = TOSTRING (120),
+ .description = "Specifies the number of seconds the "
+ "AHA translator will wait "
+ "for a CHILD_UP event before "
+ "force-unwinding the frames it has "
+ "currently stored for retry."
+ },
+ { .key = {NULL} }
+};
diff --git a/xlators/cluster/aha/src/aha.h b/xlators/cluster/aha/src/aha.h
new file mode 100644
index 00000000000..3dbf3199776
--- /dev/null
+++ b/xlators/cluster/aha/src/aha.h
@@ -0,0 +1,46 @@
+#ifndef _AHA_H
+#define _AHA_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xlator.h"
+#include "statedump.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "list.h"
+#include "timer.h"
+
+#include "aha-mem-types.h"
+
+/* new() and destroy() functions for all structs can be found in
+ * aha-helpers.c
+ */
+struct aha_conf {
+ xlator_t *this;
+ uint8_t child_up;
+ gf_lock_t lock;
+ struct list_head failed;
+ gf_timer_t *timer;
+ gf_boolean_t timer_expired;
+ uint64_t server_wait_timeout;
+};
+
+struct aha_fop {
+ call_stub_t *stub; /* Only used to store function arguments */
+ call_frame_t *frame; /* Frame corresponding to this fop */
+ uint64_t tries;
+ struct list_head list;
+};
+
+enum {
+ AHA_CHILD_STATUS_DOWN = 0,
+ AHA_CHILD_STATUS_UP = 1,
+ AHA_CHILD_STATUS_MAX
+};
+
+gf_boolean_t aha_is_timer_expired (struct aha_conf *conf);
+
+#endif