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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user