svn commit: r254375 - in projects/camlock/sys/cam: . scsi
Alexander Motin
mav at FreeBSD.org
Thu Aug 15 19:00:37 UTC 2013
Author: mav
Date: Thu Aug 15 19:00:36 2013
New Revision: 254375
URL: http://svnweb.freebsd.org/changeset/base/254375
Log:
Introduce new per-target lock to protect list of LUNs reported by device.
Modified:
projects/camlock/sys/cam/cam_xpt.c
projects/camlock/sys/cam/cam_xpt_internal.h
projects/camlock/sys/cam/scsi/scsi_xpt.c
Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c Thu Aug 15 17:44:44 2013 (r254374)
+++ projects/camlock/sys/cam/cam_xpt.c Thu Aug 15 19:00:36 2013 (r254375)
@@ -4526,6 +4526,7 @@ xpt_alloc_target(struct cam_eb *bus, tar
target->refcount = 1;
target->generation = 0;
target->luns = NULL;
+ mtx_init(&target->luns_mtx, "CAM LUNs lock", NULL, MTX_DEF);
timevalclear(&target->last_reset);
/*
* Hold a reference to our parent bus so it
@@ -4572,6 +4573,7 @@ xpt_release_target(struct cam_et *target
KASSERT(TAILQ_EMPTY(&target->ed_entries),
("destroying target, but device list is not empty"));
xpt_release_bus(bus);
+ mtx_destroy(&target->luns_mtx);
if (target->luns)
free(target->luns, M_CAMXPT);
free(target, M_CAMXPT);
Modified: projects/camlock/sys/cam/cam_xpt_internal.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt_internal.h Thu Aug 15 17:44:44 2013 (r254374)
+++ projects/camlock/sys/cam/cam_xpt_internal.h Thu Aug 15 19:00:36 2013 (r254375)
@@ -147,6 +147,7 @@ struct cam_et {
struct timeval last_reset;
u_int rpl_size;
struct scsi_report_luns_data *luns;
+ struct mtx luns_mtx; /* Protection for luns field. */
};
/*
Modified: projects/camlock/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_xpt.c Thu Aug 15 17:44:44 2013 (r254374)
+++ projects/camlock/sys/cam/scsi/scsi_xpt.c Thu Aug 15 19:00:36 2013 (r254375)
@@ -1728,11 +1728,12 @@ probe_purge_old(struct cam_path *path, s
if (path->target == NULL) {
return;
}
- if (path->target->luns == NULL) {
- path->target->luns = new;
- return;
- }
+ mtx_lock(&path->target->luns_mtx);
old = path->target->luns;
+ path->target->luns = new;
+ mtx_unlock(&path->target->luns_mtx);
+ if (old == NULL)
+ return;
nlun_old = scsi_4btoul(old->length) / 8;
nlun_new = scsi_4btoul(new->length) / 8;
@@ -1774,7 +1775,6 @@ probe_purge_old(struct cam_path *path, s
}
}
free(old, M_CAMXPT);
- path->target->luns = new;
}
static void
@@ -2011,6 +2011,7 @@ scsi_scan_bus(struct cam_periph *periph,
mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path);
mtx_lock(mtx);
+ mtx_lock(&target->luns_mtx);
if (target->luns) {
uint32_t first;
u_int nluns = scsi_4btoul(target->luns->length) / 8;
@@ -2028,6 +2029,7 @@ scsi_scan_bus(struct cam_periph *periph,
if (scan_info->lunindex[target_id] < nluns) {
CAM_GET_SIMPLE_LUN(target->luns,
scan_info->lunindex[target_id], lun_id);
+ mtx_unlock(&target->luns_mtx);
next_target = 0;
CAM_DEBUG(request_ccb->ccb_h.path,
CAM_DEBUG_PROBE,
@@ -2035,6 +2037,7 @@ scsi_scan_bus(struct cam_periph *periph,
scan_info->lunindex[target_id], lun_id));
scan_info->lunindex[target_id]++;
} else {
+ mtx_unlock(&target->luns_mtx);
/*
* We're done with scanning all luns.
*
@@ -2053,7 +2056,9 @@ scsi_scan_bus(struct cam_periph *periph,
}
}
}
- } else if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
+ } else {
+ mtx_unlock(&target->luns_mtx);
+ if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
int phl;
/*
@@ -2085,7 +2090,7 @@ scsi_scan_bus(struct cam_periph *periph,
if (lun_id == request_ccb->ccb_h.target_lun
|| lun_id > scan_info->cpi->max_lun)
next_target = 1;
- } else {
+ } else {
device = request_ccb->ccb_h.path->device;
@@ -2101,6 +2106,7 @@ scsi_scan_bus(struct cam_periph *periph,
if (lun_id == request_ccb->ccb_h.target_lun
|| lun_id > scan_info->cpi->max_lun)
next_target = 1;
+ }
}
/*
More information about the svn-src-projects
mailing list