From patchwork Thu Sep 27 18:34:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618441 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 99F1915E8 for ; Thu, 27 Sep 2018 18:35:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 832882BAE1 for ; Thu, 27 Sep 2018 18:35:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7772F2BAE7; Thu, 27 Sep 2018 18:35: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 1674B2BAE1 for ; Thu, 27 Sep 2018 18:35:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728381AbeI1Ayr (ORCPT ); Thu, 27 Sep 2018 20:54:47 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:54811 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1Ayr (ORCPT ); Thu, 27 Sep 2018 20:54:47 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b82gnnll; Thu, 27 Sep 2018 20:35:11 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073311; bh=RayBzk9LTtuweLgKHLNpPxFO2WXNzLkV3EeK30aD8Vw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=tvTDwmDMHK295zMzTOvq3I2f9jCOHjixEoxUumQ7JGFbT1I3+JGJIx7JPN6sBpjMO +SAzs+R+ApuBoql8nhdt3cgnqPv6baViiM1hasA05Iz8uwxHvUr19aXGUMGSHqwFdS y1XT2MRTS1yasN2GL9j16L0TT1A8i9661a1L+QEd6pMvqxG2fNz4MNtZYiPEp8TC0K PNTB+1RykSK9TIzQOQfy4jGXmSBORT8pQKVqWD5Y/4aU/3TR5vAGkhj6piV6xsAaVQ 8AHwaFJJaSKvgruRt7rGNdJ61xEUNpbWwcZM2pDUSp2dyzmuVbltk81IDjNnie/URH tNA3xnhmiyGBg== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==:17 a=OllNMU2MDXtvIN_fP3gA:9 a=_MINcdyXgKc-cRrr:21 a=4LBASU1KxRSeJgBc: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: Thu, 27 Sep 2018 20:34:56 +0200 Message-Id: <20180927183504.18078-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfECYO9/K1qboYXbb8hqMIdnfTMpldB55oi6MUAjXsv4RERKCmxiaLqUAcOfZhnI1+iHitiS+FZPxaCF1eNN6xfdbVWTuFXkiJVho9P/PWBgJE37Tzlxj IhxJWXsFdzkjLXZMNmfA2s8FmzL/RBfA9mBylIciLJQn5pxCXdLelGkQ0h07LzarlZKVYvJ4MMqwcXNO76mz2gPrbrS/iiGzSyWJMhsVNQCfzE6OqHJw007V Kv3OAQbNnUWJ4Xa3Os5mkaPEaOOxDUuGx7R2pbX217k= 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 Signed-off-by: Goffredo Baroncelli Signed-off-by: Daniel Kiper --- grub-core/fs/btrfs.c | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index be195448d..9bc6d399d 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,78 @@ 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, stripe_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 stripes spread on the + * disks, following a layout like the one below + * + * 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. + * Pay attention that the BTRFS terminolgy may be different + * from others RAID implementation (e.g. lvm/dm or md). In BTRFS + * a contiguous block of data of a disk (like A1) is called + * stripe. + * In the code below: + * - stripe_nr is the stripe 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 in a row (0 for A1,Q2,P3, 1 for + * B1...), + * - off is the logical address to read, + * - chunk_stripe_length is the size of a stripe (typically 64k), + * - nstripes is the number of disks of a row + * - low is the offset of the data inside a stripe, + * - stripe_offset is the data offset in an array, + * - csize is the "potential" data to read. It will be reduced to + * size if the latter is smaller. + * - nparities is the number of parities (1 for RAID5, 2 for + * RAID6); used only in RAID5/6 code. + */ + stripe_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 (stripe_nr, nstripes - nparities, &stripen); + + /* + * the stripes are spread across the disks, each row their + * position is shifted by 1 place. So to compute the real disk + * number occuped by a stripe, we need to sum also the + * "row number" in modulo nstripes (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 Thu Sep 27 18:34:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618443 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 C9DFE15E8 for ; Thu, 27 Sep 2018 18:35:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B34832BAE1 for ; Thu, 27 Sep 2018 18:35:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A772F2BAE7; Thu, 27 Sep 2018 18:35: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 4486C2BAE1 for ; Thu, 27 Sep 2018 18:35:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728430AbeI1Ayt (ORCPT ); Thu, 27 Sep 2018 20:54:49 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48601 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1Ays (ORCPT ); Thu, 27 Sep 2018 20:54:48 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b84gnnmX; Thu, 27 Sep 2018 20:35:13 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073314; bh=RUGGHq/cn673sVQLeDDqm72t/W69qY0VR71ESZAFySg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=FA9fJrt9rpyYDhgIRGwnz8/U+qxevKDbAHpFRqKEjZD7wBwJQDqcvrpPMUaoHwhVK ETJhPMI/7bAHttTmBQfBb3UHIq67CHAqiO8yGhzLsqJUCxBtaYzVqZNi4nyyCRulqo V4aeUfRVdILyhFwWlPMZJh0XMySMB+6TtVp6ocZqLF7IoZh8oIrhislUCViF8bxCP7 S7+OsIVE0Hh32jcA0dLlrqqTLQnC6wzMkUkRHaQMi9ca9jMmxf6qQw/rkMjkRcJ5xa GMkzBKQxmje9xcfHWHg7ZFZ1/2YsvmK7jovkQ+nIBcr+RSSHDZgjKBb4dQq+7VqG5v eIZIRCugiyrHA== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==: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: Thu, 27 Sep 2018 20:34:57 +0200 Message-Id: <20180927183504.18078-3-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfOx2v5hhUr1cFG1V6t/Vzq7GetQImNWHBOoJpAzhUiBaEaMBUfRuvpH93C2x6BIM8hQGC2R3s3OkBtR7Ggq51bYsrzh9xMrPvqVp7vB3I4aZYoMRrMmX umgu1r4T3YSHM0I8nJGqlFcgwwGdk0IcwjXNftwLVwjZSz2eRf9xc7TpDNcaQvQrmH9pxkUVh8Zz0a1hBfQhU/sQAMri0NV60GP3rGlQP4rP8k/QGhUS9bV5 tbrHjG54jyfF889KrQ6d96rYAyoRfAU+lZZYWzzB19Y= 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 9bc6d399d..bf0dbce21 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 Thu Sep 27 18:34:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618445 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 2AA9614BD for ; Thu, 27 Sep 2018 18:35:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 13D0A2BAE1 for ; Thu, 27 Sep 2018 18:35:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 07B362BAE7; Thu, 27 Sep 2018 18:35:18 +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 A4EF82BAE1 for ; Thu, 27 Sep 2018 18:35:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728490AbeI1Ayu (ORCPT ); Thu, 27 Sep 2018 20:54:50 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:54811 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1Ayu (ORCPT ); Thu, 27 Sep 2018 20:54:50 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b87gnnn3; Thu, 27 Sep 2018 20:35:15 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073315; bh=FC70Ohc1AbMC5cIr0xbtcjxhs1/XHdul+SAZ6Z/uJjQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fHkOrz4FHldVf+uaomEKJJ2G8E2ilLlmQTX5tCuPEcPZ/yyVVkRpuSDSnSDQcAYrG Sol+elVHHRpMAzNy9Ud6qW2v/4c5dkjbofe7bqXp+H7n4kjyoBnumNlK4Iu+B0jxAR c513xt5hL4itmowRUVOZxfcDEovOiakxxZctjI6wp42h8ftJFRsRd0+nopEmIlbRac xyA6EIKnxCMu5ni8mUexPjxE5Pe9hay7whnn4KTyJigWPvX+W4VlBpWT37LdmHrOMV tT7jU1S29U7D5WOSN8EirIXwup8qVMX2nPNqPl6YPVbaznPn30yTCHnLzrGnUg0ltR oO8m4zAXlilpw== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==: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: Thu, 27 Sep 2018 20:34:58 +0200 Message-Id: <20180927183504.18078-4-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfGy/KcnOcL0sLmqIW14sch+/wM3CAntTFnnS1dn+AFQ+j96w3TLUaeeP1+nAWEfGVEKKoN7oGDO1nPDNWgU6sHjnvuDZ1oK6ocjyKX9WarEFx42Vv/KG qjsnyt6r4kyMCgsmkPmzsur6JW4WRxG4R9TG9jUDLf7XHN7z6y76dFOVX1YrLwNsHxIEiSODLWzcl2TWdRJeignIXQlmo+PVN2oqc31GSiKh70fSUg1589qW RxyMg9OVbHyBUUZPsQ5xSqGEEal9cMNoeGsM7Cui3dk= 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 | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index bf0dbce21..2b1dd7dd4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -603,12 +603,7 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) if (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; - } + return NULL; data->n_devices_attached++; if (data->n_devices_attached > data->n_devices_allocated) { @@ -906,6 +901,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 Thu Sep 27 18:34:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618447 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 E7D1315E8 for ; Thu, 27 Sep 2018 18:35:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D10922BAE1 for ; Thu, 27 Sep 2018 18:35:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C51102BAE7; Thu, 27 Sep 2018 18:35:21 +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 61FB82BAE1 for ; Thu, 27 Sep 2018 18:35:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728501AbeI1Ayy (ORCPT ); Thu, 27 Sep 2018 20:54:54 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48601 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728251AbeI1Ayy (ORCPT ); Thu, 27 Sep 2018 20:54:54 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b88gnnnR; Thu, 27 Sep 2018 20:35:18 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073318; bh=Zd0XB2/3+InuPzTYI3AT+uOEuSwrcE2wtQ1rXUitQdA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=m5PLyeb2wDv3dLSGs4f9dURQ5qZVYHKqKREgKEc3+z/WoydCmQjD21nYhHn2ZT36C oM+LphD+rUOeb+nSjXxOslgwOh/T0tT1TR9xCZftZ7smLNII8dnVUXvuFX9lno+m4z JCAndx6N/dfP8sBOIlxQw1rGRpJqSqnkqmwGrw+1eo/K7hyCENN9JKZqItd+toNmwT h5HDACp5MWawNcVDgNF95NssKQ5lLDNOPNmttNCFfoptDvS9clvXCbbpwXkdHgAtwz xWCrJqx6DM07s3xyU/8wJH17oEr2OkWJBadjlqtMlS480wNxbTeOE2FRwslTgEZ6Uo s/8Uz3CL3Bf6Q== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==:17 a=_nex0ghXHqrwvuxp8qYA: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: Thu, 27 Sep 2018 20:34:59 +0200 Message-Id: <20180927183504.18078-5-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfH+d8sZZBMVu/nghih0NId1a/SGM9cg3t69OOUnG6cv0rFtC3hWd0bqY5PeMnizamS0Fhi7cCC4ldzoKp5ed4KerxuiDWbPya++lQCFu67S7H5Q+Q1oD 8xH0YGcbFp+qoVAPu0w22owirLrgW0rKKT3SJadfzPb9ynVsXfRQ+9sO6d/rA+dcFjwaPM2dzkl9QAOrRmEge2+3/wWpd5C44qFdJ8k8VucW6/MtTFbr9Gff Bc/GhlNCWb5WrAQqe81eNqpAm4Jc4vj9y1Cawk4h9Fo= 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 Change the behavior of find_device(): before the patch, a read of a missed device may trigger a rescan. However, it is never recorded that a device is missed, so each single read of a missed device may triggers a rescan. It is the caller who decides if a rescan is performed in case of a missed device. And it does quite often, without considering if in the past a devices was already found as "missed" This behavior causes a lot of unneeded rescan, causing a huge slowdown in case of a missed device. After the patch, the "missed device" information is stored in the data->devices_attached[] array (as a NULL value in the field dev). A rescan is triggered only if no information at all is found. This means that only the first time a read of a missed device triggers a rescan. The change in the code is done removing "return NULL" when the disk is not found. So it is always executed the code which stores in the data->devices_attached[] array the value returned by grub_device_iterate(): NULL if the device is missed, or a valid data otherwise. Signed-off-by: Goffredo Baroncelli --- grub-core/fs/btrfs.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 2b1dd7dd4..c07d91657 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,10 +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) { @@ -615,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; } @@ -898,7 +898,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", @@ -975,7 +975,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 Thu Sep 27 18:35:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618449 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 6A0EB15E8 for ; Thu, 27 Sep 2018 18:35:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52C402BAE1 for ; Thu, 27 Sep 2018 18:35:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46E882BAE7; Thu, 27 Sep 2018 18:35:23 +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 E22C72BAE1 for ; Thu, 27 Sep 2018 18:35:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728506AbeI1Ay4 (ORCPT ); Thu, 27 Sep 2018 20:54:56 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:54811 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1Ayz (ORCPT ); Thu, 27 Sep 2018 20:54:55 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b8Agnno7; Thu, 27 Sep 2018 20:35:20 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073320; bh=evlQsV+nL94B+anSlorPT7Gx3TrMpGI2ldLReuK5fIg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hUlSEsMj1io54FMNkLxA+0KNYmPd175xrSQbo0f9TiOfe8Jjf9krwLFnU83NHQ0UD sQvts14eG3RJ3Lb2LwNG5FD4+fYrrTGeBaGsD5fj8Mrncc4fBBDiYjYLpEJMX/3TGf rOJ4FOkawZSd88zSe3OuMGvh2f4lQaKRiBeRFDUoa6xrpJ7okKWjsHwZXzK6VJotn7 gBhZjmc6z26amfiFvOO3qcdJWSXAXKOjojMbf5h8ZuU0vg1ZgW40fHpPl865ebnmRp Dh6EH6/wC56zGz8+Iq3cQevuaX/SDzMSubzZ/zXCtkKgTios3cE9sw0LyMm0rAo/Iv N3+uL9E7XMbuw== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==: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: Thu, 27 Sep 2018 20:35:00 +0200 Message-Id: <20180927183504.18078-6-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfLnViWsf5K0e1cjr5mtsJFOenyINwWpVSVPx9Vk1vsxYRunXhAfDWj4QFtr2MbUem/qwhF9H5rRncBPUbxAF1JxIzBUqfBu2u9G4YIFILE2s0DCPJaqS GPXqGh+jl0TTavg3jh4dZe0N3d6R5YiAfgE8Eeo3D+IZIuZahQV7nPrDiKOz93Wd0L35+oOYSJZMJzBNf+otINpucKcKbY+naC4tPCDoz64epKHCbic0zX91 SulZhQUKRT6FUPf2m3UvQpvWikSUnRk1EMk2ZgL0HyU= 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 c07d91657..179a2da9d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -871,6 +871,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; @@ -883,20 +895,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 Thu Sep 27 18:35:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618451 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 3C5D614BD for ; Thu, 27 Sep 2018 18:35:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25A802BAE1 for ; Thu, 27 Sep 2018 18:35:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A6962BAE7; Thu, 27 Sep 2018 18:35:26 +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 AB3062BAE1 for ; Thu, 27 Sep 2018 18:35:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728525AbeI1Ay6 (ORCPT ); Thu, 27 Sep 2018 20:54:58 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48601 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1Ay6 (ORCPT ); Thu, 27 Sep 2018 20:54:58 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b8Dgnnox; Thu, 27 Sep 2018 20:35:23 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073323; bh=D8/Oa/hiwA9uvsgVgRFsMcOUXabtbTjXMPHDpvSsihE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=kCzss2I0XoCdd4ZcPtoqNzjjSKiEuQCmfi9sFshQptes9cC0Q8wXn73o91h8/7a8G EgsNFnFTh28UIp63+LJ7/Qji9+ApTO1pFulT9m1nqfIz51PMJTrFnMSu9AdTy4VCMX +UAAldGeDeZjJujATw2u8lKHSfNGRvF4C+keWU8Hh+uUMV4UhAzKWlmNKnezH3XYXG 1CY16L6P6OCgPOMGE5abKEcTzB2AkWtvZ8q1gPenIW/nXDoiu/e2yPRcf5pNrDzMhW jGLXa7Bz7fXd5RicPcsZo5SN1a+VIg7Vj8BlalS4e5Dq0cDv/TwrM6fy4kx7rxG9yZ 4Ubj2uMXvwfbQ== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==: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: Thu, 27 Sep 2018 20:35:01 +0200 Message-Id: <20180927183504.18078-7-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDu1wfsDH/PlBPoVw677ZdJ6MVoRKvgu1dgWuKRrvG1OUr9AR1vkZmFyvrowjb177op6s1kv/PcYtQY6PaEK1KMRBIf4AVKBNodtE2IHYUAnKYlsXOxJ l4dgXmD8cs8TWutN90F8pwRpcMSyI8XmApFv8ogLOmDGhXVxj3FlLuKxuFKY6xGmFv72s4IKk/sZe7XsSrJKGlEMbxrzELABSeSfeUpGW9MOhadvyoVrU7vI 5vtxtxuCqgCpy5WF76ndgcXbi/DckIxeSEtPUaou1dc= 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 179a2da9d..554f350c5 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; @@ -885,36 +924,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 Thu Sep 27 18:35:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618453 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 CDC2814BD for ; Thu, 27 Sep 2018 18:35:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B72C02BAE1 for ; Thu, 27 Sep 2018 18:35:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AB6732BAE7; Thu, 27 Sep 2018 18:35:31 +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 32A762BAE1 for ; Thu, 27 Sep 2018 18:35:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728530AbeI1AzE (ORCPT ); Thu, 27 Sep 2018 20:55:04 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:54811 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1AzE (ORCPT ); Thu, 27 Sep 2018 20:55:04 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b8GgnnpW; Thu, 27 Sep 2018 20:35:27 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073327; bh=lELwu3exI0wA279zvR3shM861i7nwO/Ax/hobnXAs7I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=POriaxR8x4WDvYGAh/vMkyHe2nkonZwYfXXeEud5fYNuMlUEnTh2r5qrjfJKHV72V FaM76I0SvSu52UMAVk9p3k275O4IBXagMh3v0w1QVPKGM2YAfDo7ZnS3LQVgNts3sI ueOpRjjMKB5sXneELauO2K9jAtYnWTIY82Jny5AMFk7YvjI/BW4m3yM6enP3vv74hW 8L1G2SX9SdtI9yjXIewojcmgJsc2el//v5fYCbU87MfBxQJmLoUfuhgswGKVFjLNCO 7l+GhR//Few5M0fvaIol1QJVzAsg2MlhbHruPMGTvztJEBjpwkvAMz4Ntwa9J+6Yhd K0lLy5y0w8WRw== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==:17 a=ljdETIpkDeTQ7q4m-5gA: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: Thu, 27 Sep 2018 20:35:02 +0200 Message-Id: <20180927183504.18078-8-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfOU8sAlsI3YOYjvIE/s+dDzyovmgO7QgkXAGrr/zv3N8lTzAz3vcZPh+xVuaXY5JsnJm80Rxt1xY370AMDIcS5dAvvN+AiX2LdSQqLFqi72cChpeZoor upAjwLC9gSjDXLHUjHPQaMGFJAa5hhkLLSoLofR3/bX1aYDuoTlmd26eoDOmkTYqFPHGvnjPqn0SIpCBLGNskRDV7aabyE0PJr9i+83x35T/Dcx0sVt+xH7/ Yu6Yu/npMJIu93wZoUFJoxk0QYxl+Qp0H4XyA0kLrVc= 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 | 160 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 554f350c5..db8df0eea 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,139 @@ 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; + + for(i = 0; 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_OUT_OF_MEMORY; + grub_uint64_t i, failed_devices; + + buffers = grub_zalloc (sizeof(*buffers) * nstripes); + if (!buffers) + goto cleanup; + + for (i = 0; i < nstripes; i++) + { + buffers[i].buf = grub_zalloc (csize); + if (!buffers[i].buf) + 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 err; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1) + 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; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buffers[i].buf); + if (err == 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"); + + ret = GRUB_ERR_NONE; + 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 +876,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) { @@ -922,17 +1060,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 Thu Sep 27 18:35:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618455 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 1ABF415E8 for ; Thu, 27 Sep 2018 18:35:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 03ED62BADF for ; Thu, 27 Sep 2018 18:35:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ECB202BAE4; Thu, 27 Sep 2018 18:35:33 +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 756A92BADF for ; Thu, 27 Sep 2018 18:35:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728541AbeI1AzG (ORCPT ); Thu, 27 Sep 2018 20:55:06 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48601 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1AzG (ORCPT ); Thu, 27 Sep 2018 20:55:06 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b8JgnnqP; Thu, 27 Sep 2018 20:35:30 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073330; bh=BYiWpzcXDH7R4zhuV9SPGwAZEi8ZW+8Agt4evHOZJug=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ZaEzAf+jV+VSrfv1j6vIAVMYwftz5+uwXfOvw9LHvjyAgzBQBPTXQaqotI+SVK0ET GTJ6g2TkjeOJ6XXQ/fAOoYh3WaZtxfb4YXHv42M6vtNMbNFCMo2F7jTLLOYqttjoTR f8iGg2JUzVYXN7MX3EGTrLLPR4FDJTb4q9IdX4TmjMaZnJVSnGGyrl/lIbguAyz2pi hbmTQI0MiNzrBEqeNQD9PzZehQm0iGpzGB6lFuGxghn6ecZpK1mzNZwBcdz/33ySrF kP+op/Jhej/AEPWPRtcEohlRMOB/R3AGg76xE8GTCMVbXFv2Ff40ljQodiyB0nRQuu vIFwn9OCYVnYg== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==: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: Thu, 27 Sep 2018 20:35:03 +0200 Message-Id: <20180927183504.18078-9-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfDK3V8psKv7mZ7X8W7NV4GqXnN07GQFEWsrJ4ht+lVLolfk3JzIssFcvNQOcDsewgrhYN5P4gWC+PxLnMbkdeo0udSvu4eGXcEPveOQRIY1mpKF8mrRT +vA585JT9+1MXPg8CcG5fZcfkVBHgK/30ZtBTUZKwJkn9Q/0pljHZnTziYsP8EZz8OVR89W6aoiP07yn0ajlCINHYZNGs0W3/czi63+TP9r3mOa7FxypcH9Y Opxx755bu5J9/B21/Zas/GCqgvCzuv7HyXlc2aO/8U8= 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 Thu Sep 27 18:35:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10618457 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 B584015E8 for ; Thu, 27 Sep 2018 18:35:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FA7D2BAE7 for ; Thu, 27 Sep 2018 18:35:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 944112BB4F; Thu, 27 Sep 2018 18:35:36 +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 23ABA2BAE1 for ; Thu, 27 Sep 2018 18:35:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728552AbeI1AzJ (ORCPT ); Thu, 27 Sep 2018 20:55:09 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:54811 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727404AbeI1AzJ (ORCPT ); Thu, 27 Sep 2018 20:55:09 -0400 Received: from venice.bhome ([84.223.214.84]) by smtp-34.iol.local with ESMTPA id 5b7zg9O8gq9Au5b8NgnnrH; Thu, 27 Sep 2018 20:35:33 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1538073333; bh=lviF3S0VB/cBGXGSZGe44X3W2Cq2PirD2HwnDmslTO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=oy6tyNMFu01e8MduDFCm/R5spcaTd6+maKXWYHmkJMjdWL/ETFl6qAvd/k59QMx31 k360jXbsgdZycKBHHoK45SDJltL3p/O+soFxzXS6h1DULbbtZJY8LAK3Db3GTw6WDK s7ZSplE0chqkjCFjpqGSsUYDe89PfbFpq5lv5tPH057PmZ//Ek0h8Nd9UXtsPYJvze rkkOs9i+WEd1Wh+ezksplWAHnaKe606YtR06lNiCwcRlbKCS6YwV6RLIn7OeoPiMsA bUZ7tB02RICnhLuc7hryNUycWsDbEVXIX3D3oRMzdxCRK8ACo9X4zHiw4sA3MFqjnX i0KSgSOAoYiSQ== X-CNFS-Analysis: v=2.3 cv=OoWeNB3t c=1 sm=1 tr=0 a=8ZjQKV1YVqnHfcWpVNE1cw==:117 a=8ZjQKV1YVqnHfcWpVNE1cw==:17 a=wuNVyYp8JoBNSc0xyE4A:9 a=0Dz7wqK0u1ibo9Q9:21 a=rErCfyRpZjE95KUB: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: Thu, 27 Sep 2018 20:35:04 +0200 Message-Id: <20180927183504.18078-10-kreijack@libero.it> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180927183504.18078-1-kreijack@libero.it> References: <20180927183504.18078-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfGndWWBkaSD0QjT8CF3IpZC0T1bW9b+0iXnn09koa4BlPUlzKFH1nyyNzRHNOOO779AMsjmiRtUvxdyMKIDmcR+ALmp4DstKYrdK4yc6spZtuKV27fRM GWeecvg16rD514Np077WOtqYC0i4PTQ+E4LZaN6yA+2E/WYN2ybTuXHsuLbBofar7iGWGF1EEzvXlCWp5+stL86tJjk4C9Zc8ZcqxnKfEqHIxjRnQ50y4fR7 4ZS6fAwu4B7F7Ez6lxqlnkEjN7I+Z+Y/EMjRJIKMUNA= 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 Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 63 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index db8df0eea..b49f714ef 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+"); @@ -702,11 +703,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); @@ -777,6 +803,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 %" @@ -787,7 +822,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); ret = GRUB_ERR_NONE; cleanup: @@ -877,9 +912,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) { @@ -1011,6 +1048,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, * size if the latter is smaller. * - nparities is the number of parities (1 for RAID5, 2 for * RAID6); used only in RAID5/6 code. + * size if the latter is smaller. + * - parities_pos is the position of the parity in a row ( + * 2 for P1, 3 for P2...) */ stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); @@ -1029,6 +1069,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, */ grub_divmod64 (high + stripen, nstripes, &stripen); + /* + * parities_pos is equal to "(high - nparities) % nstripes" + * (see the diagram above). + * However "high - nparities" might be negative (eg when high + * == 0) leading to an incorrect computation. + * Instead "high + nstripes - nparities" is always positive and + * in modulo nstripes is equal to "(high - nparities) % nstripes" + */ + grub_divmod64 (high + nstripes - nparities, nstripes, + &parities_pos); + stripe_offset = low + chunk_stripe_length * high; csize = chunk_stripe_length - low; @@ -1080,7 +1131,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;