From patchwork Thu Oct 11 18:50:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10637183 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 EE658933 for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFC8B2BFCD for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE4902BFCF; Thu, 11 Oct 2018 18:51: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 6E1742BFD8 for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729822AbeJLCTq (ORCPT ); Thu, 11 Oct 2018 22:19:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:54034 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729783AbeJLCTo (ORCPT ); Thu, 11 Oct 2018 22:19:44 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3GgbXzW; Thu, 11 Oct 2018 20:51:14 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283874; bh=39aL8uXP0JWmXPwp2S+XtwzWoh8psezJRhXBxrAk1vU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=oht47BsUZMGXvzqCGCtRMcS1778l3e6VDuOWn8auVtuh0LNrOQcExuEQ5JZOzAPoi KpgP16409sIE/4fBg1j9M70OhrgEGj2pQfebtLV17YMYSpa8hA9jlsOO3yUkUgU6Uq lLjvqtUeAUkIWMkaQwuOmY6K08NConpLOw2vp8XFrHhR/a5yLx+m0ciATKBenf7ldL SUtcJjwJj4zIPde+HcClfWYdDFudNZp/BxeqXfZWYGgMjpEtnEbU68ChUOMEWU9n9h bF//EM+axd+7DlOsqc9ogAC0gt+Tq3dGIMnagO49/LkamvRhFdufs9dZ2DMFlDC8TN FR8HElfYR3D3g== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=yPCof4ZbAAAA:8 a=10E2XUvmTi6NHy_q8tMA:9 a=NMA0j3cErYIjDTae:21 a=Uw-O9MEIAZd7h_om: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, 11 Oct 2018 20:50:55 +0200 Message-Id: <20181011185103.23146-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfB7r80I6B/TEVG9LJ70otK81y11lHjrb4zovuSXGQQOHlAqDr+PKfbm0hvVeB8RyuOopAxLsMNNUmMDCH3W9Ad/5N5PCJCR1zIQMYhWEefoEa84A14Ba fribfUjH2tDYs/uexG+h8Q+BsMz/MlOq7MKNJ8/Rv+MHx6g+g5bJMU05OEDBrFXVYyIbr/MK/3Y94ahfvXEjGfUnSsSdiR7hz65V6rTUspdOVFKR5WYARnXs iV/8iYE4ul9HJp7pG0YTFFIeQ+qn34L3hvbjLlGj+6k= 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: Daniel Kiper --- grub-core/fs/btrfs.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index be195448d..933a57d3b 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,77 @@ 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; + } + + /* + * RAID 6 layout consists of several stripes spread over + * the disks, e.g.: + * + * Disk_0 Disk_1 Disk_2 Disk_3 + * A0 B0 P0 Q0 + * Q1 A1 B1 P1 + * P2 Q2 A2 B2 + * + * Note: placement of the parities depend on row number. + * + * Pay attention that the btrfs terminology may differ from + * terminology used in other RAID implementations, e.g. LVM, + * dm or md. The main difference is that btrfs calls contiguous + * block of data on a given disk, e.g. A0, stripe instead of chunk. + * + * The variables listed below have following meaning: + * - stripe_nr is the stripe number excluding the parities + * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), + * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), + * - stripen is the disk number in a row (0 for A0, Q1, P2, + * 1 for B0, A1, Q2, etc.), + * - off is the logical address to read, + * - chunk_stripe_length is the size of a stripe (typically 64 KiB), + * - nstripes is the number of disks in 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 RAID 5, 2 for + * RAID 6); used only in RAID 5/6 code. + */ + stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); + + /* + * stripen is computed without the parities + * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). + */ + high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); + + /* + * The stripes are spread over the disks. Every each row their + * positions are shifted by 1 place. So, the real disks number + * change. Hence, we have to take current row number modulo + * nstripes into account (0 for A0, 1 for A1, 2 for A2, etc.). + */ + grub_divmod64 (high + stripen, nstripes, &stripen); + + stripe_offset = low + chunk_stripe_length * high; + csize = chunk_stripe_length - low; + break; } default: From patchwork Thu Oct 11 18:50: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: 10637181 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 AF856112B for ; Thu, 11 Oct 2018 18:51:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9F5F02BFA7 for ; Thu, 11 Oct 2018 18:51:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9D9922BFC0; Thu, 11 Oct 2018 18:51:22 +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 45C8F2BFCA for ; Thu, 11 Oct 2018 18:51:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729825AbeJLCTq (ORCPT ); Thu, 11 Oct 2018 22:19:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:43028 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729784AbeJLCTo (ORCPT ); Thu, 11 Oct 2018 22:19:44 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3GgbXzb; Thu, 11 Oct 2018 20:51:14 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283874; bh=KuTYrHl73JrlRdyNxbEMcnlyesZv8nb05pfEisUS7CE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=RYEy8qvNxmoenTwcn6LJIMmkpVR7DVkCvu19wevVQTs9D6v7ONZHVAyV0/G25ckVe T9u66RYJe7cMzzMC+dDRcCHnBIFFhoqDSatqiSFwsMP/cKvyyoD+NkY+Xbw70icYaR c5WDGygbs38RblA6+V+FdGiCZ1RTKsoXJ0udseoAvisdcStnyzHaKhJLgCxPvmS+Jo /q/J7zY5JFAkl74hBMG6N95xm2sahDerw/7qa6SHS2kS59blRmiw5qzfp7KWwBMlAj GCWE5hMXtsfbz4I7JrS/QkpZuoxsi0P8qt2x0ygKKZO2VtMtiSgdZQ3nMMBJEbB59l SSV+7ElLmtZ8g== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==: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, 11 Oct 2018 20:50:56 +0200 Message-Id: <20181011185103.23146-3-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfB7r80I6B/TEVG9LJ70otK81y11lHjrb4zovuSXGQQOHlAqDr+PKfbm0hvVeB8RyuOopAxLsMNNUmMDCH3W9Ad/5N5PCJCR1zIQMYhWEefoEa84A14Ba fribfUjH2tDYs/uexG+h8Q+BsMz/MlOq7MKNJ8/Rv+MHx6g+g5bJMU05OEDBrFXVYyIbr/MK/3Y94ahfvXEjGfUnSsSdiR7hz65V6rTUspdOVFKR5WYARnXs iV/8iYE4ul9HJp7pG0YTFFIeQ+qn34L3hvbjLlGj+6k= 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 933a57d3b..c9f0c4193 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 Oct 11 18:50: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: 10637175 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 49229933 for ; Thu, 11 Oct 2018 18:51:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B44C2BF6E for ; Thu, 11 Oct 2018 18:51:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 36FE42BFCB; Thu, 11 Oct 2018 18:51:20 +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 B33FC2BFCF for ; Thu, 11 Oct 2018 18:51:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729835AbeJLCTq (ORCPT ); Thu, 11 Oct 2018 22:19:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:33723 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729785AbeJLCTo (ORCPT ); Thu, 11 Oct 2018 22:19:44 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3GgbXzm; Thu, 11 Oct 2018 20:51:15 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283875; bh=mU0CLGmoxJNDijdmxkWh5T+f++hham1acS2GkejH0IQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hit0rE7fHBlBOeCQEeDDjUIcjP3WN4YyXsYKyUrSnf1SvSgbNB2qlXTcmhyG+zMAA 2A9Si3FzAGCyOrPyMBjP7KohGrwIpXDZCdIGicaF+v4Vd/ZzMWCxp4sG8/+Gb0Nf08 jEgA+c5ASZsBtsrrDBhv4qM0QTfVaVKKCpnKAKLq05b7aQBwGREbh8P5Q0jopw0qDl kOx1j5YZ+Nu/x4H8iTY2wCQ0lX/hJ/1D6XNUNrn+59paMlUDxnb5Co50vaaNRnBFbc s9bJqUF8aTODWYrfMVziw2Hi+JAJTY5QlRvIjib+5717GyFKvQ/bMyBZIU/+I01e3v R0AIfP/bCzTEw== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==: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, 11 Oct 2018 20:50:57 +0200 Message-Id: <20181011185103.23146-4-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfAOQ0iifhU0WYY0oY57gOQ1sRzzoHQ1p3kZH9AXynZPcZOAdcW/h8cGf3khroZoLd6ZLhS0ryzGJ90YmzoMDB8r8uRECD8mrjdMlcK/RwmZKWd2fdqla CnPlCYBOyq1CMnAImYTdlktNawuIoo+rgTAt9BM6W0SIpB0H9s58S0/N4qukv8GxiZJ3lqFdj5MI6C67eh+qnLawPSluQpwLiSZPz2wskncgBeFk9uyAvdzt KekuTSL7J2P3aZe7wD2Edh7Z8QtgtCPGraXHBKb1lfc= 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 c9f0c4193..2a87eb103 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) { @@ -905,6 +900,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 Oct 11 18:50: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: 10637187 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 DFC62679F for ; Thu, 11 Oct 2018 18:51:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CEAE92BFBE for ; Thu, 11 Oct 2018 18:51:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CCAE92BFD0; Thu, 11 Oct 2018 18:51:25 +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 6DAB12BFD4 for ; Thu, 11 Oct 2018 18:51:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729857AbeJLCTw (ORCPT ); Thu, 11 Oct 2018 22:19:52 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:37133 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729786AbeJLCTp (ORCPT ); Thu, 11 Oct 2018 22:19:45 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3HgbY02; Thu, 11 Oct 2018 20:51:15 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283875; bh=GJkLQdHACkYyoGwEvpgE86CX50jb7ab2XaJVwqcHACg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=U9jNxnstSVn3/91iWPG9sSlOl86FV8y76b/A1uE+AgKRZca0gR4ZcgQQ8qK3Zo+aS HRxB1ULiAp6zDGEzWTG6nX/DilO2eDg5r1nE0xR/DWsj0TGSn7X8gif6tRsKc7dP8n 2P9LZ44dNQ+eSaZAHi+bid6JQ1Bz3D7RmPrxgwrXAJSrOzjXfR/p1ExQcbR/tgrrDJ FSnjLHR3+yPJ/VJ+BRfhT5ym60JyLaRCowtGZBBMhbQpf9pEhG2HRIK51lXKg6ClnC B0Rf7aybrYFm1GeYAjSji5FW3M0+2C3lvSm1EeCDaahxKPRFNKpbbDUpP/hAHAXgRB vIp21WEdrcsCw== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=wqVqdCQbwCNbCc34xW0A: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, 11 Oct 2018 20:50:58 +0200 Message-Id: <20181011185103.23146-5-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfAOQ0iifhU0WYY0oY57gOQ1sRzzoHQ1p3kZH9AXynZPcZOAdcW/h8cGf3khroZoLd6ZLhS0ryzGJ90YmzoMDB8r8uRECD8mrjdMlcK/RwmZKWd2fdqla CnPlCYBOyq1CMnAImYTdlktNawuIoo+rgTAt9BM6W0SIpB0H9s58S0/N4qukv8GxiZJ3lqFdj5MI6C67eh+qnLawPSluQpwLiSZPz2wskncgBeFk9uyAvdzt KekuTSL7J2P3aZe7wD2Edh7Z8QtgtCPGraXHBKb1lfc= 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 Currently read from missing device triggers rescan. However, it is never recorded that the device is missing. So, each read of a missing device triggers rescan again and again. This behavior causes a lot of unneeded rescans leading to huge slowdowns. This patch fixes above mentioned issue. Information about missing devices is stored in the data->devices_attached[] array as NULL value in dev member. Rescan is triggered only if no information is found for a given device. This means that only first time read triggers rescan. The patch drops premature return. This way data->devices_attached[] is filled even when a given device is missing. 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 2a87eb103..b2be80c33 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; } @@ -897,7 +897,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", @@ -974,7 +974,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 Oct 11 18:50: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: 10637177 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 49CB4933 for ; Thu, 11 Oct 2018 18:51:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BC252BF5E for ; Thu, 11 Oct 2018 18:51:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 388242BF9D; Thu, 11 Oct 2018 18:51: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 D43EE2BFBE for ; Thu, 11 Oct 2018 18:51:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729837AbeJLCTq (ORCPT ); Thu, 11 Oct 2018 22:19:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:52800 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729799AbeJLCTp (ORCPT ); Thu, 11 Oct 2018 22:19:45 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3HgbY0C; Thu, 11 Oct 2018 20:51:16 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283876; bh=5oBI0qGMFDD6zfiFnly1NgYUQ377A4SniXN+v2UHtPA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VzRgdvwt6iLWeVESPIZMBRd241siCWIeyU4dJxYaFKbnCWnIu3hSqgou+x7XYAoPO bEir4GWKEeH5sHWhFRg0vhev2UECToWv7fvUKUbG1OmNC7UXGVWr2IgntizXCTPShQ SQur5+qnEtIR7qmYe4YEtNraEIAfJjdIolZLQwVCi73CQMAbRH3Ny6omLehn/VM9Io 0VxV3rVKz1V08/oOKJJUciqcUU2hgM8uy8X51WUlLwbwjEqjrMXLc1F5fr2HwiEOD3 g/iUS5EpIUFqvOytrm9Oo7mUyVTacRjFvWEN0ZOXX+nOfI8H+naujUDtuEXu+VJR/Z Xkhjf9xkAZ3QQ== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=yPCof4ZbAAAA:8 a=tbGcK1RVRLHxssNcnxoA:9 a=ROPnYPVHyosrfo3k: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, 11 Oct 2018 20:50:59 +0200 Message-Id: <20181011185103.23146-6-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfMeBmjCiNA9CZ9pgvDmeFIYY3WeUnL16lyNyCt1jGH12Omfy0EpmL1x9tU8UqVW7TSZs3cCeonhUGMsDt4Y37TLH2+Uugn7gj63cjTg7UlkOsnpi4ceD 61fitc/Y3QHgO+teqAn8FnoHs1KaiKMn8VW/gWQenS33Vs1+tO94Y60BX0oOcyJpKVxoIp4uvQMbuIUfF8sWTj9T3pgWIqTdiCUNwnVwmlv0cPq8osT8AGoX mN+mq+vQzghv9aAFC6CzmV8LoC22a+JrqeEpCQXf48E= 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 b2be80c33..a82211ccc 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -870,6 +870,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; @@ -882,20 +894,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 Oct 11 18:51: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: 10637201 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 33615679F for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 255242BF62 for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 199B82BF88; Thu, 11 Oct 2018 18:52:20 +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 9E1E42BF65 for ; Thu, 11 Oct 2018 18:52:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729908AbeJLCUq (ORCPT ); Thu, 11 Oct 2018 22:20:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:46145 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728389AbeJLCUq (ORCPT ); Thu, 11 Oct 2018 22:20:46 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3IgbY0M; Thu, 11 Oct 2018 20:51:16 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283876; bh=ztzz/YoAFGb93LDW1rNVN2i8jZCgeBqO8BuUCbSDNGE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AyGTDhwh0tgb6R67agcNSM5zPZr4CtxTOTEHXw72LF90qN6zlljWV5MDgzx7JQA/r /Cx7thLAHAg8cXIHloBKeMe792KvaLmbt+EOOEVEGkpaPpAjFjtqXWYH3Zmei0IJjb zxd0sy0ne3vtM7heQzVfQiEQedrWaVthksYSQ5rt2Pvwb6qvcYOvzOSWxf/SDCIEm9 Ojb0ZpnD8buk48hhHqQ1jzRYu+NiQRDO0LBCCr3VS6QVse5kduj1iV8ZP4XmGpUgZA VURfh8oNsOtFo2GXsVSr4Kff98xYkx4hvljY9sWOSzcJdKt0lM/9sm47QYJ3iA1wh3 4GsnAskIMMK/A== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==: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, 11 Oct 2018 20:51:00 +0200 Message-Id: <20181011185103.23146-7-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfMeBmjCiNA9CZ9pgvDmeFIYY3WeUnL16lyNyCt1jGH12Omfy0EpmL1x9tU8UqVW7TSZs3cCeonhUGMsDt4Y37TLH2+Uugn7gj63cjTg7UlkOsnpi4ceD 61fitc/Y3QHgO+teqAn8FnoHs1KaiKMn8VW/gWQenS33Vs1+tO94Y60BX0oOcyJpKVxoIp4uvQMbuIUfF8sWTj9T3pgWIqTdiCUNwnVwmlv0cPq8osT8AGoX mN+mq+vQzghv9aAFC6CzmV8LoC22a+JrqeEpCQXf48E= 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 a82211ccc..899dc32b7 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; @@ -884,36 +923,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 Oct 11 18:51: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: 10637199 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 1FB0C112B for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0FB212BF67 for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 035C42BF69; Thu, 11 Oct 2018 18:52:20 +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 734712BF62 for ; Thu, 11 Oct 2018 18:52:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729906AbeJLCUq (ORCPT ); Thu, 11 Oct 2018 22:20:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:54034 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729187AbeJLCUp (ORCPT ); Thu, 11 Oct 2018 22:20:45 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3IgbY0U; Thu, 11 Oct 2018 20:51:17 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283877; bh=dk1zaVtjiWRLe4SoUGtVdbDdffAha4dP1TJIC39qHQA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Tm9G5J08ZsB8kFEDF7UWbadNIWZUjA+b18gPYaI/QupwIY77c1n68Vi8/TVEsEh1y XWn2inehh5cC7z/z1m5Y3r2eShtRZkx+a49NhhUY0N21xCJ3MLAvtU3lf/UD58yA5V q8xTFOyYykM+KTk30J8BLmvBHwFk+pkCtVnyHUvJ10L5xElUG3mKnRu7EYLblTZ8R1 XxJX2rlwaAJXowv6HtJJZMxvL7ejV+Ul0+4wMl8mVig5VOe4ijfon6UIkMeCy8Gj36 ByFArJyxerJmhTWiJHi2p4UTBJe6f9T5ekRUqceoMdxtE4zaM3pmSypUlADusm7WIv lM25wLbMplPOQ== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=G94wEjWLTZ8BO8lEC54A: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, 11 Oct 2018 20:51:01 +0200 Message-Id: <20181011185103.23146-8-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKdBstYaSrjQl3ndoX411e2SAjZ5Ql2IE7F5378I/nI2oTUWnnaX2IIXDRh04zQN++MjPMhyiL+0YFs9rjMKnEYE5NsCBCUa6FCH5OXUsM3FMGw8v04n finTKlZRw5JFMI89rZgq3kQy5qZjmolIhr5AxI5X8UaS+Suvqczxxjq+OsA2KvAehCndmQLWNii1/uXRkj/NFIkYxjCRwubNWc6mAjeUzRaAlM8+I1Vwo0Tb cgGqTfq8jjaErakQUmsSPAkvW8uU0BYZhxfT1PxyEwI= 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 | 162 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 899dc32b7..d066d54cc 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,141 @@ 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; + + /* after the struct grub_btrfs_chunk_item, there is an array of + struct grub_btrfs_chunk_stripe */ + 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 +878,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) { @@ -921,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) + err = raid56_read_retry (data, chunk, stripe_offset, + csize, buf); } - if (i != redundancy) + if (!err) break; } if (err) From patchwork Thu Oct 11 18:51: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: 10637203 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 8F084933 for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D81C2BB0A for ; Thu, 11 Oct 2018 18:52:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7215C2BF65; Thu, 11 Oct 2018 18:52:20 +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 F334D2BB0A for ; Thu, 11 Oct 2018 18:52:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729913AbeJLCUr (ORCPT ); Thu, 11 Oct 2018 22:20:47 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:43028 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729054AbeJLCUq (ORCPT ); Thu, 11 Oct 2018 22:20:46 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3JgbY0f; Thu, 11 Oct 2018 20:51:17 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283877; bh=rRN3WhXbdv8hpdGqHvWXTQsfzlxWcpsHLNi1isTwRYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UyVnf8C54v5iVbHZrd+BiT4LpacZhuKjhgqa5MWPezEgpxl/VwBfo10A0wEqLtfPz qmwT2itXCg+pYb6uLntNUL6i8uEiz5r109T42s6EejeCsJsOQxE4NeCZlkla/zU718 5pbvWJZviucNn87eBfwjBjyjJ/lpDVy7tx83RnytmBiFMUJqQa5kd4NIY6tzCxOUxM YU9yjPUZKqApECaHASwXcHG7bO7UTuFu5O/RrwvmvzsHXUR8evbKK1/MciomOvlLJF w/apD0lQzXS5KmQtLbemjnz3d3gkXaGa9d7QjOGtVx0cDK1I9SXygOapMk9jZ3e8qD aR59GxPJbeNOg== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==: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, 11 Oct 2018 20:51:02 +0200 Message-Id: <20181011185103.23146-9-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKdBstYaSrjQl3ndoX411e2SAjZ5Ql2IE7F5378I/nI2oTUWnnaX2IIXDRh04zQN++MjPMhyiL+0YFs9rjMKnEYE5NsCBCUa6FCH5OXUsM3FMGw8v04n finTKlZRw5JFMI89rZgq3kQy5qZjmolIhr5AxI5X8UaS+Suvqczxxjq+OsA2KvAehCndmQLWNii1/uXRkj/NFIkYxjCRwubNWc6mAjeUzRaAlM8+I1Vwo0Tb cgGqTfq8jjaErakQUmsSPAkvW8uU0BYZhxfT1PxyEwI= 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 Oct 11 18:51: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: 10637205 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 C7CDF933 for ; Thu, 11 Oct 2018 18:52:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B81482BF65 for ; Thu, 11 Oct 2018 18:52:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ACA612BF67; Thu, 11 Oct 2018 18:52: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 407092BB0A for ; Thu, 11 Oct 2018 18:52:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729920AbeJLCUs (ORCPT ); Thu, 11 Oct 2018 22:20:48 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:33723 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729898AbeJLCUs (ORCPT ); Thu, 11 Oct 2018 22:20:48 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3JgbY0s; Thu, 11 Oct 2018 20:51:18 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283878; bh=1l7R2e3BsN5bABneflqCVb8J8cA4YYCXLX8/iK/hV+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=a8m8WIAJDLFsxJB8g8wa0sg+KI4/4DtOmUWmgLC2Ypix7e7ke8v4uOS3qzTpK/p0B vnbbaoctv+bn+hfruI8MEtd3J1971e9fN1t0YQ7IJjXEeEBKl7NrcWe0OURHhCUwcE 4ypsnQcKq+2hPfrauB5BzxF8zNVNg0VqQG+ZfVrZ+qvP2t2ObJ5P+JbFNxrgB7X7/C pRCMQ4wi/p2t9S1hzz+OTu6v0x2WOtMRMBGEHfwFIRbRB9NVXFeOFyyOW+tqMK/BbM XCk47tOoXPaPOgfqleg8vNGetpBWR9PAv7Wg+e2Cc/GPArjsGJl2JJneQ50yIho/ct ZfkOxyyUjziJw== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=yPCof4ZbAAAA:8 a=wuNVyYp8JoBNSc0xyE4A:9 a=hdJAPv6k9wQm8rpy:21 a=7qR9nF3qPSxaN1T8: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, 11 Oct 2018 20:51:03 +0200 Message-Id: <20181011185103.23146-10-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfOP08ZWDKKdAyegkiBPsFWmQtdzRKT85DXUug5p+mZWnZZrrL4j5QIqkuAL46mGcHKNcCtFUGBv1jKnM2Vl5EJ21llInTfpLG9J4yIaBaGP1qVxrt7nY 938WmY+656ojZmYlx+1lPO2fDQhVCnvRFDkFseZlB0YINe0BrBgMa8WKOCAeu2jbMnfbThT5HUpIzpZdH0BJLC/VqzDewywiK/FGieh4eXzxBzlVwvc3l0zE KQBXo2EHbt6Bmy6rmUkbCJiCMCX9UZ0aj/iutODO6/o= 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 | 60 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index d066d54cc..d20ee09e4 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); @@ -779,6 +805,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 %" @@ -789,7 +824,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: @@ -879,9 +914,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) { @@ -1030,6 +1067,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; @@ -1081,7 +1129,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_errno = GRUB_ERR_NONE; if (err) err = raid56_read_retry (data, chunk, stripe_offset, - csize, buf); + stripen, csize, buf, parities_pos); } if (!err) break;