From fdcd5a3a201489b1408951936e9bfc0871834a29 Mon Sep 17 00:00:00 2001 From: todd stecher Date: Mon, 16 Feb 2009 20:45:45 -0800 Subject: S3: Make changes to perfcount API set for when a single request leads to multiple replies (e.g. reply_echo). Change test and onefs modules to match new api set (thanks Volker!). --- source3/modules/perfcount_onefs.c | 64 +++++++++++++++++++++++++++++++-------- source3/modules/perfcount_test.c | 47 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 13 deletions(-) (limited to 'source3/modules') diff --git a/source3/modules/perfcount_onefs.c b/source3/modules/perfcount_onefs.c index a4fbe6ad53..9b35af699a 100644 --- a/source3/modules/perfcount_onefs.c +++ b/source3/modules/perfcount_onefs.c @@ -29,7 +29,7 @@ struct onefs_op_counter { }; struct onefs_stats_context { - bool deferred; + bool alloced; struct isp_op_delta iod; /* ANDX commands stats stored here */ @@ -107,7 +107,6 @@ static void onefs_smb_statistics_set_op(struct smb_perfcount_data *pcd, int op) if (pcd->context == NULL) return; - iod = onefs_stats_get_op_delta(ctxt); iod->op = isp_cifs_op_id(op); @@ -197,6 +196,50 @@ static void onefs_smb_statistics_set_msglen_out(struct smb_perfcount_data *pcd, ctxt->iod.out_bytes = out_bytes; } +static int onefs_copy_perfcount_context(struct onefs_stats_context *ctxt, + struct onefs_stats_context **dest) +{ + struct onefs_stats_context *new_ctxt; + + /* make an alloc'd copy of the data */ + new_ctxt = SMB_MALLOC_P(struct onefs_stats_context); + if (!new_ctxt) { + return -1; + } + + memcpy(new_ctxt, ctxt, sizeof(struct onefs_stats_context)); + new_ctxt->alloced = True; + *dest = new_ctxt; + return 0; +} + +static void onefs_smb_statistics_copy_context(struct smb_perfcount_data *pcd, + struct smb_perfcount_data *dest) +{ + struct onefs_stats_context *ctxt = pcd->context; + struct onefs_stats_context *new_ctxt; + int ret; + + /* not enabled */ + if (pcd->context == NULL) + return; + +#ifdef ONEFS_PERF_DEBUG + DEBUG(0,("******** COPYING op %s(%d)\n", + onefs_stat_debug(&ctxt->iod), ctxt->iod.op)); +#endif + + ret = onefs_copy_perfcount_context(ctxt, &new_ctxt); + if (ret) + return; + + /* instrumentation */ + if (ctxt == &g_context) + ZERO_STRUCT(g_context); + + dest->context = new_ctxt; +} + /* * For perf reasons, we usually use the global - sometimes, though, * when an operation is deferred, we need to alloc a copy. @@ -206,35 +249,29 @@ static void onefs_smb_statistics_defer_op(struct smb_perfcount_data *pcd, { struct onefs_stats_context *ctxt = pcd->context; struct onefs_stats_context *deferred_ctxt; + int ret; /* not enabled */ if (pcd->context == NULL) return; /* already allocated ? */ - if (ctxt->deferred) + if (ctxt->alloced) { def_pcd->context = ctxt; pcd->context = NULL; return; } - #ifdef ONEFS_PERF_DEBUG DEBUG(0,("******** DEFERRING op %s(%d)\n", onefs_stat_debug(&ctxt->iod), ctxt->iod.op)); #endif - /* make an alloc'd copy of the data */ - deferred_ctxt = SMB_MALLOC_P(struct onefs_stats_context); - if (!deferred_ctxt) { - /* disable for now - we'll get bogus stats, though */ - def_pcd->context = NULL; + ret = onefs_copy_perfcount_context(ctxt, &deferred_ctxt); + if (ret) return; - } - memcpy(deferred_ctxt, ctxt, sizeof(struct onefs_stats_context)); - deferred_ctxt->deferred = True; def_pcd->context = (void*) deferred_ctxt; /* instrumentation */ @@ -284,7 +321,7 @@ static void onefs_smb_statistics_end(struct smb_perfcount_data *pcd) ctxt->iod.in_bytes, ctxt->iod.out_bytes)); #endif - if (ctxt->deferred) + if (ctxt->alloced) SAFE_FREE(ctxt); else ZERO_STRUCTP(ctxt); @@ -302,6 +339,7 @@ static struct smb_perfcount_handlers onefs_pc_handlers = { onefs_smb_statistics_set_msglen_in, onefs_smb_statistics_set_msglen_out, onefs_smb_statistics_set_client, + onefs_smb_statistics_copy_context, onefs_smb_statistics_defer_op, onefs_smb_statistics_end }; diff --git a/source3/modules/perfcount_test.c b/source3/modules/perfcount_test.c index b140172af4..418d83ace5 100644 --- a/source3/modules/perfcount_test.c +++ b/source3/modules/perfcount_test.c @@ -294,6 +294,52 @@ static void perfcount_test_set_msglen_out(struct smb_perfcount_data *pcd, ctxt->ops->bytes_out = bytes_out; } +static void perfcount_test_copy_context(struct smb_perfcount_data *pcd, + struct smb_perfcount_data *new_pcd) +{ + struct perfcount_test_context *ctxt = + (struct perfcount_test_context *)pcd->context; + struct perfcount_test_context *new_ctxt; + + struct perfcount_test_counter *ctr; + struct perfcount_test_counter *new_ctr; + + if (pcd->context == NULL) + return; + + new_ctxt = SMB_MALLOC_P(struct perfcount_test_context); + if (!new_ctxt) { + return; + } + + memcpy(new_ctxt, ctxt, sizeof(struct perfcount_test_context)); + + for (ctr = ctxt->ops; ctr != NULL; ctr = ctr->next) { + new_ctr = SMB_MALLOC_P(struct perfcount_test_counter); + if (!new_ctr) { + goto error; + } + + memcpy(new_ctr, ctr, sizeof(struct perfcount_test_counter)); + new_ctr->next = NULL; + new_ctr->prev = NULL; + DLIST_ADD(new_ctxt->ops, new_ctr); + } + + new_pcd->context = new_ctxt; + return; + +error: + + for (ctr = new_ctxt->ops; ctr != NULL; ) { + new_ctr = ctr->next; + SAFE_FREE(ctr); + ctr = new_ctr; + } + + SAFE_FREE(new_ctxt); +} + /* * For perf reasons, its best to use some global state * when an operation is deferred, we need to alloc a copy. @@ -337,6 +383,7 @@ static struct smb_perfcount_handlers perfcount_test_handlers = { perfcount_test_set_msglen_in, perfcount_test_set_msglen_out, perfcount_test_set_client, + perfcount_test_copy_context, perfcount_test_defer_op, perfcount_test_end }; -- cgit