@ -6,441 +6,442 @@
# 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 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 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 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 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 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
*/
n">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
k">const gp : : optional < gp_config : : file_descriptor_t > fd ; ///< the relative root to use
* @ 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 .
err">*/
struct detach_operation : public io_operation {
k">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 )
{ }
p">} ;
/**
* @ 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 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 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 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 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 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 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 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 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 (
n">gp : : buffer < char > path ,
n">open_mode v_mode ,
n">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
k">const gp : : buffer < char > destination ; ///< the destination where to write the data
* @ 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 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 (
n">gp_config : : file_descriptor_t v_fd ,
n">file_offset off ,
n">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
k">const gp : : buffer < char > source ; ///< the source data
* @ 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
cm">/**
o">* @ brief Construct a new read operation object
o">*
* @ 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 )
{ }
p">} ;
/**
* @ 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 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 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 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 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 (
n">gp : : buffer < char * > path ,
n">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
k">const gp : : optional < gp_config : : file_descriptor_t > fd ; ///< the relative root to use
* @ 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
cm">/**
o">* @ 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 )
{ }
p">} ;
/**
* @ 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 (
n">gp : : buffer < char * > path ,
n">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
k">const gp : : optional < gp_config : : file_descriptor_t > fd ; ///< the relative root to use
* @ 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
cm">/**
o">* @ 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 )
{ }
p">} ;
/**
* @ 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 )
{ }
} ;
* @ 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 )
{ }
} ;
}