From patchwork Fri May 29 13:38:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 11578687 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2084F14C0 for ; Fri, 29 May 2020 13:39:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 083D1207BC for ; Fri, 29 May 2020 13:39:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726849AbgE2Ni7 (ORCPT ); Fri, 29 May 2020 09:38:59 -0400 Received: from mx2.suse.de ([195.135.220.15]:59242 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726476AbgE2Ni7 (ORCPT ); Fri, 29 May 2020 09:38:59 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id A0DCBAF16; Fri, 29 May 2020 13:38:57 +0000 (UTC) From: Hannes Reinecke To: "Martin K. Petersen" Cc: Christoph Hellwig , James Bottomley , linux-scsi@vger.kernel.org, Hannes Reinecke Subject: [PATCH] scsi_scan: handle REPORT LUN overflow Date: Fri, 29 May 2020 15:38:55 +0200 Message-Id: <20200529133855.146357-1-hare@suse.de> X-Mailer: git-send-email 2.16.4 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Devices might report a really large REPORT LUN buffer, which will cause kmalloc to bail if it can't allocate enough continuguous pages. However, at that time we already have received a perfectly good response, so we should continue using that buffer to allow us to register at least the LUNs from the 'good' response. Signed-off-by: Hannes Reinecke Reported-by: kbuild test robot --- drivers/scsi/scsi_scan.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 82a00d7751b3..0a344653487d 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1290,7 +1290,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag struct scsi_sense_hdr sshdr; struct scsi_device *sdev; struct Scsi_Host *shost = dev_to_shost(&starget->dev); - int ret = 0; + int ret = 0, alloc_flags = + shost->unchecked_isa_dma ? __GFP_DMA : 0; /* * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. @@ -1327,14 +1328,13 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag * value of the now removed max_report_luns parameter. */ length = (511 + 1) * sizeof(struct scsi_lun); -retry: - lun_data = kmalloc(length, GFP_KERNEL | - (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); + lun_data = kmalloc(length, GFP_KERNEL | alloc_flags); if (!lun_data) { printk(ALLOC_FAILURE_MSG, __func__); goto out; } +retry: scsi_cmd[0] = REPORT_LUNS; /* @@ -1395,12 +1395,21 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag */ if (get_unaligned_be32(lun_data->scsi_lun) + sizeof(struct scsi_lun) > length) { - length = get_unaligned_be32(lun_data->scsi_lun) + + unsigned int resp_length; + void *resp_data; + + resp_length = get_unaligned_be32(lun_data->scsi_lun) + sizeof(struct scsi_lun); - kfree(lun_data); - goto retry; - } - length = get_unaligned_be32(lun_data->scsi_lun); + resp_data = kmalloc(resp_length, GFP_KERNEL | alloc_flags); + if (resp_data) { + kfree(lun_data); + lun_data = resp_data; + length = resp_length; + goto retry; + } + printk(ALLOC_FAILURE_MSG, __func__); + } else + length = get_unaligned_be32(lun_data->scsi_lun); num_luns = (length / sizeof(struct scsi_lun));