Author: mav
Date: Tue Sep 15 09:36:46 2015
New Revision: 287816
URL: https://svnweb.freebsd.org/changeset/base/287816

Log:
  Close potential race between datamove and HA failover.

Modified:
  head/sys/cam/ctl/ctl.c

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c      Tue Sep 15 08:50:44 2015        (r287815)
+++ head/sys/cam/ctl/ctl.c      Tue Sep 15 09:36:46 2015        (r287816)
@@ -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 {
 
                /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to