diff options
| -rw-r--r-- | libglusterfs/src/fd.c | 53 | ||||
| -rw-r--r-- | libglusterfs/src/fd.h | 5 | ||||
| -rw-r--r-- | libglusterfs/src/inode.c | 116 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.c | 12 | ||||
| -rw-r--r-- | libglusterfs/src/statedump.h | 4 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 2 | ||||
| -rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 162 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 2 | 
8 files changed, 319 insertions, 37 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index 870c85e3f..9e91cdb83 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -806,3 +806,56 @@ fdtable_dump (fdtable_t *fdtable, char *prefix)          pthread_mutex_unlock(&fdtable->lock);  } + + +void +fd_ctx_dump (fd_t *fd, char *prefix) +{ +        struct _fd_ctx *fd_ctx = NULL; +        xlator_t       *xl     = NULL; +        int    i               = 0; +         + +        if ((fd == NULL) || (fd->_ctx == NULL)) { +                goto out; +        } + +        LOCK (&fd->lock); +        { +                if (fd->_ctx != NULL) { +                        fd_ctx = GF_CALLOC (fd->inode->table->xl->graph->xl_count, +                                            sizeof (*fd_ctx), +                                            gf_common_mt_fd_ctx); +                        if (fd_ctx == NULL) { +                                gf_log ("fd", GF_LOG_ERROR, "out of memory"); +                                goto unlock; +                        } + +                        for (i = 0; i < fd->inode->table->xl->graph->xl_count; +                             i++) { +                                fd_ctx[i] = fd->_ctx[i]; +                        } +                } +        } +unlock: +        UNLOCK (&fd->lock); +         +        if (fd_ctx == NULL) { +                goto out; +        } + +        for (i = 0; i < fd->inode->table->xl->graph->xl_count; i++) { +                if (fd_ctx[i].xl_key) { +                        xl = (xlator_t *)(long)fd_ctx[i].xl_key; +                        if (xl->dumpops && xl->dumpops->fdctx) +                                xl->dumpops->fdctx (xl, fd); +                } +        } + +out: +        if (fd_ctx != NULL) { +                GF_FREE (fd_ctx); +        } + +        return; +} diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h index e01ef753e..4ea7fc165 100644 --- a/libglusterfs/src/fd.h +++ b/libglusterfs/src/fd.h @@ -164,5 +164,10 @@ __fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value);  int  __fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value); +fd_t * +_fd_ref (fd_t *fd); + +void +fd_ctx_dump (fd_t *fd, char *prefix);  #endif /* _FD_H */ diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 45d151ef0..989c25217 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -23,6 +23,7 @@  #endif  #include "inode.h" +#include "fd.h"  #include "common-utils.h"  #include "statedump.h"  #include <pthread.h> @@ -36,7 +37,7 @@     move latest accessed dentry to list_head of inode  */ -#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type)           \ +#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \          {                                                               \                  int i = 1;                                              \                  inode_t *inode = NULL;                                  \ @@ -54,6 +55,9 @@ __inode_unref (inode_t *inode);  static int  inode_table_prune (inode_table_t *table); +void +fd_dump (struct list_head *head, char *prefix); +  static int  hash_dentry (inode_t *parent, const char *name, int mod)  { @@ -1351,47 +1355,105 @@ inode_ctx_del (inode_t *inode, xlator_t *key, uint64_t *value)  void  inode_dump (inode_t *inode, char *prefix)  { -        char            key[GF_DUMP_MAX_BUF_LEN]; -        int             ret = -1; -        xlator_t        *xl = NULL; -        int             i = 0; -        char            uuidbuf[256]; +        char               key[GF_DUMP_MAX_BUF_LEN]; +        int                ret       = -1; +        xlator_t          *xl        = NULL; +        int                i         = 0; +        char               uuidbuf[256]; +        fd_t              *fd        = NULL; +        struct _inode_ctx *inode_ctx = NULL; +        struct  fd_wrapper { +                fd_t *fd; +                struct list_head next; +        } *fd_wrapper, *tmp; +        struct list_head fd_list;          if (!inode)                  return; +        INIT_LIST_HEAD (&fd_list); +          ret = TRY_LOCK(&inode->lock);          if (ret != 0) { -                gf_log("", GF_LOG_WARNING, "Unable to dump inode" -                       " errno: %d", errno); +                gf_log ("", GF_LOG_WARNING, "Unable to dump inode" +                        " errno: %d", errno);                  return;          } -        uuid_unparse (inode->gfid, uuidbuf); -        gf_proc_dump_build_key(key, prefix, "gfid"); -        gf_proc_dump_write(key, "%s", uuidbuf); -        gf_proc_dump_build_key(key, prefix, "nlookup"); -        gf_proc_dump_write(key, "%ld", inode->nlookup); -        gf_proc_dump_build_key(key, prefix, "ref"); -        gf_proc_dump_write(key, "%u", inode->ref); -        gf_proc_dump_build_key(key, prefix, "ino"); -        gf_proc_dump_write(key, "%ld", inode->ino); -        gf_proc_dump_build_key(key, prefix, "ia_type"); -        gf_proc_dump_write(key, "%d", inode->ia_type); +        { +                uuid_unparse (inode->gfid, uuidbuf); +                gf_proc_dump_build_key(key, prefix, "gfid"); +                gf_proc_dump_write(key, "%s", uuidbuf); +                gf_proc_dump_build_key(key, prefix, "nlookup"); +                gf_proc_dump_write(key, "%ld", inode->nlookup); +                gf_proc_dump_build_key(key, prefix, "ref"); +                gf_proc_dump_write(key, "%u", inode->ref); +                gf_proc_dump_build_key(key, prefix, "ino"); +                gf_proc_dump_write(key, "%ld", inode->ino); +                gf_proc_dump_build_key(key, prefix, "ia_type"); +                gf_proc_dump_write(key, "%d", inode->ia_type); +                if (inode->_ctx) { +                        inode_ctx = GF_CALLOC (inode->table->xl->graph->xl_count, +                                               sizeof (*inode_ctx), +                                               gf_common_mt_inode_ctx); +                        if (inode_ctx == NULL) { +                                gf_log ("", GF_LOG_ERROR, "out of memory"); +                                goto unlock; +                        } + +                        for (i = 0; i < inode->table->xl->graph->xl_count; i++) { +                                inode_ctx[i] = inode->_ctx[i]; +                        } +                } + +                if (list_empty (&inode->fd_list)) { +                        goto unlock; +                } + +                list_for_each_entry (fd, &inode->fd_list, inode_list) { +                        fd_wrapper = GF_CALLOC (1, sizeof (*fd_wrapper), +                                                gf_common_mt_char); +                        if (fd_wrapper == NULL) { +                                gf_log ("", GF_LOG_ERROR, "out of memory"); +                                goto unlock; +                        } + +                        INIT_LIST_HEAD (&fd_wrapper->next); +                        list_add_tail (&fd_wrapper->next, &fd_list); + +                        fd_wrapper->fd = _fd_ref (fd); +                } +        } +unlock:          UNLOCK(&inode->lock); -        if (!inode->_ctx) -                goto out; -        for (i = 0; i < inode->table->xl->graph->xl_count; i++) { -                if (inode->_ctx[i].xl_key) { -                        xl = (xlator_t *)(long)inode->_ctx[i].xl_key; -                        if (xl->dumpops && xl->dumpops->inodectx) -                                xl->dumpops->inodectx (xl, inode); +        if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) { +                for (i = 0; i < inode->table->xl->graph->xl_count; i++) { +                        if (inode_ctx[i].xl_key) { +                                xl = (xlator_t *)(long)inode_ctx[i].xl_key; +                                if (xl->dumpops && xl->dumpops->inodectx) +                                        xl->dumpops->inodectx (xl, inode); +                        }                  }          } -out: +        if (!list_empty (&fd_list) +            && (dump_options.xl_options.dump_fdctx == _gf_true)) { +                list_for_each_entry_safe (fd_wrapper, tmp, &fd_list, +                                          next) { +                        list_del (&fd_wrapper->next); +                        fd_ctx_dump (fd_wrapper->fd, prefix); + +                        fd_unref (fd_wrapper->fd); +                        GF_FREE (fd_wrapper); +                } +        } + +        if (inode_ctx != NULL) { +                GF_FREE (inode_ctx); +        } +          return;  } diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 230e7c2ef..55832d2c8 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -39,7 +39,7 @@ extern xlator_t global_xlator;  static pthread_mutex_t  gf_proc_dump_mutex;  static int gf_dump_fd = -1; -static gf_dump_options_t dump_options; +gf_dump_options_t dump_options;  static void @@ -292,6 +292,10 @@ gf_proc_dump_parse_set_option (char *key, char *value)                  opt_key = &dump_options.xl_options.dump_fd;          } else if (!strncasecmp (key, "inode", 5)) {                  opt_key = &dump_options.xl_options.dump_inode; +        } else if (!strncasecmp (key, "inodectx", strlen ("inodectx"))) { +                opt_key = &dump_options.xl_options.dump_inodectx; +        } else if (!strncasecmp (key, "fdctx", strlen ("fdctx"))) { +                opt_key = &dump_options.xl_options.dump_fdctx;          }          if (!opt_key) { @@ -322,6 +326,9 @@ gf_proc_dump_enable_all_options ()          GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_true);          GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode, _gf_true);          GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_true); +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx, +                                 _gf_true); +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_true);          return 0;  } @@ -337,6 +344,9 @@ gf_proc_dump_disable_all_options ()          GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode,                                                                  _gf_false);          GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_false); +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inodectx, +                                 _gf_false); +        GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fdctx, _gf_false);          return 0;  } diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h index 02cba5bac..ba23ca559 100644 --- a/libglusterfs/src/statedump.h +++ b/libglusterfs/src/statedump.h @@ -35,6 +35,8 @@ typedef struct gf_dump_xl_options_ {          gf_boolean_t    dump_priv;          gf_boolean_t    dump_inode;          gf_boolean_t    dump_fd; +        gf_boolean_t    dump_inodectx; +        gf_boolean_t    dump_fdctx;  } gf_dump_xl_options_t;  typedef struct gf_dump_options_ { @@ -44,6 +46,8 @@ typedef struct gf_dump_options_ {          gf_dump_xl_options_t    xl_options; //options for all xlators  } gf_dump_options_t; +extern gf_dump_options_t dump_options; +  static inline  void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...)  { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index c71aa7bb3..2aa9b372b 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -732,12 +732,14 @@ typedef int32_t (*dumpop_fd_t)  (xlator_t   *this);  typedef int32_t (*dumpop_inodectx_t) (xlator_t *this, inode_t *ino); +typedef int32_t (*dumpop_fdctx_t) (xlator_t *this, fd_t *fd);  struct xlator_dumpops {  	dumpop_priv_t            priv;  	dumpop_inode_t           inode;          dumpop_fd_t              fd;  	dumpop_inodectx_t        inodectx; +        dumpop_fdctx_t           fdctx;  };  typedef struct xlator_list { diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 4437afce0..c9fc25a5b 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -66,14 +66,15 @@ typedef struct wb_file {  typedef struct wb_request { -        list_head_t  list; -        list_head_t  winds; -        list_head_t  unwinds; -        list_head_t  other_requests; -        call_stub_t *stub; -        size_t       write_size; -        int32_t      refcount; -        wb_file_t   *file; +        list_head_t     list; +        list_head_t     winds; +        list_head_t     unwinds; +        list_head_t     other_requests; +        call_stub_t    *stub; +        size_t          write_size; +        int32_t         refcount; +        wb_file_t      *file; +        glusterfs_fop_t fop;          union {                  struct  {                          char write_behind; @@ -241,6 +242,7 @@ wb_enqueue (wb_file_t *file, call_stub_t *stub)          request->stub = stub;          request->file = file; +        request->fop  = stub->fop;          frame = stub->frame;          local = frame->local; @@ -2563,6 +2565,149 @@ wb_priv_dump (xlator_t *this)          return 0;  } + +void +__wb_dump_requests (struct list_head *head, char *prefix, char passive) +{ +        char          key[GF_DUMP_MAX_BUF_LEN]; +        char          key_prefix[GF_DUMP_MAX_BUF_LEN]; +        wb_request_t *request = NULL; + +        list_for_each_entry (request, head, list) { +                gf_proc_dump_build_key (key, prefix, +                                        passive ? "passive-request" +                                        : "active-request"); +                gf_proc_dump_build_key (key_prefix, key, +                                        gf_fop_list[request->fop]); + +                gf_proc_dump_add_section(key_prefix); + +                gf_proc_dump_build_key (key, key_prefix, "request-ptr"); +                gf_proc_dump_write (key, "%p", request); + +                gf_proc_dump_build_key (key, key_prefix, "refcount"); +                gf_proc_dump_write (key, "%d", request->refcount); + +                if (request->fop == GF_FOP_WRITE) { +                        gf_proc_dump_build_key (key, key_prefix, "stack_wound"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.write_request.stack_wound); + +                        gf_proc_dump_build_key (key, key_prefix, "size"); +                        gf_proc_dump_write (key, "%"GF_PRI_SIZET, +                                            request->write_size); + +                        gf_proc_dump_build_key (key, key_prefix, "offset"); +                        gf_proc_dump_write (key, "%"PRId64, +                                            request->stub->args.writev.off); + +                        gf_proc_dump_build_key (key, key_prefix, +                                                "write_behind"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.write_request.write_behind); + +                        gf_proc_dump_build_key (key, key_prefix, "got_reply"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.write_request.got_reply); + +                        gf_proc_dump_build_key (key, key_prefix, "virgin"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.write_request.virgin); + +                        gf_proc_dump_build_key (key, key_prefix, "flush_all"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.write_request.flush_all); +                } else { +                        gf_proc_dump_build_key (key, key_prefix, +                                                "marked_for_resume"); +                        gf_proc_dump_write (key, "%d", +                                            request->flags.other_requests.marked_for_resume); +                } +        } +} + + +int +wb_file_dump (xlator_t *this, fd_t *fd) +{ +        wb_file_t *file = NULL; +        uint64_t   tmp_file = 0; +        int32_t    ret  = -1; +        char       key[GF_DUMP_MAX_BUF_LEN]; +        char       key_prefix[GF_DUMP_MAX_BUF_LEN]; + +        if ((fd == NULL) || (this == NULL)) { +                ret = 0; +                goto out; +        } + +        ret = fd_ctx_get (fd, this, &tmp_file); +        if (ret == -1) { +                ret = 0; +                goto out; +        } + +	file = (wb_file_t *)(long)tmp_file; +        if (file == NULL) { +                ret = 0; +                goto out; +        } + +        gf_proc_dump_build_key (key_prefix, +                                "xlator.performance.write-behind", +                                "file"); + +        gf_proc_dump_add_section (key_prefix); + +        gf_proc_dump_build_key (key, key_prefix, "fd"); +        gf_proc_dump_write (key, "%p", fd); + +        gf_proc_dump_build_key (key, key_prefix, "disabled"); +        gf_proc_dump_write (key, "%d", file->disabled); + +        gf_proc_dump_build_key (key, key_prefix, "disable_till"); +        gf_proc_dump_write (key, "%lu", file->disable_till); + +        gf_proc_dump_build_key (key, key_prefix, "window_conf"); +        gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_conf); + +        gf_proc_dump_build_key (key, key_prefix, "window_current"); +        gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_current); + +        gf_proc_dump_build_key (key, key_prefix, "flags"); +        gf_proc_dump_write (key, "%s", (file->flags & O_APPEND) ? "O_APPEND" +                            : "!O_APPEND"); + +        gf_proc_dump_build_key (key, key_prefix, "aggregate_current"); +        gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->aggregate_current); + +        gf_proc_dump_build_key (key, key_prefix, "refcount"); +        gf_proc_dump_write (key, "%d", file->refcount); + +        gf_proc_dump_build_key (key, key_prefix, "op_ret"); +        gf_proc_dump_write (key, "%d", file->op_ret); + +        gf_proc_dump_build_key (key, key_prefix, "op_errno"); +        gf_proc_dump_write (key, "%d", file->op_errno); + +        LOCK (&file->lock); +        { +                if (!list_empty (&file->request)) { +                        __wb_dump_requests (&file->request, key_prefix, 0); +                } + +                if (!list_empty (&file->passive_requests)) { +                        __wb_dump_requests (&file->passive_requests, key_prefix, +                                            1); +                } +        } +        UNLOCK (&file->lock); +         +out: +        return ret; +} + +  int32_t  mem_acct_init (xlator_t *this)  { @@ -2750,6 +2895,7 @@ struct xlator_cbks cbks = {  struct xlator_dumpops dumpops = {          .priv      =  wb_priv_dump, +        .fdctx     =  wb_file_dump,  };  struct volume_options options[] = { diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 3415eb35c..85d157f5f 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -803,7 +803,7 @@ get_frame_from_request (rpcsvc_request_t *req)          frame->root->uid      = req->uid;          frame->root->gid      = req->gid;          frame->root->pid      = req->pid; -        frame->root->trans    = req->trans; +        frame->root->trans    = req->trans->xl_private;          frame->root->lk_owner = req->lk_owner;          server_decode_groups (frame, req);  | 
