summaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-02-24 02:28:43 +0100
committerNicholas Bellinger <nab@linux-iscsi.org>2012-02-25 23:37:50 +0100
commitd335e6054db616bce3f040e659fa38440518ad1d (patch)
treef426c61320c4b323536a2b46203e17e5c6c3ea59 /drivers/target
parenttarget: Fix 16-bit target ports for SET TARGET PORT GROUPS emulation (diff)
downloadlinux-d335e6054db616bce3f040e659fa38440518ad1d.tar.xz
linux-d335e6054db616bce3f040e659fa38440518ad1d.zip
iscsi-target: Fix iscsit_alloc_buffs() failure cases
Make iscsit_alloc_buffs() failure case for page_alloc_failed use correct __free_page() SGL pointer, and return -ENOMEM for iscsit_allocate_iovecs failure to push se_cmd->t_mem_sg release into iscsit_release_cmd() callback during iscsit_add_reject_from_cmd() connection reset. Also drop cmd->t_mem_sg = NULL assignment from page_alloc_failed failure case. Reported-by: Roland Dreier <roland@purestorage.com> Cc: Andy Grover <agrover@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/iscsi/iscsi_target.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index cecf951e420f..c3ef2f6f3740 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -780,7 +780,7 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
struct scatterlist *sgl;
u32 length = cmd->se_cmd.data_length;
int nents = DIV_ROUND_UP(length, PAGE_SIZE);
- int i = 0, ret;
+ int i = 0, j = 0, ret;
/*
* If no SCSI payload is present, allocate the default iovecs used for
* iSCSI PDU Header
@@ -821,17 +821,15 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
*/
ret = iscsit_allocate_iovecs(cmd);
if (ret < 0)
- goto page_alloc_failed;
+ return -ENOMEM;
return 0;
page_alloc_failed:
- while (i >= 0) {
- __free_page(sg_page(&sgl[i]));
- i--;
- }
- kfree(cmd->t_mem_sg);
- cmd->t_mem_sg = NULL;
+ while (j < i)
+ __free_page(sg_page(&sgl[j++]));
+
+ kfree(sgl);
return -ENOMEM;
}