summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/debug/Makefile.am2
-rw-r--r--xlators/debug/io-stats/Makefile.am3
-rw-r--r--xlators/debug/io-stats/src/Makefile.am13
-rw-r--r--xlators/debug/io-stats/src/io-stats.c1517
4 files changed, 1534 insertions, 1 deletions
diff --git a/xlators/debug/Makefile.am b/xlators/debug/Makefile.am
index 16cf893a1..b655554ef 100644
--- a/xlators/debug/Makefile.am
+++ b/xlators/debug/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = trace error-gen
+SUBDIRS = trace error-gen io-stats
CLEANFILES =
diff --git a/xlators/debug/io-stats/Makefile.am b/xlators/debug/io-stats/Makefile.am
new file mode 100644
index 000000000..a985f42a8
--- /dev/null
+++ b/xlators/debug/io-stats/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/debug/io-stats/src/Makefile.am b/xlators/debug/io-stats/src/Makefile.am
new file mode 100644
index 000000000..91aea6ebb
--- /dev/null
+++ b/xlators/debug/io-stats/src/Makefile.am
@@ -0,0 +1,13 @@
+
+xlator_LTLIBRARIES = io-stats.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug
+
+io_stats_la_LDFLAGS = -module -avoidversion
+
+io_stats_la_SOURCES = io-stats.c
+io_stats_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
new file mode 100644
index 000000000..2a46f4d78
--- /dev/null
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -0,0 +1,1517 @@
+/*
+ Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+/**
+ * xlators/debug/io_stats :
+ * This translator maintains a counter for each fop (that is,
+ * a counter which stores the number of invocations for the certain
+ * fop), and makes these counters accessible as extended attributes.
+ */
+
+#include <errno.h>
+#include "glusterfs.h"
+#include "xlator.h"
+
+#define BUMP_HIT(op) \
+do { \
+ LOCK (&((io_stats_private_t *)this->private)->lock); \
+ { \
+ ((io_stats_private_t *)this->private) \
+ ->fop_records[GF_FOP_##op].hits++; \
+ } \
+ UNLOCK (&((io_stats_private_t *)this->private)->lock); \
+ } while (0)
+
+struct io_stats_private {
+ gf_lock_t lock;
+ struct {
+ char *name;
+ int enabled;
+ uint32_t hits;
+ } fop_records[GF_FOP_MAXVALUE];
+};
+typedef struct io_stats_private io_stats_private_t;
+
+int32_t
+io_stats_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 stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);
+ return 0;
+}
+
+int32_t
+io_stats_open_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+ return 0;
+}
+
+int32_t
+io_stats_stat_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_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 stat *buf,
+ struct iobref *iobref)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, vector, count, buf, iobref);
+ return 0;
+}
+
+int32_t
+io_stats_writev_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entries,
+ int32_t count)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, entries, count);
+ return 0;
+}
+
+int32_t
+io_stats_readdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_fsync_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_chown_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_chmod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_fchmod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_fchown_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_rename_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_readlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ const char *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_lookup_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf,
+ dict_t *xattr)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf, xattr);
+ return 0;
+}
+
+int32_t
+io_stats_symlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
+}
+
+int32_t
+io_stats_mknod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
+}
+
+
+int32_t
+io_stats_mkdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
+}
+
+int32_t
+io_stats_link_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf);
+ return 0;
+}
+
+int32_t
+io_stats_flush_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+io_stats_opendir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+ return 0;
+}
+
+int32_t
+io_stats_rmdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_truncate_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_utimens_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_statfs_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct statvfs *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_setxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_getxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
+{
+ io_stats_private_t *priv = this->private;
+ int i = 0;
+ char keycont[] = "trusted.glusterfs.hits." /* 23 chars */
+ "0123456789"
+ "0123456789"
+ "0123456789"
+ "0123456789";
+ int ret = -1;
+
+ memset (keycont + 23, '\0', 40);
+
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ if (!(priv->fop_records[i].enabled &&
+ priv->fop_records[i].name))
+ continue;
+
+ strncpy (keycont + 23, priv->fop_records[i].name, 40);
+ LOCK(&priv->lock);
+ {
+ ret = dict_set_uint32 (dict, keycont,
+ priv->fop_records[i].hits);
+ }
+ UNLOCK(&priv->lock);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "dict set failed for xattr %s",
+ keycont);
+ break;
+ }
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+int32_t
+io_stats_removexattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+io_stats_fsyncdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_access_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_ftruncate_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_fstat_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+int32_t
+io_stats_lk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct flock *lock)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, lock);
+ return 0;
+}
+
+
+int32_t
+io_stats_setdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_entrylk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+io_stats_xattrop_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+int32_t
+io_stats_fxattrop_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+int32_t
+io_stats_inodelk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+io_stats_entrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+{
+ BUMP_HIT(ENTRYLK);
+
+ STACK_WIND (frame,
+ io_stats_entrylk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->entrylk,
+ volume, loc, basename, cmd, type);
+ return 0;
+}
+
+int32_t
+io_stats_inodelk (call_frame_t *frame,
+ xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd, struct flock *flock)
+{
+
+ BUMP_HIT(INODELK);
+
+ STACK_WIND (frame,
+ io_stats_inodelk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->inodelk,
+ volume, loc, cmd, flock);
+ return 0;
+}
+
+
+int32_t
+io_stats_finodelk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+io_stats_finodelk (call_frame_t *frame,
+ xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct flock *flock)
+{
+ BUMP_HIT(FINODELK);
+
+ STACK_WIND (frame,
+ io_stats_finodelk_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->finodelk,
+ volume, fd, cmd, flock);
+ return 0;
+}
+
+
+int32_t
+io_stats_xattrop (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ gf_xattrop_flags_t flags,
+ dict_t *dict)
+{
+ BUMP_HIT(XATTROP);
+
+ STACK_WIND (frame, io_stats_xattrop_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop,
+ loc, flags, dict);
+
+ return 0;
+}
+
+int32_t
+io_stats_fxattrop (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ gf_xattrop_flags_t flags,
+ dict_t *dict)
+{
+ BUMP_HIT(FXATTROP);
+
+ STACK_WIND (frame, io_stats_fxattrop_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fxattrop,
+ fd, flags, dict);
+
+ return 0;
+}
+
+int32_t
+io_stats_lookup (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xattr_req)
+{
+ BUMP_HIT(LOOKUP);
+
+ STACK_WIND (frame, io_stats_lookup_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup,
+ loc, xattr_req);
+
+ return 0;
+}
+
+int32_t
+io_stats_stat (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ BUMP_HIT(STAT);
+
+ STACK_WIND (frame,
+ io_stats_stat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat,
+ loc);
+
+ return 0;
+}
+
+int32_t
+io_stats_readlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ size_t size)
+{
+ BUMP_HIT(READLINK);
+
+ STACK_WIND (frame,
+ io_stats_readlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink,
+ loc,
+ size);
+
+ return 0;
+}
+
+int32_t
+io_stats_mknod (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode,
+ dev_t dev)
+{
+ BUMP_HIT(MKNOD);
+
+ STACK_WIND (frame,
+ io_stats_mknod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod,
+ loc,
+ mode,
+ dev);
+
+ return 0;
+}
+
+int32_t
+io_stats_mkdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode)
+{
+ BUMP_HIT(MKDIR);
+
+ STACK_WIND (frame,
+ io_stats_mkdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir,
+ loc,
+ mode);
+ return 0;
+}
+
+int32_t
+io_stats_unlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ BUMP_HIT(UNLINK);
+
+ STACK_WIND (frame,
+ io_stats_unlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink,
+ loc);
+ return 0;
+}
+
+int32_t
+io_stats_rmdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ BUMP_HIT(RMDIR);
+
+ STACK_WIND (frame,
+ io_stats_rmdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir,
+ loc);
+
+ return 0;
+}
+
+int32_t
+io_stats_symlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *linkpath,
+ loc_t *loc)
+{
+ BUMP_HIT(SYMLINK);
+
+ STACK_WIND (frame,
+ io_stats_symlink_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink,
+ linkpath,
+ loc);
+
+ return 0;
+}
+
+int32_t
+io_stats_rename (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ BUMP_HIT(RENAME);
+
+ STACK_WIND (frame,
+ io_stats_rename_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename,
+ oldloc,
+ newloc);
+
+ return 0;
+}
+
+int32_t
+io_stats_link (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ BUMP_HIT(LINK);
+
+ STACK_WIND (frame,
+ io_stats_link_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link,
+ oldloc,
+ newloc);
+ return 0;
+}
+
+int32_t
+io_stats_chmod (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode)
+{
+ BUMP_HIT(CHMOD);
+
+ STACK_WIND (frame,
+ io_stats_chmod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->chmod,
+ loc,
+ mode);
+
+ return 0;
+}
+
+int32_t
+io_stats_chown (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ uid_t uid,
+ gid_t gid)
+{
+ BUMP_HIT(CHOWN);
+
+ STACK_WIND (frame,
+ io_stats_chown_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->chown,
+ loc,
+ uid,
+ gid);
+
+ return 0;
+}
+
+int32_t
+io_stats_truncate (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ off_t offset)
+{
+ BUMP_HIT(TRUNCATE);
+
+ STACK_WIND (frame,
+ io_stats_truncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate,
+ loc,
+ offset);
+
+ return 0;
+}
+
+int32_t
+io_stats_utimens (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ struct timespec tv[2])
+{
+ BUMP_HIT(UTIMENS);
+
+ STACK_WIND (frame,
+ io_stats_utimens_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->utimens,
+ loc,
+ tv);
+
+ return 0;
+}
+
+int32_t
+io_stats_open (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ fd_t *fd)
+{
+ BUMP_HIT(OPEN);
+
+ STACK_WIND (frame,
+ io_stats_open_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ loc,
+ flags,
+ fd);
+ return 0;
+}
+
+int32_t
+io_stats_create (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ mode_t mode,
+ fd_t *fd)
+{
+ BUMP_HIT(CREATE);
+
+ STACK_WIND (frame,
+ io_stats_create_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create,
+ loc,
+ flags,
+ mode,
+ fd);
+ return 0;
+}
+
+int32_t
+io_stats_readv (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset)
+{
+ BUMP_HIT(READ);
+
+ STACK_WIND (frame,
+ io_stats_readv_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv,
+ fd,
+ size,
+ offset);
+ return 0;
+}
+
+int32_t
+io_stats_writev (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset,
+ struct iobref *iobref)
+{
+ BUMP_HIT(WRITE);
+
+ STACK_WIND (frame,
+ io_stats_writev_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev,
+ fd,
+ vector,
+ count,
+ offset,
+ iobref);
+ return 0;
+}
+
+int32_t
+io_stats_statfs (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ BUMP_HIT(STATFS);
+
+ STACK_WIND (frame,
+ io_stats_statfs_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs,
+ loc);
+ return 0;
+}
+
+int32_t
+io_stats_flush (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ BUMP_HIT(FLUSH);
+
+ STACK_WIND (frame,
+ io_stats_flush_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ return 0;
+}
+
+
+int32_t
+io_stats_fsync (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t flags)
+{
+ BUMP_HIT(FSYNC);
+
+ STACK_WIND (frame,
+ io_stats_fsync_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync,
+ fd,
+ flags);
+ return 0;
+}
+
+int32_t
+io_stats_setxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ int32_t flags)
+{
+ BUMP_HIT(SETXATTR);
+
+ STACK_WIND (frame,
+ io_stats_setxattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr,
+ loc,
+ dict,
+ flags);
+ return 0;
+}
+
+int32_t
+io_stats_getxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ BUMP_HIT(GETXATTR);
+
+ STACK_WIND (frame,
+ io_stats_getxattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr,
+ loc,
+ name);
+ return 0;
+}
+
+int32_t
+io_stats_removexattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ BUMP_HIT(REMOVEXATTR);
+
+ STACK_WIND (frame,
+ io_stats_removexattr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr,
+ loc,
+ name);
+
+ return 0;
+}
+
+int32_t
+io_stats_opendir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ fd_t *fd)
+{
+ BUMP_HIT(OPENDIR);
+
+ STACK_WIND (frame,
+ io_stats_opendir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir,
+ loc,
+ fd);
+ return 0;
+}
+
+int32_t
+io_stats_getdents (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset,
+ int32_t flag)
+{
+ BUMP_HIT(GETDENTS);
+
+ STACK_WIND (frame,
+ io_stats_getdents_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getdents,
+ fd,
+ size,
+ offset,
+ flag);
+ return 0;
+}
+
+
+int32_t
+io_stats_readdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset)
+{
+ BUMP_HIT(READDIR);
+
+ STACK_WIND (frame,
+ io_stats_readdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdir,
+ fd,
+ size,
+ offset);
+
+ return 0;
+}
+
+
+int32_t
+io_stats_fsyncdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t datasync)
+{
+ BUMP_HIT(FSYNCDIR);
+
+ STACK_WIND (frame,
+ io_stats_fsyncdir_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsyncdir,
+ fd,
+ datasync);
+ return 0;
+}
+
+int32_t
+io_stats_access (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t mask)
+{
+ BUMP_HIT(ACCESS);
+
+ STACK_WIND (frame,
+ io_stats_access_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access,
+ loc,
+ mask);
+ return 0;
+}
+
+int32_t
+io_stats_ftruncate (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset)
+{
+ BUMP_HIT(FTRUNCATE);
+
+ STACK_WIND (frame,
+ io_stats_ftruncate_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate,
+ fd,
+ offset);
+
+ return 0;
+}
+
+int32_t
+io_stats_fchown (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ uid_t uid,
+ gid_t gid)
+{
+ BUMP_HIT(FCHOWN);
+
+ STACK_WIND (frame,
+ io_stats_fchown_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fchown,
+ fd,
+ uid,
+ gid);
+ return 0;
+}
+
+int32_t
+io_stats_fchmod (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ mode_t mode)
+{
+ BUMP_HIT(FCHMOD);
+
+ STACK_WIND (frame,
+ io_stats_fchmod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fchmod,
+ fd,
+ mode);
+ return 0;
+}
+
+int32_t
+io_stats_fstat (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ BUMP_HIT(FSTAT);
+
+ STACK_WIND (frame,
+ io_stats_fstat_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fstat,
+ fd);
+ return 0;
+}
+
+int32_t
+io_stats_lk (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t cmd,
+ struct flock *lock)
+{
+ BUMP_HIT(LK);
+
+ STACK_WIND (frame,
+ io_stats_lk_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk,
+ fd,
+ cmd,
+ lock);
+ return 0;
+}
+
+int32_t
+io_stats_setdents (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t flags,
+ dir_entry_t *entries,
+ int32_t count)
+{
+ BUMP_HIT(SETDENTS);
+
+ STACK_WIND (frame,
+ io_stats_setdents_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setdents,
+ fd,
+ flags,
+ entries,
+ count);
+ return 0;
+}
+
+
+int32_t
+io_stats_checksum_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ uint8_t *fchecksum,
+ uint8_t *dchecksum)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fchecksum, dchecksum);
+
+ return 0;
+}
+
+int32_t
+io_stats_checksum (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flag)
+{
+ STACK_WIND (frame,
+ io_stats_checksum_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->checksum,
+ loc,
+ flag);
+
+ return 0;
+}
+
+
+int32_t
+io_stats_stats_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct xlator_stats *stats)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
+ return 0;
+}
+
+int32_t
+io_stats_stats (call_frame_t *frame,
+ xlator_t *this,
+ int32_t flags)
+{
+ STACK_WIND (frame,
+ io_stats_stats_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->mops->stats,
+ flags);
+
+ return 0;
+}
+
+void
+enable_all_calls (io_stats_private_t *priv, int enabled)
+{
+ int i;
+ for (i = 0; i < GF_FOP_MAXVALUE; i++)
+ priv->fop_records[i].enabled = enabled;
+}
+
+void
+enable_call (io_stats_private_t *priv, const char *name, int enabled)
+{
+ int i;
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ if (!priv->fop_records[i].name)
+ continue;
+ if (!strcasecmp(priv->fop_records[i].name, name))
+ priv->fop_records[i].enabled = enabled;
+ }
+}
+
+
+/*
+ include = 1 for "include-ops"
+ = 0 for "exclude-ops"
+*/
+void
+process_call_list (io_stats_private_t *priv, const char *list, int include)
+{
+ enable_all_calls (priv, include ? 0 : 1);
+
+ char *call = strsep ((char **)&list, ",");
+ while (call) {
+ enable_call (priv, call, include);
+ call = strsep ((char **)&list, ",");
+ }
+}
+
+
+int32_t
+init (xlator_t *this)
+{
+ dict_t *options = this->options;
+ char *includes = NULL, *excludes = NULL;
+ io_stats_private_t *priv = NULL;
+
+ if (!this)
+ return -1;
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "io_stats translator requires one subvolume");
+ return -1;
+ }
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ priv = CALLOC (1, sizeof(*priv));
+ ERR_ABORT (priv);
+
+ includes = data_to_str (dict_get (options, "include-ops"));
+ excludes = data_to_str (dict_get (options, "exclude-ops"));
+
+ {
+ int i;
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ priv->fop_records[i].name = gf_fop_list[i];
+ priv->fop_records[i].enabled = 1;
+ }
+ }
+
+ if (includes && excludes) {
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "must specify only one of 'include-ops' and 'exclude-ops'");
+ return -1;
+ }
+ if (includes)
+ process_call_list (priv, includes, 1);
+ if (excludes)
+ process_call_list (priv, excludes, 0);
+
+ LOCK_INIT (&priv->lock);
+
+ /* Set this translator's inode table pointer to child node's pointer. */
+ this->itable = FIRST_CHILD (this)->itable;
+ this->private = priv;
+
+ return 0;
+}
+
+void
+fini (xlator_t *this)
+{
+ io_stats_private_t *priv = NULL;
+
+ if (!this)
+ return;
+
+ priv = this->private;
+ if (priv) {
+ LOCK_DESTROY (&priv->lock);
+ FREE (priv);
+ }
+
+ gf_log (this->name, GF_LOG_NORMAL,
+ "io-stats translator unloaded");
+ return;
+}
+
+struct xlator_fops fops = {
+ .stat = io_stats_stat,
+ .readlink = io_stats_readlink,
+ .mknod = io_stats_mknod,
+ .mkdir = io_stats_mkdir,
+ .unlink = io_stats_unlink,
+ .rmdir = io_stats_rmdir,
+ .symlink = io_stats_symlink,
+ .rename = io_stats_rename,
+ .link = io_stats_link,
+ .chmod = io_stats_chmod,
+ .chown = io_stats_chown,
+ .truncate = io_stats_truncate,
+ .utimens = io_stats_utimens,
+ .open = io_stats_open,
+ .readv = io_stats_readv,
+ .writev = io_stats_writev,
+ .statfs = io_stats_statfs,
+ .flush = io_stats_flush,
+ .fsync = io_stats_fsync,
+ .setxattr = io_stats_setxattr,
+ .getxattr = io_stats_getxattr,
+ .removexattr = io_stats_removexattr,
+ .opendir = io_stats_opendir,
+ .readdir = io_stats_readdir,
+ .fsyncdir = io_stats_fsyncdir,
+ .access = io_stats_access,
+ .ftruncate = io_stats_ftruncate,
+ .fstat = io_stats_fstat,
+ .create = io_stats_create,
+ .fchown = io_stats_fchown,
+ .fchmod = io_stats_fchmod,
+ .lk = io_stats_lk,
+ .inodelk = io_stats_inodelk,
+ .finodelk = io_stats_finodelk,
+ .entrylk = io_stats_entrylk,
+ .lookup = io_stats_lookup,
+ .setdents = io_stats_setdents,
+ .getdents = io_stats_getdents,
+ .checksum = io_stats_checksum,
+ .xattrop = io_stats_xattrop,
+ .fxattrop = io_stats_fxattrop,
+};
+
+struct xlator_mops mops = {
+ .stats = io_stats_stats,
+};
+
+struct xlator_cbks cbks = {
+};
+
+struct volume_options options[] = {
+ { .key = {"include-ops", "include"},
+ .type = GF_OPTION_TYPE_STR,
+ /*.value = { ""} */
+ },
+ { .key = {"exclude-ops", "exclude"},
+ .type = GF_OPTION_TYPE_STR
+ /*.value = { ""} */
+ },
+ { .key = {NULL} },
+};