kern/fs: Honour file->read_hook() in grub_fs_blocklist_read()
Unlike files accessed via a normal file system, the file->read_hook() is not honoured when using blocklist notation. This means that when trying to use a dedicated, 1 KiB, raw partition for the environment block and hence does something like save_env --file=(hd0,gpt9)0+2 X Y Z this fails with "sparse file not allowed", which is rather unexpected, as I've explicitly said exactly which blocks should be used. Adding a little debugging reveals that grub_file_size(file) is 1024 as expected, but total_length is 0, simply because the callback was never invoked, so blocklists is an empty list. Fix that by honouring the ->read_hook() set by the caller, also when a "file" is specified with blocklist notation. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
792132c72a
commit
4f6c460917
@ -215,12 +215,15 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
grub_disk_addr_t sector;
|
||||
grub_off_t offset;
|
||||
grub_ssize_t ret = 0;
|
||||
grub_disk_t disk = file->device->disk;
|
||||
|
||||
if (len > file->size - file->offset)
|
||||
len = file->size - file->offset;
|
||||
|
||||
sector = (file->offset >> GRUB_DISK_SECTOR_BITS);
|
||||
offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1));
|
||||
disk->read_hook = file->read_hook;
|
||||
disk->read_hook_data = file->read_hook_data;
|
||||
for (p = file->data; p->length && len > 0; p++)
|
||||
{
|
||||
if (sector < p->length)
|
||||
@ -232,9 +235,12 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
>> GRUB_DISK_SECTOR_BITS) > p->length - sector)
|
||||
size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset;
|
||||
|
||||
if (grub_disk_read (file->device->disk, p->offset + sector, offset,
|
||||
if (grub_disk_read (disk, p->offset + sector, offset,
|
||||
size, buf) != GRUB_ERR_NONE)
|
||||
return -1;
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
ret += size;
|
||||
len -= size;
|
||||
@ -244,6 +250,8 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
|
||||
else
|
||||
sector -= p->length;
|
||||
}
|
||||
disk->read_hook = NULL;
|
||||
disk->read_hook_data = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user