From patchwork Wed Sep 19 18:40:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606183 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E1D3115E8 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D5E142C841 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CA76C2C84D; Wed, 19 Sep 2018 18:41:15 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 6C8472C843 for ; Wed, 19 Sep 2018 18:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732349AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:60002 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731419AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPSgVZp0; Wed, 19 Sep 2018 20:41:11 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382471; bh=h+MVSqnRlAlWQ/7Bhq7lFOLE/v0DWeOjkU0L6qMnQq0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=dQu5jh45nJuilbJZqx3QgyFj4OycMiPAOJMvUtqnWy2SiPx6C7c/Fq5PTT+FlBrQg DCCaMCn3u/hzRt9dDL0UVhjwjxCLyGLbjuftT8bfrFiUQcf5ajm0+rT+AmAtUH75ZA xJCUbjL4Q8sL4TKD1FbYV/Pebq/V8jCmoWY81lsijmgBnXaQqv09/mV1vNiGkQTJJp vpJBsdU9siuHVS1a4LgxMd2s6ap46UjI5ywYMu6Dg7CgojTutUcq97FPM7kCFrCAql N95fOWbE5uHrASnK5M7H8Weq2L4ggk7ncfSxf2a9FzdejD9j6PLgwrKCdNFYAsH1N2 5BBYRt3TXsurA== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=aN2EQwbrEeMS1mtm6tgA:9 a=0HxuzKx6jGqXImNv:21 a=1lWlG15CL-aWOs4E:21 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 1/9] btrfs: Add support for reading a filesystem with a RAID 5 or RAID 6 profile. Date: Wed, 19 Sep 2018 20:40:32 +0200 Message-Id: <20180919184040.22540-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDPsmObly8e/k5E4XFRJXOI/IWpTHcTuN4PjnH30VL0BdRINHzP/xGM0hUKtYfZBlhbjzxPjkE67N/jK8qyb+JSBdqaurnf+n2/6GHiBl/7CFdEyt5fV ri0xX8kfGbURdtJIJyl1wgg5b79eB2nJe081yJPeLyXHTXWthywHYWaCUz46ow6LGTdBqooL/yu+DVMB9xBtM/nGEHEsLnXoHc7LAk+OI7pdebenL8xMWdnr zqYdyYzFVOAuub0qdj6027V0y4PMEWaWUINjH8XXK60= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli Signed-off-by: Goffredo Baroncelli --- grub-core/fs/btrfs.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index be195448d..56c42746d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -119,6 +119,8 @@ struct grub_btrfs_chunk_item #define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 #define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 +#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 +#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; grub_uint16_t nsubstripes; @@ -764,6 +766,70 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, stripe_offset = low + chunk_stripe_length * high; csize = chunk_stripe_length - low; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID5: + case GRUB_BTRFS_CHUNK_TYPE_RAID6: + { + grub_uint64_t nparities, block_nr, high, low; + + redundancy = 1; /* no redundancy for now */ + + if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) + { + grub_dprintf ("btrfs", "RAID5\n"); + nparities = 1; + } + else + { + grub_dprintf ("btrfs", "RAID6\n"); + nparities = 2; + } + + /* + * A RAID 6 layout consists of several blocks spread on the disks. + * The raid terminology is used to call all the blocks of a row + * "stripe". Unfortunately the BTRFS terminology confuses block + * and stripe. + * + * Disk0 Disk1 Disk2 Disk3 + * + * A1 B1 P1 Q1 + * Q2 A2 B2 P2 + * P3 Q3 A3 B3 + * [...] + * + * Note that the placement of the parities depends on row index. + * In the code below: + * - block_nr is the block number without the parities + * (A1 = 0, B1 = 1, A2 = 2, B2 = 3, ...), + * - high is the row number (0 for A1...Q1, 1 for Q2...P2, ...), + * - stripen is the disk number (0 for A1,Q2,P3, 1 for B1...), + * - off is the logical address to read + * - chunk_stripe_length is the size of a block (typically 64k), + * - nstripes is the number of disks, + * - low is the offset of the data inside a stripe, + * - stripe_offset is the disk offset, + * - csize is the "potential" data to read. It will be reduced to + * size if the latter is smaller. + */ + block_nr = grub_divmod64 (off, chunk_stripe_length, &low); + + /* + * stripen is computed without the parities (0 for A1, A2, A3... + * 1 for B1, B2...). + */ + high = grub_divmod64 (block_nr, nstripes - nparities, &stripen); + + /* + * stripen is recomputed considering the parities (0 for A1, 1 for + * A2, 2 for A3....). + */ + grub_divmod64 (high + stripen, nstripes, &stripen); + + stripe_offset = low + chunk_stripe_length * high; + csize = chunk_stripe_length - low; + break; } default: From patchwork Wed Sep 19 18:40:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606181 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9317217E1 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 82A052C841 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 773BE2C853; Wed, 19 Sep 2018 18:41:15 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 1A29A2C841 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732432AbeITAUZ (ORCPT ); Wed, 19 Sep 2018 20:20:25 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:49412 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727804AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPTgVZp9; Wed, 19 Sep 2018 20:41:11 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382471; bh=kMdZT04l9aiWKWnBTwL1OHC738fR1K7NoppWuTo4EZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WpCX/hzTqiSbMYLijFkhZB0Q+wTMZFfxV50uNLnNu7MsBykzckCOtqmp2NSD9hagR qZ1xY+7WtEn2+m0aMykTke/cluSpw6w1qLms9UqLEF6IRoqlBc2vEkwKc94tMa52mB DiQMc9V2of5XzLJUEmlTywmsp6ApEKP95y+Vuko7nbmDwZrDz14WSIBz8nsF1KnfHr m9s789SXQwMNJi6mCwGdGvWZJpdPfL5700AhZ9tCtrBY5xtG32EsgMSqPSU8fSsWgE qgemgmRD5rCASGxyXrcFMf1+KUiKle2G+vVwRwQcPwxuzdqKxu5SVX+Y1XGXAa+XVB W6sL/dDhv/aCw== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=yPCof4ZbAAAA:8 a=GjNF4_zslFSpHsoFBLgA:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 2/9] btrfs: Add helper to check the btrfs header. Date: Wed, 19 Sep 2018 20:40:33 +0200 Message-Id: <20180919184040.22540-3-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDPsmObly8e/k5E4XFRJXOI/IWpTHcTuN4PjnH30VL0BdRINHzP/xGM0hUKtYfZBlhbjzxPjkE67N/jK8qyb+JSBdqaurnf+n2/6GHiBl/7CFdEyt5fV ri0xX8kfGbURdtJIJyl1wgg5b79eB2nJe081yJPeLyXHTXWthywHYWaCUz46ow6LGTdBqooL/yu+DVMB9xBtM/nGEHEsLnXoHc7LAk+OI7pdebenL8xMWdnr zqYdyYzFVOAuub0qdj6027V0y4PMEWaWUINjH8XXK60= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli This helper is used in a few places to help the debugging. As conservative approach the error is only logged. This does not impact the error handling. Signed-off-by: Goffredo Baroncelli Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 56c42746d..4f404f4b2 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -77,7 +77,8 @@ struct btrfs_header { grub_btrfs_checksum_t checksum; grub_btrfs_uuid_t uuid; - grub_uint8_t dummy[0x30]; + grub_uint64_t bytenr; + grub_uint8_t dummy[0x28]; grub_uint32_t nitems; grub_uint8_t level; } GRUB_PACKED; @@ -286,6 +287,25 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc) grub_free (desc->data); } +static grub_err_t +check_btrfs_header (struct grub_btrfs_data *data, struct btrfs_header *header, + grub_disk_addr_t addr) +{ + if (grub_le_to_cpu64 (header->bytenr) != addr) + { + grub_dprintf ("btrfs", "btrfs_header.bytenr is not equal node addr\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header bytenr is not equal node addr"); + } + if (grub_memcmp (data->sblock.uuid, header->uuid, sizeof(grub_btrfs_uuid_t))) + { + grub_dprintf ("btrfs", "btrfs_header.uuid doesn't match sblock uuid\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header uuid doesn't match sblock uuid"); + } + return GRUB_ERR_NONE; +} + static grub_err_t save_ref (struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t addr, unsigned i, unsigned m, int l) @@ -341,6 +361,7 @@ next (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head, sizeof (head), 0); + check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr)); if (err) return -err; @@ -402,6 +423,7 @@ lower_bound (struct grub_btrfs_data *data, /* FIXME: preread few nodes into buffer. */ err = grub_btrfs_read_logical (data, addr, &head, sizeof (head), recursion_depth + 1); + check_btrfs_header (data, &head, addr); if (err) return err; addr += sizeof (head); From patchwork Wed Sep 19 18:40:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606179 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4567814DA for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 369B92C84D for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 29E0C2C854; Wed, 19 Sep 2018 18:41:15 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 C36452C853 for ; Wed, 19 Sep 2018 18:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732372AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:39442 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731938AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPTgVZpK; Wed, 19 Sep 2018 20:41:11 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382471; bh=rgSec24NkXvUkvf48s337E2vvOpCLcpTqsUUt0ir69Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mT4ppFVg5KFFXA2yFIKX7Xy024T0ThAd4thO7oLj9Qc7+eL+ytT5Ddys5R5klPLjB CL9jWrCbBA7yWPazJq167XixJHM6ikrpS6NUKNWJ2E0aXTXmrNDENYivIUrqhviqFG I6zSwW55ZAJ1nMr+F9UQtG8S+VZWPHTy2qcs8OiwJWxP7NLm9DAcEGHRbRMz/o5jw1 m9aXHXU5/va6+fcBcREccduYcrZEU9lnNvSxy2Ntthgmsc08NyKjXRMgSAZp6vO0d7 pN8LZPsbOD/dJMd99Pm3QiGuKwreXrJaSx2SGVCVoTz2mHmBuc9DHmTili91siTJUW tWbyL517rrq+g== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=yPCof4ZbAAAA:8 a=fGidO4j3AiKtNeS3nH0A:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 3/9] btrfs: Move the error logging from find_device() to its caller. Date: Wed, 19 Sep 2018 20:40:34 +0200 Message-Id: <20180919184040.22540-4-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDPsmObly8e/k5E4XFRJXOI/IWpTHcTuN4PjnH30VL0BdRINHzP/xGM0hUKtYfZBlhbjzxPjkE67N/jK8qyb+JSBdqaurnf+n2/6GHiBl/7CFdEyt5fV ri0xX8kfGbURdtJIJyl1wgg5b79eB2nJe081yJPeLyXHTXWthywHYWaCUz46ow6LGTdBqooL/yu+DVMB9xBtM/nGEHEsLnXoHc7LAk+OI7pdebenL8xMWdnr zqYdyYzFVOAuub0qdj6027V0y4PMEWaWUINjH8XXK60= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli The caller knows better if this error is fatal or not, i.e. another disk is available or not. This is a preparatory patch. Signed-off-by: Goffredo Baroncelli Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 4f404f4b2..0cdfaf7c0 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -604,9 +604,6 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) grub_device_iterate (find_device_iter, &ctx); if (!ctx.dev_found) { - grub_error (GRUB_ERR_BAD_FS, - N_("couldn't find a necessary member device " - "of multi-device filesystem")); return NULL; } data->n_devices_attached++; @@ -898,6 +895,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, dev = find_device (data, stripe->device_id, j); if (!dev) { + grub_dprintf ("btrfs", + "couldn't find a necessary member device " + "of multi-device filesystem\n"); err = grub_errno; grub_errno = GRUB_ERR_NONE; continue; From patchwork Wed Sep 19 18:40:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606185 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 740D017E1 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 664A32C841 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5ADD72C84E; Wed, 19 Sep 2018 18:41:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 F168E2C841 for ; Wed, 19 Sep 2018 18:41:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732457AbeITAU0 (ORCPT ); Wed, 19 Sep 2018 20:20:26 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:53628 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732232AbeITAUZ (ORCPT ); Wed, 19 Sep 2018 20:20:25 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPTgVZpT; Wed, 19 Sep 2018 20:41:12 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382472; bh=a1XyaAyvB2vvcQq0SOAv9moH0WVU9nxDSGNoFRgXreQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=rvlJzypMS3HhwuSE9lgmwyaffrbqt3c0Pord02pDhGoyNVwe3x5DA+q7xvsDOTA3c eEN3o/sFm7QEc8b/BXjsflyR8vtC9/OIRlVWTY7E2b4Maqrkjjch31Wv6bxpD4lQl4 dXmAJdIWPVi29T3HY6hWHp88aiQyixlsJX5kVeB4Yr5Ih2KwyWJ0HkrCvfhwExk+vE c85t/fvGVv6h5K42sGoHtYMPnXQIJRLRxSdtKCBFE/4EAF2mxrVXQ8BO1d5qbEetha 9pP9+IJtUno9IImvWHin5KAR9MOs0UTC+17T8YXQBo6pGj6OTlvwnWX8dziK1+sMMT 0mEnPnNQW23fA== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=tK7bS5S69CJdjAdesZkA:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 4/9] btrfs: Avoid a rescan for a device which was already not found. Date: Wed, 19 Sep 2018 20:40:35 +0200 Message-Id: <20180919184040.22540-5-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfFZcIo3ET48ebVvPHE+jIj4TnauOPMDwNPmhC0hgzHV0L8oQfX2vSujgxUKOhSgDKu977wcy8pWjjEJqI+HHVQNnJP5/JfV9rM9Spz1ha7dUX3420m9N QARbjG/JM6Om9TWPegXvwKQx6xGcWxVvnzUAM4baPumgbnSJZpFaCNIYl6GEYiIOkQPnF+ZZHvlckHqITNw6J1XFRRFkYT/c2swK0hpXxM7RXUh1MkVN6oPG qh+NUC3Hw31yFxhxa5be9wyeW4kpskpHU4oAjo+7X2Q= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli If a device is not found, do not return immediately but record this failure by storing NULL in data->devices_attached[]. This way we avoid unnecessary devices rescan, and speedup the reads in case of a degraded array. Signed-off-by: Goffredo Baroncelli --- grub-core/fs/btrfs.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 0cdfaf7c0..6e42c33f6 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -588,7 +588,7 @@ find_device_iter (const char *name, void *data) } static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) +find_device (struct grub_btrfs_data *data, grub_uint64_t id) { struct find_device_ctx ctx = { .data = data, @@ -600,12 +600,9 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) for (i = 0; i < data->n_devices_attached; i++) if (id == data->devices_attached[i].id) return data->devices_attached[i].dev; - if (do_rescan) - grub_device_iterate (find_device_iter, &ctx); - if (!ctx.dev_found) - { - return NULL; - } + + grub_device_iterate (find_device_iter, &ctx); + data->n_devices_attached++; if (data->n_devices_attached > data->n_devices_allocated) { @@ -617,7 +614,8 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) * sizeof (data->devices_attached[0])); if (!data->devices_attached) { - grub_device_close (ctx.dev_found); + if (ctx.dev_found) + grub_device_close (ctx.dev_found); data->devices_attached = tmp; return NULL; } @@ -892,7 +890,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, addr); - dev = find_device (data, stripe->device_id, j); + dev = find_device (data, stripe->device_id); if (!dev) { grub_dprintf ("btrfs", @@ -969,7 +967,8 @@ grub_btrfs_unmount (struct grub_btrfs_data *data) unsigned i; /* The device 0 is closed one layer upper. */ for (i = 1; i < data->n_devices_attached; i++) - grub_device_close (data->devices_attached[i].dev); + if (data->devices_attached[i].dev) + grub_device_close (data->devices_attached[i].dev); grub_free (data->devices_attached); grub_free (data->extent); grub_free (data); From patchwork Wed Sep 19 18:40:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606193 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C816A1390 for ; Wed, 19 Sep 2018 18:41:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB7C92C841 for ; Wed, 19 Sep 2018 18:41:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AFEC02C84D; Wed, 19 Sep 2018 18:41:19 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 5A49D2C841 for ; Wed, 19 Sep 2018 18:41:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732370AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:53100 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732270AbeITAUY (ORCPT ); Wed, 19 Sep 2018 20:20:24 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPUgVZpc; Wed, 19 Sep 2018 20:41:12 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382472; bh=RlOCe2YXy9vYtmsgCwEQ37o/Ou37adAeRmroKjY8Vu0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=g1mR5nU5D69Vr65SjY0C8SdgbImxOyWj4M/TDKEO8sDabO5UXnHLbqY4Q77meGUxy GFR16Gvk1cKQoaYqwchWmNYe4USS5zJw5QZt3HsjZQ2t7jdur7rO1hCtDSLGqOx4pv yHDDukCtd0qeULLnV504eGLMZ7HZZq3aH7ysxq0nhHVTydpGpJk+ggioLWyGyBBVLF XcYzCnmbeoRUpGK2AJ/5QkaZUy/RdxFDD8M+UWd5fPfHalUsz30W0XbjOcvxfdgRm8 Cb1sdfNxxhanBjV6u1EWQESk1N/JsqLWSxKaPKrOGAwH2HENEjKys0sjVPRfkZPP49 x9OxFjWmMjhRA== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=yPCof4ZbAAAA:8 a=tbGcK1RVRLHxssNcnxoA:9 a=R0ZrlE3BOGKx5Mtq:21 a=LACR2KO_iN7HUbMU:21 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 5/9] btrfs: Move logging code in grub_btrfs_read_logical() Date: Wed, 19 Sep 2018 20:40:36 +0200 Message-Id: <20180919184040.22540-6-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfFZcIo3ET48ebVvPHE+jIj4TnauOPMDwNPmhC0hgzHV0L8oQfX2vSujgxUKOhSgDKu977wcy8pWjjEJqI+HHVQNnJP5/JfV9rM9Spz1ha7dUX3420m9N QARbjG/JM6Om9TWPegXvwKQx6xGcWxVvnzUAM4baPumgbnSJZpFaCNIYl6GEYiIOkQPnF+ZZHvlckHqITNw6J1XFRRFkYT/c2swK0hpXxM7RXUh1MkVN6oPG qh+NUC3Hw31yFxhxa5be9wyeW4kpskpHU4oAjo+7X2Q= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli A portion of the logging code is moved outside of internal for(;;). The part that is left inside is the one which depends on the internal for(;;) index. This is a preparatory patch. The next one will refactor the code inside the for(;;) into an another function. Signed-off-by: Goffredo Baroncelli Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 6e42c33f6..ee134c167 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -863,6 +863,18 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, for (j = 0; j < 2; j++) { + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length)); + grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", + addr); + for (i = 0; i < redundancy; i++) { struct grub_btrfs_chunk_stripe *stripe; @@ -875,20 +887,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T - " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T + grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T " maps to 0x%" PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - grub_le_to_cpu16 (chunk->nsubstripes), - grub_le_to_cpu64 (chunk->stripe_length), stripen, stripe->offset); grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, - addr); + "\n", paddr); dev = find_device (data, stripe->device_id); if (!dev) From patchwork Wed Sep 19 18:40:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606187 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C849D15E8 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BBEA22C843 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B08F22C84E; Wed, 19 Sep 2018 18:41:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 47C362C843 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732598AbeITAU0 (ORCPT ); Wed, 19 Sep 2018 20:20:26 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:48986 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731253AbeITAUZ (ORCPT ); Wed, 19 Sep 2018 20:20:25 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPUgVZpn; Wed, 19 Sep 2018 20:41:13 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382473; bh=tA33AYTqGo5p8fxFJ/NC6xPOfbwZY4+CxSZEF8PXm0c=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=MPgx4ZNpDf0IoI/P8UzGhE/6j4VSQEbGXrsNauIaI35/zTop4C2IIbyWRI8SQEUjl /303/kxDxy+N686FrR30NVANLLa9Ai4Hf3gV4U30XCW6LPr5T0kypl8XALyRUnd9ul Qpb+Cidc1Jh0KRzyYgr1rpTA33tGr1+CrBK4/UCqS/bljhyoEzzjquBR3hEW6mV9IR lBpbtXPGvn0i58yfTUlTxHhKPbSMRzSpIxEGQBLIXKkL76JMscNHP8TC9/GK2LE2zW O4JpcHtv157+yqUCb0BYKoqWxd6HSFuHFyZGFPAq5SO2HYRIeQ7qBVUaCinKQykOEa MceEm1XMMHvTA== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=yPCof4ZbAAAA:8 a=54DIDk4bsIWUoIzoLckA:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 6/9] btrfs: Refactor the code that read from disk Date: Wed, 19 Sep 2018 20:40:37 +0200 Message-Id: <20180919184040.22540-7-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfD1r7PB3IyF2r47SZyvIrZsLMHRqS631eVTASPYYvck/NmLokR8cagwbnu83e2gtCpTZp3pXK/wZxzQj7FiPhsfl5optYJ1oJEXq0ysRtaBi6EHyB6Je L7GrbhD01omvUTUQdUm8XYTfweWr0s6BS5iwMEXtg6CZ5KyohW2CxON9kObOyP4DjwuX4kOsFaYTGqRdpyuTPXLvh2R0mKCYN7QlvwSLeg/LWSqhLav2NUub x+1PJ3Wh+S5wKKVaoVDBS/5LnjvvJXxJEDjWPHAg8Og= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli Move the code in charge to read the data from disk into a separate function. This helps to separate the error handling logic (which depends on the different raid profiles) from the read from disk logic. Refactoring this code increases the general readability too. This is a preparatory patch, to help the adding of the RAID 5/6 recovery code. Signed-off-by: Goffredo Baroncelli Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 75 ++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ee134c167..5c1ebae77 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -625,6 +625,46 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) return ctx.dev_found; } +static grub_err_t +btrfs_read_from_chunk (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripen, grub_uint64_t stripe_offset, + int redundancy, grub_uint64_t csize, + void *buf) +{ + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + /* Right now the redundancy handling is easy. + With RAID5-like it will be more difficult. */ + stripe += stripen + redundancy; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + + grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T + " maps to 0x%" PRIxGRUB_UINT64_T + ". Reading paddr 0x%" PRIxGRUB_UINT64_T "\n", + stripen, stripe->offset, paddr); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + grub_dprintf ("btrfs", + "couldn't find a necessary member device " + "of multi-device filesystem\n"); + grub_errno = GRUB_ERR_NONE; + return GRUB_ERR_READ_ERROR; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + return err; +} + static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size, int recursion_depth) @@ -638,7 +678,6 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_err_t err = 0; struct grub_btrfs_key key_out; int challoc = 0; - grub_device_t dev; struct grub_btrfs_key key_in; grub_size_t chsize; grub_disk_addr_t chaddr; @@ -877,36 +916,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, for (i = 0; i < redundancy; i++) { - struct grub_btrfs_chunk_stripe *stripe; - grub_disk_addr_t paddr; - - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); - /* Right now the redundancy handling is easy. - With RAID5-like it will be more difficult. */ - stripe += stripen + i; - - paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; - - grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T - " maps to 0x%" PRIxGRUB_UINT64_T "\n", - stripen, stripe->offset); - grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - "\n", paddr); - - dev = find_device (data, stripe->device_id); - if (!dev) - { - grub_dprintf ("btrfs", - "couldn't find a necessary member device " - "of multi-device filesystem\n"); - err = grub_errno; - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), - csize, buf); + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + i, /* redundancy */ + csize, buf); if (!err) break; grub_errno = GRUB_ERR_NONE; From patchwork Wed Sep 19 18:40:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606195 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 20D651390 for ; Wed, 19 Sep 2018 18:42:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1156B2C841 for ; Wed, 19 Sep 2018 18:42:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 03A7F2C84D; Wed, 19 Sep 2018 18:42:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 793532C841 for ; Wed, 19 Sep 2018 18:42:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732207AbeITAVZ (ORCPT ); Wed, 19 Sep 2018 20:21:25 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:39442 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732127AbeITAVZ (ORCPT ); Wed, 19 Sep 2018 20:21:25 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPVgVZpz; Wed, 19 Sep 2018 20:41:13 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382473; bh=K9Zlje0U48yE2hxfLhKM+2DePCDlTbe3rdT3K8Wrx8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=lTLC5PpOeZTJ417oaynpGqWis6J1bNVChJZC6rt/tHIY/yRnjfo1IAz3Ht8765+FF jaE0szQa3hdZWJzZh76+yYKDoVSLfTxcCP1aI87ieumIXsLwVdLZGQbt0OdFg/2+ZC 9fNCdYqS0I0JArD9JCluFaB5xAmCHf1bLeXdxMJXZnh92Yd4DNrn16JEh1F/2kNw/e EHglcsRZQfew1ed/fLgfrDGEi+6ZMc++KhR24Gp9Ehgwr9Hznxo3JjbIaiNfozzh2i bRcq2DLnXOjjqk4U550jzRU4idvHF1V/ggR4AdtjPsQ/3b6m4heekTpwoSoXR38ykT scj2LquNoReRg== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=IV0I3_9ijV7uQZO1mCMA:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 7/9] btrfs: Add support for recovery for a RAID 5 btrfs profiles. Date: Wed, 19 Sep 2018 20:40:38 +0200 Message-Id: <20180919184040.22540-8-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfD1r7PB3IyF2r47SZyvIrZsLMHRqS631eVTASPYYvck/NmLokR8cagwbnu83e2gtCpTZp3pXK/wZxzQj7FiPhsfl5optYJ1oJEXq0ysRtaBi6EHyB6Je L7GrbhD01omvUTUQdUm8XYTfweWr0s6BS5iwMEXtg6CZ5KyohW2CxON9kObOyP4DjwuX4kOsFaYTGqRdpyuTPXLvh2R0mKCYN7QlvwSLeg/LWSqhLav2NUub x+1PJ3Wh+S5wKKVaoVDBS/5LnjvvJXxJEDjWPHAg8Og= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli Add support for recovery for a RAID 5 btrfs profile. In addition it is added some code as preparatory work for RAID 6 recovery code. Signed-off-by: Goffredo Baroncelli --- grub-core/fs/btrfs.c | 169 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 164 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 5c1ebae77..55a7eeffc 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -29,6 +29,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -665,6 +666,148 @@ btrfs_read_from_chunk (struct grub_btrfs_data *data, return err; } +struct raid56_buffer { + void *buf; + int data_is_valid; +}; + +static void +rebuild_raid5 (char *dest, struct raid56_buffer *buffers, + grub_uint64_t nstripes, grub_uint64_t csize) +{ + grub_uint64_t i; + int first; + + i = 0; + while (buffers[i].data_is_valid && i < nstripes) + ++i; + + if (i == nstripes) + { + grub_dprintf ("btrfs", "called rebuild_raid5(), but all disks are OK\n"); + return; + } + + grub_dprintf ("btrfs", "rebuilding RAID 5 stripe #%" PRIuGRUB_UINT64_T "\n", + i); + + for (i = 0, first = 1; i < nstripes; i++) + { + if (!buffers[i].data_is_valid) + continue; + + if (first) { + grub_memcpy(dest, buffers[i].buf, csize); + first = 0; + } else + grub_crypto_xor (dest, dest, buffers[i].buf, csize); + + } +} + +static grub_err_t +raid56_read_retry (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripe_offset, + grub_uint64_t csize, void *buf) +{ + struct raid56_buffer *buffers; + grub_uint64_t nstripes = grub_le_to_cpu16 (chunk->nstripes); + grub_uint64_t chunk_type = grub_le_to_cpu64 (chunk->type); + grub_err_t ret = GRUB_ERR_NONE; + grub_uint64_t i, failed_devices; + + buffers = grub_zalloc (sizeof(*buffers) * nstripes); + if (!buffers) + { + ret = GRUB_ERR_OUT_OF_MEMORY; + goto cleanup; + } + + for (i = 0; i < nstripes; i++) + { + buffers[i].buf = grub_zalloc (csize); + if (!buffers[i].buf) + { + ret = GRUB_ERR_OUT_OF_MEMORY; + goto cleanup; + } + } + + for (failed_devices = 0, i = 0; i < nstripes; i++) + { + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err2; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + stripe += i; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + grub_dprintf ("btrfs", "reading paddr %" PRIxGRUB_UINT64_T + " from stripe ID %" PRIxGRUB_UINT64_T "\n", paddr, + stripe->device_id); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + buffers[i].data_is_valid = 0; + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " FAILED (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + failed_devices++; + continue; + } + + err2 = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buffers[i].buf); + if (err2 == GRUB_ERR_NONE) + { + buffers[i].data_is_valid = 1; + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " Ok (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + } + else + { + buffers[i].data_is_valid = 0; + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T + " FAILED (dev ID %" PRIxGRUB_UINT64_T ")\n", i, + stripe->device_id); + failed_devices++; + } + } + + if (failed_devices > 1 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5)) + { + grub_dprintf ("btrfs", + "not enough disks for RAID 5: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } + else + grub_dprintf ("btrfs", + "enough disks for RAID 5 rebuilding: total %" + PRIuGRUB_UINT64_T ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + + /* if these are enough, try to rebuild the data */ + if (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5) + rebuild_raid5 (buf, buffers, nstripes, csize); + else + grub_dprintf ("btrfs", "called rebuild_raid6(), NOT IMPLEMENTED\n"); + + cleanup: + if (buffers) + for (i = 0; i < nstripes; i++) + grub_free(buffers[i].buf); + grub_free(buffers); + + return ret; +} + static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size, int recursion_depth) @@ -742,6 +885,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_uint16_t nstripes; unsigned redundancy = 1; unsigned i, j; + int is_raid56; + + is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & + GRUB_BTRFS_CHUNK_TYPE_RAID5); if (grub_le_to_cpu64 (chunk->size) <= off) { @@ -914,17 +1061,29 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", addr); - for (i = 0; i < redundancy; i++) + if (!is_raid56) + for (i = 0; i < redundancy; i++) + { + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + i, /* redundancy */ + csize, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + else { err = btrfs_read_from_chunk (data, chunk, stripen, stripe_offset, - i, /* redundancy */ + 0, /* no mirror */ csize, buf); - if (!err) - break; grub_errno = GRUB_ERR_NONE; + if (err != GRUB_ERR_NONE) + err = raid56_read_retry (data, chunk, stripe_offset, + csize, buf); } - if (i != redundancy) + if (err == GRUB_ERR_NONE) break; } if (err) From patchwork Wed Sep 19 18:40:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606191 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0D9511390 for ; Wed, 19 Sep 2018 18:41:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0001B2C841 for ; Wed, 19 Sep 2018 18:41:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8C392C84E; Wed, 19 Sep 2018 18:41:17 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 6D9302C841 for ; Wed, 19 Sep 2018 18:41:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732633AbeITAU0 (ORCPT ); Wed, 19 Sep 2018 20:20:26 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:60002 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731938AbeITAU0 (ORCPT ); Wed, 19 Sep 2018 20:20:26 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPVgVZqE; Wed, 19 Sep 2018 20:41:14 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382474; bh=BYiWpzcXDH7R4zhuV9SPGwAZEi8ZW+8Agt4evHOZJug=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TS+dQ8mrgWa2SVOpgyEssRWWeS9bcrCKK/sI6r93xwJ94KkehYXQXhmC0YEMOx+sZ iz26Znji7osLywj24sQ/p3niXVGXGfc8rgtVzKmY5fyIIL2UnU2YhRUxHMwBhAF5Nj gOyT9VRh77s5VcYk9LyNFCq2p+TCrOhlXj+r56O+iakYa9Pb88cxfy2ftp09wL2JAd C+gTXne9PJFBKUo+OJmYJinMsWuhkPbBvybFYtkMlSmvGlxOB+OsKCQIJbagmt6K1y pSEHepW9Zom/OQa2x6+Mu96f7ct4m79kOJnU2Dy5Rq1Njov+/bUZMWH/wKoyZW15Sr a0yfsaME87+yQ== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=yPCof4ZbAAAA:8 a=veM9U-ac7Y8X2fC78R8A:9 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 8/9] btrfs: Make more generic the code for RAID 6 rebuilding Date: Wed, 19 Sep 2018 20:40:39 +0200 Message-Id: <20180919184040.22540-9-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKIWN+Ye2AtuDjSDj7PDYVkEuiBEFhTG1QxKMyHaBkF8pZBapwOcYm2Fl14NMynsPuIy9ai98M3NllDndLVhgzZcRGhfsXqGMoYSNUtYXkgAMofb0/FI 2NhR+YfISD81Sa0zmfuH9DPVib3m9NwwcGkQLfgzLXAr3HuRqv5fcwpp0CLixLqNzSeYsIkVNSu+Vw7Kzxc5D56ulq1I2FzmXS5tS7OZk/aa7w3lU/P20wFc SxoYL3518L672sWUHGlBhlJTdA9aERhro0ll9hU51NQ= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli The original code which handles the recovery of a RAID 6 disks array assumes that all reads are multiple of 1 << GRUB_DISK_SECTOR_BITS and it assumes that all the I/O is done via the struct grub_diskfilter_segment. This is not true for the btrfs code. In order to reuse the native grub_raid6_recover() code, it is modified to not call grub_diskfilter_read_node() directly, but to call an handler passed as an argument. Signed-off-by: Goffredo Baroncelli Reviewed-by: Daniel Kiper --- grub-core/disk/raid6_recover.c | 52 ++++++++++++++++++++++------------ include/grub/diskfilter.h | 9 ++++++ 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index aa674f6ca..0cf691ddf 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -74,14 +74,26 @@ mod_255 (unsigned x) } static grub_err_t -grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, - char *buf, grub_disk_addr_t sector, grub_size_t size) +raid6_recover_read_node (void *data, int disknr, + grub_uint64_t sector, + void *buf, grub_size_t size) +{ + struct grub_diskfilter_segment *array = data; + + return grub_diskfilter_read_node (&array->nodes[disknr], + (grub_disk_addr_t)sector, + size >> GRUB_DISK_SECTOR_BITS, buf); +} + +grub_err_t +grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, + char *buf, grub_uint64_t sector, grub_size_t size, + int layout, raid_recover_read_t read_func) { int i, q, pos; int bad1 = -1, bad2 = -1; char *pbuf = 0, *qbuf = 0; - size <<= GRUB_DISK_SECTOR_BITS; pbuf = grub_zalloc (size); if (!pbuf) goto quit; @@ -91,17 +103,17 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, goto quit; q = p + 1; - if (q == (int) array->node_count) + if (q == (int) nstripes) q = 0; pos = q + 1; - if (pos == (int) array->node_count) + if (pos == (int) nstripes) pos = 0; - for (i = 0; i < (int) array->node_count - 2; i++) + for (i = 0; i < (int) nstripes - 2; i++) { int c; - if (array->layout & GRUB_RAID_LAYOUT_MUL_FROM_POS) + if (layout & GRUB_RAID_LAYOUT_MUL_FROM_POS) c = pos; else c = i; @@ -109,8 +121,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, bad1 = c; else { - if (! grub_diskfilter_read_node (&array->nodes[pos], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (!read_func(data, pos, sector, buf, size)) { grub_crypto_xor (pbuf, pbuf, buf, size); grub_raid_block_mulx (c, buf, size); @@ -128,7 +139,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, } pos++; - if (pos == (int) array->node_count) + if (pos == (int) nstripes) pos = 0; } @@ -139,16 +150,14 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, if (bad2 < 0) { /* One bad device */ - if ((! grub_diskfilter_read_node (&array->nodes[p], sector, - size >> GRUB_DISK_SECTOR_BITS, buf))) + if (!read_func(data, p, sector, buf, size)) { grub_crypto_xor (buf, buf, pbuf, size); goto quit; } grub_errno = GRUB_ERR_NONE; - if (grub_diskfilter_read_node (&array->nodes[q], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func(data, q, sector, buf, size)) goto quit; grub_crypto_xor (buf, buf, qbuf, size); @@ -160,14 +169,12 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, /* Two bad devices */ unsigned c; - if (grub_diskfilter_read_node (&array->nodes[p], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func(data, p, sector, buf, size)) goto quit; grub_crypto_xor (pbuf, pbuf, buf, size); - if (grub_diskfilter_read_node (&array->nodes[q], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func(data, q, sector, buf, size)) goto quit; grub_crypto_xor (qbuf, qbuf, buf, size); @@ -190,6 +197,15 @@ quit: return grub_errno; } +static grub_err_t +grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, + char *buf, grub_disk_addr_t sector, grub_size_t size) +{ + return grub_raid6_recover_gen (array, array->node_count, disknr, p, buf, + sector, size << GRUB_DISK_SECTOR_BITS, + array->layout, raid6_recover_read_node); +} + GRUB_MOD_INIT(raid6rec) { grub_raid6_init_table (); diff --git a/include/grub/diskfilter.h b/include/grub/diskfilter.h index d89273c1b..8deb1a8c3 100644 --- a/include/grub/diskfilter.h +++ b/include/grub/diskfilter.h @@ -189,6 +189,15 @@ typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_diskfilter_segment extern grub_raid5_recover_func_t grub_raid5_recover_func; extern grub_raid6_recover_func_t grub_raid6_recover_func; +typedef grub_err_t (* raid_recover_read_t)(void *data, int disk_nr, + grub_uint64_t addr, void *dest, + grub_size_t size); + +extern grub_err_t +grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, + char *buf, grub_uint64_t sector, grub_size_t size, + int layout, raid_recover_read_t read_func); + grub_err_t grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg); grub_err_t From patchwork Wed Sep 19 18:40:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10606189 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1653114DA for ; Wed, 19 Sep 2018 18:41:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09C392C841 for ; Wed, 19 Sep 2018 18:41:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F285C2C84D; Wed, 19 Sep 2018 18:41:16 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 885AE2C841 for ; Wed, 19 Sep 2018 18:41:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732700AbeITAU1 (ORCPT ); Wed, 19 Sep 2018 20:20:27 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:53100 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732383AbeITAU0 (ORCPT ); Wed, 19 Sep 2018 20:20:26 -0400 Received: from venice.bhome ([94.38.18.13]) by smtp-33.iol.local with ESMTPA id 2hPRgg79sQGOz2hPWgVZqP; Wed, 19 Sep 2018 20:41:14 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1537382474; bh=/1XqRaTXCsHo+rA38/dZIymau4dnSDa5EtPtfsQX4/k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=PibHO2BWl0XWpPs+fmj3RQh1eYEF5osvy7GJiK/LjI0bfumdAph6zLCdGmZ4SfMZy iGbmbupVd7chNj5XY8WqPzMHSO6/r/kdLZ/yjSh6zPwbnsosZR+vT8a6cQPXGQ46mf 6QDA5WBu805q2SJ7wPPaPNe2J7T585Ndzeuqyul730Zyv9I2CCR1e6Ef09Q3i2sqr2 GLnwmT/iGnKsKJvTroP7s2DQU9AcJ1sUV3Pk8w+64fzIZ+FUWki4J+9DJBx3ffu2PC 7ZesLa3zHrAX7ZcvZvKI2D6y8pg0wfPXsmDuax56LJTUmxw7hIpvbAGlNgkEjuh6Yt XN5Yset+mSMNA== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=y+pHRDKYf/eurU+tzaSv/w==:117 a=y+pHRDKYf/eurU+tzaSv/w==:17 a=BCKAIGb-U2-J7aaID9cA:9 a=XcH6xWQlFlHiQAyA:21 a=zgsFb7WtHGuUQyt4:21 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 9/9] btrfs: Add RAID 6 recovery for a btrfs filesystem. Date: Wed, 19 Sep 2018 20:40:40 +0200 Message-Id: <20180919184040.22540-10-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180919184040.22540-1-kreijack@libero.it> References: <20180919184040.22540-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKIWN+Ye2AtuDjSDj7PDYVkEuiBEFhTG1QxKMyHaBkF8pZBapwOcYm2Fl14NMynsPuIy9ai98M3NllDndLVhgzZcRGhfsXqGMoYSNUtYXkgAMofb0/FI 2NhR+YfISD81Sa0zmfuH9DPVib3m9NwwcGkQLfgzLXAr3HuRqv5fcwpp0CLixLqNzSeYsIkVNSu+Vw7Kzxc5D56ulq1I2FzmXS5tS7OZk/aa7w3lU/P20wFc SxoYL3518L672sWUHGlBhlJTdA9aERhro0ll9hU51NQ= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli Add the RAID 6 recovery, in order to use a RAID 6 filesystem even if some disks (up to two) are missing. This code use the md RAID 6 code already present in grub. Signed-off-by: Goffredo Baroncelli --- grub-core/fs/btrfs.c | 54 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 55a7eeffc..400cd56b6 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -705,11 +706,36 @@ rebuild_raid5 (char *dest, struct raid56_buffer *buffers, } } +static grub_err_t +raid6_recover_read_buffer (void *data, int disk_nr, + grub_uint64_t addr __attribute__ ((unused)), + void *dest, grub_size_t size) +{ + struct raid56_buffer *buffers = data; + + if (!buffers[disk_nr].data_is_valid) + return grub_errno = GRUB_ERR_READ_ERROR; + + grub_memcpy(dest, buffers[disk_nr].buf, size); + + return grub_errno = GRUB_ERR_NONE; +} + +static void +rebuild_raid6 (struct raid56_buffer *buffers, grub_uint64_t nstripes, + grub_uint64_t csize, grub_uint64_t parities_pos, void *dest, + grub_uint64_t stripen) + +{ + grub_raid6_recover_gen (buffers, nstripes, stripen, parities_pos, + dest, 0, csize, 0, raid6_recover_read_buffer); +} + static grub_err_t raid56_read_retry (struct grub_btrfs_data *data, struct grub_btrfs_chunk_item *chunk, - grub_uint64_t stripe_offset, - grub_uint64_t csize, void *buf) + grub_uint64_t stripe_offset, grub_uint64_t stripen, + grub_uint64_t csize, void *buf, grub_uint64_t parities_pos) { struct raid56_buffer *buffers; grub_uint64_t nstripes = grub_le_to_cpu16 (chunk->nstripes); @@ -787,6 +813,15 @@ raid56_read_retry (struct grub_btrfs_data *data, ret = GRUB_ERR_READ_ERROR; goto cleanup; } + else if (failed_devices > 2 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID6)) + { + grub_dprintf ("btrfs", + "not enough disks for raid6: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } else grub_dprintf ("btrfs", "enough disks for RAID 5 rebuilding: total %" @@ -797,7 +832,7 @@ raid56_read_retry (struct grub_btrfs_data *data, if (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5) rebuild_raid5 (buf, buffers, nstripes, csize); else - grub_dprintf ("btrfs", "called rebuild_raid6(), NOT IMPLEMENTED\n"); + rebuild_raid6 (buffers, nstripes, csize, parities_pos, buf, stripen); cleanup: if (buffers) @@ -886,9 +921,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, unsigned redundancy = 1; unsigned i, j; int is_raid56; + grub_uint64_t parities_pos = 0; - is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & - GRUB_BTRFS_CHUNK_TYPE_RAID5); + is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & + (GRUB_BTRFS_CHUNK_TYPE_RAID5 | + GRUB_BTRFS_CHUNK_TYPE_RAID6)); if (grub_le_to_cpu64 (chunk->size) <= off) { @@ -1015,6 +1052,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, * - stripe_offset is the disk offset, * - csize is the "potential" data to read. It will be reduced to * size if the latter is smaller. + * - parities_pos is the position of the parity inside a row ( + * 2 for P1, 3 for P2...) */ block_nr = grub_divmod64 (off, chunk_stripe_length, &low); @@ -1030,6 +1069,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, */ grub_divmod64 (high + stripen, nstripes, &stripen); + grub_divmod64 (high + nstripes - nparities, nstripes, + &parities_pos); + stripe_offset = low + chunk_stripe_length * high; csize = chunk_stripe_length - low; @@ -1081,7 +1123,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_errno = GRUB_ERR_NONE; if (err != GRUB_ERR_NONE) err = raid56_read_retry (data, chunk, stripe_offset, - csize, buf); + stripen, csize, buf, parities_pos); } if (err == GRUB_ERR_NONE) break;