|
|
- #pragma once
-
- #include "gp/containers/array.hpp"
-
- #include <cstddef>
- #include <cstdint>
-
- // TODO: File locking and fsync/fdatasync
- namespace gp {
- /**
- * @brief this enum represents the types of operations available
- */
- enum class operation_type {
- version, ///< this operation queries properties of the filesystem
- flush, ///< flushes any buffer for writing on the filesystem
- attach, ///< adds a filesystem to the system
- detach, ///< remove a filesystem from the system
- walk, ///< change the current directory
- create, ///< creates a file
- open, ///< opens a file, yielding a fid
- read, ///< reads from a file
- write, ///< writes to a file
- clunk, ///< relinquishes a fid
- remove, ///< removes a file
- stat, ///< reads a file metadata
- wstat ///< writes a file metadata
- };
-
- /**
- * @brief this enum represent the type of file handled
- */
- enum class file_type {
- directory, ///< the file is a normal directory
- master_directory, ///< the file is the root directory of a non-root filesystem
- device_directory, ///< the file is a driver mapped to a directory
- root_directory, ///< the file is the root directory
- file, ///< the file is a normal file
- file_device, ///< the file is a driver mapped to a file
- message_pipe ///< the file is a channel to read and write messages to
- };
-
- /**
- * @brief represents file permissions
- */
- struct permission_list {
- bool
- read : 1,
- write : 1,
- execute : 1;
- };
-
- /**
- * @brief represents all levels of permissions in a file
- */
- struct file_permissions {
- permission_list
- user, ///< list of permissions for the owner
- group, ///< list of permissions for the owning group
- others; ///< list of permissions for other users
- };
-
- /**
- * @brief represent a value that should be unique for every entity of the system
- */
- using unique_node = uint64_t;
-
- /**
- * @brief represent a timestamp in seconds
- */
- using timestamp = uint64_t;
-
- /**
- * @brief represent a value that represent an offset into a file
- */
- using file_offset = uint64_t;
-
- /**
- * @brief the expected return type of a stat query, as well as its writing counterpart
- */
- struct f_stats {
- file_type type; ///< the type of file
- unique_node file_id; ///< the unique file id
- unique_node owner_user_id; ///< the user id of the owner of the file
- unique_node owner_group_id; ///< the group id of the file
- unique_node last_modifier_id; ///< the user id of the last user that wrote data to the file
- timestamp last_access; ///< the timestamp for the last time the file was opened or created. If the current user is not root, it is replaced by the system on wstat
- timestamp last_modification; ///< the last modification timestamp. If the current user is not root, it is replaced by the system on wstat
- file_offset file_size; ///< the filesize in bytes
- gp::array<char, 255> filename; ///< the filename, padded with null characters
- };
-
- /**
- * @brief Represent an IO operation as sent to the system, this is an abstract class.
- */
- struct io_operation {
- const operation_type type; ///< the discriminant for the operation type
- protected:
- io_operation(operation_type a) : type(a) {}
- };
-
- /**
- * @brief This operation obtains the version of the targeted filesystem
- */
- struct version_operation : public io_operation {
- const gp::buffer<char> destination; ///< the destination where the data is written
- const gp::buffer<char> root_path; ///< the path of the file system to query for version
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new version operation object
- *
- * @param dest the destination where the data is written
- * @param path the path to the target filesystem
- * @param v_fd a relative root that is used
- */
- version_operation(
- gp::buffer<char> dest,
- gp::buffer<char> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::version}
- , destination(dest)
- , root_path(path)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation flushes a filesystem, writing the data to the associated medium
- */
- struct flush_operation : public io_operation {
- const gp::buffer<char> root_path; ///< the path that is going to be flushed
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new flush operation object
- *
- * @param path the path to a file or to a master directory that is to be flushed
- * @param v_fd a relative root that is used
- */
- flush_operation(
- gp::buffer<char> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::flush}
- , root_path(path)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation mounts a filesystem given a format and a configuration data.
- *
- * It also mounts devices.
- */
- struct attach_operation : public io_operation {
- const gp::buffer<char> target_path; ///< location where the filesystem is going to be attached
- const gp::buffer<char> format; ///< format string of the filesystem
- const gp::buffer<char> configuration; ///< configuration data
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new attach operation object
- *
- * @param path path where the filesystem will be attached, must be either not existing or an empty directory
- * @param v_format the format name that will be invoked with the config
- * @param config the configuration to send
- * @param v_fd a relative root that is used
- */
- attach_operation(
- gp::buffer<char> path,
- gp::buffer<char> v_format,
- gp::buffer<char> config,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::attach}
- , target_path(path)
- , format(v_format)
- , configuration(config)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation removes the master status of a directory and dismounts the
- * filesystem attached to it after flushing it. Will fail if any file is still attached
- * in the filesystem.
- *
- * This applies to the devices too.
- */
- struct detach_operation : public io_operation {
- const gp::buffer<char> target_path; ///< the target master directory
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new detach operation object
- *
- * @param path the item to be detached
- * @param v_fd a relative root that is used
- */
- detach_operation(
- gp::buffer<char> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::attach}
- , target_path(path)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation will move the focus of the target directory relative to itself or absolutely
- */
- struct walk_operation : public io_operation {
- const gp::buffer<char> target_path; ///< the target to move to
- const gp_config::file_descriptor_t fd_to_alter; ///< the fd that will be modified
-
- /**
- * @brief Construct a new walk operation object
- *
- * @param path the target to move to
- * @param dir the original file descriptor
- */
- walk_operation(
- gp::buffer<char> path,
- gp_config::file_descriptor_t dir
- )
- : io_operation{operation_type::walk}
- , target_path(path)
- , fd_to_alter(dir)
- {}
- };
-
- /**
- * @brief selector for the type of file to be created in a given environment
- */
- enum class create_type {
- file, ///< normal file
- directory, ///< directory file
- temporary, ///< file which is to be remove upon all of his descriptors being closed
- pipe_read_side, ///< pipe, read side returned
- pipe_write_side ///< pipe, write side returned
- };
-
- /**
- * @brief This operation will attempt to create a file at the specified destination
- */
- struct create_operation : public io_operation {
- const gp::buffer<char> target_path;
- const create_type mode;
- const gp::optional<gp_config::file_descriptor_t> fd;
-
- /**
- * @brief Create a new create operation object
- *
- * @param path the new file that is created
- * @param v_mode the type of file to create
- * @param v_fd a relative root that is used
- */
- create_operation(
- gp::buffer<char> path,
- create_type v_mode,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::create}
- , target_path(path)
- , mode(v_mode)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief selector for the properties expected from an opened file descriptor
- */
- enum class open_mode {
- read_only, ///< the descriptor will be read only, will fail if no read permissions
- read_write, ///< the descriptor is read-write, will fail if no write permissions, but not if no read permissions
- read_write_create ///< the descriptor is read-write, and has the same proterties as the read-write. The file will be created if it does not exist.
- };
-
- /**
- * @brief This operation will attempt to open a file at the specified destination
- */
- struct open_operation : public io_operation {
- const gp::buffer<char> target_path; ///< the specified path
- open_mode mode; ///< the openning mode
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new open operation object
- *
- * @param path the path where to open a file
- * @param v_mode the mode of opening
- * @param v_fd a relative root that is used
- */
- open_operation(
- gp::buffer<char> path,
- open_mode v_mode,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::create}
- , target_path(path)
- , mode(v_mode)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation will attempt to read a file into the destination starting at the specified offset in the file
- */
- struct read_operation : public io_operation {
- const gp_config::file_descriptor_t fd; ///< the file to read
- const file_offset offset; ///< the offset to start reading at
- const gp::buffer<char> destination; ///< the destination where to write the data
-
- /**
- * @brief Construct a new read operation object
- *
- * @param v_fd the descriptor to read
- * @param off the offset to read
- * @param v_destination the location where the data will be written
- */
- read_operation(
- gp_config::file_descriptor_t v_fd,
- file_offset off,
- gp::buffer<char> v_destination
- )
- : io_operation{operation_type::read}
- , fd{v_fd}
- , offset(off)
- , destination(v_destination)
- {}
- };
-
- /**
- * @brief This operation will attempt to write in file from the source starting at the specified offset in the file
- */
- struct write_operation : public io_operation {
- const gp_config::file_descriptor_t fd; ///< the descriptor of the file where writing happens
- const file_offset offset; ///< the offset in the file where writing starts
- const gp::buffer<char> source; ///< the source data
-
- /**
- * @brief Construct a new write operation object
- *
- * @param v_fd the target file
- * @param off the target offset
- * @param v_source the data source buffer
- */
- write_operation(
- gp_config::file_descriptor_t v_fd,
- file_offset off,
- gp::buffer<char> v_source
- )
- : io_operation{operation_type::write}
- , fd{v_fd}
- , offset(off)
- , source(v_source)
- {}
- };
-
- /**
- * @brief This operation closes a file by relinquishing its file descriptor
- */
- struct clunk_operation : public io_operation {
- const gp_config::file_descriptor_t fd; ///< The descriptor that will be disposed of
-
- /**
- * @brief Construct a new clunk operation object
- *
- * @param v_fd the fd to close
- */
- clunk_operation(gp_config::file_descriptor_t v_fd)
- : io_operation{operation_type::clunk}
- , fd{v_fd}
- {}
- };
-
- /**
- * @brief This operation removes a fileas soon as all its file descriptors are given back
- */
- struct remove_operation : public io_operation {
- const gp::buffer<char*> target_path; ///< the target file
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new remove operation object
- *
- * @param path the path to the file to remove
- * @param v_fd a relative root that is used
- */
- remove_operation(
- gp::buffer<char*> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::remove}
- , target_path(path)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation fetches metadata about a file
- */
- struct stat_operation : public io_operation {
- const gp::buffer<char*> target_path; ///< the file to query metadata about
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new stat operation object
- *
- * @param path the path to the file to query about
- * @param v_fd a relative root that is used
- */
- stat_operation(
- gp::buffer<char*> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::stat}
- , target_path(path)
- , fd(v_fd)
- {}
- };
-
- /**
- * @brief This operation writes metadata about a file
- */
- struct wstat_operation : public io_operation {
- const gp::buffer<char*> target_path; ///< the file to set metadata on
- const gp::optional<gp_config::file_descriptor_t> fd; ///< the relative root to use
-
- /**
- * @brief Construct a new wstat operation object
- *
- * @param path the path to the file to write about
- * @param v_fd a relative root that is used
- */
- wstat_operation(
- gp::buffer<char*> path,
- gp::optional<gp_config::file_descriptor_t> v_fd
- )
- : io_operation{operation_type::wstat}
- , target_path(path)
- , fd(v_fd)
- {}
- };
- }
|