From b69c4c843ce0c6a361c46fd53cbbbb9ce0e27cd8 Mon Sep 17 00:00:00 2001 From: Varun Shastry Date: Wed, 5 Feb 2014 13:02:34 +0530 Subject: features/barrier: add barrier translator gluster feature page: http://www.gluster.org/community/documentation/index.php/Features/Server-side_Barrier_feature Change-Id: Ia9f8802a54d1ffbd1cf789b80f5d30819bf65f64 BUG: 1060002 Signed-off-by: Varun Shastry Reviewed-on: http://review.gluster.org/6928 Tested-by: Gluster Build System Reviewed-by: Krishnan Parthasarathi Reviewed-by: Atin Mukherjee Reviewed-by: Vijay Bellur --- configure.ac | 2 + libglusterfs/src/defaults.c | 502 +++++++++++++++++++++- libglusterfs/src/defaults.h | 312 +++++++++++++- xlators/features/Makefile.am | 2 +- xlators/features/barrier/Makefile.am | 3 + xlators/features/barrier/src/Makefile.am | 16 + xlators/features/barrier/src/barrier-mem-types.h | 20 + xlators/features/barrier/src/barrier.c | 520 +++++++++++++++++++++++ xlators/features/barrier/src/barrier.h | 91 ++++ 9 files changed, 1424 insertions(+), 44 deletions(-) create mode 100644 xlators/features/barrier/Makefile.am create mode 100644 xlators/features/barrier/src/Makefile.am create mode 100644 xlators/features/barrier/src/barrier-mem-types.h create mode 100644 xlators/features/barrier/src/barrier.c create mode 100644 xlators/features/barrier/src/barrier.h diff --git a/configure.ac b/configure.ac index 696ebfa36..f1bb2a184 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 f5fb2aa9d..8a1c281a5 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 f0b786ddf..1b33e8099 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,8 +491,278 @@ 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, @@ -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 d2f5ef192..1fdd474c2 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 000000000..a985f42a8 --- /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 000000000..8859be328 --- /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 000000000..36647a669 --- /dev/null +++ b/xlators/features/barrier/src/barrier-mem-types.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2014 Red Hat, Inc. + 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 000000000..566c67f30 --- /dev/null +++ b/xlators/features/barrier/src/barrier.c @@ -0,0 +1,520 @@ +/* + Copyright (c) 2014 Red Hat, Inc. + 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 000000000..8face9f65 --- /dev/null +++ b/xlators/features/barrier/src/barrier.h @@ -0,0 +1,91 @@ +/* + Copyright (c) 2014 Red Hat, Inc. + 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 -- cgit