From 5ed554f014d10a216fa37242c2e676f89e5fb6b8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 1 May 2012 15:05:26 +0200 Subject: [PATCH] Handle RAIDZ on non-512B sectors. * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member max_children_ashift. (fill_vdev_info_real): Fill max_children_ashift. (read_device): Use max_children_ashift. --- ChangeLog | 9 +++++++++ grub-core/fs/zfs/zfs.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e37c0a59..ec61fa063 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-05-01 Vladimir Serbinenko + + Handle RAIDZ on non-512B sectors. + + * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member + max_children_ashift. + (fill_vdev_info_real): Fill max_children_ashift. + (read_device): Use max_children_ashift. + 2012-05-01 Vladimir Serbinenko * grub-core/fs/fshelp.c (grub_fshelp_find_file): Fix memory leak. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 0bbbe54e7..a3486ef9b 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -194,6 +194,7 @@ struct grub_zfs_device_desc grub_uint64_t id; grub_uint64_t guid; unsigned ashift; + unsigned max_children_ashift; /* Valid only for non-leafs. */ unsigned n_children; @@ -630,6 +631,8 @@ fill_vdev_info_real (struct grub_zfs_data *data, } } + fill->max_children_ashift = 0; + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 || grub_strcmp (type, VDEV_TYPE_FILE) == 0) { @@ -706,6 +709,8 @@ fill_vdev_info_real (struct grub_zfs_data *data, grub_free (type); return err; } + if (fill->children[i].ashift > fill->max_children_ashift) + fill->max_children_ashift = fill->children[i].ashift; } grub_free (type); return GRUB_ERR_NONE; @@ -1274,7 +1279,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, bsize = s / (desc->n_children - desc->nparity); if (desc->nparity == 1 - && ((offset >> (desc->ashift + 11)) & 1) == c) + && ((offset >> (desc->ashift + 20 - desc->max_children_ashift)) + & 1) == c) c++; high = grub_divmod64 ((offset >> desc->ashift) + c, @@ -1342,7 +1348,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, high = grub_divmod64 ((offset >> desc->ashift) + cur_redundancy_pow + ((desc->nparity == 1) - && ((offset >> (desc->ashift + 11)) + && ((offset >> (desc->ashift + 20 + - desc->max_children_ashift)) & 1)), desc->n_children, &devn); err = read_device ((high << desc->ashift)