mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-23 07:39:22 +00:00
2006-05-28 Yoshinori K. Okuji <okuji@enbug.org>
* fs/hfsplus.c (grub_hfsplus_btree_recoffset): Moved to near the
top.
(grub_hfsplus_btree_recptr): Likewise.
(grub_hfsplus_find_block): Do not take RETRY any longer. Use
FILEBLOCK both to pass a block number and store next block
number.
(grub_hfsplus_read_block): Rewritten heavily to support an extent
overflow file correctly. Specify errors appropriately, because
fshelp expects that GRUB_ERRNO is set when fails. Reuse
grub_hfsplus_btree_recptr to get the pointer to a found key.
(grub_hfsplus_btree_search): Return 1 instead of 0 when no match
is found.
* conf/i386-efi.rmk (pkgdata_MODULES): Added _linux.mod and
linux.mod.
(_linux_mod_SOURCES): New variable.
(_linux_mod_CFLAGS): Likewise.
(_linux_mod_LDFLAGS): Likewise.
(linux_mod_SOURCES): Likewise.
(linux_mod_CFLAGS): Likewise.
(linux_mod_LDFLAGS): Likewise.
* DISTLIST: Added loader/i386/efi/linux.c,
loader/i386/efi/linux_normal.c and
include/grub/i386/efi/loader.h.
* loader/i386/efi/linux.c: New file.
* loader/i386/efi/linux_normal.c: Likewise.
* include/grub/i386/efi/loader.h: Likewise.
This commit is contained in:
1 parent
43b553ada7
commit
118f4fb31e
9 files changed
+1022
-58
No files matched your search
+57
-56
@@ -226,15 +226,41 @@ static grub_dl_t my_mod;
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the offset of the record with the index INDEX, in the node
|
||||
NODE which is part of the B+ tree BTREE. */
|
||||
static inline unsigned int
|
||||
grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
|
||||
struct grub_hfsplus_btnode *node, int index)
|
||||
{
|
||||
char *cnode = (char *) node;
|
||||
grub_uint16_t *recptr;
|
||||
recptr = (grub_uint16_t *) (&cnode[btree->nodesize
|
||||
- index * sizeof (grub_uint16_t) - 2]);
|
||||
return grub_be_to_cpu16 (*recptr);
|
||||
}
|
||||
|
||||
/* Return a pointer to the record with the index INDEX, in the node
|
||||
NODE which is part of the B+ tree BTREE. */
|
||||
static inline struct grub_hfsplus_key *
|
||||
grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
|
||||
struct grub_hfsplus_btnode *node, int index)
|
||||
{
|
||||
char *cnode = (char *) node;
|
||||
unsigned int offset;
|
||||
offset = grub_hfsplus_btree_recoffset (btree, node, index);
|
||||
return (struct grub_hfsplus_key *) &cnode[offset];
|
||||
}
|
||||
|
||||
|
||||
/* Find the extent that points to FILEBLOCK. If it is not in one of
|
||||
the 8 extents described by EXTENT, return -1. In that case set
|
||||
RETRY to the last block that was found in the last extent. */
|
||||
FILEBLOCK to the next block. */
|
||||
static int
|
||||
grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
|
||||
int fileblock, int *retry)
|
||||
int *fileblock)
|
||||
{
|
||||
int i;
|
||||
grub_size_t blksleft = fileblock;
|
||||
grub_size_t blksleft = *fileblock;
|
||||
|
||||
/* First lookup the file in the given extents. */
|
||||
for (i = 0; i < 8; i++)
|
||||
@@ -244,7 +270,7 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
|
||||
blksleft -= grub_be_to_cpu32 (extent[i].count);
|
||||
}
|
||||
|
||||
*retry = fileblock - blksleft;
|
||||
*fileblock = blksleft;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -263,21 +289,19 @@ static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
|
||||
static int
|
||||
grub_hfsplus_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
{
|
||||
struct grub_hfsplus_extkey_internal extoverflow;
|
||||
struct grub_hfsplus_extkey *keyfound;
|
||||
int blk;
|
||||
struct grub_hfsplus_btnode *nnode = 0;
|
||||
int ptr;
|
||||
int retry = 0;
|
||||
|
||||
int blksleft = fileblock;
|
||||
struct grub_hfsplus_extent *extents = &node->extents[0];
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *cnode;
|
||||
struct grub_hfsplus_extkey *key;
|
||||
struct grub_hfsplus_extkey_internal extoverflow;
|
||||
int blk;
|
||||
int ptr;
|
||||
|
||||
/* Try to find this block in the current set of extents. */
|
||||
blk = grub_hfsplus_find_block (extents, fileblock, &retry);
|
||||
blk = grub_hfsplus_find_block (extents, &blksleft);
|
||||
|
||||
/* The previous iteration of this loop allocated memory. The
|
||||
code above used this memory, it can be free'ed now. */
|
||||
@@ -293,30 +317,33 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, int fileblock)
|
||||
the extent overflow file. If this happens, you found a
|
||||
bug... */
|
||||
if (node->fileid == GRUB_HFSPLUS_FILEID_OVERFLOW)
|
||||
break;
|
||||
{
|
||||
grub_error (GRUB_ERR_READ_ERROR,
|
||||
"extra extents found in an extend overflow file");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up the key to look for in the extent overflow file. */
|
||||
extoverflow.fileid = node->fileid;
|
||||
extoverflow.start = retry;
|
||||
extoverflow.start = fileblock - blksleft;
|
||||
|
||||
if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
|
||||
(struct grub_hfsplus_key_internal *) &extoverflow,
|
||||
grub_hfsplus_cmp_extkey, &nnode, &ptr))
|
||||
break;
|
||||
{
|
||||
grub_error (GRUB_ERR_READ_ERROR,
|
||||
"no block found for the file id 0x%x and the block offset 0x%x",
|
||||
node->fileid, fileblock);
|
||||
break;
|
||||
}
|
||||
|
||||
cnode = (char *) nnode;
|
||||
|
||||
/* The extent overflow file has a 8 extents right after the key. */
|
||||
keyfound = (struct grub_hfsplus_extkey *)
|
||||
&cnode[(int) cnode[node->data->extoverflow_tree.nodesize - ptr - 1]];
|
||||
extents = (struct grub_hfsplus_extent *)
|
||||
((char *) keyfound + sizeof (struct grub_hfsplus_extkey));
|
||||
/* The extent overflow file has 8 extents right after the key. */
|
||||
key = (struct grub_hfsplus_extkey *)
|
||||
grub_hfsplus_btree_recptr (&node->data->extoverflow_tree, nnode, ptr);
|
||||
extents = (struct grub_hfsplus_extent *) (key + 1);
|
||||
|
||||
/* The block wasn't found. Perhaps the next iteration will find
|
||||
it. The last block we found is stored in FILEBLOCK now. */
|
||||
/* XXX: Multiple iterations for locating the right extent was
|
||||
not tested enough... */
|
||||
fileblock = retry;
|
||||
it. The last block we found is stored in BLKSLEFT now. */
|
||||
}
|
||||
|
||||
grub_free (nnode);
|
||||
@@ -517,32 +544,6 @@ grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
|
||||
return diff;
|
||||
}
|
||||
|
||||
/* Return the offset of the record with the index INDEX, in the node
|
||||
NODE which is part of the B+ tree BTREE. */
|
||||
static inline unsigned int
|
||||
grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
|
||||
struct grub_hfsplus_btnode *node, int index)
|
||||
{
|
||||
char *cnode = (char *) node;
|
||||
grub_uint16_t *recptr;
|
||||
recptr = (grub_uint16_t *) (&cnode[btree->nodesize
|
||||
- index * sizeof (grub_uint16_t) - 2]);
|
||||
return grub_be_to_cpu16 (*recptr);
|
||||
}
|
||||
|
||||
/* Return a pointer to the record with the index INDEX, in the node
|
||||
NODE which is part of the B+ tree BTREE. */
|
||||
static inline struct grub_hfsplus_key *
|
||||
grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
|
||||
struct grub_hfsplus_btnode *node, int index)
|
||||
{
|
||||
char *cnode = (char *) node;
|
||||
unsigned int offset;
|
||||
offset = grub_hfsplus_btree_recoffset (btree, node, index);
|
||||
return (struct grub_hfsplus_key *) &cnode[offset];
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
grub_hfsplus_read_symlink (grub_fshelp_node_t node)
|
||||
{
|
||||
@@ -639,8 +640,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||
for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++)
|
||||
{
|
||||
struct grub_hfsplus_key *currkey;
|
||||
currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
|
||||
|
||||
currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
|
||||
|
||||
/* The action that has to be taken depend on the type of
|
||||
record. */
|
||||
if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF
|
||||
@@ -675,13 +676,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||
}
|
||||
}
|
||||
|
||||
/* No match was found, no record with this key exists in the
|
||||
/* No match is found, no record with this key exists in the
|
||||
tree. */
|
||||
if (! match)
|
||||
{
|
||||
*matchnode = 0;
|
||||
grub_free (node);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user