From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752706AbcLEX47 (ORCPT ); Mon, 5 Dec 2016 18:56:59 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:36472 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751201AbcLEX4y (ORCPT ); Mon, 5 Dec 2016 18:56:54 -0500 From: Nicolai Stange To: Jens Axboe Cc: "James E.J. Bottomley" , "Martin K. Petersen" , Shaun Tancheff , Chaitanya Kulkarni , Christoph Hellwig , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Nicolai Stange Subject: [PATCH] sd: make ->no_write_same independent of reported ->max_ws_blocks Date: Tue, 6 Dec 2016 00:56:38 +0100 Message-Id: <20161205235638.11539-1-nicstange@gmail.com> X-Mailer: git-send-email 2.10.2 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Due to reported problems with Write Same on ATA devices, commit 0ce1b18c42a5 ("libata: Some drives failing on SCT Write Same") strived to report non-support for Write Same on non-zoned ATA devices. However, due to the following control flow in sd_config_write_same() this doesn't always take effect, namely if the ->max_ws_blocks as set in the by the ATA Identify Device exceeds SD_WS10_BLOCKS: if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) [...] else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes) [...] else { sdkp->device->no_write_same = 1; sdkp->max_ws_blocks = 0; } Since commit e73c23ff736e ("block: add async variant of blkdev_issue_zeroout"), blkdev_issue_zeroout() got a little bit more sensitive towards failing Write Sames on devices that claim to support them and this results in messages like EXT4-fs (dm-1): Delayed block allocation failed for inode 2625094 at logical offset 2032 with max blocks 2 with error 121 EXT4-fs (dm-1): This should not happen!! Data will be lost The block limits VPD page of the device in question quotes a value of 0x3fffc0 > 0xffff == SD_MAX_WS10_BLOCKS for the device in question. The error code 121 is EREMOTEIO which gets asserted by scsi_io_completion() in case of invalid requests due to invalid command opcodes. Fix this by doing the sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS handling only if some kind of Write Same support is reported, i.e. only if sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes holds. Let the handling code for the non-support case thus take effect, if needed. Fixes: e73c23ff736e ("block: add async variant of blkdev_issue_zeroout") Fixes: 0ce1b18c42a5 ("libata: Some drives failing on SCT Write Same") Signed-off-by: Nicolai Stange --- Applicable to next-20161202. drivers/scsi/sd.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2cfeb3c..ef1bab5 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -806,18 +806,21 @@ static void sd_config_write_same(struct scsi_disk *sdkp) goto out; } - /* Some devices can not handle block counts above 0xffff despite - * supporting WRITE SAME(16). Consequently we default to 64k - * blocks per I/O unless the device explicitly advertises a - * bigger limit. - */ - if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) - sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS16_BLOCKS); - else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes) - sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, - (u32)SD_MAX_WS10_BLOCKS); - else { + if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes) { + /* + * Some devices can not handle block counts above 0xffff despite + * supporting WRITE SAME(16). Consequently we default to 64k + * blocks per I/O unless the device explicitly advertises a + * bigger limit. + */ + if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) { + sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); + } else { + sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); + } + } else { sdkp->device->no_write_same = 1; sdkp->max_ws_blocks = 0; } -- 2.10.2