Close potential race between datamove and HA failover.

This commit is contained in:
Alexander Motin 2015-09-15 09:36:46 +00:00
parent eec33ea052
commit 923863546a

View File

@ -10950,6 +10950,7 @@ ctl_failover_lun(struct ctl_lun *lun)
if (io->flags & CTL_FLAG_FROM_OTHER_SC) {
if (io->flags & CTL_FLAG_IO_ACTIVE) {
io->flags |= CTL_FLAG_ABORT;
io->flags |= CTL_FLAG_FAILOVER;
} else { /* This can be only due to DATAMOVE */
io->msg_type = CTL_MSG_DATAMOVE_DONE;
io->flags |= CTL_FLAG_IO_ACTIVE;
@ -12102,12 +12103,14 @@ ctl_datamove_timer_wakeup(void *arg)
void
ctl_datamove(union ctl_io *io)
{
struct ctl_lun *lun;
void (*fe_datamove)(union ctl_io *io);
mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED);
CTL_DEBUG_PRINT(("ctl_datamove\n"));
lun = (struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
#ifdef CTL_TIME_IO
if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) {
char str[256];
@ -12148,9 +12151,6 @@ ctl_datamove(union ctl_io *io)
if (io->io_hdr.flags & CTL_FLAG_DELAY_DONE) {
io->io_hdr.flags &= ~CTL_FLAG_DELAY_DONE;
} else {
struct ctl_lun *lun;
lun =(struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
if ((lun != NULL)
&& (lun->delay_info.datamove_delay > 0)) {
@ -12326,7 +12326,24 @@ ctl_datamove(union ctl_io *io)
msg.dt.sent_sg_entries = sg_entries_sent;
}
/*
* Officially handover the request from us to peer.
* If failover has just happened, then we must return error.
* If failover happen just after, then it is not our problem.
*/
if (lun)
mtx_lock(&lun->lun_lock);
if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
if (lun)
mtx_unlock(&lun->lun_lock);
io->io_hdr.port_status = 31342;
io->scsiio.be_move_done(io);
return;
}
io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
if (lun)
mtx_unlock(&lun->lun_lock);
} else {
/*