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:
Norman Feske
2019-09-25 17:13:29 +02:00
committed by Christian Helmuth
parent 1297a8fb57
commit 5ab1505d43
52 changed files with 1049 additions and 668 deletions

View File

@@ -197,25 +197,28 @@ class Vfs::Rump_file_system : public File_system
struct stat s;
rump_sys_lstat(path, &s);
vfs_dir.fileno = s.st_ino;
auto dirent_type = [] (unsigned mode)
{
if (S_ISREG (mode)) return Dirent_type::CONTINUOUS_FILE;
if (S_ISDIR (mode)) return Dirent_type::DIRECTORY;
if (S_ISLNK (mode)) return Dirent_type::SYMLINK;
if (S_ISBLK (mode)) return Dirent_type::CONTINUOUS_FILE;
if (S_ISCHR (mode)) return Dirent_type::CONTINUOUS_FILE;
if (S_ISFIFO(mode)) return Dirent_type::CONTINUOUS_FILE;
if (S_ISREG(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_FILE;
else if (S_ISDIR(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_DIRECTORY;
else if (S_ISLNK(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_SYMLINK;
else if (S_ISBLK(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_BLOCKDEV;
else if (S_ISCHR(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_CHARDEV;
else if (S_ISFIFO(s.st_mode))
vfs_dir.type = Dirent_type::DIRENT_TYPE_FIFO;
else
vfs_dir.type = Dirent_type::DIRENT_TYPE_FILE;
return Dirent_type::END;
};
strncpy(vfs_dir.name, dent->d_name, sizeof(Dirent::name));
Node_rwx const rwx { .readable = (s.st_mode & S_IRUSR),
.writeable = (s.st_mode & S_IWUSR),
.executable = (s.st_mode & S_IXUSR) };
vfs_dir = {
.fileno = s.st_ino,
.type = dirent_type(s.st_mode),
.rwx = rwx,
.name = { dent->d_name }
};
return READ_OK;
}
@@ -699,12 +702,25 @@ class Vfs::Rump_file_system : public File_system
struct stat sb;
if (rump_sys_lstat(path, &sb) != 0) return STAT_ERR_NO_ENTRY;
stat.size = sb.st_size;
stat.mode = sb.st_mode;
stat.uid = sb.st_uid;
stat.gid = sb.st_gid;
stat.inode = sb.st_ino;
stat.device = sb.st_dev;
auto type = [] (unsigned mode)
{
if (S_ISDIR(mode)) return Node_type::DIRECTORY;
if (S_ISLNK(mode)) return Node_type::SYMLINK;
return Node_type::CONTINUOUS_FILE;
};
stat = {
.size = (file_size)sb.st_size,
.type = type(sb.st_mode),
.rwx = { .readable = (sb.st_mode & S_IRUSR),
.writeable = (sb.st_mode & S_IWUSR),
.executable = (sb.st_mode & S_IXUSR) },
.inode = sb.st_ino,
.device = sb.st_dev,
.modification_time = { 0 }
};
return STAT_OK;
}

View File

@@ -218,18 +218,26 @@ class Rump_fs::Directory : public Node
struct stat s;
rump_sys_lstat(path, &s);
Directory_entry *e = (Directory_entry *)(dst);
if (S_ISDIR(s.st_mode))
e->type = Directory_entry::TYPE_DIRECTORY;
else if (S_ISREG(s.st_mode))
e->type = Directory_entry::TYPE_FILE;
else if (S_ISLNK(s.st_mode))
e->type = Directory_entry::TYPE_SYMLINK;
else
return 0;
auto type = [] (unsigned mode)
{
if (S_ISDIR(mode)) return Node_type::DIRECTORY;
else if (S_ISREG(mode)) return Node_type::CONTINUOUS_FILE;
else if (S_ISLNK(mode)) return Node_type::SYMLINK;
else return Node_type::CONTINUOUS_FILE;
};
Node_rwx const rwx { .readable = (s.st_mode & S_IRUSR),
.writeable = (s.st_mode & S_IWUSR),
.executable = (s.st_mode & S_IXUSR) };
Directory_entry &e = *(Directory_entry *)(dst);
e = {
.inode = s.st_ino,
.type = type(s.st_mode),
.rwx = rwx,
.name = { dent->d_name }
};
e->inode = s.st_ino;
strncpy(e->name, dent->d_name, dent->d_namlen + 1);
return sizeof(Directory_entry);
}
@@ -245,13 +253,15 @@ class Rump_fs::Directory : public Node
if (rump_sys_fstat(_fd, &st) < 0)
st.st_mtime = 0;
Status s;
s.inode = inode();
s.size = num_entries() * sizeof (Directory_entry);
s.mode = File_system::Status::MODE_DIRECTORY;
s.modification_time = { (int64_t)st.st_mtime };
return s;
return {
.size = num_entries() * sizeof (Directory_entry),
.type = File_system::Node_type::DIRECTORY,
.rwx = { .readable = (st.st_mode & S_IRUSR),
.writeable = (st.st_mode & S_IWUSR),
.executable = (st.st_mode & S_IXUSR) },
.inode = inode(),
.modification_time = { (int64_t)st.st_mtime }
};
}
size_t num_entries() const

View File

@@ -153,20 +153,21 @@ class Rump_fs::File : public Node
virtual Status status() override
{
struct stat st;
struct stat st { };
if (rump_sys_fstat(_fd, &st) < 0) {
st.st_size = 0;
st.st_mtime = 0;
}
Status s;
s.inode = inode();
s.size = st.st_size;
s.mode = File_system::Status::MODE_FILE;
s.modification_time = { (int64_t)st.st_mtime };
return s;
return {
.size = (file_size_t)st.st_size,
.type = File_system::Node_type::CONTINUOUS_FILE,
.rwx = { .readable = (st.st_mode & S_IRUSR),
.writeable = (st.st_mode & S_IWUSR),
.executable = (st.st_mode & S_IXUSR) },
.inode = inode(),
.modification_time = { (int64_t)st.st_mtime }
};
}
void truncate(file_size_t size) override

View File

@@ -78,13 +78,15 @@ class Rump_fs::Symlink : public Node
st.st_mtime = 0;
}
Status s;
s.inode = inode();
s.size = length();
s.mode = File_system::Status::MODE_SYMLINK;
s.modification_time = { (int64_t)st.st_mtime };
return s;
return {
.size = length(),
.type = File_system::Node_type::SYMLINK,
.rwx = { .readable = true,
.writeable = true,
.executable = true },
.inode = inode(),
.modification_time = { (int64_t)st.st_mtime }
};
}
file_size_t length()