From patchwork Mon Oct 22 17:29:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652289 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 4FD4214BB for ; Mon, 22 Oct 2018 17:30:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A71B29116 for ; Mon, 22 Oct 2018 17:30:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58E952912D; Mon, 22 Oct 2018 17:30: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 E72D429142 for ; Mon, 22 Oct 2018 17:30:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728723AbeJWBtg (ORCPT ); Mon, 22 Oct 2018 21:49:36 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52199 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728550AbeJWBtf (ORCPT ); Mon, 22 Oct 2018 21:49:35 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1ngfjqr; Mon, 22 Oct 2018 19:30:07 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229408; bh=CUQsVc80lMhXUTtNLr7dJdbhnCqVLGPeIgG4l+HtXx0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=K6/RPAmG3wfE6Go40eglHuwqlkmc0H+jaIYRDF8eR9toTeyOMth9uP0siAU5/E7Fj JNCPr3lw2bKHwPUFK3d3UyGUNO0fpy5GpILGzViFjg4t1MuB72cswhLfDrBFXILyA2 kEHizh8igHY3dOrKXZ7cXYkAiSVszR0Nzd1+k4RbqvbEF4Swk/8ggk2zqcMQYQLv3F tk+VsGkrmC2wmfx0+9PN05fHXzKRkQH0SlNp47094i15wwD/6oU6e/KQXZXY9u9yOA iqhJZCBqH8Ij6sNfdSk7YHGzSq5Vxczg9fNa9eygGFwPmmDYGmnHcMIK7IjFA/ROPW SwIUJZ6bhCpmw== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==:17 a=yPCof4ZbAAAA:8 a=10E2XUvmTi6NHy_q8tMA:9 a=O12Uk9nZU-Ayzfzf:21 a=BXEPnZTIIX6eRtaI: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: Mon, 22 Oct 2018 19:29:31 +0200 Message-Id: <20181022172938.7936-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHqgJISiJS6fR51Hz35O38qAU8jUYCd2mJjZwGQXqLnn0oSVIrdq4xL/N1oHu5RaWXKhBDG2g33WOvfIQhz8nCztBY4TelCEE9R4D4V6NaZZcRC6OiIN NHlwiqryoAHta9tk86WAaS12ILtL2HQvqHFcOybCzoK8bPalDOibCl+Gsk4QE+7a/0npPpRJk9Usrq17L792ao2bFEPzvD5IqXn5X67WZ2JbmUhAi+1nztyF KvCFs62XgqPcB9H8xIhigY7THSiJd3z1ENgIUiT9Uug= 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 Reviewed-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..9122169aa 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 into account current row number + * modulo nstripes (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 Mon Oct 22 17:29:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652283 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 56F3714BB for ; Mon, 22 Oct 2018 17:30:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6330A29130 for ; Mon, 22 Oct 2018 17:30:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 57B0729133; Mon, 22 Oct 2018 17:30:14 +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 AFE8E29131 for ; Mon, 22 Oct 2018 17:30:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728663AbeJWBtf (ORCPT ); Mon, 22 Oct 2018 21:49:35 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:39350 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728566AbeJWBtf (ORCPT ); Mon, 22 Oct 2018 21:49:35 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1ogfjr5; Mon, 22 Oct 2018 19:30:08 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229408; bh=rBCv2aOPJtIw+dlR3woR1f4IXLbCloRw2O+TGV2oeWQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=DZXUI6LJ97u3Qoyo7SYpO/+8js4gJbnFtaWQr80A+gqIm+ARinpV1wnvTDxrII6kX SKQZn59Hknih78fgqw4zn+dSpwWQ0hy0iSBb97TfMnuKN9weGPe9pj7/xutf7+HABo Ryd/UAOQM99X4VMoR3Ru60rcyGp/OeGFl/UR+DQyu12uLpb3jeasVt4bNBuzxT+ps1 TZ/qnjf8svAtU+uUVwr1DpYKFUuejLyGQYRQy/PKQ8k3yjUVWhFjkT19V6FgMJ4i6U P8wSGIHYyp+dMzXwStM/jWyEigEyEhZknj440H3iLCc/Bq5KVPAZQIJ2G/XzR/lsBL c4uQEbKlG1ECA== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==: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: Mon, 22 Oct 2018 19:29:32 +0200 Message-Id: <20181022172938.7936-3-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHqgJISiJS6fR51Hz35O38qAU8jUYCd2mJjZwGQXqLnn0oSVIrdq4xL/N1oHu5RaWXKhBDG2g33WOvfIQhz8nCztBY4TelCEE9R4D4V6NaZZcRC6OiIN NHlwiqryoAHta9tk86WAaS12ILtL2HQvqHFcOybCzoK8bPalDOibCl+Gsk4QE+7a/0npPpRJk9Usrq17L792ao2bFEPzvD5IqXn5X67WZ2JbmUhAi+1nztyF KvCFs62XgqPcB9H8xIhigY7THSiJd3z1ENgIUiT9Uug= 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 9122169aa..0cbf3551a 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 Mon Oct 22 17:29:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652291 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 34D6914BB for ; Mon, 22 Oct 2018 17:30:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CD7029120 for ; Mon, 22 Oct 2018 17:30:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3B3FE29123; Mon, 22 Oct 2018 17:30:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E16F92912F for ; Mon, 22 Oct 2018 17:30:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728714AbeJWBtg (ORCPT ); Mon, 22 Oct 2018 21:49:36 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:50769 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728568AbeJWBtf (ORCPT ); Mon, 22 Oct 2018 21:49:35 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1ogfjrI; Mon, 22 Oct 2018 19:30:08 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229408; bh=R1USxw4Z/+qNRKevXadq2m1pnIUHt6KDSJ0uysAgReQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=rqzo+IIsmJFsCRhH0rUY13Phy2yfHnt613lmwkDEyz0e1maZXICYztwMpmMbDHfji hHtxe30IGylurjvR7tG8d3pVEfOcAxQYAQQbE+kPC5hogH36ANhXT+RRqwgA+WPZeN KSUi6lc9PUNMqI+vMOKAWTJd62+/OmdUgM8mLA554kl/zhzBTkqLkcDbcE36G9C8Ll DOooSNvQ/O/y/uCfy9kL89RE+M/QJteLsWpyZsiMAG7++SKgFkl4XYS2DcfJn9Tfdq K+gro5H7hjIwKaZYNnidwfb4vRgI2hJGM1D76PEyULQeO5g1dV6e1gYB/zjNm6QAjU DFmRhnRleMBVw== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==: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: Mon, 22 Oct 2018 19:29:33 +0200 Message-Id: <20181022172938.7936-4-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHqgJISiJS6fR51Hz35O38qAU8jUYCd2mJjZwGQXqLnn0oSVIrdq4xL/N1oHu5RaWXKhBDG2g33WOvfIQhz8nCztBY4TelCEE9R4D4V6NaZZcRC6OiIN NHlwiqryoAHta9tk86WAaS12ILtL2HQvqHFcOybCzoK8bPalDOibCl+Gsk4QE+7a/0npPpRJk9Usrq17L792ao2bFEPzvD5IqXn5X67WZ2JbmUhAi+1nztyF KvCFs62XgqPcB9H8xIhigY7THSiJd3z1ENgIUiT9Uug= 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 0cbf3551a..6b6e91cd1 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 Mon Oct 22 17:29:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652281 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 63391109C for ; Mon, 22 Oct 2018 17:30:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DC2B29112 for ; Mon, 22 Oct 2018 17:30:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6276429119; Mon, 22 Oct 2018 17:30:13 +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 00F1D29112 for ; Mon, 22 Oct 2018 17:30:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728727AbeJWBtg (ORCPT ); Mon, 22 Oct 2018 21:49:36 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48960 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728575AbeJWBtf (ORCPT ); Mon, 22 Oct 2018 21:49:35 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1ogfjrV; Mon, 22 Oct 2018 19:30:09 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229409; bh=d6AQBEgz0RNa61javY0WhaXZw6LSZcXpCmyDysS3KyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QgYJk/LQWL/bPjUiRFxVRngmyaBbAfzr+2gyhIPeAfCOL0m7mwEOTTdIjlrn/vpOw Aq46af9mMmJny7znbZ2MGWN/rZXdys4/8FNYxihB6bJTgbEFxfsLcV677M1S3ghInx X8sEnr5wMiX8/MWLLSc8HwswT8nJ69eKmRoBxZ9Z5kdfPSKQg5msZoZQQlpXOAvUMd F7Lu5Od/t8eI68iIWj6/qsWSKFIXdCYBJ7gk7pJfoTdaWOjV/cIRSOPn1SwCpnrnoo cJYYXtBz2N9nGb4p91KhVyfARsfaWLfu3J/SfKn77/WMu6VVHgrixgCIUmZNTKt34p UqVbaoS2eyT2w== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==:17 a=yPCof4ZbAAAA:8 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: Mon, 22 Oct 2018 19:29:34 +0200 Message-Id: <20181022172938.7936-5-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfK8Fiko8mK1TTbWzjwX/xLamVqnzTuLzyMSzvwVm3cSyiB0N8NJkeYyWQRQKij2vZV5tC+WJCvua905K/M2v0cz2XXMIzRh2ZLgUPyngIhGCFNowQtYI g6FXGnh+GCjcQzpe2WA/TqWzKeP/ZW4UWlbkakLP5orf5O3IBXi+QaCh8Hr54u+25WQUTi2aaw9Wo+ibKYkB0EUt6uF5IuI7fqHjGt4IHe3e6ZujU48lb3qG 93HzhZp+DvfRyvL4CBAkTgMyKUsJjnNC6fxKUVfnbfI= 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 Signed-off-by: Daniel Kiper Reviewed-by: Daniel Kiper --- 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 6b6e91cd1..81f3bc120 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 Mon Oct 22 17:29:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652293 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 17BA0109C for ; Mon, 22 Oct 2018 17:30:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21D2B29123 for ; Mon, 22 Oct 2018 17:30:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 205A22912F; Mon, 22 Oct 2018 17:30: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 C1AB029123 for ; Mon, 22 Oct 2018 17:30:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728690AbeJWBtg (ORCPT ); Mon, 22 Oct 2018 21:49:36 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:47744 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728584AbeJWBtg (ORCPT ); Mon, 22 Oct 2018 21:49:36 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1pgfjrd; Mon, 22 Oct 2018 19:30:09 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229409; bh=JgAMnYNIHiju5Rd63/hYsQIu/hu1AUy86GiQKVcTUZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=qhiaHviXVOf/nPbVaIFR5ys67CoxaI7iLafJY27TZz368766HvcFehpj+y6NgGrI/ Nt74Ua8i9bCsrg41eABMuzD8Ud653XW1uAqM7TwSzS2qJ4B4bsUwmk21m5Ffu7Z4Jb V6rfxGH7R2ux7vl1F0uAZEXDA2IPjIKbIiBvOAA2A4d1Gm1hD301Kul93YRuxAa77o qPTn/kB3heMRDzri1YYeVuEdWTXnlGf/FhGWTS7aIT0p4kuxv6VlNiH+1qPhdpBGNE asH6rCYblPIcGvJ5QnrUn+1jou59CdHc5dX5bGQtNXMYf6qVZM3UNnukd2mYEMg1Pk Or1SLmEQrIJtA== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==: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: Mon, 22 Oct 2018 19:29:35 +0200 Message-Id: <20181022172938.7936-6-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfK8Fiko8mK1TTbWzjwX/xLamVqnzTuLzyMSzvwVm3cSyiB0N8NJkeYyWQRQKij2vZV5tC+WJCvua905K/M2v0cz2XXMIzRh2ZLgUPyngIhGCFNowQtYI g6FXGnh+GCjcQzpe2WA/TqWzKeP/ZW4UWlbkakLP5orf5O3IBXi+QaCh8Hr54u+25WQUTi2aaw9Wo+ibKYkB0EUt6uF5IuI7fqHjGt4IHe3e6ZujU48lb3qG 93HzhZp+DvfRyvL4CBAkTgMyKUsJjnNC6fxKUVfnbfI= 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 81f3bc120..dde0edd03 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 Mon Oct 22 17:29:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652297 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 020211815 for ; Mon, 22 Oct 2018 17:31:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 089962917D for ; Mon, 22 Oct 2018 17:31:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E95B129139; Mon, 22 Oct 2018 17:31:13 +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 47F092917A for ; Mon, 22 Oct 2018 17:31:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728813AbeJWBug (ORCPT ); Mon, 22 Oct 2018 21:50:36 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:48960 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728439AbeJWBuf (ORCPT ); Mon, 22 Oct 2018 21:50:35 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1pgfjrj; Mon, 22 Oct 2018 19:30:09 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229409; bh=1emG1V12wB2MYi1b9SVurpKNgMWp+bRbTFT100nQPQQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gCUOJFiCFnLYLKcqGRTuRp+jBl9FZ99hZJ0UKacgdNEJAbBBCKpl6RD/xIQEQ6FPE 3dYiGHc7mW1qIfOtn+PEmsWz6pvrZ+cytp80VnKQUFStGrEHCieYuaA8Ets7P7a1qx 7qIo4Uf0aymbDbaj+Uq4lSsPF5J3d/TewqcZgPTMx26kEZ+PE5z9F32Ikl3O8f7VSl 2It/3LQqN5CMgrDWTB1j5gypivIOV2anFs3nd4dfuiELzWy4QVRrRy8bHFNtSt7wCQ fmgx+CSkBVOLjJOyBXlpct0d2l72755v+Gq/jRqi3/+GZlhAPURg48AEFMZYXlGlrM gaYuX6K80CDtQ== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==: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: Mon, 22 Oct 2018 19:29:36 +0200 Message-Id: <20181022172938.7936-7-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfK8Fiko8mK1TTbWzjwX/xLamVqnzTuLzyMSzvwVm3cSyiB0N8NJkeYyWQRQKij2vZV5tC+WJCvua905K/M2v0cz2XXMIzRh2ZLgUPyngIhGCFNowQtYI g6FXGnh+GCjcQzpe2WA/TqWzKeP/ZW4UWlbkakLP5orf5O3IBXi+QaCh8Hr54u+25WQUTi2aaw9Wo+ibKYkB0EUt6uF5IuI7fqHjGt4IHe3e6ZujU48lb3qG 93HzhZp+DvfRyvL4CBAkTgMyKUsJjnNC6fxKUVfnbfI= 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 dde0edd03..ea97f0502 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 Mon Oct 22 17:29:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652285 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 3265014BB for ; Mon, 22 Oct 2018 17:30:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AFB029133 for ; Mon, 22 Oct 2018 17:30:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3944929116; Mon, 22 Oct 2018 17:30: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 B1B1D29116 for ; Mon, 22 Oct 2018 17:30:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728731AbeJWBth (ORCPT ); Mon, 22 Oct 2018 21:49:37 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:41164 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727877AbeJWBth (ORCPT ); Mon, 22 Oct 2018 21:49:37 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1qgfjry; Mon, 22 Oct 2018 19:30:10 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229410; bh=DvsKvToV8rNLNcM58/t/dOylA7ZRdlxwc4fLGXCKzgs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=E7PlTAoCEO9rSRU/63qJ4YpBtR014772dqtlfZl1+uBDSRtMzgs5vaCkuYYI749qi UvLjXHZdhyTmUR46wWtTTqzhBpAEqQMoL29ehJlqQaPbGezIHhiD6A5WRhyphQ1jji q3OcNR+psgehPjgmUAtePwaQkM/pdss75ZxxwSRQZ7fN5wpE+V8jGQXCHWaSKuWHCX sARaP8Y4QzNi42P50UAE7k7BahGKrLhSQpehNfYbJoprIq1BXczMJAoii+l2vagRwI W/kp55/5O/KdsPr6hypWJrx5q/UKUfvcy469YQowRxlQS5NGaz0QPA0XsiDjH4Sivc WCbBKRHdPvbow== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==:17 a=yPCof4ZbAAAA:8 a=CeMkgl4g4FRAAXCLeEgA: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: Mon, 22 Oct 2018 19:29:37 +0200 Message-Id: <20181022172938.7936-8-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfGDWjgNbXbf3OBVhZYY1SNXx0zJ+aeGIr4xevcNmkDBHWvZIXRICLvotT5goHlP+azFdky998YxTXym1l5/C4IrynQDpF8e5k28VzA6T5PnHxCIeNvmI LfZT+XMQHhijHJ4WjeKfVXA34dVMzDRu8FUGuM8cFJF0PvoQ1cf+xGoNipH08AM9NgY1TIgQg3K9karYwNFSRPWcfBBFwoPjkz6G70O9p2hONawTHRQooEfr oP0AFRi2ZSUtWX2eCObhDCiORXa5B+uzoSwmK0XZh1o= 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 Reviewed-by: Daniel Kiper --- grub-core/fs/btrfs.c | 159 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ea97f0502..965888da4 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,138 @@ 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; + + /* The struct grub_btrfs_chunk_stripe array lives behind struct + grub_btrfs_chunk_item. */ + 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) + { + 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 + { + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T + " READ 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: total %" + PRIuGRUB_UINT64_T ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + + /* We have enough disks. So, 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 +875,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 +1058,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) { 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) + else + 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; + } + if (!err) break; } if (err) From patchwork Mon Oct 22 17:29:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652295 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 A4A3A14BB for ; Mon, 22 Oct 2018 17:31:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE9B829187 for ; Mon, 22 Oct 2018 17:31:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ACB7D29195; Mon, 22 Oct 2018 17:31:13 +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 28E972918B for ; Mon, 22 Oct 2018 17:31:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728820AbeJWBuh (ORCPT ); Mon, 22 Oct 2018 21:50:37 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52199 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728758AbeJWBug (ORCPT ); Mon, 22 Oct 2018 21:50:36 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1qgfjs8; Mon, 22 Oct 2018 19:30:10 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229410; bh=rRN3WhXbdv8hpdGqHvWXTQsfzlxWcpsHLNi1isTwRYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cKRFc21C0QqQynXpl/nbzhtLshMGc3nEEPdWPO4yLOYuvSN2ItBIJKi3b7bD7Ekxr HcEW86UQ2y8IFftDmMcnNb+34dkFg3b6qlll2WOPS9JlSI4SuAtaKHibkznIoP03p1 DTjBrCGfj/J0KqKJWglxKTRAbYTmrVgsDhQaIZQFdg3lZpIJr4qzaFBD087sh/7KlS pVlODqujOwaiEx1vmyYe2oJA4U102YOi2XmKWqMPlI9kLUHxk9RyDcPUPxSpZJJ4Gw ZzA1OjbBgixLOuUV6yNKhv3MIiWkrLpCBG0ze+smqRANSVUCGoPAFOZsrQe+1HNLvV EIb+ixYPqB6Tg== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==: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: Mon, 22 Oct 2018 19:29:38 +0200 Message-Id: <20181022172938.7936-9-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfGDWjgNbXbf3OBVhZYY1SNXx0zJ+aeGIr4xevcNmkDBHWvZIXRICLvotT5goHlP+azFdky998YxTXym1l5/C4IrynQDpF8e5k28VzA6T5PnHxCIeNvmI LfZT+XMQHhijHJ4WjeKfVXA34dVMzDRu8FUGuM8cFJF0PvoQ1cf+xGoNipH08AM9NgY1TIgQg3K9karYwNFSRPWcfBBFwoPjkz6G70O9p2hONawTHRQooEfr oP0AFRi2ZSUtWX2eCObhDCiORXa5B+uzoSwmK0XZh1o= 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 Mon Oct 22 17:29:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10652287 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 570B7109C for ; Mon, 22 Oct 2018 17:30:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6271E29116 for ; Mon, 22 Oct 2018 17:30:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5C4B32911B; Mon, 22 Oct 2018 17:30: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 E43292911B for ; Mon, 22 Oct 2018 17:30:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728742AbeJWBth (ORCPT ); Mon, 22 Oct 2018 21:49:37 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:39350 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728566AbeJWBth (ORCPT ); Mon, 22 Oct 2018 21:49:37 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id Ee1mgPeG98KmnEe1qgfjsG; Mon, 22 Oct 2018 19:30:11 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1540229411; bh=crGM2SK0YdtsDWwusnwq41BdYFqwzW/7F6pgVdNQG5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Yhrg1jwyKptipFzRAwdTIs6eSrWpBbNiBzJauJHob7c5aQ1dTJBqhwvQ/fwJly/mq WkzXYAP7RejxmYcZbmxi6vHXb3YCV3hFjWg3SEd98theDma+uM2cZxumfA+u8TSvXW 8NAcfqNH5fUD8IP+TezZvEQLJw5ZJ95wBj1Vf7PanptYwj/kkQALeLyOKW56TsZeA2 Ygys0HPhz3Nlr3GqqerRW5gk31wh+956Zo9KF2MIjHtG4VuP0XR7warHMfAbBVXFBJ ikBFycnqgZq5oSNOX78H+a55JqtM5ii35hI1UslYsDEtyf20Efo75LS2tKID+LCrV8 4sFajBOlXBsGw== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==:17 a=yPCof4ZbAAAA:8 a=X3SSP0U7tytczLKPzpUA:9 a=jz4e0QIFRHllRBIp:21 a=OcE7XaoNLwjyrDjE: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: Mon, 22 Oct 2018 19:29:39 +0200 Message-Id: <20181022172938.7936-10-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181022172938.7936-1-kreijack@libero.it> References: <20181022172938.7936-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfM0PvmGUcMJmuHaXzLO8Ua+zt4xT86fa58ssbKW94yq78QUi4OjcXse0tc4Qsr2tUBmo2IV/raYcFb9By1rdsqM3d+asJ2PhuQ9qCSSNhD1LlP6/7TCD FhBoicsH3zNIUttmIrKQSCvkhD/aNLThXJqibwJUvYAQiLtzO8OjTPC+a7KaXuJhaSMKzgeI0A6tyGEAirnL0qc59tu+WFSCT99mH6SI2liWqArs/WTitPw0 PUvuLo3pPAKYguOFH3HT722qUO5oxkpudfmUDzojaew= 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 965888da4..7c316fd33 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+"); @@ -701,11 +702,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); @@ -776,6 +802,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 RAID 6: 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: total %" @@ -786,7 +821,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: @@ -876,9 +911,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) { @@ -1027,6 +1064,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" can be negative, eg. when high + * == 0 leading to an incorrect computation. + * "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; @@ -1067,7 +1115,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); } else for (i = 0; i < redundancy; i++)