summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-03-12 23:15:57 +0000
committerRobert Mustacchi <rm@joyent.com>2014-03-24 08:45:01 -0700
commita92ef4b03ff951f27904ba300cef72e8d3430035 (patch)
tree009996dc2f6c84d9aabb9b9a9860117e46c6b7d2
parent652fb50dec8e8b074b60a3c82d00248a2aeb5eb9 (diff)
downloadillumos-joyent-a92ef4b03ff951f27904ba300cef72e8d3430035.tar.gz
4682 panic in mptsas refhash
Reviewed by: Dan McDonald <danmcd@omniti.com> Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com> Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com> Approved by: Albert Lee <trisk@nexenta.com>
-rw-r--r--usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c17
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h4
2 files changed, 20 insertions, 1 deletions
diff --git a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
index 90ddbb8988..1dc8a27aef 100644
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
+++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
@@ -15274,6 +15274,15 @@ mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
return (tmp_tgt);
}
+static void
+mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
+{
+ dst->m_devhdl = src->m_devhdl;
+ dst->m_deviceinfo = src->m_deviceinfo;
+ dst->m_pdevhdl = src->m_pdevhdl;
+ dst->m_pdevinfo = src->m_pdevinfo;
+}
+
static mptsas_smp_t *
mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
{
@@ -15283,8 +15292,14 @@ mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
addr.mta_wwn = data->m_addr.mta_wwn;
addr.mta_phymask = data->m_addr.mta_phymask;
ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
+ /*
+ * If there's already a matching SMP target, update its fields
+ * in place. Since the address is not changing, it's safe to do
+ * this. We cannot just bcopy() here because the structure we've
+ * been given has invalid hash links.
+ */
if (ret_data != NULL) {
- bcopy(data, ret_data, sizeof (mptsas_smp_t)); /* XXX - dupl */
+ mptsas_smp_target_copy(data, ret_data);
return (ret_data);
}
diff --git a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
index 9768c4ea80..96b9b11464 100644
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
+++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h
@@ -224,6 +224,10 @@ typedef struct mptsas_target {
} mptsas_target_t;
+/*
+ * If you change this structure, be sure that mptsas_smp_target_copy()
+ * does the right thing.
+ */
typedef struct mptsas_smp {
mptsas_target_addr_t m_addr;
refhash_link_t m_link;