]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[SCSI] libiscsi: Restructure iscsi_tcp r2t response logic
authorShlomo Pongratz <shlomop@mellanox.com>
Fri, 7 Feb 2014 06:41:37 +0000 (00:41 -0600)
committerJames Bottomley <JBottomley@Parallels.com>
Sat, 15 Mar 2014 17:19:18 +0000 (10:19 -0700)
Restructure the iscsi_tcp_r2t_rsp routine in order to avoid allocating
r2t from r2tpool.queue and returning it back in case the parameters
rhdr->data_length and or rhdr->data_offset prohibit the requing.

Since the values of these parameters are known prior to the allocation,
we can pre-check and thus avoid futile allocations.

[jejb: checkpatch fixes]
Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/libiscsi_tcp.c

index 1d58d5336018ca4a55a1a5df49e1a49882f5fbb0..2f738dddd07812e765abedddda9a74bc60e0618c 100644 (file)
@@ -529,6 +529,8 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
        struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
        struct iscsi_r2t_info *r2t;
        int r2tsn = be32_to_cpu(rhdr->r2tsn);
+       u32 data_length;
+       u32 data_offset;
        int rc;
 
        if (tcp_conn->in.datalen) {
@@ -554,40 +556,39 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
                return 0;
        }
 
-       rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
-       if (!rc) {
-               iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
-                                 "Target has sent more R2Ts than it "
-                                 "negotiated for or driver has leaked.\n");
-               return ISCSI_ERR_PROTO;
-       }
-
-       r2t->exp_statsn = rhdr->statsn;
-       r2t->data_length = be32_to_cpu(rhdr->data_length);
-       if (r2t->data_length == 0) {
+       data_length = be32_to_cpu(rhdr->data_length);
+       if (data_length == 0) {
                iscsi_conn_printk(KERN_ERR, conn,
                                  "invalid R2T with zero data len\n");
-               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
-                           sizeof(void*));
                return ISCSI_ERR_DATALEN;
        }
 
-       if (r2t->data_length > session->max_burst)
+       if (data_length > session->max_burst)
                ISCSI_DBG_TCP(conn, "invalid R2T with data len %u and max "
                              "burst %u. Attempting to execute request.\n",
-                             r2t->data_length, session->max_burst);
+                             data_length, session->max_burst);
 
-       r2t->data_offset = be32_to_cpu(rhdr->data_offset);
-       if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) {
+       data_offset = be32_to_cpu(rhdr->data_offset);
+       if (data_offset + data_length > scsi_out(task->sc)->length) {
                iscsi_conn_printk(KERN_ERR, conn,
                                  "invalid R2T with data len %u at offset %u "
-                                 "and total length %d\n", r2t->data_length,
-                                 r2t->data_offset, scsi_out(task->sc)->length);
-               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
-                           sizeof(void*));
+                                 "and total length %d\n", data_length,
+                                 data_offset, scsi_out(task->sc)->length);
                return ISCSI_ERR_DATALEN;
        }
 
+       rc = kfifo_out(&tcp_task->r2tpool.queue, (void *)&r2t, sizeof(void *));
+       if (!rc) {
+               iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
+                                 "Target has sent more R2Ts than it "
+                                 "negotiated for or driver has leaked.\n");
+               return ISCSI_ERR_PROTO;
+       }
+
+       r2t->exp_statsn = rhdr->statsn;
+       r2t->data_length = data_length;
+       r2t->data_offset = data_offset;
+
        r2t->ttt = rhdr->ttt; /* no flip */
        r2t->datasn = 0;
        r2t->sent = 0;