From patchwork Tue Nov 21 13:58:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rui Hua X-Patchwork-Id: 10068207 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 364456022E for ; Tue, 21 Nov 2017 13:58:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 295262962C for ; Tue, 21 Nov 2017 13:58:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1DF8429634; Tue, 21 Nov 2017 13:58:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B801A2962C for ; Tue, 21 Nov 2017 13:58:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751388AbdKUN6v (ORCPT ); Tue, 21 Nov 2017 08:58:51 -0500 Received: from mail-ua0-f193.google.com ([209.85.217.193]:42249 "EHLO mail-ua0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751303AbdKUN6v (ORCPT ); Tue, 21 Nov 2017 08:58:51 -0500 Received: by mail-ua0-f193.google.com with SMTP id p33so8282961uag.9; Tue, 21 Nov 2017 05:58:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:from:date:message-id:subject:to:cc; bh=ZiFEmMQPt16V/laFY6FLq2i1K0kCAzrSQqyCxCmI684=; b=ti2W0WyoLh+6Ar7cLo8UvSiWSYc9mCcm8wIQbPLDTUcpbn9C5lJ/P5bRuA2jV/kMT7 T7AG44tuLXjTvtdnNaB5oDvugFfbl20FUVhxzCJOcvH8m1odh3HFNLGSQxPuk4JXPNhU 2jt2nXIgJY9icTtBUivzs2yBzO/NkDPHX1CWNyAMSF3Hg0kcdHdYTf0QGMcbKzK9+u7L 7Inuxa/UQoeKdcaqiDzq+dJahxByYCZfMZYXFRSxTSrorfp82/fOsNREVn61FtW3T1kO F0kYY4dltWN2NWNHwRWbRTUHrAce0RtrWzw5Og4A/K5+HFDIulwgZdvTv+A0vxaZGKSu mKJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:from:date:message-id:subject :to:cc; bh=ZiFEmMQPt16V/laFY6FLq2i1K0kCAzrSQqyCxCmI684=; b=U4iDE4x6o5vcXuN0VTBvpvl7MA3WxBAeBeYqEBvUG8KLhzPmXk9nbCNgIOAMlHEeNm Wv/y0yWS7afi8Ptcin0A4+NqJ8PxRR9uEEVp9V4tjUTs41tCHJdjMIo1ccTSpn4n6vQr db8XTyyTjEOsDPR+Khm6dnnL1zSL3ufm+PdijNuqoxuPQZC33jeQE624Qf1SH+ZEX7aq C18CJunGhoTLB6/88dXIjZzpwKNUQ53gYQeejqLMR3Wy51sLbHa/r+BACKMqXsIJpIrt ZoXwQJCSqutGYFv/4/uMP8vqRSPQm83trlFmLxSZypxaZCmYu55QrwG+fRwf4xhADwNB xMLg== X-Gm-Message-State: AJaThX7pLZFd/XrFFy+GeCo2HQY1nHuClNdYdbI4F08msZ5j866LmgAM Osw4jIGhcoWG0y1W8tNDYAIDa4kE6uO6m7w7YxewAg== X-Google-Smtp-Source: AGs4zMb40eHKyD0FaH/fJldGwEw62G/FJzQwv91oF6Rvie/8FzBXph4ikUjtKPXh0J2KJw4zMdQ4rRBAD38QeiiTdcA= X-Received: by 10.176.95.138 with SMTP id b10mr15442522uaj.55.1511272730357; Tue, 21 Nov 2017 05:58:50 -0800 (PST) MIME-Version: 1.0 Received: by 10.103.120.136 with HTTP; Tue, 21 Nov 2017 05:58:30 -0800 (PST) From: Rui Hua Date: Tue, 21 Nov 2017 21:58:30 +0800 X-Google-Sender-Auth: JC6vVeFZ8xHOazBWuOsrmDjtzzc Message-ID: Subject: [PATCH] bcache: return IOERR to upper layer when read request meet metadata error To: Coly Li , Michael Lyle Cc: linux-bcache , linux-block@vger.kernel.org Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The read request might meet error when searching the btree, but the error was not handled in cache_lookup(), and this kind of metadata failure will not go into cached_dev_read_error(), finally, the upper layer will receive bi_status=0. In this patch we judge the metadata error by the return value of bch_btree_map_keys(), there are two potential paths give rise to the error: 1.Because the btree is not totally cached in memery, we maybe get error when read btree node from cache device (see bch_btree_node_get()), the likely errno is -EIO, -ENOMEM 2.When read miss happend, bch_btree_insert_check_key() will be called to insert a "replace_key" to btree(see cached_dev_cache_miss(), just for doing preparatory work before insert the missed data to cache device), a failure can also happen in this situation, the likely errno is -ENOMEM bch_btree_map_keys() will return MAP_DONE in normal scenario, but we will get either -EIO or -ENOMEM in above two cases. if these happend, we should NOT recover data from backing device (when cache device is dirty) because we don't know whether bkeys the read request covered are all clean. And after that happend, s->iop.status is still its initially value(0) before we submit s->bio.bio, we set it to BLK_STS_IOERR, so it can go into cached_dev_read_error(), and finally it can be passed to upper layer, or recovered by reread from backing device. Signed-off-by: Hua Rui Reviewed-by: Michael Lyle --- drivers/md/bcache/request.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index f02fefb..b749431 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -576,6 +576,7 @@ static void cache_lookup(struct closure *cl) { struct search *s = container_of(cl, struct search, iop.cl); struct bio *bio = &s->bio.bio; + struct cached_dev *dc; int ret; bch_btree_op_init(&s->op, -1); @@ -588,6 +589,27 @@ static void cache_lookup(struct closure *cl) return; } + /* + * We might meet err when searching the btree, If that happend, we will + * get negative ret, in this scenario we should not recover data from + * backing device (when cache device is dirty) because we don't know + * whether bkeys the read request covered are all clean. + * + * And after that happend, s->iop.status is still its initially value + * before we submit s->bio.bio + */ + if (ret < 0) { + BUG_ON(ret == -EINTR); + if (s->d && s->d->c && + !UUID_FLASH_ONLY(&s->d->c->uuids[s->d->id])) { + dc = container_of(s->d, struct cached_dev, disk); + if (dc && atomic_read(&dc->has_dirty)) + s->recoverable = false; + } + if (!s->iop.status) + s->iop.status = BLK_STS_IOERR; + } + closure_return(cl); }