summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-10-12 17:18:24 +0000
committermav <mav@FreeBSD.org>2012-10-12 17:18:24 +0000
commitc5f476d2d7820c7b7b4c31187aa82e69111ec748 (patch)
tree8b5f5e6ab8e907cfbc0b2a9b51189d423ca630e9 /sys/cam
parent6e22acd47bf1dfd002d3a75ebc6decf639036bc5 (diff)
downloadFreeBSD-src-c5f476d2d7820c7b7b4c31187aa82e69111ec748.zip
FreeBSD-src-c5f476d2d7820c7b7b4c31187aa82e69111ec748.tar.gz
Protect xpt_getattr() calls with the SIM lock and assert that.
Submitted by: ken@ (earlier version)
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_da.c10
-rw-r--r--sys/cam/cam_xpt.c2
-rw-r--r--sys/cam/scsi/scsi_da.c10
-rw-r--r--sys/cam/scsi/scsi_pass.c12
4 files changed, 19 insertions, 15 deletions
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index bb63ac8..e35e462 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -914,17 +914,17 @@ adasysctlinit(void *context, int pending)
static int
adagetattr(struct bio *bp)
{
- int ret = -1;
+ int ret;
struct cam_periph *periph;
- if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL)
- return ENXIO;
periph = (struct cam_periph *)bp->bio_disk->d_drv1;
- if (periph->path == NULL)
- return ENXIO;
+ if (periph == NULL)
+ return (ENXIO);
+ cam_periph_lock(periph);
ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
periph->path);
+ cam_periph_unlock(periph);
if (ret == 0)
bp->bio_completed = bp->bio_length;
return ret;
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 374e870..a5ae5bc 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -1111,6 +1111,8 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
int ret = -1;
struct ccb_dev_advinfo cdai;
+ mtx_assert(path->bus->sim->mtx, MA_OWNED);
+
memset(&cdai, 0, sizeof(cdai));
xpt_setup_ccb(&cdai.ccb_h, path, CAM_PRIORITY_NORMAL);
cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index aea2cd3..0d91049 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -1211,17 +1211,17 @@ dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t leng
static int
dagetattr(struct bio *bp)
{
- int ret = -1;
+ int ret;
struct cam_periph *periph;
- if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL)
- return ENXIO;
periph = (struct cam_periph *)bp->bio_disk->d_drv1;
- if (periph->path == NULL)
- return ENXIO;
+ if (periph == NULL)
+ return (ENXIO);
+ cam_periph_lock(periph);
ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
periph->path);
+ cam_periph_unlock(periph);
if (ret == 0)
bp->bio_completed = bp->bio_length;
return ret;
diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c
index 756fe52..65a7aee 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -212,27 +212,26 @@ pass_add_physpath(void *context, int pending)
*/
periph = context;
softc = periph->softc;
+ physpath = malloc(MAXPATHLEN, M_DEVBUF, M_WAITOK);
cam_periph_lock(periph);
if (periph->flags & CAM_PERIPH_INVALID) {
cam_periph_unlock(periph);
- return;
+ goto out;
}
- cam_periph_unlock(periph);
- physpath = malloc(MAXPATHLEN, M_DEVBUF, M_WAITOK);
if (xpt_getattr(physpath, MAXPATHLEN,
"GEOM::physpath", periph->path) == 0
&& strlen(physpath) != 0) {
+ cam_periph_unlock(periph);
make_dev_physpath_alias(MAKEDEV_WAITOK, &softc->alias_dev,
softc->dev, softc->alias_dev, physpath);
+ cam_periph_lock(periph);
}
- free(physpath, M_DEVBUF);
/*
* Now that we've made our alias, we no longer have to have a
* reference to the device.
*/
- cam_periph_lock(periph);
if ((softc->flags & PASS_FLAG_INITIAL_PHYSPATH) == 0) {
softc->flags |= PASS_FLAG_INITIAL_PHYSPATH;
cam_periph_unlock(periph);
@@ -240,6 +239,9 @@ pass_add_physpath(void *context, int pending)
}
else
cam_periph_unlock(periph);
+
+out:
+ free(physpath, M_DEVBUF);
}
static void
OpenPOWER on IntegriCloud