Skip to content

Commit

Permalink
优化blocklist_func
Browse files Browse the repository at this point in the history
  • Loading branch information
chenall committed Dec 27, 2014
1 parent 2c7e39e commit dd98da0
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
37 changes: 22 additions & 15 deletions stage2/builtins.c
Expand Up @@ -276,14 +276,16 @@ static unsigned long long blklst_start_sector;
static unsigned long long blklst_num_sectors; static unsigned long long blklst_num_sectors;
static unsigned long blklst_num_entries; static unsigned long blklst_num_entries;
static unsigned long blklst_last_length; static unsigned long blklst_last_length;

static void disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsigned long length); static void disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsigned long length);

/* Collect contiguous blocks into one entry as many as possible, /* Collect contiguous blocks into one entry as many as possible,
and print the blocklist notation on the screen. */ and print the blocklist notation on the screen. */
static void static void
disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsigned long length) disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsigned long length)
{ {
unsigned long sectorsize = buf_geom.sector_size;
unsigned char sector_bit = (sectorsize == 2048 ? 11:9);
#ifdef FSYS_INITRD #ifdef FSYS_INITRD
if (fsys_table[fsys_type].mount_func == initrdfs_mount) if (fsys_table[fsys_type].mount_func == initrdfs_mount)
{ {
Expand All @@ -292,20 +294,21 @@ disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsig
return; return;
} }
#endif #endif
if (blklst_num_sectors > 0)
if (blklst_num_sectors > 0)
{ {
if (blklst_start_sector + blklst_num_sectors == sector if (blklst_start_sector + blklst_num_sectors == sector
&& offset == 0 && blklst_last_length == buf_geom.sector_size) && offset == 0 && blklst_last_length == 0)
{ {
blklst_num_sectors++; blklst_num_sectors += (length + (sectorsize - 1)) >> sector_bit;
blklst_last_length = length; blklst_last_length = (length - (sectorsize - offset))&(sectorsize - 1);
return; return;
} }
else else
{ {
if (query_block_entries >= 0) if (query_block_entries >= 0)
{ {
if (blklst_last_length == buf_geom.sector_size) if (blklst_last_length == 0)
grub_printf ("%s%ld+%ld", (blklst_num_entries ? "," : ""), grub_printf ("%s%ld+%ld", (blklst_num_entries ? "," : ""),
(unsigned long long)(blklst_start_sector - part_start), blklst_num_sectors); (unsigned long long)(blklst_start_sector - part_start), blklst_num_sectors);
else if (blklst_num_sectors > 1) else if (blklst_num_sectors > 1)
Expand All @@ -317,7 +320,7 @@ disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsig
grub_printf ("%s%ld[0-%d]", (blklst_num_entries ? "," : ""), grub_printf ("%s%ld[0-%d]", (blklst_num_entries ? "," : ""),
(unsigned long long)(blklst_start_sector - part_start), blklst_last_length); (unsigned long long)(blklst_start_sector - part_start), blklst_last_length);
} }
else if (blklst_last_length == buf_geom.sector_size && blklst_num_entries < DRIVE_MAP_FRAGMENT) else if (blklst_last_length == 0 && blklst_num_entries < DRIVE_MAP_FRAGMENT)
{ {
map_start_sector[blklst_num_entries] = blklst_start_sector; map_start_sector[blklst_num_entries] = blklst_start_sector;
map_num_sectors[blklst_num_entries] = blklst_num_sectors; map_num_sectors[blklst_num_entries] = blklst_num_sectors;
Expand All @@ -327,18 +330,22 @@ disk_read_blocklist_func (unsigned long long sector, unsigned long offset, unsig
} }
} }


if (offset > 0) if (offset > 0)
{ {
if (query_block_entries >= 0) if (query_block_entries >= 0)
grub_printf("%s%ld[%d-%d]", (blklst_num_entries ? "," : ""), {
(unsigned long long)(sector - part_start), offset, (offset + length)); unsigned long len = sectorsize - offset;
if (len > length) len = length;
grub_printf("%s%ld[%d-%d]", (blklst_num_entries ? "," : ""),
(unsigned long long)(sector - part_start), offset, (offset + len));
}
blklst_num_entries++; blklst_num_entries++;
} }
else else
{ {
blklst_start_sector = sector; blklst_start_sector = sector;
blklst_num_sectors = 1; blklst_num_sectors = (length + sectorsize - 1) >> sector_bit;
blklst_last_length = length; blklst_last_length = (length - (sectorsize - offset))&(sectorsize - 1);
} }
} }


Expand Down Expand Up @@ -373,7 +380,7 @@ blocklist_func (char *arg, int flags)
if (fsys_table[fsys_type].mount_func == initrdfs_mount) if (fsys_table[fsys_type].mount_func == initrdfs_mount)
{ {
disk_read_hook = disk_read_blocklist_func; disk_read_hook = disk_read_blocklist_func;
err = grub_read ((unsigned long long)(unsigned int)dummy,-1ULL, GRUB_READ); err = grub_read ((unsigned long long)(unsigned int)dummy,-1ULL, GRUB_LISTBLK);
disk_read_hook = 0; disk_read_hook = 0;
goto fail_read; goto fail_read;
} }
Expand Down Expand Up @@ -402,7 +409,7 @@ blocklist_func (char *arg, int flags)
/* Read in the whole file to DUMMY. */ /* Read in the whole file to DUMMY. */
disk_read_hook = disk_read_blocklist_func; disk_read_hook = disk_read_blocklist_func;
// err = grub_read ((unsigned long long)(unsigned int)dummy, (query_block_entries < 0 ? buf_geom.sector_size : -1ULL), 0xedde0d90); // err = grub_read ((unsigned long long)(unsigned int)dummy, (query_block_entries < 0 ? buf_geom.sector_size : -1ULL), 0xedde0d90);
err = grub_read ((unsigned long long)(unsigned int)dummy, -1ULL, 0xedde0d90); err = grub_read ((unsigned long long)(unsigned int)dummy, -1ULL, GRUB_LISTBLK);
disk_read_hook = 0; disk_read_hook = 0;
rawread_ignore_memmove_overflow = 0; rawread_ignore_memmove_overflow = 0;
if (! err) if (! err)
Expand Down
11 changes: 9 additions & 2 deletions stage2/disk_io.c
Expand Up @@ -284,7 +284,7 @@ rawread (unsigned long drive, unsigned long long sector, unsigned long byte_offs
unsigned long slen, sectors_per_vtrack; unsigned long slen, sectors_per_vtrack;
unsigned long sector_size_bits = log2_tmp (buf_geom.sector_size); unsigned long sector_size_bits = log2_tmp (buf_geom.sector_size);


if (write != 0x900ddeed && write != 0xedde0d90) if (write != 0x900ddeed && write != 0xedde0d90 && write != GRUB_LISTBLK)
return !(errnum = ERR_FUNC_CALL); return !(errnum = ERR_FUNC_CALL);


errnum = 0; errnum = 0;
Expand All @@ -306,8 +306,15 @@ rawread (unsigned long drive, unsigned long long sector, unsigned long byte_offs
sector_size_bits = log2_tmp (buf_geom.sector_size); sector_size_bits = log2_tmp (buf_geom.sector_size);
} }


if (write == GRUB_LISTBLK)
{
if (disk_read_func) (*disk_read_func)(sector, byte_offset, byte_len);
return 1;
}

if (!buf) if (!buf)
{ /* Don't waste time reading from disk, just call disk_read_func. */ { /* Don't waste time reading from disk, just call disk_read_func. */

if (disk_read_func) if (disk_read_func)
{ {
unsigned long sectorsize = buf_geom.sector_size; unsigned long sectorsize = buf_geom.sector_size;
Expand Down Expand Up @@ -486,7 +493,7 @@ devread (unsigned long long sector, unsigned long long byte_offset, unsigned lon
unsigned long sector_size_bits = log2_tmp(buf_geom.sector_size); unsigned long sector_size_bits = log2_tmp(buf_geom.sector_size);
unsigned long rw_flag = write; unsigned long rw_flag = write;


if (rw_flag != 0x900ddeed && rw_flag != 0xedde0d90) if (rw_flag != 0x900ddeed && rw_flag != 0xedde0d90 && rw_flag != GRUB_LISTBLK)
{//for old devread with 32-bit byte_offset compatibility. {//for old devread with 32-bit byte_offset compatibility.
rw_flag = *(unsigned long*)(&write - 1); rw_flag = *(unsigned long*)(&write - 1);
if (rw_flag != 0x900ddeed && rw_flag != 0xedde0d90) if (rw_flag != 0x900ddeed && rw_flag != 0xedde0d90)
Expand Down
1 change: 1 addition & 0 deletions stage2/shared.h
Expand Up @@ -1393,6 +1393,7 @@ int next_partition (void);
int grub_open (char *filename); int grub_open (char *filename);
#define GRUB_READ 0xedde0d90 #define GRUB_READ 0xedde0d90
#define GRUB_WRITE 0x900ddeed #define GRUB_WRITE 0x900ddeed
#define GRUB_LISTBLK 0x4B42534C
/* Read LEN bytes into BUF from the file that was opened with /* Read LEN bytes into BUF from the file that was opened with
GRUB_OPEN. If LEN is -1, read all the remaining data in the file. */ GRUB_OPEN. If LEN is -1, read all the remaining data in the file. */
unsigned long long grub_read (unsigned long long buf, unsigned long long len, unsigned long write); unsigned long long grub_read (unsigned long long buf, unsigned long long len, unsigned long write);
Expand Down

0 comments on commit dd98da0

Please sign in to comment.