Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753272AbdDDNvA (ORCPT ); Tue, 4 Apr 2017 09:51:00 -0400 Received: from mail-wm0-f46.google.com ([74.125.82.46]:35898 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751092AbdDDNu6 (ORCPT ); Tue, 4 Apr 2017 09:50:58 -0400 Cc: Shaohua Li , NeilBrown , Jinpu Wang To: linux-raid@vger.kernel.org, "linux-kernel@vger.kernel.org" From: Michael Wang Subject: [RFC PATCH] raid1: reset 'bi_next' before reuse the bio Message-ID: Date: Tue, 4 Apr 2017 15:50:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1474 Lines: 57 During the testing we found the sync read bio can go through path: md_do_sync() sync_request() generic_make_request() blk_queue_bio() blk_attempt_plug_merge() bio->bi_next CHAINED HERE ... raid1d() sync_request_write() fix_sync_read_error() if FailFast && Faulty bio->bi_end_io = end_sync_write generic_make_request() BUG_ON(bio->bi_next) This need to meet the conditions: * bio once merged * read disk have FailFast enabled * read disk is Faulty And since the block layer won't reset the 'bi_next' after bio is done inside request, we hit the BUG like that. This patch simply reset the bi_next before we reuse it. Signed-off-by: Michael Wang --- drivers/md/raid1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7d67235..0554110 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1986,11 +1986,13 @@ static int fix_sync_read_error(struct r1bio *r1_bio) /* Don't try recovering from here - just fail it * ... unless it is the last working device of course */ md_error(mddev, rdev); - if (test_bit(Faulty, &rdev->flags)) + if (test_bit(Faulty, &rdev->flags)) { /* Don't try to read from here, but make sure * put_buf does it's thing */ bio->bi_end_io = end_sync_write; + bio->bi_next = NULL; + } } while(sectors) { -- 2.5.0