summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--libglusterfs/src/defaults.c502
-rw-r--r--libglusterfs/src/defaults.h312
-rw-r--r--xlators/features/Makefile.am2
-rw-r--r--xlators/features/barrier/Makefile.am3
-rw-r--r--xlators/features/barrier/src/Makefile.am16
-rw-r--r--xlators/features/barrier/src/barrier-mem-types.h20
-rw-r--r--xlators/features/barrier/src/barrier.c520
-rw-r--r--xlators/features/barrier/src/barrier.h91
9 files changed, 1424 insertions, 44 deletions
diff --git a/configure.ac b/configure.ac
index 696ebfa3695..f1bb2a184ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,6 +121,8 @@ AC_CONFIG_FILES([Makefile
xlators/features/mac-compat/src/Makefile
xlators/features/quiesce/Makefile
xlators/features/quiesce/src/Makefile
+ xlators/features/barrier/Makefile
+ xlators/features/barrier/src/Makefile
xlators/features/index/Makefile
xlators/features/index/src/Makefile
xlators/features/protect/Makefile
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index f5fb2aa9d0a..8a1c281a5e0 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -373,6 +373,464 @@ default_getspec_failure_cbk (call_frame_t *frame, int32_t op_errno)
return 0;
}
+/* _cbk_resume section */
+
+int32_t
+default_lookup_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
+ xdata, postparent);
+ return 0;
+}
+
+int32_t
+default_stat_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+
+int32_t
+default_truncate_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
+ postbuf, xdata);
+ return 0;
+}
+
+int32_t
+default_ftruncate_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
+ postbuf, xdata);
+ return 0;
+}
+
+int32_t
+default_access_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+default_readlink_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
+ xdata);
+ return 0;
+}
+
+
+int32_t
+default_mknod_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
+ buf, preparent, postparent, xdata);
+ return 0;
+}
+
+int32_t
+default_mkdir_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
+ buf, preparent, postparent, xdata);
+ return 0;
+}
+
+int32_t
+default_unlink_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+int32_t
+default_rmdir_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
+ postparent, xdata);
+ return 0;
+}
+
+
+int32_t
+default_symlink_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int32_t
+default_rename_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent, xdata);
+ return 0;
+}
+
+
+int32_t
+default_link_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+
+int32_t
+default_create_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent, xdata);
+ return 0;
+}
+
+int32_t
+default_open_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+int32_t
+default_readv_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
+ stbuf, iobref, xdata);
+ return 0;
+}
+
+
+int32_t
+default_writev_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
+
+
+int32_t
+default_flush_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+
+int32_t
+default_fsync_cbk_resume (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)
+{
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
+ xdata);
+ return 0;
+}
+
+int32_t
+default_fstat_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+int32_t
+default_opendir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
+ return 0;
+}
+
+int32_t
+default_fsyncdir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+default_statfs_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct statvfs *buf, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
+ return 0;
+}
+
+
+int32_t
+default_setxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_fsetxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+
+int32_t
+default_fgetxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int32_t
+default_getxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+default_xattrop_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+int32_t
+default_fxattrop_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
+ return 0;
+}
+
+
+int32_t
+default_removexattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_fremovexattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+default_lk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
+ return 0;
+}
+
+int32_t
+default_inodelk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_finodelk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+default_entrylk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+int32_t
+default_fentrylk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
+ return 0;
+}
+
+
+int32_t
+default_rchecksum_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ uint32_t weak_checksum, uint8_t *strong_checksum,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
+ strong_checksum, xdata);
+ return 0;
+}
+
+
+int32_t
+default_readdir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+
+int32_t
+default_readdirp_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
+ return 0;
+}
+
+int32_t
+default_setattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
+ statpost, xdata);
+ return 0;
+}
+
+int32_t
+default_fsetattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
+ statpost, xdata);
+ return 0;
+}
+
+int32_t
+default_fallocate_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *pre, struct iatt *post,
+ dict_t *xdata)
+{
+ STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno,
+ pre, post, xdata);
+ return 0;
+}
+
+int32_t
+default_discard_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
+default_zerofill_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre,
+ post, xdata);
+ return 0;
+}
+
+
+int32_t
+default_getspec_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, char *spec_data)
+{
+ STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
+ return 0;
+}
+
/* _CBK function section */
int32_t
@@ -805,8 +1263,8 @@ default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
struct iatt *post, dict_t *xdata)
{
- STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
+ STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
}
int32_t
@@ -814,8 +1272,8 @@ default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
struct iatt *post, dict_t *xdata)
{
- STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
+ STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
}
int32_t
@@ -1239,21 +1697,21 @@ default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_fallocate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
{
- STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len,
- xdata);
+ STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len,
+ xdata);
return 0;
}
int32_t
default_discard_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
+ off_t offset, size_t len, dict_t *xdata)
{
- STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len,
- xdata);
+ STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->discard, fd, offset, len,
+ xdata);
return 0;
}
@@ -1674,22 +2132,22 @@ default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
{
- STACK_WIND_TAIL(frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset,
- len, xdata);
- return 0;
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset,
+ len, xdata);
+ return 0;
}
int32_t
default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
+ off_t offset, size_t len, dict_t *xdata)
{
- STACK_WIND_TAIL(frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len,
- xdata);
- return 0;
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->discard, fd, offset, len,
+ xdata);
+ return 0;
}
int32_t
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index f0b786ddf5a..1b33e809900 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -244,16 +244,16 @@ int32_t default_fsetattr (call_frame_t *frame,
int32_t valid, dict_t *xdata);
int32_t default_fallocate(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t keep_size, off_t offset,
- size_t len, dict_t *xdata);
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
int32_t default_discard(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- size_t len, dict_t *xdata);
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
int32_t default_zerofill(call_frame_t *frame,
xlator_t *this,
@@ -473,16 +473,16 @@ int32_t default_fsetattr_resume (call_frame_t *frame,
int32_t valid, dict_t *xdata);
int32_t default_fallocate_resume(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t keep_size, off_t offset,
- size_t len, dict_t *xdata);
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
int32_t default_discard_resume(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- size_t len, dict_t *xdata);
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset,
+ size_t len, dict_t *xdata);
int32_t default_zerofill_resume(call_frame_t *frame,
xlator_t *this,
@@ -491,9 +491,279 @@ int32_t default_zerofill_resume(call_frame_t *frame,
off_t len, dict_t *xdata);
-/* _cbk */
+/* _cbk_resume */
+
+int32_t
+default_lookup_cbk_resume (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);
+
+int32_t
+default_stat_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t * xdata);
+
+
+int32_t
+default_truncate_cbk_resume (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);
+
+int32_t
+default_ftruncate_cbk_resume (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);
+
+int32_t
+default_access_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata);
+
+int32_t
+default_readlink_cbk_resume (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);
+
+
+int32_t
+default_mknod_cbk_resume (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);
+
+int32_t
+default_mkdir_cbk_resume (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);
+
+int32_t
+default_unlink_cbk_resume (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);
+
+int32_t
+default_rmdir_cbk_resume (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);
+
+
+int32_t
+default_symlink_cbk_resume (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);
+
+
+int32_t
+default_rename_cbk_resume (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);
+
+
+int32_t
+default_link_cbk_resume (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);
+
+
+int32_t
+default_create_cbk_resume (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);
+
+int32_t
+default_open_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, fd_t * fd,
+ dict_t * xdata);
+
+int32_t
+default_readv_cbk_resume (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);
+
+
+int32_t
+default_writev_cbk_resume (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);
+
+
+int32_t
+default_flush_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, dict_t * xdata);
+
+
+
+int32_t
+default_fsync_cbk_resume (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);
+
+int32_t
+default_fstat_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t * xdata);
int32_t
+default_opendir_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ fd_t * fd, dict_t * xdata);
+
+int32_t
+default_fsyncdir_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+int32_t
+default_statfs_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct statvfs *buf, dict_t * xdata);
+
+
+int32_t
+default_setxattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+
+int32_t
+default_fsetxattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+
+
+int32_t
+default_fgetxattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * dict,
+ dict_t * xdata);
+
+
+int32_t
+default_getxattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * dict, dict_t * xdata);
+
+int32_t
+default_xattrop_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * dict, dict_t * xdata);
+
+int32_t
+default_fxattrop_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * dict, dict_t * xdata);
+
+
+int32_t
+default_removexattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+int32_t
+default_fremovexattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+int32_t
+default_lk_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
+ int32_t op_ret, int32_t op_errno,
+ struct gf_flock *lock, dict_t * xdata);
+
+int32_t
+default_inodelk_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata);
+
+
+int32_t
+default_finodelk_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+int32_t
+default_entrylk_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ dict_t * xdata);
+
+int32_t
+default_fentrylk_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, dict_t * xdata);
+
+
+int32_t
+default_rchecksum_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, uint32_t weak_checksum,
+ uint8_t * strong_checksum, dict_t * xdata);
+
+
+int32_t
+default_readdir_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ gf_dirent_t * entries, dict_t * xdata);
+
+
+int32_t
+default_readdirp_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t * entries,
+ dict_t * xdata);
+
+int32_t
+default_setattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t * xdata);
+
+int32_t
+default_fsetattr_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t * xdata);
+
+int32_t default_fallocate_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t * xdata);
+
+int32_t default_discard_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t * xdata);
+
+int32_t default_zerofill_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret,
+ int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t * xdata);
+
+int32_t
+default_getspec_cbk_resume (call_frame_t * frame, void *cookie,
+ xlator_t * this, int32_t op_ret, int32_t op_errno,
+ char *spec_data);
+
+/* _CBK */
+int32_t
default_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);
@@ -702,12 +972,12 @@ default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct iatt *statpost, dict_t *xdata);
int32_t default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata);
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
int32_t default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata);
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
int32_t default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am
index d2f5ef19290..1fdd474c20a 100644
--- a/xlators/features/Makefile.am
+++ b/xlators/features/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = locks quota read-only mac-compat quiesce marker index \
+SUBDIRS = locks quota read-only mac-compat quiesce marker index barrier \
protect compress changelog gfid-access $(GLUPY_SUBDIR) qemu-block # trash path-converter # filter
CLEANFILES =
diff --git a/xlators/features/barrier/Makefile.am b/xlators/features/barrier/Makefile.am
new file mode 100644
index 00000000000..a985f42a877
--- /dev/null
+++ b/xlators/features/barrier/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/features/barrier/src/Makefile.am b/xlators/features/barrier/src/Makefile.am
new file mode 100644
index 00000000000..8859be328d3
--- /dev/null
+++ b/xlators/features/barrier/src/Makefile.am
@@ -0,0 +1,16 @@
+xlator_LTLIBRARIES = barrier.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
+
+barrier_la_LDFLAGS = -module -avoid-version
+
+barrier_la_SOURCES = barrier.c
+
+barrier_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = barrier.h barrier-mem-types.h
+
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/features/barrier/src/barrier-mem-types.h b/xlators/features/barrier/src/barrier-mem-types.h
new file mode 100644
index 00000000000..36647a66966
--- /dev/null
+++ b/xlators/features/barrier/src/barrier-mem-types.h
@@ -0,0 +1,20 @@
+/*
+ Copyright (c) 2014 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 __BARRIER_MEM_TYPES_H__
+#define __BARRIER_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_barrier_mem_types_ {
+ gf_barrier_mt_priv_t = gf_common_mt_end + 1,
+ gf_barrier_mt_end
+};
+#endif
diff --git a/xlators/features/barrier/src/barrier.c b/xlators/features/barrier/src/barrier.c
new file mode 100644
index 00000000000..566c67f305f
--- /dev/null
+++ b/xlators/features/barrier/src/barrier.c
@@ -0,0 +1,520 @@
+/*
+ Copyright (c) 2014 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "barrier.h"
+#include "defaults.h"
+#include "call-stub.h"
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (writev, out, frame, this, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ BARRIER_FOP_CBK (fremovexattr, out, frame, this, op_ret, op_errno,
+ xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ BARRIER_FOP_CBK (removexattr, out, frame, this, op_ret, op_errno,
+ xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (truncate, out, frame, this, op_ret, op_errno, prebuf,
+ postbuf, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (ftruncate, out, frame, this, op_ret, op_errno, prebuf,
+ postbuf, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (rename, out, frame, this, op_ret, op_errno, buf,
+ preoldparent, postoldparent, prenewparent,
+ postnewparent, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (rmdir, out, frame, this, op_ret, op_errno, preparent,
+ postparent, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (unlink, out, frame, this, op_ret, op_errno, preparent,
+ postparent, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ BARRIER_FOP_CBK (fsync, out, frame, this, op_ret, op_errno,
+ prebuf, postbuf, xdata);
+out:
+ return 0;
+}
+
+int32_t
+barrier_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)
+{
+ if (!(flags & O_SYNC)) {
+ STACK_WIND_TAIL (frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev,
+ fd, vector, count, off, flags, iobref, xdata);
+
+ return 0;
+ }
+
+ STACK_WIND (frame, barrier_writev_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev, fd, vector, count,
+ off, flags, iobref, xdata);
+ return 0;
+}
+
+int32_t
+barrier_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_fremovexattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fremovexattr,
+ fd, name, xdata);
+ return 0;
+}
+
+int32_t
+barrier_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_removexattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->removexattr,
+ loc, name, xdata);
+ return 0;
+}
+
+int32_t
+barrier_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_truncate_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->truncate,
+ loc, offset, xdata);
+ return 0;
+}
+
+int32_t
+barrier_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_rename_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rename,
+ oldloc, newloc, xdata);
+ return 0;
+}
+
+int
+barrier_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_rmdir_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->rmdir,
+ loc, flags, xdata);
+ return 0;
+}
+
+int32_t
+barrier_unlink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int xflag, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_unlink_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->unlink,
+ loc, xflag, xdata);
+ return 0;
+}
+
+int32_t
+barrier_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_ftruncate_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->ftruncate,
+ fd, offset, xdata);
+ return 0;
+}
+
+int32_t
+barrier_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t flags, dict_t *xdata)
+{
+ STACK_WIND (frame, barrier_fsync_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsync,
+ fd, flags, xdata);
+ return 0;
+}
+
+call_stub_t *
+__barrier_dequeue (xlator_t *this, struct list_head *queue)
+{
+ call_stub_t *stub = NULL;
+ barrier_priv_t *priv = NULL;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (list_empty (queue))
+ goto out;
+
+ stub = list_entry (queue->next, call_stub_t, list);
+ list_del_init (&stub->list);
+
+out:
+ return stub;
+}
+
+void
+barrier_dequeue_all (xlator_t *this, struct list_head *queue)
+{
+ call_stub_t *stub = NULL;
+
+ gf_log (this->name, GF_LOG_INFO, "Dequeuing all the barriered fops");
+
+ /* TODO: Start the below task in a new thread */
+ while ((stub = __barrier_dequeue (this, queue)))
+ call_resume (stub);
+
+ gf_log (this->name, GF_LOG_INFO, "Dequeuing the barriered fops is "
+ "finished");
+ return;
+}
+
+void
+barrier_timeout (void *data)
+{
+ xlator_t *this = NULL;
+ barrier_priv_t *priv = NULL;
+ struct list_head queue = {0,};
+
+ this = data;
+ THIS = this;
+ priv = this->private;
+
+ INIT_LIST_HEAD (&queue);
+
+ gf_log (this->name, GF_LOG_CRITICAL, "Disabling barrier because of "
+ "the barrier timeout.");
+
+ LOCK (&priv->lock);
+ {
+ __barrier_disable (this, &queue);
+ }
+ UNLOCK (&priv->lock);
+
+ barrier_dequeue_all (this, &queue);
+
+ return;
+}
+
+void
+__barrier_enqueue (xlator_t *this, call_stub_t *stub)
+{
+ barrier_priv_t *priv = NULL;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ list_add_tail (&stub->list, &priv->queue);
+ priv->queue_size++;
+
+ return;
+}
+
+void
+__barrier_disable (xlator_t *this, struct list_head *queue)
+{
+ GF_UNUSED int ret = 0;
+ barrier_priv_t *priv = NULL;
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (priv->timer) {
+ ret = gf_timer_call_cancel (this->ctx, priv->timer);
+ priv->timer = NULL;
+ }
+
+ list_splice_init (&priv->queue, queue);
+ priv->queue_size = 0;
+ priv->barrier_enabled = _gf_false;
+}
+
+int
+__barrier_enable (xlator_t *this, barrier_priv_t *priv)
+{
+ int ret = -1;
+
+ priv->timer = gf_timer_call_after (this->ctx, priv->timeout,
+ barrier_timeout, (void *) this);
+ if (!priv->timer) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Couldn't add barrier "
+ "timeout event.");
+ goto out;
+ }
+
+ priv->barrier_enabled = _gf_true;
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+reconfigure (xlator_t *this, dict_t *options)
+{
+ barrier_priv_t *priv = NULL;
+ gf_boolean_t past = _gf_false;
+ int ret = -1;
+ gf_boolean_t barrier_enabled = _gf_false;
+ uint32_t timeout = {0,};
+ struct list_head queue = {0,};
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ GF_OPTION_RECONF ("barrier", barrier_enabled, options, bool, out);
+ GF_OPTION_RECONF ("timeout", timeout, options, time, out);
+
+ INIT_LIST_HEAD (&queue);
+
+ LOCK (&priv->lock);
+ {
+ past = priv->barrier_enabled;
+
+ switch (past) {
+ case _gf_false:
+ if (barrier_enabled) {
+ ret = __barrier_enable (this, priv);
+ if (ret)
+ goto unlock;
+
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Already disabled");
+ goto unlock;
+ }
+ break;
+
+ case _gf_true:
+ if (!barrier_enabled) {
+ __barrier_disable (this, &queue);
+
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Already enabled");
+ goto unlock;
+ }
+ break;
+ }
+
+ priv->timeout.tv_sec = timeout;
+
+ ret = 0;
+ }
+unlock:
+ UNLOCK (&priv->lock);
+
+ if (!list_empty (&queue))
+ barrier_dequeue_all (this, &queue);
+
+out:
+ return ret;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init (this, gf_barrier_mt_end + 1);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting "
+ "initialization failed.");
+
+ return ret;
+}
+
+int
+init (xlator_t *this)
+{
+ int ret = -1;
+ barrier_priv_t *priv = NULL;
+ uint32_t timeout = {0,};
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'barrier' not configured with exactly one child");
+ goto out;
+ }
+
+ if (!this->parents)
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+
+ priv = GF_CALLOC (1, sizeof (*priv), gf_barrier_mt_priv_t);
+ if (!priv)
+ goto out;
+
+ LOCK_INIT (&priv->lock);
+
+ GF_OPTION_INIT ("barrier", priv->barrier_enabled, bool, out);
+ GF_OPTION_INIT ("timeout", timeout, time, out);
+ priv->timeout.tv_sec = timeout;
+
+ INIT_LIST_HEAD (&priv->queue);
+
+ if (priv->barrier_enabled) {
+ ret = __barrier_enable (this, priv);
+ if (ret == -1)
+ goto out;
+ }
+
+ this->private = priv;
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ barrier_priv_t *priv = NULL;
+ struct list_head queue = {0,};
+
+ priv = this->private;
+ if (!priv)
+ goto out;
+
+ INIT_LIST_HEAD (&queue);
+
+ gf_log (this->name, GF_LOG_INFO, "Disabling barriering and dequeuing "
+ "all the queued fops");
+ LOCK (&priv->lock);
+ {
+ __barrier_disable (this, &queue);
+ }
+ UNLOCK (&priv->lock);
+
+ if (!list_empty (&queue))
+ barrier_dequeue_all (this, &queue);
+
+ this->private = NULL;
+
+ LOCK_DESTROY (&priv->lock);
+ GF_FREE (priv);
+out:
+ return;
+}
+
+struct xlator_fops fops = {
+
+ /* Barrier Class fops */
+ .rmdir = barrier_rmdir,
+ .unlink = barrier_unlink,
+ .rename = barrier_rename,
+ .removexattr = barrier_removexattr,
+ .fremovexattr = barrier_fremovexattr,
+ .truncate = barrier_truncate,
+ .ftruncate = barrier_ftruncate,
+ .fsync = barrier_fsync,
+
+ /* Writes with only O_SYNC flag */
+ .writev = barrier_writev,
+};
+
+struct xlator_dumpops dumpops;
+
+struct xlator_cbks cbks;
+
+struct volume_options options[] = {
+ { .key = {"barrier"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "When \"on\", blocks acknowledgements to application "
+ "for file operations such as rmdir, rename, unlink, "
+ "removexattr, fremovexattr, truncate, ftruncate, "
+ "write (with O_SYNC), fsync. It is turned \"off\" by "
+ "default."
+ },
+ { .key = {"timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .default_value = "120",
+ .description = "After 'timeout' seconds since the time 'barrier' "
+ "option was set to \"on\", acknowledgements to file "
+ "operations are no longer blocked and previously "
+ "blocked acknowledgements are sent to the application"
+ },
+ { .key = {NULL} },
+};
diff --git a/xlators/features/barrier/src/barrier.h b/xlators/features/barrier/src/barrier.h
new file mode 100644
index 00000000000..8face9f6512
--- /dev/null
+++ b/xlators/features/barrier/src/barrier.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (c) 2014 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 __BARRIER_H__
+#define __BARRIER_H__
+
+#include "barrier-mem-types.h"
+#include "xlator.h"
+#include "timer.h"
+#include "call-stub.h"
+
+#define BARRIER_SAFE_ASSIGN(lock, to, value) \
+ do { \
+ LOCK (&(lock)); \
+ { \
+ to = value; \
+ } \
+ UNLOCK (&(lock)); \
+ } while (0)
+
+#define BARRIER_FOP_CBK(fop_name, label, frame, this, params ...) \
+ do { \
+ barrier_priv_t *_priv = NULL; \
+ call_stub_t *_stub = NULL; \
+ gf_boolean_t _barrier_enabled= _gf_false; \
+ struct list_head queue = {0, }; \
+ \
+ INIT_LIST_HEAD (&queue); \
+ \
+ _priv = this->private; \
+ GF_ASSERT (_priv); \
+ \
+ LOCK (&_priv->lock); \
+ { \
+ if (_priv->barrier_enabled) { \
+ _barrier_enabled = _priv->barrier_enabled;\
+ \
+ _stub = fop_##fop_name##_cbk_stub \
+ (frame, \
+ default_##fop_name##_cbk_resume,\
+ params); \
+ if (!_stub) { \
+ __barrier_disable (this, &queue);\
+ goto unlock; \
+ } \
+ \
+ __barrier_enqueue (this, _stub); \
+ } \
+ } \
+unlock: \
+ UNLOCK (&_priv->lock); \
+ \
+ if (_stub) \
+ goto label; \
+ \
+ if (_barrier_enabled && !_stub) { \
+ gf_log (this->name, GF_LOG_CRITICAL, \
+ "Failed to barrier FOPs, disabling " \
+ "barrier. FOP: %s, ERROR: %s", \
+ #fop_name, strerror (ENOMEM)); \
+ barrier_dequeue_all (this, &queue); \
+ } \
+ \
+ STACK_UNWIND_STRICT (fop_name, frame, params); \
+ goto label; \
+ } while (0)
+
+typedef struct {
+ gf_timer_t *timer;
+ gf_boolean_t barrier_enabled;
+ gf_lock_t lock;
+ struct list_head queue;
+ struct timespec timeout;
+ uint32_t queue_size;
+} barrier_priv_t;
+
+int __barrier_enable (xlator_t *this, barrier_priv_t *priv);
+void __barrier_enqueue (xlator_t *this, call_stub_t *stub);
+void __barrier_disable (xlator_t *this, struct list_head *queue);
+void barrier_timeout (void *data);
+void barrier_dequeue_all (xlator_t *this, struct list_head *queue);
+call_stub_t *__barrier_dequeue (xlator_t *this, struct list_head *queue);
+
+#endif