lib/vfs: consistent device and inode enumeration

Issue #1751
This commit is contained in:
Emery Hemingway 2016-04-01 16:10:40 +02:00 committed by Christian Helmuth
parent b8e52189d5
commit 1d301e9c14
8 changed files with 54 additions and 50 deletions

View File

@ -185,9 +185,10 @@ struct File_system::Control { /* to manipulate the executable bit */ };
struct File_system::Directory_entry
{
enum Type { TYPE_FILE, TYPE_DIRECTORY, TYPE_SYMLINK };
unsigned inode;
Type type;
char name[MAX_NAME_LEN];
unsigned long inode;
Type type;
char name[MAX_NAME_LEN];
};

View File

@ -207,6 +207,8 @@ class File_system::Directory : public Node
Directory_entry *e = (Directory_entry *)(dst);
e->inode = node->inode();
if (dynamic_cast<File *>(node)) e->type = Directory_entry::TYPE_FILE;
if (dynamic_cast<Directory *>(node)) e->type = Directory_entry::TYPE_DIRECTORY;
if (dynamic_cast<Symlink *>(node)) e->type = Directory_entry::TYPE_SYMLINK;

View File

@ -168,9 +168,7 @@ class Vfs::Dir_file_system : public File_system
*/
if (index - base < fs_num_dirent) {
index = index - base;
Dirent_result const err = fs->dirent(path, index, out);
out.fileno += base;
return err;
return fs->dirent(path, index, out);;
}
/* adjust base index for next file system */
@ -289,10 +287,12 @@ class Vfs::Dir_file_system : public File_system
* current directory.
*/
if (strlen(path) == 0 || (strcmp(path, "/") == 0)) {
out.size = 0;
out.mode = STAT_MODE_DIRECTORY | 0755;
out.uid = 0;
out.gid = 0;
out.size = 0;
out.mode = STAT_MODE_DIRECTORY | 0755;
out.uid = 0;
out.gid = 0;
out.inode = 1;
out.device = (Genode::addr_t)this;
return STAT_OK;
}

View File

@ -86,12 +86,12 @@ struct Vfs::Directory_service
struct Stat
{
file_size size;
unsigned mode;
unsigned uid;
unsigned gid;
unsigned long inode;
unsigned device;
file_size size;
unsigned mode;
unsigned uid;
unsigned gid;
unsigned long inode;
unsigned long device;
};
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,
@ -120,9 +120,9 @@ struct Vfs::Directory_service
struct Dirent
{
int fileno;
Dirent_type type;
char name[DIRENT_MAX_NAME_LEN];
unsigned long fileno;
Dirent_type type;
char name[DIRENT_MAX_NAME_LEN];
};
virtual Dirent_result dirent(char const *path, file_offset index, Dirent &) = 0;

View File

@ -60,8 +60,6 @@ class Vfs_ram::Node : public Genode::Avl_node<Node>, public Genode::Lock
/**
* Generate unique inode number
*
* XXX: these inodes could clash with other VFS plugins
*/
static unsigned _unique_inode()
{
@ -309,33 +307,32 @@ class Vfs_ram::Directory : public Vfs_ram::Node
void dirent(file_offset index, Directory_service::Dirent &dirent)
{
dirent.fileno = index+1;
dirent.type = Directory_service::DIRENT_TYPE_END;
dirent.name[0] = '\0';
Node *node = _entries.first();
if (node) {
node = node->index(index);
if (!node) return;
if (node) node = node->index(index);
if (!node) {
dirent.type = Directory_service::DIRENT_TYPE_END;
return;
}
strncpy(dirent.name, node->name(), sizeof(dirent.name));
dirent.fileno = node->inode;
strncpy(dirent.name, node->name(), sizeof(dirent.name));
File *file = dynamic_cast<File *>(node);
if (file) {
dirent.type = Directory_service::DIRENT_TYPE_FILE;
return;
}
File *file = dynamic_cast<File *>(node);
if (file) {
dirent.type = Directory_service::DIRENT_TYPE_FILE;
return;
}
Directory *dir = dynamic_cast<Directory *>(node);
if (dir) {
dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY;
return;
}
Directory *dir = dynamic_cast<Directory *>(node);
if (dir) {
dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY;
return;
}
Symlink *symlink = dynamic_cast<Symlink *>(node);
if (symlink) {
dirent.type = Directory_service::DIRENT_TYPE_SYMLINK;
}
Symlink *symlink = dynamic_cast<Symlink *>(node);
if (symlink) {
dirent.type = Directory_service::DIRENT_TYPE_SYMLINK;
return;
}
}
};
@ -531,8 +528,9 @@ class Vfs::Ram_file_system : public Vfs::File_system
if (!node) return STAT_ERR_NO_ENTRY;
Node::Guard guard(node);
stat.inode = node->inode;
stat.size = node->length();
stat.inode = node->inode;
stat.device = (Genode::addr_t)this;
File *file = dynamic_cast<File *>(node);
if (file) {

View File

@ -71,6 +71,7 @@ class Vfs::Single_file_system : public File_system
Stat_result stat(char const *path, Stat &out) override
{
out = { 0, 0, 0, 0, 0, 0 };
out.device = (Genode::addr_t)this;
if (_is_root(path)) {
out.mode = STAT_MODE_DIRECTORY;
@ -81,6 +82,7 @@ class Vfs::Single_file_system : public File_system
case NODE_TYPE_CHAR_DEVICE: out.mode = STAT_MODE_CHARDEV; break;
case NODE_TYPE_BLOCK_DEVICE: out.mode = STAT_MODE_BLOCKDEV; break;
}
out.inode = 1;
} else {
return STAT_ERR_NO_ENTRY;
}
@ -93,6 +95,7 @@ class Vfs::Single_file_system : public File_system
return DIRENT_ERR_INVALID_PATH;
if (index == 0) {
out.fileno = (Genode::addr_t)this;
switch (_node_type) {
case NODE_TYPE_FILE: out.type = DIRENT_TYPE_FILE; break;
case NODE_TYPE_CHAR_DEVICE: out.type = DIRENT_TYPE_CHARDEV; break;

View File

@ -76,12 +76,14 @@ class Vfs::Symlink_file_system : public File_system
Stat_result stat(char const *path, Stat &out) override
{
out = { 0, 0, 0, 0, 0, 0 };
out.device = (Genode::addr_t)this;
if (_is_root(path)) {
out.mode = STAT_MODE_DIRECTORY;
} else if (_is_single_file(path)) {
out.mode = STAT_MODE_SYMLINK;
out.inode = 1;
} else {
return STAT_ERR_NO_ENTRY;
}
@ -114,15 +116,13 @@ class Vfs::Symlink_file_system : public File_system
if (!_is_root(path))
return DIRENT_ERR_INVALID_PATH;
out.fileno = 1;
if (index == 0) {
out.fileno = (Genode::addr_t)this;
out.type = DIRENT_TYPE_SYMLINK;
strncpy(out.name, _filename, sizeof(out.name));
} else {
out.type = DIRENT_TYPE_END;
out.name[0] = '\0';
}
return DIRENT_OK;
}

View File

@ -457,7 +457,8 @@ class Vfs::Tar_file_system : public File_system
out.size = record->size();
out.uid = record->uid();
out.gid = record->gid();
out.inode = (unsigned long)node;
out.inode = (Genode::addr_t)node;
out.device = (Genode::addr_t)this;
return STAT_OK;
}
@ -472,12 +473,11 @@ class Vfs::Tar_file_system : public File_system
node = node->lookup_child(index);
if (!node) {
out.name[0] = '\0';
out.type = DIRENT_TYPE_END;
return DIRENT_OK;
}
out.fileno = (unsigned long)node;
out.fileno = (Genode::addr_t)node;
Record const *record = node->record;