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 struct File_system::Directory_entry
{ {
enum Type { TYPE_FILE, TYPE_DIRECTORY, TYPE_SYMLINK }; enum Type { TYPE_FILE, TYPE_DIRECTORY, TYPE_SYMLINK };
unsigned inode;
Type type; unsigned long inode;
char name[MAX_NAME_LEN]; 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); Directory_entry *e = (Directory_entry *)(dst);
e->inode = node->inode();
if (dynamic_cast<File *>(node)) e->type = Directory_entry::TYPE_FILE; 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<Directory *>(node)) e->type = Directory_entry::TYPE_DIRECTORY;
if (dynamic_cast<Symlink *>(node)) e->type = Directory_entry::TYPE_SYMLINK; 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) { if (index - base < fs_num_dirent) {
index = index - base; index = index - base;
Dirent_result const err = fs->dirent(path, index, out); return fs->dirent(path, index, out);;
out.fileno += base;
return err;
} }
/* adjust base index for next file system */ /* adjust base index for next file system */
@ -289,10 +287,12 @@ class Vfs::Dir_file_system : public File_system
* current directory. * current directory.
*/ */
if (strlen(path) == 0 || (strcmp(path, "/") == 0)) { if (strlen(path) == 0 || (strcmp(path, "/") == 0)) {
out.size = 0; out.size = 0;
out.mode = STAT_MODE_DIRECTORY | 0755; out.mode = STAT_MODE_DIRECTORY | 0755;
out.uid = 0; out.uid = 0;
out.gid = 0; out.gid = 0;
out.inode = 1;
out.device = (Genode::addr_t)this;
return STAT_OK; return STAT_OK;
} }

View File

@ -86,12 +86,12 @@ struct Vfs::Directory_service
struct Stat struct Stat
{ {
file_size size; file_size size;
unsigned mode; unsigned mode;
unsigned uid; unsigned uid;
unsigned gid; unsigned gid;
unsigned long inode; unsigned long inode;
unsigned device; unsigned long device;
}; };
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS, enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,
@ -120,9 +120,9 @@ struct Vfs::Directory_service
struct Dirent struct Dirent
{ {
int fileno; unsigned long fileno;
Dirent_type type; Dirent_type type;
char name[DIRENT_MAX_NAME_LEN]; char name[DIRENT_MAX_NAME_LEN];
}; };
virtual Dirent_result dirent(char const *path, file_offset index, Dirent &) = 0; 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 * Generate unique inode number
*
* XXX: these inodes could clash with other VFS plugins
*/ */
static unsigned _unique_inode() 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) 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(); Node *node = _entries.first();
if (node) { if (node) node = node->index(index);
node = node->index(index); if (!node) {
if (!node) return; 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); File *file = dynamic_cast<File *>(node);
if (file) { if (file) {
dirent.type = Directory_service::DIRENT_TYPE_FILE; dirent.type = Directory_service::DIRENT_TYPE_FILE;
return; return;
} }
Directory *dir = dynamic_cast<Directory *>(node); Directory *dir = dynamic_cast<Directory *>(node);
if (dir) { if (dir) {
dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY; dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY;
return; return;
} }
Symlink *symlink = dynamic_cast<Symlink *>(node); Symlink *symlink = dynamic_cast<Symlink *>(node);
if (symlink) { if (symlink) {
dirent.type = Directory_service::DIRENT_TYPE_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; if (!node) return STAT_ERR_NO_ENTRY;
Node::Guard guard(node); Node::Guard guard(node);
stat.inode = node->inode;
stat.size = node->length(); stat.size = node->length();
stat.inode = node->inode;
stat.device = (Genode::addr_t)this;
File *file = dynamic_cast<File *>(node); File *file = dynamic_cast<File *>(node);
if (file) { 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 Stat_result stat(char const *path, Stat &out) override
{ {
out = { 0, 0, 0, 0, 0, 0 }; out = { 0, 0, 0, 0, 0, 0 };
out.device = (Genode::addr_t)this;
if (_is_root(path)) { if (_is_root(path)) {
out.mode = STAT_MODE_DIRECTORY; 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_CHAR_DEVICE: out.mode = STAT_MODE_CHARDEV; break;
case NODE_TYPE_BLOCK_DEVICE: out.mode = STAT_MODE_BLOCKDEV; break; case NODE_TYPE_BLOCK_DEVICE: out.mode = STAT_MODE_BLOCKDEV; break;
} }
out.inode = 1;
} else { } else {
return STAT_ERR_NO_ENTRY; return STAT_ERR_NO_ENTRY;
} }
@ -93,6 +95,7 @@ class Vfs::Single_file_system : public File_system
return DIRENT_ERR_INVALID_PATH; return DIRENT_ERR_INVALID_PATH;
if (index == 0) { if (index == 0) {
out.fileno = (Genode::addr_t)this;
switch (_node_type) { switch (_node_type) {
case NODE_TYPE_FILE: out.type = DIRENT_TYPE_FILE; break; case NODE_TYPE_FILE: out.type = DIRENT_TYPE_FILE; break;
case NODE_TYPE_CHAR_DEVICE: out.type = DIRENT_TYPE_CHARDEV; 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 Stat_result stat(char const *path, Stat &out) override
{ {
out = { 0, 0, 0, 0, 0, 0 }; out = { 0, 0, 0, 0, 0, 0 };
out.device = (Genode::addr_t)this;
if (_is_root(path)) { if (_is_root(path)) {
out.mode = STAT_MODE_DIRECTORY; out.mode = STAT_MODE_DIRECTORY;
} else if (_is_single_file(path)) { } else if (_is_single_file(path)) {
out.mode = STAT_MODE_SYMLINK; out.mode = STAT_MODE_SYMLINK;
out.inode = 1;
} else { } else {
return STAT_ERR_NO_ENTRY; return STAT_ERR_NO_ENTRY;
} }
@ -114,15 +116,13 @@ class Vfs::Symlink_file_system : public File_system
if (!_is_root(path)) if (!_is_root(path))
return DIRENT_ERR_INVALID_PATH; return DIRENT_ERR_INVALID_PATH;
out.fileno = 1;
if (index == 0) { if (index == 0) {
out.fileno = (Genode::addr_t)this;
out.type = DIRENT_TYPE_SYMLINK; out.type = DIRENT_TYPE_SYMLINK;
strncpy(out.name, _filename, sizeof(out.name)); strncpy(out.name, _filename, sizeof(out.name));
} else { } else {
out.type = DIRENT_TYPE_END; out.type = DIRENT_TYPE_END;
out.name[0] = '\0';
} }
return DIRENT_OK; return DIRENT_OK;
} }

View File

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