]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iscsi-target: Fix bug in handling of ExpStatSN ACK during u32 wrap-around
authorSteve Hodgson <steve@purestorage.com>
Tue, 6 Nov 2012 02:02:41 +0000 (18:02 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jan 2013 16:45:57 +0000 (08:45 -0800)
commit 64c13330a38935120501b19c97a3e6095747c7a1 upstream.

This patch fixes a bug in the hanlding of initiator provided ExpStatSN and
individual iscsi_cmd->stat_sn comparision during iscsi_conn->stat_sn
wrap-around within iscsit_ack_from_expstatsn() code.

This bug would manifest itself as iscsi_cmd descriptors not being Acked
by a lower ExpStatSn, causing them to be leaked until an iSCSI connection
or session reinstatement event occurs to release all commands.

Also fix up two other uses of incorrect CmdSN SNA comparison to use wrapper
usage from include/scsi/iscsi_proto.h.

Signed-off-by: Steve Hodgson <steve@purestorage.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_erl2.c
drivers/target/iscsi/iscsi_target_tmr.c

index 035c2c762537c63e9bf62210b5476f7aef5c687a..6de6584bbe2324f026fec43c2b247b0ba8546993 100644 (file)
@@ -735,7 +735,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
        list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
                spin_lock(&cmd->istate_lock);
                if ((cmd->i_state == ISTATE_SENT_STATUS) &&
-                   (cmd->stat_sn < exp_statsn)) {
+                   iscsi_sna_lt(cmd->stat_sn, exp_statsn)) {
                        cmd->i_state = ISTATE_REMOVE;
                        spin_unlock(&cmd->istate_lock);
                        iscsit_add_cmd_to_immediate_queue(cmd, conn,
index 17d8c20094fd13e5cd276afbc86ab47a6ca634d3..9ac4c151eae43af4efdaac0b0f36c1ef301f068f 100644 (file)
@@ -372,7 +372,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
                 * made generic here.
                 */
                if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd &&
-                    (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) {
+                    iscsi_sna_gte(cmd->stat_sn, conn->sess->exp_cmd_sn)) {
                        list_del(&cmd->i_conn_node);
                        spin_unlock_bh(&conn->cmd_lock);
                        iscsit_free_cmd(cmd);
index 4a99820d063be4d07c9d14e0239486793779c837..9d4417aae9213c326b2f76ffc0f54fd888bf1baa 100644 (file)
@@ -50,8 +50,8 @@ u8 iscsit_tmr_abort_task(
        if (!ref_cmd) {
                pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
                        " %hu.\n", hdr->rtt, conn->cid);
-               return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn &&
-                       be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ?
+               return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) &&
+                       iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ?
                        ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
        }
        if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {