From patchwork Thu Feb 4 06:48:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 8214081 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DE507BEEE5 for ; Thu, 4 Feb 2016 06:48:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0B6C8202F2 for ; Thu, 4 Feb 2016 06:48:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 124A720373 for ; Thu, 4 Feb 2016 06:48:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932527AbcBDGsa (ORCPT ); Thu, 4 Feb 2016 01:48:30 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:44640 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932319AbcBDGs3 (ORCPT ); Thu, 4 Feb 2016 01:48:29 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u146mMpM010927 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 4 Feb 2016 06:48:23 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u146mL7M031993 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 4 Feb 2016 06:48:22 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u146mLMI014773; Thu, 4 Feb 2016 06:48:21 GMT Received: from ca-mkp.ca.oracle.com (/10.156.108.201) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 03 Feb 2016 22:48:21 -0800 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org, linux-block@vger.kernel.org Cc: jiangyiwen@huawei.com, snitzer@redhat.com, "Martin K. Petersen" Subject: [PATCH] block/sd: Return -EREMOTEIO when WRITE SAME and DISCARD are disabled Date: Thu, 4 Feb 2016 01:48:03 -0500 Message-Id: <1454568483-11298-1-git-send-email-martin.petersen@oracle.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <20160204042528.GA15599@redhat.com> References: <20160204042528.GA15599@redhat.com> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When a storage device rejects a WRITE SAME command we will disable write same functionality for the device and return -EREMOTEIO to the block layer. -EREMOTEIO will in turn prevent DM from retrying the I/O and/or failing the path. Yiwen Jiang discovered a small race where WRITE SAME requests issued simultaneously would cause -EIO to be returned. This happened because any requests being prepared after WRITE SAME had been disabled for the device caused us to return BLKPREP_KILL. The latter caused the block layer to return -EIO upon completion. To overcome this we introduce BLKPREP_INVALID which indicates that this is an invalid request for the device. blk_peek_request() is modified to return -EREMOTEIO in that case. Reported-by: Yiwen Jiang Suggested-by: Mike Snitzer Signed-off-by: Martin K. Petersen Reviewed-by: Hannes Reinecke Reviewed-by: Ewan D. Milne Reviewed-by: Yiwen Jiang --- I contemplated making blk_peek_request() use rq->errors to decide what to return up the stack. However, I cringed at mixing errnos and SCSI midlayer status information in the same location. --- block/blk-core.c | 6 ++++-- drivers/scsi/sd.c | 4 ++-- include/linux/blkdev.h | 9 ++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 33e2f62d5062..ee833af2f892 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2446,14 +2446,16 @@ struct request *blk_peek_request(struct request_queue *q) rq = NULL; break; - } else if (ret == BLKPREP_KILL) { + } else if (ret == BLKPREP_KILL || ret == BLKPREP_INVALID) { + int err = ret == BLKPREP_INVALID ? -EREMOTEIO : -EIO; + rq->cmd_flags |= REQ_QUIET; /* * Mark this request as started so we don't trigger * any debug logic in the end I/O path. */ blk_start_request(rq); - __blk_end_request_all(rq, -EIO); + __blk_end_request_all(rq, err); } else { printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); break; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ec163d08f6c3..6e841c6da632 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -761,7 +761,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd) break; default: - ret = BLKPREP_KILL; + ret = BLKPREP_INVALID; goto out; } @@ -839,7 +839,7 @@ static int sd_setup_write_same_cmnd(struct scsi_cmnd *cmd) int ret; if (sdkp->device->no_write_same) - return BLKPREP_KILL; + return BLKPREP_INVALID; BUG_ON(bio_offset(bio) || bio_iovec(bio).bv_len != sdp->sector_size); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c70e3588a48c..e990d181625a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -680,9 +680,12 @@ static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b) /* * q->prep_rq_fn return values */ -#define BLKPREP_OK 0 /* serve it */ -#define BLKPREP_KILL 1 /* fatal error, kill */ -#define BLKPREP_DEFER 2 /* leave on queue */ +enum { + BLKPREP_OK, /* serve it */ + BLKPREP_KILL, /* fatal error, kill, return -EIO */ + BLKPREP_INVALID, /* invalid command, kill, return -EREMOTEIO */ + BLKPREP_DEFER, /* leave on queue */ +}; extern unsigned long blk_max_low_pfn, blk_max_pfn;