]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 May 2017 18:44:13 +0000 (11:44 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 May 2017 18:44:13 +0000 (11:44 -0700)
Pull SCSI target updates from Nicholas Bellinger:
 "Things were a lot more calm than previously expected. It's primarily
  fixes in various areas, with most of the new functionality centering
  around TCMU backend driver work that Xiubo Li has been driving.

  Here's the summary on the feature side:

   - Make T10-PI verify configurable for emulated (FILEIO + RD) backends
    (Dmitry Monakhov)
   - Allow target-core/TCMU pass-through to use in-kernel SPC-PR logic
    (Bryant Ly + MNC)
   - Add TCMU support for growing ring buffer size (Xiubo Li + MNC)
   - Add TCMU support for global block data pool (Xiubo Li + MNC)

  and on the bug-fix side:

   - Fix COMPARE_AND_WRITE non GOOD status handling for READ phase
    failures (Gary Guo + nab)
   - Fix iscsi-target hang with explicitly changing per NodeACL
    CmdSN number depth with concurrent login driven session
    reinstatement.  (Gary Guo + nab)
   - Fix ibmvscsis fabric driver ABORT task handling (Bryant Ly)
   - Fix target-core/FILEIO zero length handling (Bart Van Assche)

  Also, there was an OOPs introduced with the WRITE_VERIFY changes that
  I ended up reverting at the last minute, because as not unusual Bart
  and I could not agree on the fix in time for -rc1. Since it's specific
  to a conformance test, it's been reverted for now.

  There is a separate patch in the queue to address the underlying
  control CDB write overflow regression in >= v4.3 separate from the
  WRITE_VERIFY revert here, that will be pushed post -rc1"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (30 commits)
  Revert "target: Fix VERIFY and WRITE VERIFY command parsing"
  IB/srpt: Avoid that aborting a command triggers a kernel warning
  IB/srpt: Fix abort handling
  target/fileio: Fix zero-length READ and WRITE handling
  ibmvscsis: Do not send aborted task response
  tcmu: fix module removal due to stuck thread
  target: Don't force session reset if queue_depth does not change
  iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement
  target: Fix compare_and_write_callback handling for non GOOD status
  tcmu: Recalculate the tcmu_cmd size to save cmd area memories
  tcmu: Add global data block pool support
  tcmu: Add dynamic growing data area feature support
  target: fixup error message in target_tg_pt_gp_tg_pt_gp_id_store()
  target: fixup error message in target_tg_pt_gp_alua_access_type_store()
  target/user: PGR Support
  target: Add WRITE_VERIFY_16
  Documentation/target: add an example script to configure an iSCSI target
  target: Use kmalloc_array() in transport_kmap_data_sg()
  target: Use kmalloc_array() in compare_and_write_callback()
  target: Improve size determinations in two functions
  ...

1  2 
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_pscsi.c

index 7d6c199de2d6430b52f8d387786db6055525dbc6,ee026b6b4f0de99b16e158e10d1e77f791c479f6..1ced0731c1400950f59e31b1638800afec92daad
@@@ -417,7 -417,7 +417,7 @@@ static void srpt_mgmt_method_get(struc
  static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent,
                                  struct ib_mad_send_wc *mad_wc)
  {
 -      ib_destroy_ah(mad_wc->send_buf->ah);
 +      rdma_destroy_ah(mad_wc->send_buf->ah);
        ib_free_send_mad(mad_wc->send_buf);
  }
  
@@@ -481,7 -481,7 +481,7 @@@ static void srpt_mad_recv_handler(struc
        ib_free_send_mad(rsp);
  
  err_rsp:
 -      ib_destroy_ah(ah);
 +      rdma_destroy_ah(ah);
  err:
        ib_free_recv_mad(mad_wc);
  }
@@@ -2302,12 -2302,8 +2302,8 @@@ static void srpt_queue_response(struct 
        }
        spin_unlock_irqrestore(&ioctx->spinlock, flags);
  
-       if (unlikely(transport_check_aborted_status(&ioctx->cmd, false)
-                    || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) {
-               atomic_inc(&ch->req_lim_delta);
-               srpt_abort_cmd(ioctx);
+       if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT)))
                return;
-       }
  
        /* For read commands, transfer the data to the initiator. */
        if (ioctx->cmd.data_direction == DMA_FROM_DEVICE &&
@@@ -2689,7 -2685,8 +2685,8 @@@ static void srpt_release_cmd(struct se_
        struct srpt_rdma_ch *ch = ioctx->ch;
        unsigned long flags;
  
-       WARN_ON(ioctx->state != SRPT_STATE_DONE);
+       WARN_ON_ONCE(ioctx->state != SRPT_STATE_DONE &&
+                    !(ioctx->cmd.transport_state & CMD_T_ABORTED));
  
        if (ioctx->n_rw_ctx) {
                srpt_free_rw_ctxs(ch, ioctx);
index 5798810197ecf6f5fcf6f5d219de0f45e607b20c,96d9c73af1ae5f612f696b4dc5f09a1f1a6cecc8..535a8e06a4010f63a2744c1e1d0152d965d6630b
@@@ -167,7 -167,10 +167,7 @@@ static struct se_tpg_np *lio_target_cal
        struct iscsi_portal_group *tpg;
        struct iscsi_tpg_np *tpg_np;
        char *str, *str2, *ip_str, *port_str;
 -      struct sockaddr_storage sockaddr;
 -      struct sockaddr_in *sock_in;
 -      struct sockaddr_in6 *sock_in6;
 -      unsigned long port;
 +      struct sockaddr_storage sockaddr = { };
        int ret;
        char buf[MAX_PORTAL_LEN + 1];
  
        memset(buf, 0, MAX_PORTAL_LEN + 1);
        snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name);
  
 -      memset(&sockaddr, 0, sizeof(struct sockaddr_storage));
 -
        str = strstr(buf, "[");
        if (str) {
 -              const char *end;
 -
                str2 = strstr(str, "]");
                if (!str2) {
                        pr_err("Unable to locate trailing \"]\""
                                " in IPv6 iSCSI network portal address\n");
                        return ERR_PTR(-EINVAL);
                }
 -              str++; /* Skip over leading "[" */
 +
 +              ip_str = str + 1; /* Skip over leading "[" */
                *str2 = '\0'; /* Terminate the unbracketed IPv6 address */
                str2++; /* Skip over the \0 */
 +
                port_str = strstr(str2, ":");
                if (!port_str) {
                        pr_err("Unable to locate \":port\""
                }
                *port_str = '\0'; /* Terminate string for IP */
                port_str++; /* Skip over ":" */
 -
 -              ret = kstrtoul(port_str, 0, &port);
 -              if (ret < 0) {
 -                      pr_err("kstrtoul() failed for port_str: %d\n", ret);
 -                      return ERR_PTR(ret);
 -              }
 -              sock_in6 = (struct sockaddr_in6 *)&sockaddr;
 -              sock_in6->sin6_family = AF_INET6;
 -              sock_in6->sin6_port = htons((unsigned short)port);
 -              ret = in6_pton(str, -1,
 -                              (void *)&sock_in6->sin6_addr.in6_u, -1, &end);
 -              if (ret <= 0) {
 -                      pr_err("in6_pton returned: %d\n", ret);
 -                      return ERR_PTR(-EINVAL);
 -              }
        } else {
 -              str = ip_str = &buf[0];
 +              ip_str = &buf[0];
                port_str = strstr(ip_str, ":");
                if (!port_str) {
                        pr_err("Unable to locate \":port\""
                }
                *port_str = '\0'; /* Terminate string for IP */
                port_str++; /* Skip over ":" */
 +      }
  
 -              ret = kstrtoul(port_str, 0, &port);
 -              if (ret < 0) {
 -                      pr_err("kstrtoul() failed for port_str: %d\n", ret);
 -                      return ERR_PTR(ret);
 -              }
 -              sock_in = (struct sockaddr_in *)&sockaddr;
 -              sock_in->sin_family = AF_INET;
 -              sock_in->sin_port = htons((unsigned short)port);
 -              sock_in->sin_addr.s_addr = in_aton(ip_str);
 +      ret = inet_pton_with_scope(&init_net, AF_UNSPEC, ip_str,
 +                      port_str, &sockaddr);
 +      if (ret) {
 +              pr_err("malformed ip/port passed: %s\n", name);
 +              return ERR_PTR(ret);
        }
 +
        tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
        ret = iscsit_get_tpg(tpg);
        if (ret < 0)
@@@ -1506,6 -1528,7 +1506,7 @@@ static void lio_tpg_close_session(struc
                return;
        }
        atomic_set(&sess->session_reinstatement, 1);
+       atomic_set(&sess->session_fall_back_to_erl0, 1);
        spin_unlock(&sess->conn_lock);
  
        iscsit_stop_time2retain_timer(sess);
index d2f089cfa9aedcd63f204aa898d775c16330d150,c4845678eb918fa0b0ebda6ef5683111af5684d5..8add07f387f9dbf38a1effc84a2a846b95fbd8f3
@@@ -851,7 -851,7 +851,7 @@@ bool target_configure_unmap_from_queue(
        attrib->unmap_granularity = q->limits.discard_granularity / block_size;
        attrib->unmap_granularity_alignment = q->limits.discard_alignment /
                                                                block_size;
 -      attrib->unmap_zeroes_data = q->limits.discard_zeroes_data;
 +      attrib->unmap_zeroes_data = 0;
        return true;
  }
  EXPORT_SYMBOL(target_configure_unmap_from_queue);
@@@ -1045,6 -1045,8 +1045,8 @@@ passthrough_parse_cdb(struct se_cmd *cm
        sense_reason_t (*exec_cmd)(struct se_cmd *cmd))
  {
        unsigned char *cdb = cmd->t_task_cdb;
+       struct se_device *dev = cmd->se_dev;
+       unsigned int size;
  
        /*
         * Clear a lun set in the cdb if the initiator talking to use spoke
                return TCM_NO_SENSE;
        }
  
+       /*
+        * For PERSISTENT RESERVE IN/OUT, RELEASE, and RESERVE we need to
+        * emulate the response, since tcmu does not have the information
+        * required to process these commands.
+        */
+       if (!(dev->transport->transport_flags &
+             TRANSPORT_FLAG_PASSTHROUGH_PGR)) {
+               if (cdb[0] == PERSISTENT_RESERVE_IN) {
+                       cmd->execute_cmd = target_scsi3_emulate_pr_in;
+                       size = (cdb[7] << 8) + cdb[8];
+                       return target_cmd_size_check(cmd, size);
+               }
+               if (cdb[0] == PERSISTENT_RESERVE_OUT) {
+                       cmd->execute_cmd = target_scsi3_emulate_pr_out;
+                       size = (cdb[7] << 8) + cdb[8];
+                       return target_cmd_size_check(cmd, size);
+               }
+               if (cdb[0] == RELEASE || cdb[0] == RELEASE_10) {
+                       cmd->execute_cmd = target_scsi2_reservation_release;
+                       if (cdb[0] == RELEASE_10)
+                               size = (cdb[7] << 8) | cdb[8];
+                       else
+                               size = cmd->data_length;
+                       return target_cmd_size_check(cmd, size);
+               }
+               if (cdb[0] == RESERVE || cdb[0] == RESERVE_10) {
+                       cmd->execute_cmd = target_scsi2_reservation_reserve;
+                       if (cdb[0] == RESERVE_10)
+                               size = (cdb[7] << 8) | cdb[8];
+                       else
+                               size = cmd->data_length;
+                       return target_cmd_size_check(cmd, size);
+               }
+       }
        /* Set DATA_CDB flag for ops that should have it */
        switch (cdb[0]) {
        case READ_6:
index a93d94e68ab5faf5eea22d88ea8d9fe1b26aa897,8943a62eb203a6ecd0cf4a464bdb9d7e443856f8..3e4abb13f8ea4b46ad78de13eae74fd17ccda67a
@@@ -1008,7 -1008,7 +1008,7 @@@ pscsi_execute_cmd(struct se_cmd *cmd
                req->timeout = PS_TIMEOUT_DISK;
        else
                req->timeout = PS_TIMEOUT_OTHER;
 -      req->retries = PS_RETRY;
 +      scsi_req(req)->retries = PS_RETRY;
  
        blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, req,
                        (cmd->sam_task_attr == TCM_HEAD_TAG),
@@@ -1050,7 -1050,7 +1050,7 @@@ static void pscsi_req_done(struct reque
        struct se_cmd *cmd = req->end_io_data;
        struct pscsi_plugin_task *pt = cmd->priv;
  
 -      pt->pscsi_result = req->errors;
 +      pt->pscsi_result = scsi_req(req)->result;
        pt->pscsi_resid = scsi_req(req)->resid_len;
  
        cmd->scsi_status = status_byte(pt->pscsi_result) << 1;
@@@ -1081,7 -1081,8 +1081,8 @@@ static const struct target_backend_ops 
        .name                   = "pscsi",
        .owner                  = THIS_MODULE,
        .transport_flags        = TRANSPORT_FLAG_PASSTHROUGH |
-                                 TRANSPORT_FLAG_PASSTHROUGH_ALUA,
+                                 TRANSPORT_FLAG_PASSTHROUGH_ALUA |
+                                 TRANSPORT_FLAG_PASSTHROUGH_PGR,
        .attach_hba             = pscsi_attach_hba,
        .detach_hba             = pscsi_detach_hba,
        .pmode_enable_hba       = pscsi_pmode_enable_hba,