Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Oct 2012 17:18:24 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241485 - in head/sys/cam: . ata scsi
Message-ID:  <201210121718.q9CHIOmV044128@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Oct 12 17:18:24 2012
New Revision: 241485
URL: http://svn.freebsd.org/changeset/base/241485

Log:
  Protect xpt_getattr() calls with the SIM lock and assert that.
  
  Submitted by:	ken@ (earlier version)

Modified:
  head/sys/cam/ata/ata_da.c
  head/sys/cam/cam_xpt.c
  head/sys/cam/scsi/scsi_da.c
  head/sys/cam/scsi/scsi_pass.c

Modified: head/sys/cam/ata/ata_da.c
==============================================================================
--- head/sys/cam/ata/ata_da.c	Fri Oct 12 15:03:28 2012	(r241484)
+++ head/sys/cam/ata/ata_da.c	Fri Oct 12 17:18:24 2012	(r241485)
@@ -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;

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Fri Oct 12 15:03:28 2012	(r241484)
+++ head/sys/cam/cam_xpt.c	Fri Oct 12 17:18:24 2012	(r241485)
@@ -1111,6 +1111,8 @@ xpt_getattr(char *buf, size_t len, const
 	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;

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Fri Oct 12 15:03:28 2012	(r241484)
+++ head/sys/cam/scsi/scsi_da.c	Fri Oct 12 17:18:24 2012	(r241485)
@@ -1211,17 +1211,17 @@ dadump(void *arg, void *virtual, vm_offs
 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;

Modified: head/sys/cam/scsi/scsi_pass.c
==============================================================================
--- head/sys/cam/scsi/scsi_pass.c	Fri Oct 12 15:03:28 2012	(r241484)
+++ head/sys/cam/scsi/scsi_pass.c	Fri Oct 12 17:18:24 2012	(r241485)
@@ -212,27 +212,26 @@ pass_add_physpath(void *context, int pen
 	 */
 	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 pen
 	}
 	else
 		cam_periph_unlock(periph);
+
+out:
+	free(physpath, M_DEVBUF);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210121718.q9CHIOmV044128>