[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: hfs breakage
From: |
Bean |
Subject: |
Re: hfs breakage |
Date: |
Sat, 19 Jan 2008 15:12:12 +0800 |
On Jan 16, 2008 8:38 AM, Pavel Roskin <address@hidden> wrote:
> Hello!
>
> I have noticed that GRUB won't list all files on the boot partition of
> my PowerMAC. I can still get the full list if I mount the partition in
> Linux of use hfsutils.
>
> I put the image here:
> http://red-bean.com/proski/sda2.img.bz2
>
> It's just 210k compressed. The problem can be reproduced on any
> ordinary PC. Just uncompress the image and create a file called
> device.map with the following contents:
>
> (hd0) sda2.img
>
> Compile grub with grub-emu support:
>
> ./configure --enable-grub-emu && make
>
> Run grub-emu:
>
> grub-emu -m device.map -r hd0
>
> grub> ls (hd0)/
> acorn.mod affs.mod amiga.mod apple.mod blocklist.mod boot.mod cat.mod
> cmp.mod configfile.mod cpio.mod elf.mod ext2.mod fat.mod font.mod
> fshelp.mod gpt.mod grub
> grub>
>
> Files after "grub" are not shown.
>
> I have already considered the possibility that having files with similar
> names "grub" and "grub.cfg" may be a problem. But renaming "grub" to
> "gurb" makes no difference.
>
> I have been rewriting the file called "grub" many times, so maybe it was
> moved to some additional leaf of the directory tree, confusing the hfs
> implementation in GRUB (I'm just guessing, I don't know anything about
> hfs).
>
> Moreover, if I mount the image as loop in Linux and remove files "grub"
> and "grub.cfg", "ls" in grub-emu will go into infinite loop and print
> "ofboot.b pc.mod raid.mod reboot.mod reiserfs.mod search.mod sfs.mod
> sun.mod suspend.mod terminal.mod" over and over again.
I think i figure out the problem, please try the following patch.
* fs/hfs.c : Add magic values for cnid
(grub_hfs_iterate_records): Use the correct file number for extents
and catalog file. Fix problem in next index calculation.
(grub_hfs_find_node): Replace recursive function call with loop.
(grub_hfs_iterate_dir): Replace recursive function call with loop.
diff --git a/fs/hfs.c b/fs/hfs.c
index e8e9c3e..3480d3e 100644
--- a/fs/hfs.c
+++ b/fs/hfs.c
@@ -43,6 +43,16 @@ enum
GRUB_HFS_FILETYPE_FILE = 2
};
+/* Catalog node ID (CNID). */
+enum
+ {
+ GRUB_HFS_CNID_ROOT_PARENT = 1,
+ GRUB_HFS_CNID_ROOT = 2,
+ GRUB_HFS_CNID_EXT = 3,
+ GRUB_HFS_CNID_CAT = 4,
+ GRUB_HFS_CNID_BAD = 5
+ };
+
/* A node descriptor. This is the header of every node. */
struct grub_hfs_node
{
@@ -447,7 +457,8 @@ grub_hfs_iterate_records (struct grub_hfs_data
*data, int type, int idx,
/* Read the node into memory. */
blk = grub_hfs_block (data, dat,
- 0, idx / (data->blksz / nodesize), 0);
+ (type == 0) ? GRUB_HFS_CNID_CAT :
GRUB_HFS_CNID_EXT,
+ idx / (data->blksz / nodesize), 0);
blk += (idx % (data->blksz / nodesize));
if (grub_errno)
return grub_errno;
@@ -481,10 +492,7 @@ grub_hfs_iterate_records (struct grub_hfs_data
*data, int type, int idx,
return 0;
}
- if (idx % (data->blksz / nodesize) == 0)
- idx = grub_be_to_cpu32 (node.node.next);
- else
- idx++;
+ idx = grub_be_to_cpu32 (node.node.next);
} while (idx && this);
return 0;
@@ -501,6 +509,7 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key,
{
int found = -1;
int isleaf = 0;
+ int done = 0;
auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
@@ -532,6 +541,8 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key,
/* Found it!!!! */
if (cmp == 0)
{
+ done = 1;
+
grub_memcpy (datar, rec->data,
rec->datalen < datalen ? rec->datalen : datalen);
return 1;
@@ -541,16 +552,20 @@ grub_hfs_find_node (struct grub_hfs_data *data, char *key,
return 0;
}
- if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
- return 0;
+ do
+ {
+ found = -1;
+
+ if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
+ return 0;
- if (found == -1)
- return 0;
+ if (found == -1)
+ return 0;
- if (isleaf)
- return 1;
+ idx = found;
+ } while (! isleaf);
- return grub_hfs_find_node (data, key, found, type, datar, datalen);
+ return done;
}
@@ -607,21 +622,23 @@ grub_hfs_iterate_dir (struct grub_hfs_data
*data, grub_uint32_t root_idx,
return hook (rec);
}
- if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
- return grub_errno;
+ do
+ {
+ found = -1;
+
+ if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
+ return grub_errno;
- if (found == -1)
- return 0;
+ if (found == -1)
+ return 0;
+ root_idx = found;
+ } while (! isleaf);
+
/* If there was a matching record in this leaf node, continue the
iteration until the last record was found. */
- if (isleaf)
- {
- grub_hfs_iterate_records (data, 0, next, 1, it_dir);
- return grub_errno;
- }
-
- return grub_hfs_iterate_dir (data, found, dir, hook);
+ grub_hfs_iterate_records (data, 0, next, 1, it_dir);
+ return grub_errno;
}
--
Bean
- hfs breakage, Pavel Roskin, 2008/01/15
- Re: hfs breakage,
Bean <=
- Re: hfs breakage, Pavel Roskin, 2008/01/20
- Re: hfs breakage, Marco Gerards, 2008/01/21
- Re: hfs breakage, Bean, 2008/01/22
- Re: hfs breakage, Marco Gerards, 2008/01/23
- Re: hfs breakage, Bean, 2008/01/23
- Re: hfs breakage, Marco Gerards, 2008/01/23
- Re: hfs breakage, Bean, 2008/01/23