summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-05 11:05:56 +0000
committermav <mav@FreeBSD.org>2015-10-05 11:05:56 +0000
commitb37b5b0e0eac51779ff8977ecb64749f99865840 (patch)
treef8699f1ea3f4db38ee1977f572d32464635ab6a2 /sys/cam
parentb4e393c34e4403e7d195fbc8a888f4b1b110a971 (diff)
downloadFreeBSD-src-b37b5b0e0eac51779ff8977ecb64749f99865840.zip
FreeBSD-src-b37b5b0e0eac51779ff8977ecb64749f99865840.tar.gz
MFC r288239: Properly lock LUN in ctl_failover_lun().
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index e4dc9b4..5ce90e9 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -426,7 +426,7 @@ static int ctl_check_blocked(struct ctl_lun *lun);
static int ctl_scsiio_lun_check(struct ctl_lun *lun,
const struct ctl_cmd_entry *entry,
struct ctl_scsiio *ctsio);
-static void ctl_failover_lun(struct ctl_lun *lun);
+static void ctl_failover_lun(union ctl_io *io);
static int ctl_scsiio_precheck(struct ctl_softc *ctl_softc,
struct ctl_scsiio *ctsio);
static int ctl_scsiio(struct ctl_scsiio *ctsio);
@@ -11201,12 +11201,31 @@ ctl_failover_io(union ctl_io *io, int have_lock)
}
static void
-ctl_failover_lun(struct ctl_lun *lun)
+ctl_failover_lun(union ctl_io *rio)
{
- struct ctl_softc *softc = lun->ctl_softc;
+ struct ctl_softc *softc = control_softc;
+ struct ctl_lun *lun;
struct ctl_io_hdr *io, *next_io;
+ uint32_t targ_lun;
+
+ targ_lun = rio->io_hdr.nexus.targ_mapped_lun;
+ CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", targ_lun));
+
+ /* Find and lock the LUN. */
+ mtx_lock(&softc->ctl_lock);
+ if ((targ_lun < CTL_MAX_LUNS) &&
+ ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
+ mtx_lock(&lun->lun_lock);
+ mtx_unlock(&softc->ctl_lock);
+ if (lun->flags & CTL_LUN_DISABLED) {
+ mtx_unlock(&lun->lun_lock);
+ return;
+ }
+ } else {
+ mtx_unlock(&softc->ctl_lock);
+ return;
+ }
- CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", lun->lun));
if (softc->ha_mode == CTL_HA_MODE_XFER) {
TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) {
/* We are master */
@@ -11264,6 +11283,7 @@ ctl_failover_lun(struct ctl_lun *lun)
}
ctl_check_blocked(lun);
}
+ mtx_unlock(&lun->lun_lock);
}
static int
@@ -12196,9 +12216,7 @@ ctl_handle_isc(union ctl_io *io)
io->scsiio.be_move_done(io);
break;
case CTL_MSG_FAILOVER:
- mtx_lock(&lun->lun_lock);
- ctl_failover_lun(lun);
- mtx_unlock(&lun->lun_lock);
+ ctl_failover_lun(io);
free_io = 1;
break;
default:
OpenPOWER on IntegriCloud