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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-05-01 15:05:26 +02:00
parent ddc583571e
commit 5ed554f014
2 changed files with 18 additions and 2 deletions

View file

@ -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> 2012-05-01 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/fshelp.c (grub_fshelp_find_file): Fix memory leak. * grub-core/fs/fshelp.c (grub_fshelp_find_file): Fix memory leak.

View file

@ -194,6 +194,7 @@ struct grub_zfs_device_desc
grub_uint64_t id; grub_uint64_t id;
grub_uint64_t guid; grub_uint64_t guid;
unsigned ashift; unsigned ashift;
unsigned max_children_ashift;
/* Valid only for non-leafs. */ /* Valid only for non-leafs. */
unsigned n_children; 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 if (grub_strcmp (type, VDEV_TYPE_DISK) == 0
|| grub_strcmp (type, VDEV_TYPE_FILE) == 0) || grub_strcmp (type, VDEV_TYPE_FILE) == 0)
{ {
@ -706,6 +709,8 @@ fill_vdev_info_real (struct grub_zfs_data *data,
grub_free (type); grub_free (type);
return err; return err;
} }
if (fill->children[i].ashift > fill->max_children_ashift)
fill->max_children_ashift = fill->children[i].ashift;
} }
grub_free (type); grub_free (type);
return GRUB_ERR_NONE; 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); bsize = s / (desc->n_children - desc->nparity);
if (desc->nparity == 1 if (desc->nparity == 1
&& ((offset >> (desc->ashift + 11)) & 1) == c) && ((offset >> (desc->ashift + 20 - desc->max_children_ashift))
& 1) == c)
c++; c++;
high = grub_divmod64 ((offset >> desc->ashift) + 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) high = grub_divmod64 ((offset >> desc->ashift)
+ cur_redundancy_pow + cur_redundancy_pow
+ ((desc->nparity == 1) + ((desc->nparity == 1)
&& ((offset >> (desc->ashift + 11)) && ((offset >> (desc->ashift + 20
- desc->max_children_ashift))
& 1)), & 1)),
desc->n_children, &devn); desc->n_children, &devn);
err = read_device ((high << desc->ashift) err = read_device ((high << desc->ashift)