On Jan 16, 2008 8:38 AM, Pavel Roskin <[EMAIL PROTECTED]> 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 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel