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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to