mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
file system: enhanced file status info
This patch extends the 'File_system::Status', 'File_system::Directory_entry', and the related 'Vfs' types with the following additional information: - Distinction between continuous and transactional files (Node_type) (issue #3507) - Readable, writeable, and executable attributes (Node_rwx), replacing the former 'mode' bits (issue #3030) The types 'Node_rwx', 'Node_type' are defined twice, once for the VFS (vfs/types.h) and once for the 'File_system' session (file_system_session/file_system_session.h). Similarly, there is a direct correspondance between 'Vfs::Directory_service::Dirent' and 'File_system::Directory_entry'. This duplication of types follows the existing pattern of keeping the VFS and file-system session independent from each other.
This commit is contained in:
committed by
Christian Helmuth
parent
1297a8fb57
commit
5ab1505d43
@ -69,6 +69,50 @@ class Vfs::Fs_file_system : public File_system
|
||||
struct Fs_vfs_handle;
|
||||
typedef Genode::Fifo<Fs_vfs_handle> Fs_vfs_handle_queue;
|
||||
|
||||
/**
|
||||
* Convert 'File_system::Node_type' to 'Dirent_type'
|
||||
*/
|
||||
static Dirent_type _dirent_type(::File_system::Node_type type)
|
||||
{
|
||||
using ::File_system::Node_type;
|
||||
|
||||
switch (type) {
|
||||
case Node_type::DIRECTORY: return Dirent_type::DIRECTORY;
|
||||
case Node_type::CONTINUOUS_FILE: return Dirent_type::CONTINUOUS_FILE;
|
||||
case Node_type::TRANSACTIONAL_FILE: return Dirent_type::TRANSACTIONAL_FILE;
|
||||
case Node_type::SYMLINK: return Dirent_type::SYMLINK;
|
||||
}
|
||||
return Dirent_type::END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 'File_system::Node_type' to 'Vfs::Node_type'
|
||||
*/
|
||||
static Node_type _node_type(::File_system::Node_type type)
|
||||
{
|
||||
using Type = ::File_system::Node_type;
|
||||
|
||||
switch (type) {
|
||||
case Type::DIRECTORY: return Node_type::DIRECTORY;
|
||||
case Type::CONTINUOUS_FILE: return Node_type::CONTINUOUS_FILE;
|
||||
case Type::TRANSACTIONAL_FILE: return Node_type::TRANSACTIONAL_FILE;
|
||||
case Type::SYMLINK: return Node_type::SYMLINK;
|
||||
}
|
||||
|
||||
Genode::error("invalid File_system::Node_type");
|
||||
return Node_type::CONTINUOUS_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 'File_system::Node_rwx' to 'Vfs::Node_rwx'
|
||||
*/
|
||||
static Node_rwx _node_rwx(::File_system::Node_rwx rwx)
|
||||
{
|
||||
return { .readable = rwx.readable,
|
||||
.writeable = rwx.writeable,
|
||||
.executable = rwx.executable };
|
||||
}
|
||||
|
||||
struct Fs_vfs_handle : Vfs_handle,
|
||||
private ::File_system::Node,
|
||||
private Handle_space::Element,
|
||||
@ -295,41 +339,38 @@ class Vfs::Fs_file_system : public File_system
|
||||
|
||||
using ::File_system::Directory_entry;
|
||||
|
||||
Directory_entry entry;
|
||||
file_size entry_out_count;
|
||||
Directory_entry entry { };
|
||||
file_size entry_out_count = 0;
|
||||
|
||||
Read_result read_result =
|
||||
Read_result const read_result =
|
||||
_complete_read(&entry, DIRENT_SIZE, entry_out_count);
|
||||
|
||||
if (read_result != READ_OK)
|
||||
return read_result;
|
||||
|
||||
Dirent *dirent = (Dirent*)dst;
|
||||
entry.sanitize();
|
||||
|
||||
Dirent &dirent = *(Dirent*)dst;
|
||||
|
||||
if (entry_out_count < DIRENT_SIZE) {
|
||||
|
||||
/* no entry found for the given index, or error */
|
||||
*dirent = Dirent();
|
||||
dirent = Dirent {
|
||||
.fileno = 0,
|
||||
.type = Dirent_type::END,
|
||||
.rwx = { },
|
||||
.name = { }
|
||||
};
|
||||
out_count = sizeof(Dirent);
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* The default value has no meaning because the switch below
|
||||
* assigns a value in each possible branch. But it is needed to
|
||||
* keep the compiler happy.
|
||||
*/
|
||||
Dirent_type type = DIRENT_TYPE_END;
|
||||
|
||||
/* copy-out payload into destination buffer */
|
||||
switch (entry.type) {
|
||||
case Directory_entry::TYPE_DIRECTORY: type = DIRENT_TYPE_DIRECTORY; break;
|
||||
case Directory_entry::TYPE_FILE: type = DIRENT_TYPE_FILE; break;
|
||||
case Directory_entry::TYPE_SYMLINK: type = DIRENT_TYPE_SYMLINK; break;
|
||||
}
|
||||
|
||||
dirent->fileno = entry.inode;
|
||||
dirent->type = type;
|
||||
strncpy(dirent->name, entry.name, sizeof(dirent->name));
|
||||
dirent = Dirent {
|
||||
.fileno = entry.inode,
|
||||
.type = _dirent_type(entry.type),
|
||||
.rwx = _node_rwx(entry.rwx),
|
||||
.name = { entry.name.buf }
|
||||
};
|
||||
|
||||
out_count = sizeof(Dirent);
|
||||
|
||||
@ -646,20 +687,13 @@ class Vfs::Fs_file_system : public File_system
|
||||
|
||||
out = Stat();
|
||||
|
||||
out.size = status.size;
|
||||
out.mode = STAT_MODE_FILE | 0777;
|
||||
|
||||
if (status.symlink())
|
||||
out.mode = STAT_MODE_SYMLINK | 0777;
|
||||
|
||||
if (status.directory())
|
||||
out.mode = STAT_MODE_DIRECTORY | 0777;
|
||||
|
||||
out.uid = 0;
|
||||
out.gid = 0;
|
||||
out.inode = status.inode;
|
||||
out.size = status.size;
|
||||
out.type = _node_type(status.type);
|
||||
out.rwx = _node_rwx(status.rwx);
|
||||
out.inode = status.inode;
|
||||
out.device = (Genode::addr_t)this;
|
||||
out.modification_time.value = status.modification_time.value;
|
||||
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user