Currently the dir word works by using /packages/misc-files to open a directory in a similar way to a file and then

special-casing directory actions. This is wrong in that in order to list the contents of a directory, open-dev must return true 
for any device which contains a valid filesystem, regardless of whether or not the supplied arguments reference a valid path.

This causes us a problem because in order to implement multiple references in boot-device correctly, we have to fail if we open 
a specific device with invalid arguments (such as a non-existent file reference). This patch therefore makes the following changes:

1) Create a static method in each of the filesystem packages to implement dir
2) Enhance the partition/disk handlers to record the phandle of any detected filesystem during open
3) Create a new dir method in the partition/disk handlers which invokes the static dir method for the currently detected 
filesystem

Hence we can now open a raw device/partition and invoke dir on its filesystem without having to open a specific file-reference 
first. Following shortly is a patch to switch the main dir word over to use this new system.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@816 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Mark Cave-Ayland
2010-07-10 13:11:22 +00:00
committed by Mark Cave-Ayland
parent 930ce00f5f
commit a5511ad95c
9 changed files with 263 additions and 30 deletions

View File

@@ -41,6 +41,7 @@ typedef struct {
int type; /* partition type or -1 */
ihandle_t part_ih;
phandle_t filesystem_ph;
} dlabel_info_t;
DECLARE_NODE( dlabel, 0, sizeof(dlabel_info_t), "/packages/disk-label" );
@@ -72,6 +73,7 @@ dlabel_open( dlabel_info_t *di )
di->part_ih = 0;
/* Find parent methods */
di->filesystem_ph = 0;
di->parent_seek_xt = find_parent_method("seek");
di->parent_tell_xt = find_parent_method("tell");
di->parent_read_xt = find_parent_method("read");
@@ -115,6 +117,9 @@ dlabel_open( dlabel_info_t *di )
ph = POP_ph();
if( ph ) {
/* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */
di->filesystem_ph = ph;
DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph);
DPRINTF("path: %s length: %d\n", path, strlen(path));
if (strlen(path)) {
@@ -205,6 +210,24 @@ dlabel_load( __attribute__((unused)) dlabel_info_t *di )
}
}
/* ( pathstr len -- ) */
static void
dlabel_dir( dlabel_info_t *di )
{
if ( di->filesystem_ph ) {
PUSH( my_self() );
push_str("dir");
PUSH( di->filesystem_ph );
fword("find-method");
POP();
fword("execute");
} else {
forth_printf("disk-label: Unable to determine filesystem\n");
POP();
POP();
}
}
NODE_METHODS( dlabel ) = {
{ "open", dlabel_open },
{ "close", dlabel_close },
@@ -213,6 +236,7 @@ NODE_METHODS( dlabel ) = {
{ "write", dlabel_write },
{ "seek", dlabel_seek },
{ "tell", dlabel_tell },
{ "dir", dlabel_dir },
};
void

View File

@@ -181,7 +181,6 @@ macparts_open( macparts_info_t *di )
ret = -1;
goto out;
}
}
/* not found */
if (firstHFS != -1) {
@@ -341,12 +340,34 @@ macparts_load( __attribute__((unused))macparts_info_t *di )
load(my_self());
}
/* ( pathstr len -- ) */
static void
macparts_dir( macparts_info_t *di )
{
/* On PPC Mac, the first partition chosen according to the CHRP boot
specification (i.e. marked as bootable) may not necessarily contain
a valid FS */
if ( di->filesystem_ph ) {
PUSH( my_self() );
push_str("dir");
PUSH( di->filesystem_ph );
fword("find-method");
POP();
fword("execute");
} else {
forth_printf("mac-parts: Unable to determine filesystem\n");
POP();
POP();
}
}
NODE_METHODS( macparts ) = {
{ "probe", macparts_probe },
{ "open", macparts_open },
{ "seek", macparts_seek },
{ "read", macparts_read },
{ "load", macparts_load },
{ "dir", macparts_dir },
{ "get-info", macparts_get_info },
{ "block-size", macparts_block_size },
{ NULL, macparts_initialize },

View File

@@ -365,6 +365,23 @@ pcparts_load( __attribute__((unused))pcparts_info_t *di )
load(my_self());
}
/* ( pathstr len -- ) */
static void
pcparts_dir( pcparts_info_t *di )
{
if ( di->filesystem_ph ) {
PUSH( my_self() );
push_str("dir");
PUSH( di->filesystem_ph );
fword("find-method");
POP();
fword("execute");
} else {
forth_printf("pc-parts: Unable to determine filesystem\n");
POP();
POP();
}
}
NODE_METHODS( pcparts ) = {
{ "probe", pcparts_probe },
@@ -372,6 +389,7 @@ NODE_METHODS( pcparts ) = {
{ "seek", pcparts_seek },
{ "read", pcparts_read },
{ "load", pcparts_load },
{ "dir", pcparts_dir },
{ "get-info", pcparts_get_info },
{ "block-size", pcparts_block_size },
{ NULL, pcparts_initialize },

View File

@@ -297,6 +297,23 @@ sunparts_load( __attribute__((unused))sunparts_info_t *di )
load(my_self());
}
/* ( pathstr len -- ) */
static void
sunparts_dir( sunparts_info_t *di )
{
if ( di->filesystem_ph) {
PUSH( my_self() );
push_str("dir");
PUSH( di->filesystem_ph );
fword("find-method");
POP();
fword("execute");
} else {
forth_printf("sun-parts: Unable to determine filesystem\n");
POP();
POP();
}
}
NODE_METHODS( sunparts ) = {
{ "probe", sunparts_probe },
@@ -306,6 +323,7 @@ NODE_METHODS( sunparts ) = {
{ "seek", sunparts_seek },
{ "read", sunparts_read },
{ "load", sunparts_load },
{ "dir", sunparts_dir },
{ NULL, sunparts_initialize },
};