* grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge

chunks.
	* include/grub/err.h (grub_err_t): New enum value GRUB_ERR_BUG.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-18 23:10:19 +02:00
parent 93a777e388
commit 34faa5955a
3 changed files with 28 additions and 10 deletions

View file

@ -1,3 +1,9 @@
2011-04-18 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge
chunks.
* include/grub/err.h (grub_err_t): New enum value GRUB_ERR_BUG.
2011-04-18 Vladimir Serbinenko <phcoder@gmail.com> 2011-04-18 Vladimir Serbinenko <phcoder@gmail.com>
Complete 64-bit division support. Complete 64-bit division support.

View file

@ -588,7 +588,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
grub_uint8_t *ptr; grub_uint8_t *ptr;
struct grub_btrfs_key *key; struct grub_btrfs_key *key;
struct grub_btrfs_chunk_item *chunk; struct grub_btrfs_chunk_item *chunk;
grub_ssize_t csize; grub_uint64_t csize;
grub_err_t err; grub_err_t err;
struct grub_btrfs_key key_out; struct grub_btrfs_key key_out;
int challoc = 0; int challoc = 0;
@ -648,11 +648,18 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
chunk_found: chunk_found:
{ {
grub_uint32_t stripen; grub_uint32_t stripen;
grub_uint32_t stripe_offset; grub_uint64_t stripe_offset;
grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset);
unsigned redundancy = 1; unsigned redundancy = 1;
unsigned i, j; unsigned i, j;
if (grub_le_to_cpu64 (chunk->size) <= off)
{
grub_dprintf ("btrfs", "no chunk\n");
return grub_error (GRUB_ERR_BAD_FS,
"couldn't find the chunk descriptor");
}
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
"+0x%" PRIxGRUB_UINT64_T "+0x%" PRIxGRUB_UINT64_T
" (%d stripes (%d substripes) of %" " (%d stripes (%d substripes) of %"
@ -668,17 +675,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
{ {
case GRUB_BTRFS_CHUNK_TYPE_SINGLE: case GRUB_BTRFS_CHUNK_TYPE_SINGLE:
{ {
grub_uint32_t stripe_length; grub_uint64_t stripe_length;
stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), grub_dprintf ("btrfs", "single\n");
grub_le_to_cpu16 (chunk->nstripes), stripe_length = grub_divmod64_full (grub_le_to_cpu64 (chunk->size),
NULL); grub_le_to_cpu16 (chunk->nstripes),
stripen = grub_divmod64 (off, stripe_length, &stripe_offset); NULL);
stripen = grub_divmod64_full (off, stripe_length, &stripe_offset);
csize = (stripen + 1) * stripe_length - off; csize = (stripen + 1) * stripe_length - off;
break; break;
} }
case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED:
case GRUB_BTRFS_CHUNK_TYPE_RAID1: case GRUB_BTRFS_CHUNK_TYPE_RAID1:
{ {
grub_dprintf ("btrfs", "RAID1\n");
stripen = 0; stripen = 0;
stripe_offset = off; stripe_offset = off;
csize = grub_le_to_cpu64 (chunk->size) - off; csize = grub_le_to_cpu64 (chunk->size) - off;
@ -689,6 +698,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
{ {
grub_uint64_t middle, high; grub_uint64_t middle, high;
grub_uint32_t low; grub_uint32_t low;
grub_dprintf ("btrfs", "RAID0\n");
middle = grub_divmod64 (off, middle = grub_divmod64 (off,
grub_le_to_cpu64 (chunk->stripe_length), grub_le_to_cpu64 (chunk->stripe_length),
&low); &low);
@ -721,12 +731,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data,
break; break;
} }
default: default:
grub_dprintf ("btrfs", "unsupported RAID\n");
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID flags %" PRIxGRUB_UINT64_T, "unsupported RAID flags %" PRIxGRUB_UINT64_T,
grub_le_to_cpu64 (chunk->type)); grub_le_to_cpu64 (chunk->type));
} }
if (csize <= 0) if (csize == 0)
return grub_error (GRUB_ERR_BAD_FS, return grub_error (GRUB_ERR_BUG,
"couldn't find the chunk descriptor"); "couldn't find the chunk descriptor");
if ((grub_size_t) csize > size) if ((grub_size_t) csize > size)
csize = size; csize = size;

View file

@ -55,7 +55,8 @@ typedef enum
GRUB_ERR_TIMEOUT, GRUB_ERR_TIMEOUT,
GRUB_ERR_IO, GRUB_ERR_IO,
GRUB_ERR_ACCESS_DENIED, GRUB_ERR_ACCESS_DENIED,
GRUB_ERR_EXTRACTOR GRUB_ERR_EXTRACTOR,
GRUB_ERR_BUG
} }
grub_err_t; grub_err_t;