]> git.proxmox.com Git - grub2.git/commitdiff
Handle RAIDZ on non-512B sectors.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 1 May 2012 13:05:26 +0000 (15:05 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 1 May 2012 13:05:26 +0000 (15:05 +0200)
* 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
grub-core/fs/zfs/zfs.c

index 1e37c0a59b37860b0f04594a1f5ee06f0188d236..ec61fa063333fd5163da3749993746c737f64ef6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       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  <phcoder@gmail.com>
 
        * grub-core/fs/fshelp.c (grub_fshelp_find_file): Fix memory leak.
index 0bbbe54e78b34f5d3a270ef3a9ca35434f8b7c06..a3486ef9b428a8b7dee4a71fa110e80f95b6f4e6 100644 (file)
@@ -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)