diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2014-03-12 23:15:57 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2014-03-24 08:45:01 -0700 |
commit | a92ef4b03ff951f27904ba300cef72e8d3430035 (patch) | |
tree | 009996dc2f6c84d9aabb9b9a9860117e46c6b7d2 | |
parent | 652fb50dec8e8b074b60a3c82d00248a2aeb5eb9 (diff) | |
download | illumos-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.c | 17 | ||||
-rw-r--r-- | usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h | 4 |
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; |