Skip to content

Commit

Permalink
libc: make Vfs_plugin::Sync accessible
Browse files Browse the repository at this point in the history
Make the Sync object accessible outside of Vfs_plugin implementation,
e.g., for use in AIO.

Issue genodelabs#5302
  • Loading branch information
atopia authored and chelmuth committed Sep 6, 2024
1 parent 39838ce commit a7da360
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 38 deletions.
25 changes: 24 additions & 1 deletion repos/libports/src/lib/libc/internal/vfs_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <unistd.h>

/* libc-internal includes */
#include <internal/current_time.h>
#include <internal/plugin.h>
#include <internal/fd_alloc.h>
#include <internal/errno.h>
Expand All @@ -36,9 +37,31 @@ namespace Libc { class Vfs_plugin; }
class Libc::Vfs_plugin final : public Plugin
{
public:

enum class Update_mtime { NO, YES };

/*
* Needed to construct a sync object from a Vfs_plugin / Plugin reference.
*/
class Sync
{
private:

enum { INITIAL, TIMESTAMP_UPDATED, QUEUED, COMPLETE } _state { INITIAL };

Vfs::Vfs_handle &_vfs_handle;
Vfs::Timestamp _mtime { Vfs::Timestamp::INVALID };

public:

Sync(Vfs::Vfs_handle &vfs_handle, Libc::Vfs_plugin::Update_mtime update_mtime,
Libc::Current_real_time &current_real_time);

Sync(Vfs::Vfs_handle &vfs_handle, Plugin & plugin);

bool complete();
};


/**
* Return path to pseudo files used for ioctl operations of a given FD
*
Expand Down
85 changes: 48 additions & 37 deletions repos/libports/src/lib/libc/vfs_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include <internal/errno.h>
#include <internal/init.h>
#include <internal/monitor.h>
#include <internal/current_time.h>


static Libc::Monitor *_monitor_ptr;
Expand Down Expand Up @@ -543,51 +542,63 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags)
}


struct Sync
Libc::Vfs_plugin::Sync::Sync(Vfs::Vfs_handle &vfs_handle, Libc::Vfs_plugin::Update_mtime update_mtime,
Libc::Current_real_time &current_real_time)
:
_vfs_handle(vfs_handle)
{
enum { INITIAL, TIMESTAMP_UPDATED, QUEUED, COMPLETE } state { INITIAL };
if (update_mtime == Libc::Vfs_plugin::Update_mtime::NO
|| !current_real_time.has_real_time()) {

Vfs::Vfs_handle &vfs_handle;
Vfs::Timestamp mtime { Vfs::Timestamp::INVALID };
_state = TIMESTAMP_UPDATED;

Sync(Vfs::Vfs_handle &vfs_handle, Libc::Vfs_plugin::Update_mtime update_mtime,
Libc::Current_real_time &current_real_time)
:
vfs_handle(vfs_handle)
{
if (update_mtime == Libc::Vfs_plugin::Update_mtime::NO
|| !current_real_time.has_real_time()) {
} else {
timespec const ts = current_real_time.current_real_time();

state = TIMESTAMP_UPDATED;
_mtime = { .value = (long long)ts.tv_sec };
}
}

} else {
timespec const ts = current_real_time.current_real_time();

mtime = { .value = (long long)ts.tv_sec };
}

Libc::Vfs_plugin::Sync::Sync(Vfs::Vfs_handle &vfs_handle, Plugin & plugin)
:
_vfs_handle(vfs_handle)
{
Vfs_plugin & vfs_plugin = reinterpret_cast<Vfs_plugin &>(plugin);
if (vfs_plugin._update_mtime == Libc::Vfs_plugin::Update_mtime::NO
|| !vfs_plugin._current_real_time.has_real_time()) {

_state = TIMESTAMP_UPDATED;

} else {
timespec const ts = vfs_plugin._current_real_time.current_real_time();

_mtime = { .value = (long long)ts.tv_sec };
}
}

bool complete()
{
switch (state) {
case Sync::INITIAL:
if (!vfs_handle.fs().update_modification_timestamp(&vfs_handle, mtime))
return false;
state = Sync::TIMESTAMP_UPDATED; [[ fallthrough ]];
case Sync::TIMESTAMP_UPDATED:
if (!vfs_handle.fs().queue_sync(&vfs_handle))
return false;
state = Sync::QUEUED; [[ fallthrough ]];
case Sync::QUEUED:
if (vfs_handle.fs().complete_sync(&vfs_handle) == Vfs::File_io_service::SYNC_QUEUED)
return false;
state = Sync::COMPLETE; [[ fallthrough ]];
case Sync::COMPLETE:
break;
}
return true;

bool Libc::Vfs_plugin::Sync::complete()
{
switch (_state) {
case Sync::INITIAL:
if (!_vfs_handle.fs().update_modification_timestamp(&_vfs_handle, _mtime))
return false;
_state = Sync::TIMESTAMP_UPDATED; [[ fallthrough ]];
case Sync::TIMESTAMP_UPDATED:
if (!_vfs_handle.fs().queue_sync(&_vfs_handle))
return false;
_state = Sync::QUEUED; [[ fallthrough ]];
case Sync::QUEUED:
if (_vfs_handle.fs().complete_sync(&_vfs_handle) == Vfs::File_io_service::SYNC_QUEUED)
return false;
_state = Sync::COMPLETE; [[ fallthrough ]];
case Sync::COMPLETE:
break;
}
};
return true;
}


int Libc::Vfs_plugin::close_from_kernel(File_descriptor *fd)
Expand Down

0 comments on commit a7da360

Please sign in to comment.