diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | xlators/debug/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/debug/io-stats/Makefile.am | 3 | ||||
| -rw-r--r-- | xlators/debug/io-stats/src/Makefile.am | 13 | ||||
| -rw-r--r-- | xlators/debug/io-stats/src/io-stats.c | 1517 | 
5 files changed, 1536 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 5e44081c0aa..621c26a14c7 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,8 @@ AC_CONFIG_FILES([Makefile  		xlators/debug/trace/src/Makefile  		xlators/debug/error-gen/Makefile  		xlators/debug/error-gen/src/Makefile +		xlators/debug/io-stats/Makefile +		xlators/debug/io-stats/src/Makefile  		xlators/protocol/Makefile  		xlators/protocol/client/Makefile  		xlators/protocol/client/src/Makefile diff --git a/xlators/debug/Makefile.am b/xlators/debug/Makefile.am index 16cf893a11c..b655554efec 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 00000000000..a985f42a877 --- /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 00000000000..91aea6ebbc2 --- /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 00000000000..2a46f4d7812 --- /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} }, +};  | 
