Rewrite blocklist functions in order to get progress when
reading large extents and decrease amount of blocklist hook calls.
This commit is contained in:
parent
896f913571
commit
cb72aa1809
20 changed files with 220 additions and 181 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2013-11-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Rewrite blocklist functions in order to get progress when
|
||||||
|
reading large extents and decrease amount of blocklist hook calls.
|
||||||
|
|
||||||
2013-11-01 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-11-01 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/term/serial.c (options), (grub_cmd_serial): Fix handling
|
* grub-core/term/serial.c (options), (grub_cmd_serial): Fix handling
|
||||||
|
|
|
@ -62,23 +62,47 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length,
|
||||||
if (ctx->num_sectors > 0)
|
if (ctx->num_sectors > 0)
|
||||||
{
|
{
|
||||||
if (ctx->start_sector + ctx->num_sectors == sector
|
if (ctx->start_sector + ctx->num_sectors == sector
|
||||||
&& offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
|
&& offset == 0 && length >= GRUB_DISK_SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
ctx->num_sectors++;
|
ctx->num_sectors += length >> GRUB_DISK_SECTOR_BITS;
|
||||||
return;
|
sector += length >> GRUB_DISK_SECTOR_BITS;
|
||||||
|
length &= (GRUB_DISK_SECTOR_SIZE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!length)
|
||||||
|
return;
|
||||||
print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
|
print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
|
||||||
ctx->num_sectors = 0;
|
ctx->num_sectors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
|
if (offset)
|
||||||
{
|
{
|
||||||
ctx->start_sector = sector;
|
unsigned l = length + offset;
|
||||||
ctx->num_sectors++;
|
l &= (GRUB_DISK_SECTOR_SIZE - 1);
|
||||||
|
l -= offset;
|
||||||
|
print_blocklist (sector, 0, offset, l, ctx);
|
||||||
|
length -= l;
|
||||||
|
sector++;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (length & (GRUB_DISK_SECTOR_SIZE - 1))
|
||||||
|
{
|
||||||
|
if (length >> GRUB_DISK_SECTOR_BITS)
|
||||||
|
{
|
||||||
|
print_blocklist (sector, length >> GRUB_DISK_SECTOR_BITS, 0, 0, ctx);
|
||||||
|
sector += length >> GRUB_DISK_SECTOR_BITS;
|
||||||
|
}
|
||||||
|
print_blocklist (sector, 0, 0, length & (GRUB_DISK_SECTOR_SIZE - 1), ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
print_blocklist (sector, 0, offset, length, ctx);
|
{
|
||||||
|
ctx->start_sector = sector;
|
||||||
|
ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
|
|
@ -259,10 +259,28 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
||||||
for (p = blocklists; p; p = p->next)
|
for (p = blocklists; p; p = p->next)
|
||||||
{
|
{
|
||||||
struct blocklist *q;
|
struct blocklist *q;
|
||||||
|
/* Check if any pair of blocks overlap. */
|
||||||
for (q = p->next; q; q = q->next)
|
for (q = p->next; q; q = q->next)
|
||||||
{
|
{
|
||||||
/* Check if any pair of blocks overlap. */
|
grub_disk_addr_t s1, s2;
|
||||||
if (p->sector == q->sector)
|
grub_disk_addr_t e1, e2, t;
|
||||||
|
|
||||||
|
s1 = p->sector;
|
||||||
|
e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||||
|
|
||||||
|
s2 = q->sector;
|
||||||
|
e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
|
||||||
|
|
||||||
|
if (s2 > s1)
|
||||||
|
{
|
||||||
|
t = s2;
|
||||||
|
s2 = s1;
|
||||||
|
s1 = t;
|
||||||
|
t = e2;
|
||||||
|
e2 = e1;
|
||||||
|
e1 = t;
|
||||||
|
}
|
||||||
|
if (e1 > s2)
|
||||||
{
|
{
|
||||||
/* This might be actually valid, but it is unbelievable that
|
/* This might be actually valid, but it is unbelievable that
|
||||||
any filesystem makes such a silly allocation. */
|
any filesystem makes such a silly allocation. */
|
||||||
|
@ -286,9 +304,18 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
||||||
part_start = grub_partition_get_start (disk->partition);
|
part_start = grub_partition_get_start (disk->partition);
|
||||||
|
|
||||||
buf = grub_envblk_buffer (envblk);
|
buf = grub_envblk_buffer (envblk);
|
||||||
|
char *blockbuf = NULL;
|
||||||
|
grub_size_t blockbuf_len = 0;
|
||||||
for (p = blocklists, index = 0; p; index += p->length, p = p->next)
|
for (p = blocklists, index = 0; p; index += p->length, p = p->next)
|
||||||
{
|
{
|
||||||
char blockbuf[GRUB_DISK_SECTOR_SIZE];
|
if (p->length > blockbuf_len)
|
||||||
|
{
|
||||||
|
grub_free (blockbuf);
|
||||||
|
blockbuf_len = 2 * p->length;
|
||||||
|
blockbuf = grub_malloc (blockbuf_len);
|
||||||
|
if (!blockbuf)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_disk_read (disk, p->sector - part_start,
|
if (grub_disk_read (disk, p->sector - part_start,
|
||||||
p->offset, p->length, blockbuf))
|
p->offset, p->length, blockbuf))
|
||||||
|
@ -340,10 +367,6 @@ save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length,
|
||||||
struct grub_cmd_save_env_ctx *ctx = data;
|
struct grub_cmd_save_env_ctx *ctx = data;
|
||||||
struct blocklist *block;
|
struct blocklist *block;
|
||||||
|
|
||||||
if (offset + length > GRUB_DISK_SECTOR_SIZE)
|
|
||||||
/* Seemingly a bug. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
block = grub_malloc (sizeof (*block));
|
block = grub_malloc (sizeof (*block));
|
||||||
if (! block)
|
if (! block)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -35,9 +35,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
static void
|
static void
|
||||||
read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
|
read_progress (grub_disk_addr_t sector __attribute__ ((unused)),
|
||||||
unsigned offset __attribute__ ((unused)),
|
unsigned offset __attribute__ ((unused)),
|
||||||
unsigned len __attribute__ ((unused)),
|
unsigned len,
|
||||||
void *data __attribute__ ((unused)))
|
void *data __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
|
for (; len >= GRUB_DISK_SECTOR_SIZE; len -= GRUB_DISK_SECTOR_SIZE)
|
||||||
|
grub_xputs (".");
|
||||||
|
if (len)
|
||||||
grub_xputs (".");
|
grub_xputs (".");
|
||||||
grub_refresh ();
|
grub_refresh ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,6 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
|
||||||
if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
|
if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
|
||||||
{
|
{
|
||||||
batch = 65536;
|
|
||||||
if (ata->dma)
|
if (ata->dma)
|
||||||
{
|
{
|
||||||
cmd = GRUB_ATA_CMD_READ_SECTORS_DMA_EXT;
|
cmd = GRUB_ATA_CMD_READ_SECTORS_DMA_EXT;
|
||||||
|
@ -301,10 +300,6 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
{
|
{
|
||||||
if (addressing == GRUB_ATA_LBA48)
|
if (addressing == GRUB_ATA_LBA48)
|
||||||
addressing = GRUB_ATA_LBA;
|
addressing = GRUB_ATA_LBA;
|
||||||
if (addressing != GRUB_ATA_CHS)
|
|
||||||
batch = 256;
|
|
||||||
else
|
|
||||||
batch = 1;
|
|
||||||
if (ata->dma)
|
if (ata->dma)
|
||||||
{
|
{
|
||||||
cmd = GRUB_ATA_CMD_READ_SECTORS_DMA;
|
cmd = GRUB_ATA_CMD_READ_SECTORS_DMA;
|
||||||
|
@ -317,8 +312,10 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch > (ata->maxbuffer >> ata->log_sector_size))
|
if (addressing != GRUB_ATA_CHS)
|
||||||
batch = (ata->maxbuffer >> ata->log_sector_size);
|
batch = 256;
|
||||||
|
else
|
||||||
|
batch = 1;
|
||||||
|
|
||||||
while (nsectors < size)
|
while (nsectors < size)
|
||||||
{
|
{
|
||||||
|
@ -464,6 +461,10 @@ grub_ata_open (const char *name, grub_disk_t disk)
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
|
||||||
|
|
||||||
disk->total_sectors = ata->size;
|
disk->total_sectors = ata->size;
|
||||||
|
disk->max_agglomerate = (ata->maxbuffer >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS));
|
||||||
|
if (disk->max_agglomerate > (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size)))
|
||||||
|
disk->max_agglomerate = (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size));
|
||||||
|
|
||||||
disk->log_sector_size = ata->log_sector_size;
|
disk->log_sector_size = ata->log_sector_size;
|
||||||
|
|
||||||
disk->id = grub_make_scsi_id (id, bus, 0);
|
disk->id = grub_make_scsi_id (id, bus, 0);
|
||||||
|
|
|
@ -517,6 +517,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
|
||||||
|
|
||||||
disk->data = dev;
|
disk->data = dev;
|
||||||
disk->total_sectors = dev->total_length;
|
disk->total_sectors = dev->total_length;
|
||||||
|
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||||
disk->id = dev->id;
|
disk->id = dev->id;
|
||||||
dev->ref++;
|
dev->ref++;
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
|
@ -445,6 +445,7 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||||
disk->data = lv;
|
disk->data = lv;
|
||||||
|
|
||||||
disk->total_sectors = lv->size;
|
disk->total_sectors = lv->size;
|
||||||
|
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,6 +518,8 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
|
||||||
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
|
grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
|
||||||
m, (unsigned long long) m->last_block, m->block_size);
|
m, (unsigned long long) m->last_block, m->block_size);
|
||||||
disk->total_sectors = m->last_block + 1;
|
disk->total_sectors = m->last_block + 1;
|
||||||
|
/* Don't increase this value due to bug in some EFI. */
|
||||||
|
disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
|
||||||
if (m->block_size & (m->block_size - 1) || !m->block_size)
|
if (m->block_size & (m->block_size - 1) || !m->block_size)
|
||||||
return grub_error (GRUB_ERR_IO, "invalid sector size %d",
|
return grub_error (GRUB_ERR_IO, "invalid sector size %d",
|
||||||
m->block_size);
|
m->block_size);
|
||||||
|
@ -550,24 +552,11 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector,
|
||||||
d = disk->data;
|
d = disk->data;
|
||||||
bio = d->block_io;
|
bio = d->block_io;
|
||||||
|
|
||||||
while (size > 0)
|
return efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
|
||||||
{
|
|
||||||
grub_size_t len;
|
|
||||||
len = 0x500;
|
|
||||||
if (len > size)
|
|
||||||
len = size;
|
|
||||||
status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio,
|
|
||||||
bio->media->media_id,
|
bio->media->media_id,
|
||||||
(grub_efi_uint64_t) sector,
|
(grub_efi_uint64_t) sector,
|
||||||
(grub_efi_uintn_t) len << disk->log_sector_size,
|
(grub_efi_uintn_t) size << disk->log_sector_size,
|
||||||
buf);
|
buf);
|
||||||
size -= len;
|
|
||||||
buf += len << disk->log_sector_size;
|
|
||||||
sector += len;
|
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
return GRUB_EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
|
|
@ -424,6 +424,9 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
disk->total_sectors = total_sectors;
|
disk->total_sectors = total_sectors;
|
||||||
|
/* Limit the max to 0x7f because of Phoenix EDD. */
|
||||||
|
disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS;
|
||||||
|
|
||||||
disk->data = data;
|
disk->data = data;
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
@ -548,10 +551,6 @@ get_safe_sectors (grub_disk_t disk, grub_disk_addr_t sector)
|
||||||
|
|
||||||
size = sectors - offset;
|
size = sectors - offset;
|
||||||
|
|
||||||
/* Limit the max to 0x7f because of Phoenix EDD. */
|
|
||||||
if (size > ((0x7fU << GRUB_DISK_SECTOR_BITS) >> disk->log_sector_size))
|
|
||||||
size = ((0x7fU << GRUB_DISK_SECTOR_BITS) >> disk->log_sector_size);
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,10 @@ grub_loopback_open (const char *name, grub_disk_t disk)
|
||||||
/ GRUB_DISK_SECTOR_SIZE);
|
/ GRUB_DISK_SECTOR_SIZE);
|
||||||
else
|
else
|
||||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||||
|
/* Avoid reading more than 512M. */
|
||||||
|
disk->max_agglomerate = 1 << (29 - GRUB_DISK_SECTOR_BITS
|
||||||
|
- GRUB_DISK_CACHE_BITS);
|
||||||
|
|
||||||
disk->id = (unsigned long) dev;
|
disk->id = (unsigned long) dev;
|
||||||
|
|
||||||
disk->data = dev;
|
disk->data = dev;
|
||||||
|
|
|
@ -46,6 +46,7 @@ grub_memdisk_open (const char *name, grub_disk_t disk)
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
|
||||||
|
|
||||||
disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
|
disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
|
||||||
|
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||||
disk->id = (unsigned long) "mdsk";
|
disk->id = (unsigned long) "mdsk";
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
|
@ -606,6 +606,13 @@ grub_scsi_open (const char *name, grub_disk_t disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
disk->total_sectors = scsi->last_block + 1;
|
disk->total_sectors = scsi->last_block + 1;
|
||||||
|
/* PATA doesn't support more than 32K reads.
|
||||||
|
Not sure about AHCI and USB. If it's confirmed that either of
|
||||||
|
them can do bigger reads reliably this value can be moved to 'scsi'
|
||||||
|
structure. */
|
||||||
|
disk->max_agglomerate = 32768 >> (GRUB_DISK_SECTOR_BITS
|
||||||
|
+ GRUB_DISK_CACHE_BITS);
|
||||||
|
|
||||||
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
|
if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize)
|
||||||
{
|
{
|
||||||
grub_free (scsi);
|
grub_free (scsi);
|
||||||
|
@ -647,41 +654,28 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
|
||||||
scsi = disk->data;
|
scsi = disk->data;
|
||||||
|
|
||||||
while (size)
|
|
||||||
{
|
|
||||||
/* PATA doesn't support more than 32K reads.
|
|
||||||
Not sure about AHCI and USB. If it's confirmed that either of
|
|
||||||
them can do bigger reads reliably this value can be moved to 'scsi'
|
|
||||||
structure. */
|
|
||||||
grub_size_t len = 32768 >> disk->log_sector_size;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
if (len > size)
|
|
||||||
len = size;
|
|
||||||
/* Depending on the type, select a read function. */
|
/* Depending on the type, select a read function. */
|
||||||
switch (scsi->devtype)
|
switch (scsi->devtype)
|
||||||
{
|
{
|
||||||
case grub_scsi_devtype_direct:
|
case grub_scsi_devtype_direct:
|
||||||
if (sector >> 32)
|
if (sector >> 32)
|
||||||
err = grub_scsi_read16 (disk, sector, len, buf);
|
err = grub_scsi_read16 (disk, sector, size, buf);
|
||||||
else
|
else
|
||||||
err = grub_scsi_read10 (disk, sector, len, buf);
|
err = grub_scsi_read10 (disk, sector, size, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case grub_scsi_devtype_cdrom:
|
case grub_scsi_devtype_cdrom:
|
||||||
if (sector >> 32)
|
if (sector >> 32)
|
||||||
err = grub_scsi_read16 (disk, sector, len, buf);
|
err = grub_scsi_read16 (disk, sector, size, buf);
|
||||||
else
|
else
|
||||||
err = grub_scsi_read12 (disk, sector, len, buf);
|
err = grub_scsi_read12 (disk, sector, size, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size -= len;
|
|
||||||
sector += len;
|
|
||||||
buf += len << disk->log_sector_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
@ -718,10 +712,10 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_scsi_write (grub_disk_t disk __attribute((unused)),
|
grub_scsi_write (grub_disk_t disk,
|
||||||
grub_disk_addr_t sector __attribute((unused)),
|
grub_disk_addr_t sector,
|
||||||
grub_size_t size __attribute((unused)),
|
grub_size_t size,
|
||||||
const char *buf __attribute((unused)))
|
const char *buf)
|
||||||
{
|
{
|
||||||
grub_scsi_t scsi;
|
grub_scsi_t scsi;
|
||||||
|
|
||||||
|
@ -730,32 +724,19 @@ grub_scsi_write (grub_disk_t disk __attribute((unused)),
|
||||||
if (scsi->devtype == grub_scsi_devtype_cdrom)
|
if (scsi->devtype == grub_scsi_devtype_cdrom)
|
||||||
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
|
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
|
||||||
|
|
||||||
while (size)
|
|
||||||
{
|
|
||||||
/* PATA doesn't support more than 32K reads.
|
|
||||||
Not sure about AHCI and USB. If it's confirmed that either of
|
|
||||||
them can do bigger reads reliably this value can be moved to 'scsi'
|
|
||||||
structure. */
|
|
||||||
grub_size_t len = 32768 >> disk->log_sector_size;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
if (len > size)
|
|
||||||
len = size;
|
|
||||||
/* Depending on the type, select a read function. */
|
/* Depending on the type, select a read function. */
|
||||||
switch (scsi->devtype)
|
switch (scsi->devtype)
|
||||||
{
|
{
|
||||||
case grub_scsi_devtype_direct:
|
case grub_scsi_devtype_direct:
|
||||||
if (sector >> 32)
|
if (sector >> 32)
|
||||||
err = grub_scsi_write16 (disk, sector, len, buf);
|
err = grub_scsi_write16 (disk, sector, size, buf);
|
||||||
else
|
else
|
||||||
err = grub_scsi_write10 (disk, sector, len, buf);
|
err = grub_scsi_write10 (disk, sector, size, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size -= len;
|
|
||||||
sector += len;
|
|
||||||
buf += len << disk->log_sector_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,6 +289,7 @@ grub_cbfsdisk_open (const char *name, grub_disk_t disk)
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a cbfsdisk");
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a cbfsdisk");
|
||||||
|
|
||||||
disk->total_sectors = cbfsdisk_size / GRUB_DISK_SECTOR_SIZE;
|
disk->total_sectors = cbfsdisk_size / GRUB_DISK_SECTOR_SIZE;
|
||||||
|
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||||
disk->id = (unsigned long) "cbfs";
|
disk->id = (unsigned long) "cbfs";
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
|
@ -199,6 +199,9 @@ grub_disk_open (const char *name)
|
||||||
if (! disk)
|
if (! disk)
|
||||||
return 0;
|
return 0;
|
||||||
disk->log_sector_size = GRUB_DISK_SECTOR_BITS;
|
disk->log_sector_size = GRUB_DISK_SECTOR_BITS;
|
||||||
|
/* Default 1MiB of maximum agglomerate. */
|
||||||
|
disk->max_agglomerate = 1048576 >> (GRUB_DISK_SECTOR_BITS
|
||||||
|
+ GRUB_DISK_CACHE_BITS);
|
||||||
|
|
||||||
p = find_part_sep (name);
|
p = find_part_sep (name);
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -311,7 +314,7 @@ grub_disk_close (grub_disk_t disk)
|
||||||
sector is already adjusted and is divisible by cache unit size.
|
sector is already adjusted and is divisible by cache unit size.
|
||||||
*/
|
*/
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
|
grub_disk_read_small_real (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
grub_off_t offset, grub_size_t size, void *buf)
|
grub_off_t offset, grub_size_t size, void *buf)
|
||||||
{
|
{
|
||||||
char *data;
|
char *data;
|
||||||
|
@ -389,15 +392,27 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_off_t offset, grub_size_t size, void *buf)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
err = grub_disk_read_small_real (disk, sector, offset, size, buf);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
if (disk->read_hook)
|
||||||
|
(disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS),
|
||||||
|
offset & (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
|
size, disk->read_hook_data);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read data from the disk. */
|
/* Read data from the disk. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
grub_off_t offset, grub_size_t size, void *buf)
|
grub_off_t offset, grub_size_t size, void *buf)
|
||||||
{
|
{
|
||||||
grub_off_t real_offset;
|
|
||||||
grub_disk_addr_t real_sector;
|
|
||||||
grub_size_t real_size;
|
|
||||||
|
|
||||||
/* First of all, check if the region is within the disk. */
|
/* First of all, check if the region is within the disk. */
|
||||||
if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
|
if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
|
||||||
{
|
{
|
||||||
|
@ -408,10 +423,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
real_sector = sector;
|
|
||||||
real_offset = offset;
|
|
||||||
real_size = size;
|
|
||||||
|
|
||||||
/* First read until first cache boundary. */
|
/* First read until first cache boundary. */
|
||||||
if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1)))
|
if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1)))
|
||||||
{
|
{
|
||||||
|
@ -446,7 +457,8 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
|
||||||
/* agglomerate read until we find a first cached entry. */
|
/* agglomerate read until we find a first cached entry. */
|
||||||
for (agglomerate = 0; agglomerate
|
for (agglomerate = 0; agglomerate
|
||||||
< (size >> (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS));
|
< (size >> (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS))
|
||||||
|
&& agglomerate < disk->max_agglomerate;
|
||||||
agglomerate++)
|
agglomerate++)
|
||||||
{
|
{
|
||||||
data = grub_disk_cache_fetch (disk->dev->id, disk->id,
|
data = grub_disk_cache_fetch (disk->dev->id, disk->id,
|
||||||
|
@ -486,6 +498,11 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
+ (i << (GRUB_DISK_CACHE_BITS
|
+ (i << (GRUB_DISK_CACHE_BITS
|
||||||
+ GRUB_DISK_SECTOR_BITS)));
|
+ GRUB_DISK_SECTOR_BITS)));
|
||||||
|
|
||||||
|
|
||||||
|
if (disk->read_hook)
|
||||||
|
(disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS),
|
||||||
|
disk->read_hook_data);
|
||||||
|
|
||||||
sector += agglomerate << GRUB_DISK_CACHE_BITS;
|
sector += agglomerate << GRUB_DISK_CACHE_BITS;
|
||||||
size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
|
size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS);
|
||||||
buf = (char *) buf
|
buf = (char *) buf
|
||||||
|
@ -494,6 +511,9 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
if (disk->read_hook)
|
||||||
|
(disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS),
|
||||||
|
disk->read_hook_data);
|
||||||
sector += GRUB_DISK_CACHE_SIZE;
|
sector += GRUB_DISK_CACHE_SIZE;
|
||||||
buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
|
buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
|
||||||
size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
|
size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS);
|
||||||
|
@ -509,26 +529,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the read hook, if any. */
|
|
||||||
if (disk->read_hook)
|
|
||||||
{
|
|
||||||
grub_disk_addr_t s = real_sector;
|
|
||||||
grub_size_t l = real_size;
|
|
||||||
grub_off_t o = real_offset;
|
|
||||||
|
|
||||||
while (l)
|
|
||||||
{
|
|
||||||
grub_size_t cl;
|
|
||||||
cl = GRUB_DISK_SECTOR_SIZE - o;
|
|
||||||
if (cl > l)
|
|
||||||
cl = l;
|
|
||||||
(disk->read_hook) (s, o, cl, disk->read_hook_data);
|
|
||||||
s++;
|
|
||||||
l -= cl;
|
|
||||||
o = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
disk->total_sectors = grub_util_get_fd_size (fd, map[drive].device,
|
disk->total_sectors = grub_util_get_fd_size (fd, map[drive].device,
|
||||||
&disk->log_sector_size);
|
&disk->log_sector_size);
|
||||||
disk->total_sectors >>= disk->log_sector_size;
|
disk->total_sectors >>= disk->log_sector_size;
|
||||||
|
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||||
|
|
||||||
#if GRUB_UTIL_FD_STAT_IS_FUNCTIONAL
|
#if GRUB_UTIL_FD_STAT_IS_FUNCTIONAL
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,6 +123,13 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
len = size & ~((1 << disk->log_sector_size) - 1);
|
len = size & ~((1 << disk->log_sector_size) - 1);
|
||||||
n = size >> disk->log_sector_size;
|
n = size >> disk->log_sector_size;
|
||||||
|
|
||||||
|
if (n > (disk->max_agglomerate
|
||||||
|
<< (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS
|
||||||
|
- disk->log_sector_size)))
|
||||||
|
n = (disk->max_agglomerate
|
||||||
|
<< (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS
|
||||||
|
- disk->log_sector_size));
|
||||||
|
|
||||||
if ((disk->dev->write) (disk, transform_sector (disk, sector),
|
if ((disk->dev->write) (disk, transform_sector (disk, sector),
|
||||||
n, buf) != GRUB_ERR_NONE)
|
n, buf) != GRUB_ERR_NONE)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
|
@ -70,7 +70,7 @@ grub_install_get_blocklist (grub_device_t root_dev,
|
||||||
|
|
||||||
if (ioctl (fd, FS_IOC_FIEMAP, &fie1) < 0)
|
if (ioctl (fd, FS_IOC_FIEMAP, &fie1) < 0)
|
||||||
{
|
{
|
||||||
int nblocks, i, j;
|
int nblocks, i;
|
||||||
int bsize;
|
int bsize;
|
||||||
int mul;
|
int mul;
|
||||||
|
|
||||||
|
@ -88,27 +88,25 @@ grub_install_get_blocklist (grub_device_t root_dev,
|
||||||
for (i = 0; i < nblocks; i++)
|
for (i = 0; i < nblocks; i++)
|
||||||
{
|
{
|
||||||
unsigned blk = i;
|
unsigned blk = i;
|
||||||
|
int rest;
|
||||||
if (ioctl (fd, FIBMAP, &blk) < 0)
|
if (ioctl (fd, FIBMAP, &blk) < 0)
|
||||||
grub_util_error (_("can't retrieve blocklists: %s"),
|
grub_util_error (_("can't retrieve blocklists: %s"),
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
|
|
||||||
for (j = 0; j < mul; j++)
|
rest = core_size - ((i * mul) << GRUB_DISK_SECTOR_BITS);
|
||||||
{
|
|
||||||
int rest = core_size - ((i * mul + j) << GRUB_DISK_SECTOR_BITS);
|
|
||||||
if (rest <= 0)
|
if (rest <= 0)
|
||||||
break;
|
break;
|
||||||
if (rest > GRUB_DISK_SECTOR_SIZE)
|
if (rest > GRUB_DISK_SECTOR_SIZE * mul)
|
||||||
rest = GRUB_DISK_SECTOR_SIZE;
|
rest = GRUB_DISK_SECTOR_SIZE * mul;
|
||||||
callback (((grub_uint64_t) blk) * mul + j
|
callback (((grub_uint64_t) blk) * mul
|
||||||
+ container_start,
|
+ container_start,
|
||||||
0, rest, hook_data);
|
0, rest, hook_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct fiemap *fie2;
|
struct fiemap *fie2;
|
||||||
int i, j;
|
int i;
|
||||||
fie2 = xmalloc (sizeof (*fie2)
|
fie2 = xmalloc (sizeof (*fie2)
|
||||||
+ fie1.fm_mapped_extents
|
+ fie1.fm_mapped_extents
|
||||||
* sizeof (fie1.fm_extents[1]));
|
* sizeof (fie1.fm_extents[1]));
|
||||||
|
@ -122,22 +120,12 @@ grub_install_get_blocklist (grub_device_t root_dev,
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
for (i = 0; i < fie2->fm_mapped_extents; i++)
|
for (i = 0; i < fie2->fm_mapped_extents; i++)
|
||||||
{
|
{
|
||||||
for (j = 0;
|
|
||||||
j < ((fie2->fm_extents[i].fe_length
|
|
||||||
+ GRUB_DISK_SECTOR_SIZE - 1)
|
|
||||||
>> GRUB_DISK_SECTOR_BITS);
|
|
||||||
j++)
|
|
||||||
{
|
|
||||||
size_t len = (fie2->fm_extents[i].fe_length
|
|
||||||
- j * GRUB_DISK_SECTOR_SIZE);
|
|
||||||
if (len > GRUB_DISK_SECTOR_SIZE)
|
|
||||||
len = GRUB_DISK_SECTOR_SIZE;
|
|
||||||
callback ((fie2->fm_extents[i].fe_physical
|
callback ((fie2->fm_extents[i].fe_physical
|
||||||
>> GRUB_DISK_SECTOR_BITS)
|
>> GRUB_DISK_SECTOR_BITS)
|
||||||
+ j + container_start,
|
+ container_start,
|
||||||
fie2->fm_extents[i].fe_physical
|
fie2->fm_extents[i].fe_physical
|
||||||
& (GRUB_DISK_SECTOR_SIZE - 1), len, hook_data);
|
& (GRUB_DISK_SECTOR_SIZE - 1),
|
||||||
}
|
fie2->fm_extents[i].fe_length, hook_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
|
@ -49,7 +49,7 @@ grub_install_get_blocklist (grub_device_t root_dev,
|
||||||
DWORD rets;
|
DWORD rets;
|
||||||
RETRIEVAL_POINTERS_BUFFER *extbuf;
|
RETRIEVAL_POINTERS_BUFFER *extbuf;
|
||||||
size_t extbuf_size;
|
size_t extbuf_size;
|
||||||
DWORD i, j, k;
|
DWORD i;
|
||||||
grub_uint64_t sec_per_lcn;
|
grub_uint64_t sec_per_lcn;
|
||||||
grub_uint64_t curvcn = 0;
|
grub_uint64_t curvcn = 0;
|
||||||
STARTING_VCN_INPUT_BUFFER start_vcn;
|
STARTING_VCN_INPUT_BUFFER start_vcn;
|
||||||
|
@ -108,12 +108,8 @@ grub_install_get_blocklist (grub_device_t root_dev,
|
||||||
CloseHandle (filehd);
|
CloseHandle (filehd);
|
||||||
|
|
||||||
for (i = 0; i < extbuf->ExtentCount; i++)
|
for (i = 0; i < extbuf->ExtentCount; i++)
|
||||||
{
|
callback (extbuf->Extents[i].Lcn.QuadPart
|
||||||
for (j = 0; j < extbuf->Extents[i].NextVcn.QuadPart - curvcn; j++)
|
* sec_per_lcn + first_lcn,
|
||||||
for (k = 0; k < sec_per_lcn; k++)
|
0, 512 * sec_per_lcn * (extbuf->Extents[i].NextVcn.QuadPart - curvcn), hook_data);
|
||||||
callback ((extbuf->Extents[i].Lcn.QuadPart + j)
|
|
||||||
* sec_per_lcn + first_lcn
|
|
||||||
+ k, 0, 512, hook_data);
|
|
||||||
}
|
|
||||||
free (extbuf);
|
free (extbuf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,9 @@ struct grub_disk
|
||||||
/* Logarithm of sector size. */
|
/* Logarithm of sector size. */
|
||||||
unsigned int log_sector_size;
|
unsigned int log_sector_size;
|
||||||
|
|
||||||
|
/* Maximum number of sectors read divided by GRUB_DISK_CACHE_SIZE. */
|
||||||
|
unsigned int max_agglomerate;
|
||||||
|
|
||||||
/* The id used by the disk cache manager. */
|
/* The id used by the disk cache manager. */
|
||||||
unsigned long id;
|
unsigned long id;
|
||||||
|
|
||||||
|
@ -164,6 +167,8 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
|
||||||
#define GRUB_DISK_CACHE_BITS 6
|
#define GRUB_DISK_CACHE_BITS 6
|
||||||
#define GRUB_DISK_CACHE_SIZE (1 << GRUB_DISK_CACHE_BITS)
|
#define GRUB_DISK_CACHE_SIZE (1 << GRUB_DISK_CACHE_BITS)
|
||||||
|
|
||||||
|
#define GRUB_DISK_MAX_MAX_AGGLOMERATE ((1 << (30 - GRUB_DISK_CACHE_BITS - GRUB_DISK_SECTOR_BITS)) - 1)
|
||||||
|
|
||||||
/* Return value of grub_disk_get_size() in case disk size is unknown. */
|
/* Return value of grub_disk_get_size() in case disk size is unknown. */
|
||||||
#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL
|
#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL
|
||||||
|
|
||||||
|
|
23
util/setup.c
23
util/setup.c
|
@ -149,33 +149,40 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length,
|
||||||
{
|
{
|
||||||
struct blocklists *bl = data;
|
struct blocklists *bl = data;
|
||||||
struct grub_boot_blocklist *prev = bl->block + 1;
|
struct grub_boot_blocklist *prev = bl->block + 1;
|
||||||
|
grub_uint64_t seclen;
|
||||||
|
|
||||||
grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>",
|
grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>",
|
||||||
sector, offset, length);
|
sector, offset, length);
|
||||||
|
|
||||||
if (bl->first_sector == (grub_disk_addr_t) -1)
|
if (bl->first_sector == (grub_disk_addr_t) -1)
|
||||||
{
|
{
|
||||||
if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
|
if (offset != 0 || length < GRUB_DISK_SECTOR_SIZE)
|
||||||
grub_util_error ("%s", _("the first sector of the core file is not sector-aligned"));
|
grub_util_error ("%s", _("the first sector of the core file is not sector-aligned"));
|
||||||
|
|
||||||
bl->first_sector = sector;
|
bl->first_sector = sector;
|
||||||
|
sector++;
|
||||||
|
length -= GRUB_DISK_SECTOR_SIZE;
|
||||||
|
if (!length)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != 0 || bl->last_length != GRUB_DISK_SECTOR_SIZE)
|
if (offset != 0 || bl->last_length != 0)
|
||||||
grub_util_error ("%s", _("non-sector-aligned data is found in the core file"));
|
grub_util_error ("%s", _("non-sector-aligned data is found in the core file"));
|
||||||
|
|
||||||
|
seclen = (length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
|
||||||
|
|
||||||
if (bl->block != bl->first_block
|
if (bl->block != bl->first_block
|
||||||
&& (grub_target_to_host64 (prev->start)
|
&& (grub_target_to_host64 (prev->start)
|
||||||
+ grub_target_to_host16 (prev->len)) == sector)
|
+ grub_target_to_host16 (prev->len)) == sector)
|
||||||
{
|
{
|
||||||
grub_uint16_t t = grub_target_to_host16 (prev->len) + 1;
|
grub_uint16_t t = grub_target_to_host16 (prev->len);
|
||||||
|
t += seclen;
|
||||||
prev->len = grub_host_to_target16 (t);
|
prev->len = grub_host_to_target16 (t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bl->block->start = grub_host_to_target64 (sector);
|
bl->block->start = grub_host_to_target64 (sector);
|
||||||
bl->block->len = grub_host_to_target16 (1);
|
bl->block->len = grub_host_to_target16 (seclen);
|
||||||
#ifdef GRUB_SETUP_BIOS
|
#ifdef GRUB_SETUP_BIOS
|
||||||
bl->block->segment = grub_host_to_target16 (bl->current_segment);
|
bl->block->segment = grub_host_to_target16 (bl->current_segment);
|
||||||
#endif
|
#endif
|
||||||
|
@ -185,9 +192,9 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length,
|
||||||
grub_util_error ("%s", _("the sectors of the core file are too fragmented"));
|
grub_util_error ("%s", _("the sectors of the core file are too fragmented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bl->last_length = length;
|
bl->last_length = length & (GRUB_DISK_SECTOR_SIZE - 1);
|
||||||
#ifdef GRUB_SETUP_BIOS
|
#ifdef GRUB_SETUP_BIOS
|
||||||
bl->current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
|
bl->current_segment += seclen << (GRUB_DISK_SECTOR_BITS - 4);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +267,7 @@ SETUP (const char *dir,
|
||||||
bl.current_segment =
|
bl.current_segment =
|
||||||
GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
|
GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
|
||||||
#endif
|
#endif
|
||||||
bl.last_length = GRUB_DISK_SECTOR_SIZE;
|
bl.last_length = 0;
|
||||||
|
|
||||||
/* Read the boot image by the OS service. */
|
/* Read the boot image by the OS service. */
|
||||||
boot_path = grub_util_get_path (dir, boot_file);
|
boot_path = grub_util_get_path (dir, boot_file);
|
||||||
|
@ -731,6 +738,8 @@ unable_to_embed:
|
||||||
if ((char *) bl.block <= core_img)
|
if ((char *) bl.block <= core_img)
|
||||||
grub_util_error ("%s", _("no terminator in the core image"));
|
grub_util_error ("%s", _("no terminator in the core image"));
|
||||||
}
|
}
|
||||||
|
if (len)
|
||||||
|
grub_util_error ("%s", _("blocklists are incomplete"));
|
||||||
core_dev->disk->partition = container;
|
core_dev->disk->partition = container;
|
||||||
free (buf);
|
free (buf);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue