From patchwork Thu Feb 4 02:08:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiangyiwen X-Patchwork-Id: 8213201 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 385E2BEEE5 for ; Thu, 4 Feb 2016 02:08:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 206F420364 for ; Thu, 4 Feb 2016 02:08:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 21CC12035B for ; Thu, 4 Feb 2016 02:08:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752877AbcBDCIa (ORCPT ); Wed, 3 Feb 2016 21:08:30 -0500 Received: from szxga01-in.huawei.com ([58.251.152.64]:24079 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751755AbcBDCI3 (ORCPT ); Wed, 3 Feb 2016 21:08:29 -0500 Received: from 172.24.1.47 (EHLO szxeml428-hub.china.huawei.com) ([172.24.1.47]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DED04058; Thu, 04 Feb 2016 10:08:13 +0800 (CST) Received: from [127.0.0.1] (10.177.16.168) by szxeml428-hub.china.huawei.com (10.82.67.183) with Microsoft SMTP Server id 14.3.235.1; Thu, 4 Feb 2016 10:08:03 +0800 From: jiangyiwen To: CC: , , Christoph Hellwig , James Bottomley , , "Qijiang (Joseph, Euler)" , Subject: [dm-devel] [PATCH] dm-mpath: fix a tiny case which can cause an infinite loop Message-ID: <56B2B282.60400@huawei.com> Date: Thu, 4 Feb 2016 10:08:02 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 X-Originating-IP: [10.177.16.168] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020205.56B2B28E.014A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 10e043259515e9a5cecb2c57b43c6fde 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.3 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 two processes submit WRTIE SAME bio simultaneously and first IO return failed because of INVALID FIELD IN CDB, and then second IO can enter into an infinite loop. The problem can be described as follows: process 1 process 2 submit_bio(REQ_WRITE_SAME) and wait io completion begin submit_bio(REQ_WRITE_SAME) -> blk_queue_bio() -> dm_request_fn() -> map_request() -> scsi_request_fn() -> blk_peek_request() -> scsi_prep_fn() In the moment, IO return and sense_key with illegal_request, sense_code with 0x24(INVALID FIELD IN CDB). In this way it will set no_write_same = 1 in sd_done() and disable write same In sd_setup_write_same_cmnd() when find (no_write_same == 1) will return BLKPREP_KILL, and then in blk_peek_request() set error to EIO. However, in multipath_end_io() when find error is EIO it will fail path and retry even if device doesn't support WRITE SAME. In this situation, when process of multipathd reinstate path by using test_unit_ready periodically, it will cause second WRITE SAME IO enters into an infinite loop and loop never terminates. In do_end_io(), when finding device doesn't support WRITE SAME and request is WRITE SAME, return EOPNOTSUPP to applications. Signed-off-by: Yiwen Jiang Reviewed-by: Joseph Qi Reviewed-by: xuejiufei --- drivers/md/dm-mpath.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index cfa29f5..ad1602a 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1269,6 +1269,11 @@ static int do_end_io(struct multipath *m, struct request *clone, if (noretry_error(error)) return error; + /* do not retry in case of WRITE SAME not supporting */ + if ((clone->cmd_flags & REQ_WRITE_SAME) && + !clone->q->limits.max_write_same_sectors) + return -EOPNOTSUPP; + if (mpio->pgpath) fail_path(mpio->pgpath);