From patchwork Thu Oct 11 18:50:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goffredo Baroncelli X-Patchwork-Id: 10637183 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE658933 for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFC8B2BFCD for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE4902BFCF; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E1742BFD8 for ; Thu, 11 Oct 2018 18:51:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729822AbeJLCTq (ORCPT ); Thu, 11 Oct 2018 22:19:46 -0400 Received: from smtp-33-i6.italiaonline.it ([213.209.14.33]:54034 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729783AbeJLCTo (ORCPT ); Thu, 11 Oct 2018 22:19:44 -0400 Received: from venice.bhome ([94.38.186.31]) by smtp-33.iol.local with ESMTPA id Ag3FgMwlrQGOzAg3GgbXzW; Thu, 11 Oct 2018 20:51:14 +0200 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1539283874; bh=39aL8uXP0JWmXPwp2S+XtwzWoh8psezJRhXBxrAk1vU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=oht47BsUZMGXvzqCGCtRMcS1778l3e6VDuOWn8auVtuh0LNrOQcExuEQ5JZOzAPoi KpgP16409sIE/4fBg1j9M70OhrgEGj2pQfebtLV17YMYSpa8hA9jlsOO3yUkUgU6Uq lLjvqtUeAUkIWMkaQwuOmY6K08NConpLOw2vp8XFrHhR/a5yLx+m0ciATKBenf7ldL SUtcJjwJj4zIPde+HcClfWYdDFudNZp/BxeqXfZWYGgMjpEtnEbU68ChUOMEWU9n9h bF//EM+axd+7DlOsqc9ogAC0gt+Tq3dGIMnagO49/LkamvRhFdufs9dZ2DMFlDC8TN FR8HElfYR3D3g== X-CNFS-Analysis: v=2.3 cv=OvCeNB3t c=1 sm=1 tr=0 a=I+JNyrl7/zjgsFWlY3jFdA==:117 a=I+JNyrl7/zjgsFWlY3jFdA==:17 a=yPCof4ZbAAAA:8 a=10E2XUvmTi6NHy_q8tMA:9 a=NMA0j3cErYIjDTae:21 a=Uw-O9MEIAZd7h_om:21 From: Goffredo Baroncelli To: grub-devel@gnu.org Cc: Daniel Kiper , linux-btrfs@vger.kernel.org, Goffredo Baroncelli Subject: [PATCH 1/9] btrfs: Add support for reading a filesystem with a RAID 5 or RAID 6 profile. Date: Thu, 11 Oct 2018 20:50:55 +0200 Message-Id: <20181011185103.23146-2-kreijack@libero.it> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181011185103.23146-1-kreijack@libero.it> References: <20181011185103.23146-1-kreijack@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfB7r80I6B/TEVG9LJ70otK81y11lHjrb4zovuSXGQQOHlAqDr+PKfbm0hvVeB8RyuOopAxLsMNNUmMDCH3W9Ad/5N5PCJCR1zIQMYhWEefoEa84A14Ba fribfUjH2tDYs/uexG+h8Q+BsMz/MlOq7MKNJ8/Rv+MHx6g+g5bJMU05OEDBrFXVYyIbr/MK/3Y94ahfvXEjGfUnSsSdiR7hz65V6rTUspdOVFKR5WYARnXs iV/8iYE4ul9HJp7pG0YTFFIeQ+qn34L3hvbjLlGj+6k= Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Goffredo Baroncelli Signed-off-by: Goffredo Baroncelli Signed-off-by: Daniel Kiper --- grub-core/fs/btrfs.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index be195448d..933a57d3b 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -119,6 +119,8 @@ struct grub_btrfs_chunk_item #define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 #define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 +#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 +#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; grub_uint16_t nsubstripes; @@ -764,6 +766,77 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, stripe_offset = low + chunk_stripe_length * high; csize = chunk_stripe_length - low; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID5: + case GRUB_BTRFS_CHUNK_TYPE_RAID6: + { + grub_uint64_t nparities, stripe_nr, high, low; + + redundancy = 1; /* no redundancy for now */ + + if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) + { + grub_dprintf ("btrfs", "RAID5\n"); + nparities = 1; + } + else + { + grub_dprintf ("btrfs", "RAID6\n"); + nparities = 2; + } + + /* + * RAID 6 layout consists of several stripes spread over + * the disks, e.g.: + * + * Disk_0 Disk_1 Disk_2 Disk_3 + * A0 B0 P0 Q0 + * Q1 A1 B1 P1 + * P2 Q2 A2 B2 + * + * Note: placement of the parities depend on row number. + * + * Pay attention that the btrfs terminology may differ from + * terminology used in other RAID implementations, e.g. LVM, + * dm or md. The main difference is that btrfs calls contiguous + * block of data on a given disk, e.g. A0, stripe instead of chunk. + * + * The variables listed below have following meaning: + * - stripe_nr is the stripe number excluding the parities + * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), + * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), + * - stripen is the disk number in a row (0 for A0, Q1, P2, + * 1 for B0, A1, Q2, etc.), + * - off is the logical address to read, + * - chunk_stripe_length is the size of a stripe (typically 64 KiB), + * - nstripes is the number of disks in a row, + * - low is the offset of the data inside a stripe, + * - stripe_offset is the data offset in an array, + * - csize is the "potential" data to read; it will be reduced + * to size if the latter is smaller, + * - nparities is the number of parities (1 for RAID 5, 2 for + * RAID 6); used only in RAID 5/6 code. + */ + stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); + + /* + * stripen is computed without the parities + * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). + */ + high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); + + /* + * The stripes are spread over the disks. Every each row their + * positions are shifted by 1 place. So, the real disks number + * change. Hence, we have to take current row number modulo + * nstripes into account (0 for A0, 1 for A1, 2 for A2, etc.). + */ + grub_divmod64 (high + stripen, nstripes, &stripen); + + stripe_offset = low + chunk_stripe_length * high; + csize = chunk_stripe_length - low; + break; } default: