Add vfs file size detection to ROM modules

When mounting a ROM module with binary="no", the
vfs will detect the 0-termination to calculate the
file size instead of using the dataspace size.

Fixes #2903
This commit is contained in:
Johannes Schlatow 2018-07-04 14:59:02 +02:00 committed by Christian Helmuth
parent b1b83f4d6d
commit c43ed44b17

View File

@ -24,12 +24,17 @@ class Vfs::Rom_file_system : public Single_file_system
{ {
private: private:
enum Rom_type { ROM_TEXT, ROM_BINARY };
struct Label struct Label
{ {
enum { LABEL_MAX_LEN = 64 }; enum { LABEL_MAX_LEN = 64 };
char string[LABEL_MAX_LEN]; char string[LABEL_MAX_LEN];
bool const binary;
Label(Xml_node config) Label(Xml_node config)
:
binary(config.attribute_value("binary", true))
{ {
/* obtain label from config */ /* obtain label from config */
string[0] = 0; string[0] = 0;
@ -52,19 +57,33 @@ class Vfs::Rom_file_system : public Single_file_system
Genode::Attached_rom_dataspace &_rom; Genode::Attached_rom_dataspace &_rom;
file_size const _content_size;
file_size _init_content_size(Rom_type type)
{
if (type == ROM_TEXT) {
for (file_size pos = 0; pos < _rom.size(); pos++)
if (_rom.local_addr<char>()[pos] == 0x00)
return pos;
}
return _rom.size();
}
public: public:
Rom_vfs_handle(Directory_service &ds, Rom_vfs_handle(Directory_service &ds,
File_io_service &fs, File_io_service &fs,
Genode::Allocator &alloc, Genode::Allocator &alloc,
Genode::Attached_rom_dataspace &rom) Genode::Attached_rom_dataspace &rom,
: Single_vfs_handle(ds, fs, alloc, 0), _rom(rom) { } Rom_type type)
: Single_vfs_handle(ds, fs, alloc, 0), _rom(rom), _content_size(_init_content_size(type)) { }
Read_result read(char *dst, file_size count, Read_result read(char *dst, file_size count,
file_size &out_count) override file_size &out_count) override
{ {
/* file read limit is the size of the dataspace */ /* file read limit is the size of the dataspace */
file_size const max_size = _rom.size(); file_size const max_size = _content_size;
/* current read offset */ /* current read offset */
file_size const read_offset = seek(); file_size const read_offset = seek();
@ -128,7 +147,7 @@ class Vfs::Rom_file_system : public Single_file_system
try { try {
*out_handle = new (alloc) *out_handle = new (alloc)
Rom_vfs_handle(*this, *this, alloc, _rom); Rom_vfs_handle(*this, *this, alloc, _rom, _label.binary ? ROM_BINARY : ROM_TEXT);
return OPEN_OK; return OPEN_OK;
} }
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; } catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }