On Wed, May 16, 2018 at 08:48:19PM +0200, Goffredo Baroncelli wrote: > 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 old md RAID 6 code already
s/the old md/the md/ > present in grub. > > Signed-off-by: Goffredo Baroncelli <kreij...@inwind.it> > --- > grub-core/fs/btrfs.c | 45 +++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 40 insertions(+), 5 deletions(-) > > diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c > index 5fcaad86f..3d71b954e 100644 > --- a/grub-core/fs/btrfs.c > +++ b/grub-core/fs/btrfs.c > @@ -30,6 +30,7 @@ > #include <grub/i18n.h> > #include <grub/btrfs.h> > #include <grub/crypto.h> > +#include <grub/diskfilter.h> > > GRUB_MOD_LICENSE ("GPLv3+"); > > @@ -695,11 +696,35 @@ rebuild_raid5 (struct raid56_buffer *buffers, > grub_uint64_t nstripes, > csize); > } > > +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; > + > + grub_memcpy(dest, buffers[disk_nr].buf, size); Could we avoid this grub_memcpy() call somehow? > + grub_errno = buffers[disk_nr].data_is_valid ? GRUB_ERR_NONE : > + GRUB_ERR_READ_ERROR; > + return grub_errno; > +} > + > +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, raid6_recover_read_buffer, 0); > +} > + > 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 stripen, > - grub_uint64_t csize, void *buf) > + grub_uint64_t csize, void *buf, grub_uint64_t parities_pos) > { > > struct raid56_buffer *buffers = NULL; > @@ -780,6 +805,15 @@ raid56_read_retry (struct grub_btrfs_data *data, > ret = GRUB_ERR_READ_ERROR; > goto cleanup; > } > + else if (failed_devices > 2 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID6)) > + { > + grub_dprintf ("btrfs", > + "not enough disks for raid6: total %" PRIuGRUB_UINT64_T > + ", missing %" PRIuGRUB_UINT64_T "\n", > + nstripes, failed_devices); > + ret = GRUB_ERR_READ_ERROR; > + goto cleanup; > + } > else > { > grub_dprintf ("btrfs", > @@ -796,7 +830,7 @@ raid56_read_retry (struct grub_btrfs_data *data, > } > else > { > - grub_dprintf ("btrfs", "called rebuild_raid6(), NOT IMPLEMENTED\n"); > + rebuild_raid6 (buffers, nstripes, csize, parities_pos, buf, stripen); > } > > cleanup: > @@ -891,8 +925,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, > grub_disk_addr_t addr, > 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| Space before "|" please? > + GRUB_BTRFS_CHUNK_TYPE_RAID6)); > > if (grub_le_to_cpu64 (chunk->size) <= off) > { > @@ -1089,7 +1124,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, > grub_disk_addr_t addr, > csize, buf); > if (err != GRUB_ERR_NONE) > err = raid56_read_retry (data, chunk, stripe_offset, > - stripen, csize, buf); > + stripen, csize, buf, parities_pos); I am not sure what is parities_pos and where it is initialized. If it is a part of earlier patch but it is not used then I think that it should be a part of this patch. Daniel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel