From 1418bac978b1cf56358828dec29a2fb2602e5b9b Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Tue, 26 Oct 2010 13:01:04 +0000 Subject: [PATCH] Merge of the trunk's r2472: Fix possible crash on access to not existing LUN with CONFIG_SCST_MEASURE_LATENCY enabled reported by ido benda git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.0.0.x@2473 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 85 ++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 837833f1f..58d398d41 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -7586,7 +7586,10 @@ void scst_update_lat_stats(struct scst_cmd *cmd) else if (data_len <= SCST_IO_SIZE_THRESHOLD_VERY_LARGE) i = SCST_LATENCY_STAT_INDEX_VERY_LARGE; latency_stat = &sess->sess_latency_stat[i]; - dev_latency_stat = &cmd->tgt_dev->dev_latency_stat[i]; + if (cmd->tgt_dev != NULL) + dev_latency_stat = &cmd->tgt_dev->dev_latency_stat[i]; + else + dev_latency_stat = NULL; /* Calculate the latencies */ scst_time = finish - cmd->start - (cmd->parse_time + @@ -7649,27 +7652,29 @@ void scst_update_lat_stats(struct scst_cmd *cmd) if (latency_stat->max_dev_time_rd < dev_time) latency_stat->max_dev_time_rd = dev_time; - dev_latency_stat->scst_time_rd += scst_time; - dev_latency_stat->tgt_time_rd += tgt_time; - dev_latency_stat->dev_time_rd += dev_time; - dev_latency_stat->processed_cmds_rd++; + if (dev_latency_stat != NULL) { + dev_latency_stat->scst_time_rd += scst_time; + dev_latency_stat->tgt_time_rd += tgt_time; + dev_latency_stat->dev_time_rd += dev_time; + dev_latency_stat->processed_cmds_rd++; - if ((dev_latency_stat->min_scst_time_rd == 0) || - (dev_latency_stat->min_scst_time_rd > scst_time)) - dev_latency_stat->min_scst_time_rd = scst_time; - if ((dev_latency_stat->min_tgt_time_rd == 0) || - (dev_latency_stat->min_tgt_time_rd > tgt_time)) - dev_latency_stat->min_tgt_time_rd = tgt_time; - if ((dev_latency_stat->min_dev_time_rd == 0) || - (dev_latency_stat->min_dev_time_rd > dev_time)) - dev_latency_stat->min_dev_time_rd = dev_time; + if ((dev_latency_stat->min_scst_time_rd == 0) || + (dev_latency_stat->min_scst_time_rd > scst_time)) + dev_latency_stat->min_scst_time_rd = scst_time; + if ((dev_latency_stat->min_tgt_time_rd == 0) || + (dev_latency_stat->min_tgt_time_rd > tgt_time)) + dev_latency_stat->min_tgt_time_rd = tgt_time; + if ((dev_latency_stat->min_dev_time_rd == 0) || + (dev_latency_stat->min_dev_time_rd > dev_time)) + dev_latency_stat->min_dev_time_rd = dev_time; - if (dev_latency_stat->max_scst_time_rd < scst_time) - dev_latency_stat->max_scst_time_rd = scst_time; - if (dev_latency_stat->max_tgt_time_rd < tgt_time) - dev_latency_stat->max_tgt_time_rd = tgt_time; - if (dev_latency_stat->max_dev_time_rd < dev_time) - dev_latency_stat->max_dev_time_rd = dev_time; + if (dev_latency_stat->max_scst_time_rd < scst_time) + dev_latency_stat->max_scst_time_rd = scst_time; + if (dev_latency_stat->max_tgt_time_rd < tgt_time) + dev_latency_stat->max_tgt_time_rd = tgt_time; + if (dev_latency_stat->max_dev_time_rd < dev_time) + dev_latency_stat->max_dev_time_rd = dev_time; + } } else if (cmd->data_direction & SCST_DATA_WRITE) { latency_stat->scst_time_wr += scst_time; latency_stat->tgt_time_wr += tgt_time; @@ -7693,27 +7698,29 @@ void scst_update_lat_stats(struct scst_cmd *cmd) if (latency_stat->max_dev_time_wr < dev_time) latency_stat->max_dev_time_wr = dev_time; - dev_latency_stat->scst_time_wr += scst_time; - dev_latency_stat->tgt_time_wr += tgt_time; - dev_latency_stat->dev_time_wr += dev_time; - dev_latency_stat->processed_cmds_wr++; + if (dev_latency_stat != NULL) { + dev_latency_stat->scst_time_wr += scst_time; + dev_latency_stat->tgt_time_wr += tgt_time; + dev_latency_stat->dev_time_wr += dev_time; + dev_latency_stat->processed_cmds_wr++; - if ((dev_latency_stat->min_scst_time_wr == 0) || - (dev_latency_stat->min_scst_time_wr > scst_time)) - dev_latency_stat->min_scst_time_wr = scst_time; - if ((dev_latency_stat->min_tgt_time_wr == 0) || - (dev_latency_stat->min_tgt_time_wr > tgt_time)) - dev_latency_stat->min_tgt_time_wr = tgt_time; - if ((dev_latency_stat->min_dev_time_wr == 0) || - (dev_latency_stat->min_dev_time_wr > dev_time)) - dev_latency_stat->min_dev_time_wr = dev_time; + if ((dev_latency_stat->min_scst_time_wr == 0) || + (dev_latency_stat->min_scst_time_wr > scst_time)) + dev_latency_stat->min_scst_time_wr = scst_time; + if ((dev_latency_stat->min_tgt_time_wr == 0) || + (dev_latency_stat->min_tgt_time_wr > tgt_time)) + dev_latency_stat->min_tgt_time_wr = tgt_time; + if ((dev_latency_stat->min_dev_time_wr == 0) || + (dev_latency_stat->min_dev_time_wr > dev_time)) + dev_latency_stat->min_dev_time_wr = dev_time; - if (dev_latency_stat->max_scst_time_wr < scst_time) - dev_latency_stat->max_scst_time_wr = scst_time; - if (dev_latency_stat->max_tgt_time_wr < tgt_time) - dev_latency_stat->max_tgt_time_wr = tgt_time; - if (dev_latency_stat->max_dev_time_wr < dev_time) - dev_latency_stat->max_dev_time_wr = dev_time; + if (dev_latency_stat->max_scst_time_wr < scst_time) + dev_latency_stat->max_scst_time_wr = scst_time; + if (dev_latency_stat->max_tgt_time_wr < tgt_time) + dev_latency_stat->max_tgt_time_wr = tgt_time; + if (dev_latency_stat->max_dev_time_wr < dev_time) + dev_latency_stat->max_dev_time_wr = dev_time; + } } spin_unlock_bh(&sess->lat_lock);