From 1d301e9c142783497ebdffb159cb8bc203fe2ff0 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 1 Apr 2016 16:10:40 +0200 Subject: [PATCH] lib/vfs: consistent device and inode enumeration Issue #1751 --- .../file_system_session/file_system_session.h | 7 +-- repos/os/include/ram_fs/directory.h | 2 + repos/os/include/vfs/dir_file_system.h | 14 +++--- repos/os/include/vfs/directory_service.h | 18 +++---- repos/os/include/vfs/ram_file_system.h | 48 +++++++++---------- repos/os/include/vfs/single_file_system.h | 3 ++ repos/os/include/vfs/symlink_file_system.h | 6 +-- repos/os/include/vfs/tar_file_system.h | 6 +-- 8 files changed, 54 insertions(+), 50 deletions(-) diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index 88bf14326..6460b7e8b 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -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]; }; diff --git a/repos/os/include/ram_fs/directory.h b/repos/os/include/ram_fs/directory.h index 479245886..90b1e3dba 100644 --- a/repos/os/include/ram_fs/directory.h +++ b/repos/os/include/ram_fs/directory.h @@ -207,6 +207,8 @@ class File_system::Directory : public Node Directory_entry *e = (Directory_entry *)(dst); + e->inode = node->inode(); + if (dynamic_cast(node)) e->type = Directory_entry::TYPE_FILE; if (dynamic_cast(node)) e->type = Directory_entry::TYPE_DIRECTORY; if (dynamic_cast(node)) e->type = Directory_entry::TYPE_SYMLINK; diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index fdef8d66f..129263119 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -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; } diff --git a/repos/os/include/vfs/directory_service.h b/repos/os/include/vfs/directory_service.h index 50747f5de..7cafcb164 100644 --- a/repos/os/include/vfs/directory_service.h +++ b/repos/os/include/vfs/directory_service.h @@ -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; diff --git a/repos/os/include/vfs/ram_file_system.h b/repos/os/include/vfs/ram_file_system.h index 02cab0139..18e746b91 100644 --- a/repos/os/include/vfs/ram_file_system.h +++ b/repos/os/include/vfs/ram_file_system.h @@ -60,8 +60,6 @@ class Vfs_ram::Node : public Genode::Avl_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(node); - if (file) { - dirent.type = Directory_service::DIRENT_TYPE_FILE; - return; - } + File *file = dynamic_cast(node); + if (file) { + dirent.type = Directory_service::DIRENT_TYPE_FILE; + return; + } - Directory *dir = dynamic_cast(node); - if (dir) { - dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY; - return; - } + Directory *dir = dynamic_cast(node); + if (dir) { + dirent.type = Directory_service::DIRENT_TYPE_DIRECTORY; + return; + } - Symlink *symlink = dynamic_cast(node); - if (symlink) { - dirent.type = Directory_service::DIRENT_TYPE_SYMLINK; - } + Symlink *symlink = dynamic_cast(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(node); if (file) { diff --git a/repos/os/include/vfs/single_file_system.h b/repos/os/include/vfs/single_file_system.h index 4b7424c30..5cdff5860 100644 --- a/repos/os/include/vfs/single_file_system.h +++ b/repos/os/include/vfs/single_file_system.h @@ -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; diff --git a/repos/os/include/vfs/symlink_file_system.h b/repos/os/include/vfs/symlink_file_system.h index 1e3c42fb9..2712b9ae8 100644 --- a/repos/os/include/vfs/symlink_file_system.h +++ b/repos/os/include/vfs/symlink_file_system.h @@ -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; } diff --git a/repos/os/include/vfs/tar_file_system.h b/repos/os/include/vfs/tar_file_system.h index 7b2f93c70..38f8ae038 100644 --- a/repos/os/include/vfs/tar_file_system.h +++ b/repos/os/include/vfs/tar_file_system.h @@ -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;