IB/srp: Eliminate state SRP_TARGET_CONNECTING
authorBart Van Assche <bvanassche@acm.org>
Sat, 17 Mar 2012 17:18:54 +0000 (17:18 +0000)
committerRoland Dreier <roland@purestorage.com>
Sat, 1 Dec 2012 01:40:29 +0000 (17:40 -0800)
Block the SCSI host while reconnecting instead of representing the
reconnection activity as a distinct SRP target state.  This allows us
to eliminate the target state SRP_TARGET_CONNECTING.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: David Dillow <dillowda@ornl.gov>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h

index 5aa70e9..a226199 100644 (file)
@@ -646,13 +646,16 @@ static void srp_reset_req(struct srp_target_port *target, struct srp_request *re
 
 static int srp_reconnect_target(struct srp_target_port *target)
 {
+       struct Scsi_Host *shost = target->scsi_host;
        struct ib_qp_attr qp_attr;
        struct ib_wc wc;
        int i, ret;
 
-       if (!srp_change_state(target, SRP_TARGET_LIVE, SRP_TARGET_CONNECTING))
+       if (target->state != SRP_TARGET_LIVE)
                return -EAGAIN;
 
+       scsi_target_block(&shost->shost_gendev);
+
        srp_disconnect_target(target);
        /*
         * Now get a new local CM ID so that we avoid confusing the
@@ -660,16 +663,16 @@ static int srp_reconnect_target(struct srp_target_port *target)
         */
        ret = srp_new_cm_id(target);
        if (ret)
-               goto err;
+               goto unblock;
 
        qp_attr.qp_state = IB_QPS_RESET;
        ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE);
        if (ret)
-               goto err;
+               goto unblock;
 
        ret = srp_init_qp(target, target->qp);
        if (ret)
-               goto err;
+               goto unblock;
 
        while (ib_poll_cq(target->recv_cq, 1, &wc) > 0)
                ; /* nothing */
@@ -688,11 +691,15 @@ static int srp_reconnect_target(struct srp_target_port *target)
 
        target->qp_in_error = 0;
        ret = srp_connect_target(target);
+
+unblock:
+       scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING :
+                           SDEV_TRANSPORT_OFFLINE);
+
        if (ret)
                goto err;
 
-       if (!srp_change_state(target, SRP_TARGET_CONNECTING, SRP_TARGET_LIVE))
-               ret = -EAGAIN;
+       shost_printk(KERN_INFO, target->scsi_host, PFX "reconnect succeeded\n");
 
        return ret;
 
@@ -710,7 +717,7 @@ err:
         * the flush_scheduled_work() in srp_remove_one().
         */
        spin_lock_irq(&target->lock);
-       if (target->state == SRP_TARGET_CONNECTING) {
+       if (target->state == SRP_TARGET_LIVE) {
                target->state = SRP_TARGET_DEAD;
                INIT_WORK(&target->work, srp_remove_work);
                queue_work(ib_wq, &target->work);
@@ -1311,9 +1318,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
        unsigned long flags;
        int len;
 
-       if (target->state == SRP_TARGET_CONNECTING)
-               goto err;
-
        if (target->state == SRP_TARGET_DEAD ||
            target->state == SRP_TARGET_REMOVED) {
                scmnd->result = DID_BAD_TARGET << 16;
@@ -1377,7 +1381,6 @@ err_iu:
 err_unlock:
        spin_unlock_irqrestore(&target->lock, flags);
 
-err:
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
index e3a6304..8b436ce 100644 (file)
@@ -80,7 +80,6 @@ enum {
 
 enum srp_target_state {
        SRP_TARGET_LIVE,
-       SRP_TARGET_CONNECTING,
        SRP_TARGET_DEAD,
        SRP_TARGET_REMOVED
 };