From patchwork Thu Oct 18 17:55: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: 10647711 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 C8A47181D for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA1A328E84 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE3D528F25; Thu, 18 Oct 2018 17:55:56 +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 3F9B528E84 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728348AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:44872 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726507AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWWgOdUf; Thu, 18 Oct 2018 19:55:52 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885352; bh=CUQsVc80lMhXUTtNLr7dJdbhnCqVLGPeIgG4l+HtXx0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=iZkOnvw7MUXLdtcqqKmbWFLnavShkOIRi7k/iWFoh10+HHV4TNb2QiIlIcMllRTqp Jbf27QpnkY+53HZ7sHTE+TEDMDwA7DdckODO7QmfgVIz0rbYsqP93FlerbBEA0VrYr sgc73WHf39jZXweJrmdDg/3vRh5k4P5VQjVvGPHDiMfbu2j0immhuRHjrOhha8Skew tUO2yfjHmJlTlj5Z5lRx8PAGDBCzQeDKimNReWD1XjcFXSHvX66mI9hiXlebkp4uuK DJqXCB5q0hR0SXXpHmhwpj3+KP39Qm1mBr4lxLiYhhLleIn4kfYksELAPE9iHrizAd eZURlSD3oW9hw== 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: Thu, 18 Oct 2018 19:55:33 +0200 Message-Id: <20181018175541.9532-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfNL1fYobHY7OOyWh4B9XlEOJUJi9iSvu/GgQov9RUz9u22NgLKD6V8GsDuzix3QOuQqUIJ6Qj0tPO56+X4WymHJ1yrwcTLXAOfrplRXQ+T/kPu//lsu2 rtP6E+e0dUfaoFXX4o1UXXKhELGQtsw/877aCpYLZMiEMxXcpSZvILzgS0t8ik4zXKFoJ14bD39O0aJGtqqgvuakzkCDSANWs+Khn3myc3nHzM5yZtPZ3O5G 28rlFCAY/IA6UUUrFpbnMS8s/2B6Jhn8fkED/xg18vc= 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 Thu Oct 18 17:55: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: 10647709 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 BBD1A1508 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AAE2028E65 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9DE4328EA9; Thu, 18 Oct 2018 17:55:56 +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 1A81F28E65 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728340AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52986 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728327AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWWgOdUm; Thu, 18 Oct 2018 19:55:52 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885352; bh=rBCv2aOPJtIw+dlR3woR1f4IXLbCloRw2O+TGV2oeWQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pQpsuX9YOcr39A2TUBS8LGc7hFNdwAeHjP06j2GbpPGLVBOYRp2XAzi7hYxhZrCsr 84TQ7QNKOMUZjJc2ihzPEx9KyiOBgaFHUDtFWbjlZYklkbT9GZ57Ga78yExFjxUILt fmLml5MGwLF3XTJzidfya8iWZ3wGLlF06CIagpP3FIi6cpcZpNQnEqsvMp7NB4WrpQ YOEri8ZUjHas2HgIpg2Mbog+GcPmvOU/s8T4YSZiPtingipd93UVHKOGYCpkxoPxuU Dfyk9xXWBa8528nSuEgJKD+rwES+8yE6ZaxeThOj/zePVk0mwcRwuVVLHWIwUiEjiW sd0vBtqDxxLbA== 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: Thu, 18 Oct 2018 19:55:34 +0200 Message-Id: <20181018175541.9532-3-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfNL1fYobHY7OOyWh4B9XlEOJUJi9iSvu/GgQov9RUz9u22NgLKD6V8GsDuzix3QOuQqUIJ6Qj0tPO56+X4WymHJ1yrwcTLXAOfrplRXQ+T/kPu//lsu2 rtP6E+e0dUfaoFXX4o1UXXKhELGQtsw/877aCpYLZMiEMxXcpSZvILzgS0t8ik4zXKFoJ14bD39O0aJGtqqgvuakzkCDSANWs+Khn3myc3nHzM5yZtPZ3O5G 28rlFCAY/IA6UUUrFpbnMS8s/2B6Jhn8fkED/xg18vc= 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 Thu Oct 18 17:55: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: 10647745 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 EC53215E2 for ; Thu, 18 Oct 2018 18:15:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE5B628CE6 for ; Thu, 18 Oct 2018 18:15:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D00AF28ED3; Thu, 18 Oct 2018 18:15:05 +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 7160328CE6 for ; Thu, 18 Oct 2018 18:15:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728633AbeJSB6o (ORCPT ); Thu, 18 Oct 2018 21:58:44 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:56338 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727754AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWXgOdUv; Thu, 18 Oct 2018 19:55:53 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885353; bh=R1USxw4Z/+qNRKevXadq2m1pnIUHt6KDSJ0uysAgReQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AyJZqRKFQ3Bt3NJBszJSn9eFeqC0J88nusZMTq6fxnCIXmMtGUjBfPkH3S9p5oEcS Makl2qqBZtAkdy+PvzAsiGiyIOwrJsncpWLeILMRX7Ohj2vzsApHgKE9r3roYq3nPs 21WUem3VMVnRL/A6iMU6jDg9Hx4qEPdsjwQBW7u+G2kMcc+lMWSzfDJfWJ1c8EdkrA nRG8lMVySZa0BF1IoQnu9/g3J0A0lvsXwslj++KIYPIXucTbvN2pASul31IfaMPBrv DQFWJj1kEd6zt56UFqEJ1ageZ1Ml1l8AJG/JZWx0DmiDCbqRDVv1AqaLLvF9F8oEqS 0dGDpEAWF2RaA== 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: Thu, 18 Oct 2018 19:55:35 +0200 Message-Id: <20181018175541.9532-4-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKA6V6PKlekOD9Xx3BgJQdYoZIsHhxncncqu7jLtqWvEsiVogfu1H92MLiQbTtt9HjZJhtYm4tUgQYEchll6c5BLL+9qYzxNirSzF0KT1ErLgBOh9x38 5Ir5fpb0ZxA5F8q7FDDzf4Pq4/dPxFTuclskxMOZRmj0fVmHs+cFjjoyObV9uIBEIiFzAjW9WxPtrauquePY6FgUsrZdyxDAu6a4d20GtH4kuLTDZHo/uwnC sMBtTZuGEWCZ3UsF24TlbU+01MLtO3hAjSkBaHOoXqQ= 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 Thu Oct 18 17:55: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: 10647713 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 907E517DE for ; Thu, 18 Oct 2018 17:55:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8199728E65 for ; Thu, 18 Oct 2018 17:55:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 75B5928E87; Thu, 18 Oct 2018 17:55:57 +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 D18A728E65 for ; Thu, 18 Oct 2018 17:55:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728354AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52820 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728331AbeJSB57 (ORCPT ); Thu, 18 Oct 2018 21:57:59 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWXgOdV4; Thu, 18 Oct 2018 19:55:53 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885353; bh=d6AQBEgz0RNa61javY0WhaXZw6LSZcXpCmyDysS3KyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WE5TgxFI7iF+lNU3BkD5Zrk9ECxcTnMRg1HZsUvQA+hNdUF89mYdWwqQQV7j2CsWd Zr7kfn3tKpbZm8FGkq+dJiQzdBSit0/HVjJuHns405pc0qhZoNnyAvkBcWk5qvbd92 fbtr5YN99+ATJTjxNVBhpfVrwM749rxHmKMV8AzOnrF8tWawSJas3aqkpVRTtls9vW qck4LAgasgHYGI+g9ZsZLIp33YvJaZ+6tEZ0aDPket7HPXAVdv8lOFDrKeg4uyOWCR keMQyeWz9sLijDNC9y8+Uu/RDxL0OtYZ3DlmhK6t9wlKDV98/S3U1hutzWk1UXiSj/ VYRS0vVLbdc8w== 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: Thu, 18 Oct 2018 19:55:36 +0200 Message-Id: <20181018175541.9532-5-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKA6V6PKlekOD9Xx3BgJQdYoZIsHhxncncqu7jLtqWvEsiVogfu1H92MLiQbTtt9HjZJhtYm4tUgQYEchll6c5BLL+9qYzxNirSzF0KT1ErLgBOh9x38 5Ir5fpb0ZxA5F8q7FDDzf4Pq4/dPxFTuclskxMOZRmj0fVmHs+cFjjoyObV9uIBEIiFzAjW9WxPtrauquePY6FgUsrZdyxDAu6a4d20GtH4kuLTDZHo/uwnC sMBtTZuGEWCZ3UsF24TlbU+01MLtO3hAjSkBaHOoXqQ= 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 Thu Oct 18 17:55: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: 10647717 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 D44841508 for ; Thu, 18 Oct 2018 17:55:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C72B328E65 for ; Thu, 18 Oct 2018 17:55:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBD3228E87; Thu, 18 Oct 2018 17:55:58 +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 6A27828E65 for ; Thu, 18 Oct 2018 17:55:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728362AbeJSB6A (ORCPT ); Thu, 18 Oct 2018 21:58:00 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:40315 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728333AbeJSB6A (ORCPT ); Thu, 18 Oct 2018 21:58:00 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWXgOdVG; Thu, 18 Oct 2018 19:55:53 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885353; bh=JgAMnYNIHiju5Rd63/hYsQIu/hu1AUy86GiQKVcTUZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=sA4VQyPrD/6EN/ECp3t+m2gj/Rtq2rEk1kdXAttSJ6zaraZO6BqaOVuVvyLcu6kep HOxe4ex+a8oP+OVslukZtCK/+7X2G0wpHwWorZ39dpCZYasBVYEbrikxyTtoYI3j87 oqiB/xKL2HK4w0cNQruuYdYzVY7aQTCM5UmKHZLCP616KxqvC21M2nYt6fgsLH5ghe vSEMfO0X1f1Qo9XRp7xuGsMT7X9p1wTKr1nntmY633SzD3kJRvN0GB7k9UZCAS6ZAa 2C8zNkEvtT6zaqg5h9WKlhpD/TfHxtcX4Q2vWQBpZPVcxLqbU21wYVQUXGlr5qqpXu /yRsnbAb1mi7g== 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: Thu, 18 Oct 2018 19:55:37 +0200 Message-Id: <20181018175541.9532-6-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfKA6V6PKlekOD9Xx3BgJQdYoZIsHhxncncqu7jLtqWvEsiVogfu1H92MLiQbTtt9HjZJhtYm4tUgQYEchll6c5BLL+9qYzxNirSzF0KT1ErLgBOh9x38 5Ir5fpb0ZxA5F8q7FDDzf4Pq4/dPxFTuclskxMOZRmj0fVmHs+cFjjoyObV9uIBEIiFzAjW9WxPtrauquePY6FgUsrZdyxDAu6a4d20GtH4kuLTDZHo/uwnC sMBtTZuGEWCZ3UsF24TlbU+01MLtO3hAjSkBaHOoXqQ= 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 Thu Oct 18 17:55: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: 10647743 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 81A7C109C for ; Thu, 18 Oct 2018 18:14:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 739CF28CE6 for ; Thu, 18 Oct 2018 18:14:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6696028ED3; Thu, 18 Oct 2018 18:14:47 +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 0001528CE6 for ; Thu, 18 Oct 2018 18:14:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728739AbeJSB67 (ORCPT ); Thu, 18 Oct 2018 21:58:59 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:44872 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726463AbeJSB67 (ORCPT ); Thu, 18 Oct 2018 21:58:59 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWYgOdVN; Thu, 18 Oct 2018 19:55:54 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885354; bh=1emG1V12wB2MYi1b9SVurpKNgMWp+bRbTFT100nQPQQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=g/kWlKH9lIvVXfNmJ38d2+gSpOPodJQfwm71gyomaasrVin0RLLlky8RGazPs1WD0 4gpoaj6fJ6VEXfYbuTb4CwqtxVBuS5/CiqOtlwVqMR2oMc41e86aECUld3J4cd+Hy9 u6pLuRJTYdYct6es4Q6bt6WVIfsZPvS0iNHX/olhM2Mg80qikiuvEmi3w2HktYeeqR wWFjkhhEzCN/pWeb5OVLQMrFRgxtXAz/hBevREMJKJArOt3oKbmMguSG/4f92Srvk9 C1vAzFUviULfSlDMHB7+ACk0uXhN0F1POq7/m9LGK4VK3PsKOmQ8SqixpuwmZY8HLm DHipfyOnLKe6Q== 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: Thu, 18 Oct 2018 19:55:38 +0200 Message-Id: <20181018175541.9532-7-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfAFQAnepgIR3LhuFW2Fjl/FIaf3qkFj8u+brT0BLCHmZmfrQ0Is8/YzEiDOyDcOWLmOliFfBjP3hdPCkOTpNj9t6ngE1Frezq815uyiL8zmlFfhWRiQM 9XHOg4zC5DjSxFGgd4dYm+YZNumU9SeaMgBkP5cSqXz4i4vvunrcN5EYfG2rHBEh6+FLFpOJUbmkE0wiudJiTROxuf7NcquoA5tCTxokGuRBO0f/ynufzR+X 5J+6qdpvHaoWib/vaCOHQFuippeJekSSWfz0NAOm7S4= 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 Thu Oct 18 17:55: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: 10647719 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 D24CA1508 for ; Thu, 18 Oct 2018 17:56:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C364F28E87 for ; Thu, 18 Oct 2018 17:56:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6DBF28EA9; Thu, 18 Oct 2018 17:56:58 +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 3275128E87 for ; Thu, 18 Oct 2018 17:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbeJSB7A (ORCPT ); Thu, 18 Oct 2018 21:59:00 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:56338 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728728AbeJSB7A (ORCPT ); Thu, 18 Oct 2018 21:59:00 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWYgOdVT; Thu, 18 Oct 2018 19:55:54 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885354; bh=irh2ZmtKhbCKDmrZLPHnQiOjhCO8A2q6xbOgii2YIdM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=swKFuv4xTS9GjsJ4HPpP3u+DGynK1cA35pXTfAXQs7J3sSDUZQReMcv8Ktnt3C5os rnGjS9vivh0qB0O4JMNYyzxiQXlHmnIiptnCvvzsyBMzO3gieCjnqTeP5keTHheIt2 6f30DXyXeFKrt5pK5YQ8egPQm7LiNjXzT4ITdWJ7/R5SGsideeeuiVyPr4m7kzh49o zdYBsTuHOtXLBfHQHu0PC5AILDSoMBLc/8HiEBpM+t2TCYphtis+4TyXXJR63+oQd6 MuQq8DZo7Mr21PdJOv0cmk3T2U3DRHUp1s8/6b+39wRaLErTWnjV3gxo4VKDuOcCml Ziv4jy7AMqZDw== X-CNFS-Analysis: v=2.3 cv=ZbLMyfdA c=1 sm=1 tr=0 a=nqgIlLay6LNLiZJCVl9G2Q==:117 a=nqgIlLay6LNLiZJCVl9G2Q==:17 a=6S_NExIckfwTSdTspAoA: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, 18 Oct 2018 19:55:39 +0200 Message-Id: <20181018175541.9532-8-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfAFQAnepgIR3LhuFW2Fjl/FIaf3qkFj8u+brT0BLCHmZmfrQ0Is8/YzEiDOyDcOWLmOliFfBjP3hdPCkOTpNj9t6ngE1Frezq815uyiL8zmlFfhWRiQM 9XHOg4zC5DjSxFGgd4dYm+YZNumU9SeaMgBkP5cSqXz4i4vvunrcN5EYfG2rHBEh6+FLFpOJUbmkE0wiudJiTROxuf7NcquoA5tCTxokGuRBO0f/ynufzR+X 5J+6qdpvHaoWib/vaCOHQFuippeJekSSWfz0NAOm7S4= 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 | 161 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ea97f0502..b277f2904 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,140 @@ 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) + { + 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: 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 +877,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 +1060,29 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", addr); - for (i = 0; i < redundancy; i++) + if (is_raid56) { 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 Thu Oct 18 17:55:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10647721 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 BD5421508 for ; Thu, 18 Oct 2018 17:56:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE13D28E87 for ; Thu, 18 Oct 2018 17:56:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A073928EA9; Thu, 18 Oct 2018 17:56:59 +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 1DB1928E87 for ; Thu, 18 Oct 2018 17:56:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728757AbeJSB7C (ORCPT ); Thu, 18 Oct 2018 21:59:02 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52820 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728731AbeJSB7A (ORCPT ); Thu, 18 Oct 2018 21:59:00 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWYgOdVa; Thu, 18 Oct 2018 19:55:55 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885355; bh=rRN3WhXbdv8hpdGqHvWXTQsfzlxWcpsHLNi1isTwRYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Lmzzxw0OXMIX2mW32UMDkDH9u0PLj2D6MjzqHREGa2vwq4X0PnRpElLOdjdyjp85I 3oHsJxB+ZAjhEsxZ6Im0aowFFOK0guRFsZ17fW8jgJ46+z99ikWPs9blUX3G9DLzA0 GyPEMw5EeSW66zjddGb4js0KMr67vjSQJ2HdZfwYEQ/PBihthv53vxy9eZC8nnAUL5 5J5U+WnTFn/yvW63+T7iJWmtjWHHGqQOhu6k58hqsEJ9l1BHdXGfibXUm2MrqcY+nH 99dv9P8JZN2v2Mv0PeSGHDs1F6ZMfFUAt2KR41g+8yFoQRvmHAfXH443UZFaHKo0xv xaQeAwoYedFLA== 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: Thu, 18 Oct 2018 19:55:40 +0200 Message-Id: <20181018175541.9532-9-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfP5/51Tfhwi/29ZzrnTJIZGBic5tmpkSS/d/bH098qIF1N7xAf5yvsWHVCXSsKNN51ymYlPeusWeadoca3wFPlYeK4ayHbeuy380x1qcreUbySOSHhJA ezuxl98UbUN6IMMxeArDiiOxc1MAUFPO26MqOWW9FNFK8msmM0fek/xt8/02ehbn4CP7ZZzeAkw8o17BuzTyo89YGkMLQGfy9O50AEWYlG8UFRrUos3/xuMW UidwpjMm4c74ydEmdfeUSvzFQF0Ht5KZXeQ9cFa9guo= 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 18 17:55:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10647715 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 36F381508 for ; Thu, 18 Oct 2018 17:55:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27CAB28E65 for ; Thu, 18 Oct 2018 17:55:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1C33928E87; Thu, 18 Oct 2018 17:55:58 +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 A72CD28E65 for ; Thu, 18 Oct 2018 17:55:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728369AbeJSB6A (ORCPT ); Thu, 18 Oct 2018 21:58:00 -0400 Received: from smtp-34-i6.italiaonline.it ([213.209.14.34]:52986 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726507AbeJSB6A (ORCPT ); Thu, 18 Oct 2018 21:58:00 -0400 Received: from venice.bhome ([94.38.16.140]) by smtp-34.iol.local with ESMTPA id DCWVgs2H18KmnDCWZgOdVo; Thu, 18 Oct 2018 19:55:55 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539885355; bh=ewgUHr+/sryYtmIv/Spf+tbaSc0Y9WxAYkFfGWWD9hA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cTJN827b7SpF9bWxgJFMGkqOGSHgDCUfw6uWjUroHvkOANxHl2rl+6LeNdO75zoMV EvNqEhpoWM5mXJD3I7dLELDo3pDES2lkAdClHLQ/OmybvCzO4pGGIMTdndtk+BGVQO XxI712/81O0fvRJbz0Zimqbpa7HB8TE5oZmj2FR0uBEMdf47THQZ2P6eT/7L77g0DH FEr5nSNEi4gVEg18mnRqVywze/IDGykgWMwh74McpJm8BMUIrAF887y0LI4t8dH7a4 5IVRwFfQXmOvv3klM30f77iHfr9JxopdxXfSJyI7tneTJENoOQ8k8P/z0w2jD4mxQJ 3kSWB3/Ta6uuw== 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: Thu, 18 Oct 2018 19:55:41 +0200 Message-Id: <20181018175541.9532-10-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018175541.9532-1-kreijack@libero.it> References: <20181018175541.9532-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfP5/51Tfhwi/29ZzrnTJIZGBic5tmpkSS/d/bH098qIF1N7xAf5yvsWHVCXSsKNN51ymYlPeusWeadoca3wFPlYeK4ayHbeuy380x1qcreUbySOSHhJA ezuxl98UbUN6IMMxeArDiiOxc1MAUFPO26MqOWW9FNFK8msmM0fek/xt8/02ehbn4CP7ZZzeAkw8o17BuzTyo89YGkMLQGfy9O50AEWYlG8UFRrUos3/xuMW UidwpjMm4c74ydEmdfeUSvzFQF0Ht5KZXeQ9cFa9guo= 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 b277f2904..9419d313d 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); @@ -778,6 +804,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 %" @@ -788,7 +823,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: @@ -878,9 +913,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) { @@ -1029,6 +1066,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; @@ -1069,7 +1117,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++)