mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
vfs: add Append_file class
This reverts commit cf904e0a5d
and
introduces the Append_file class instead.
genodelabs/genode#4352
This commit is contained in:
parent
06f24a73d2
commit
bc57e9e647
@ -23,12 +23,12 @@ void Writer::start_iteration(Directory &root,
|
||||
_file_path = Directory::join(path, info.thread_name());
|
||||
|
||||
try {
|
||||
_dst_file.construct(root, _file_path, true);
|
||||
_dst_file.construct(root, _file_path);
|
||||
|
||||
/* initialise packet header */
|
||||
_packet_buffer.init_header(info);
|
||||
}
|
||||
catch (New_file::Create_failed) {
|
||||
catch (Append_file::Create_failed) {
|
||||
error("Could not create file."); }
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace Ctf {
|
||||
using namespace Trace_recorder;
|
||||
|
||||
using Genode::Directory;
|
||||
using Genode::New_file;
|
||||
using Genode::Append_file;
|
||||
|
||||
using Buffer = Write_buffer<32*1024>;
|
||||
|
||||
@ -40,7 +40,7 @@ class Ctf::Writer : public Trace_recorder::Writer_base
|
||||
{
|
||||
private:
|
||||
Buffer &_packet_buffer;
|
||||
Constructible<New_file> _dst_file { };
|
||||
Constructible<Append_file> _dst_file { };
|
||||
Directory::Path _file_path { };
|
||||
|
||||
public:
|
||||
|
@ -64,12 +64,12 @@ class Ctf::Write_buffer
|
||||
});
|
||||
}
|
||||
|
||||
void write_to_file(Genode::New_file &dst, Genode::Directory::Path const &path)
|
||||
void write_to_file(Genode::Append_file &dst, Genode::Directory::Path const &path)
|
||||
{
|
||||
if (_header().empty())
|
||||
return;
|
||||
|
||||
if (dst.append(_buffer, _header().total_length_bytes()) != New_file::Append_result::OK)
|
||||
if (dst.append(_buffer, _header().total_length_bytes()) != Append_file::Append_result::OK)
|
||||
error("Write error for ", path);
|
||||
|
||||
_header().reset();
|
||||
|
@ -35,14 +35,14 @@ void Writer::start_iteration(Directory &root,
|
||||
|
||||
/* append to file */
|
||||
try {
|
||||
_dst_file.construct(root, _file_path, true);
|
||||
_dst_file.construct(root, _file_path);
|
||||
|
||||
_interface_registry.clear();
|
||||
_buffer.clear();
|
||||
_buffer.append<Section_header_block>();
|
||||
_empty_section = true;
|
||||
}
|
||||
catch (New_file::Create_failed) {
|
||||
catch (Append_file::Create_failed) {
|
||||
error("Could not create file."); }
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace Pcapng {
|
||||
using namespace Trace_recorder;
|
||||
|
||||
using Genode::Directory;
|
||||
using Genode::New_file;
|
||||
using Genode::Append_file;
|
||||
|
||||
using Buffer = Write_buffer<32*1024>;
|
||||
|
||||
@ -42,7 +42,7 @@ class Pcapng::Writer : public Trace_recorder::Writer_base
|
||||
Interface_registry &_interface_registry;
|
||||
Buffer &_buffer;
|
||||
Timestamp_calibrator const &_ts_calibrator;
|
||||
Constructible<New_file> _dst_file { };
|
||||
Constructible<Append_file> _dst_file { };
|
||||
Directory::Path _file_path { };
|
||||
bool _empty_section { false };
|
||||
|
||||
|
@ -62,12 +62,12 @@ class Pcapng::Write_buffer
|
||||
return Append_ok();
|
||||
}
|
||||
|
||||
void write_to_file(Genode::New_file &dst, Directory::Path const &path)
|
||||
void write_to_file(Genode::Append_file &dst, Directory::Path const &path)
|
||||
{
|
||||
if (_total_length == 0)
|
||||
return;
|
||||
|
||||
if (dst.append(_buffer, _total_length) != New_file::Append_result::OK)
|
||||
if (dst.append(_buffer, _total_length) != Append_file::Append_result::OK)
|
||||
error("Write error for ", path);
|
||||
|
||||
clear();
|
||||
|
@ -27,6 +27,8 @@ namespace Genode {
|
||||
struct File;
|
||||
class Readonly_file;
|
||||
class File_content;
|
||||
class Writeable_file;
|
||||
class Append_file;
|
||||
class New_file;
|
||||
class Watcher;
|
||||
template <typename>
|
||||
@ -124,6 +126,8 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
friend class Readonly_file;
|
||||
friend class Root_directory;
|
||||
friend class Watcher;
|
||||
friend class Writeable_file;
|
||||
friend class Append_file;
|
||||
friend class New_file;
|
||||
|
||||
/*
|
||||
@ -668,24 +672,21 @@ class Genode::File_content
|
||||
|
||||
|
||||
/**
|
||||
* Utility for writing data to a file via the Genode VFS library
|
||||
* Base class of `New_file` and `Append_file` providing open for write, sync,
|
||||
* and append functionality.
|
||||
*/
|
||||
class Genode::New_file : Noncopyable
|
||||
class Genode::Writeable_file : Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
struct Create_failed : Exception { };
|
||||
|
||||
private:
|
||||
enum class Append_result { OK, WRITE_ERROR };
|
||||
|
||||
Entrypoint &_ep;
|
||||
Allocator &_alloc;
|
||||
Vfs::File_system &_fs;
|
||||
Vfs::Vfs_handle &_handle;
|
||||
protected:
|
||||
|
||||
Vfs::Vfs_handle &_init_handle(Directory &dir,
|
||||
Directory::Path const &rel_path,
|
||||
bool append)
|
||||
static Vfs::Vfs_handle &_init_handle(Directory &dir,
|
||||
Directory::Path const &rel_path)
|
||||
{
|
||||
/* create compound directory */
|
||||
{
|
||||
@ -703,43 +704,24 @@ class Genode::New_file : Noncopyable
|
||||
|
||||
Vfs::Vfs_handle *handle_ptr = nullptr;
|
||||
Vfs::Directory_service::Open_result const res =
|
||||
_fs.open(path.string(), mode, &handle_ptr, _alloc);
|
||||
dir._fs.open(path.string(), mode, &handle_ptr, dir._alloc);
|
||||
|
||||
if (res != Vfs::Directory_service::OPEN_OK || (handle_ptr == nullptr)) {
|
||||
error("failed to create file '", path, "', res=", (int)res);
|
||||
error("failed to create/open file '", path, "' for writing, res=", (int)res);
|
||||
throw Create_failed();
|
||||
}
|
||||
|
||||
Vfs::Directory_service::Stat stat { };
|
||||
if (!append)
|
||||
handle_ptr->fs().ftruncate(handle_ptr, 0);
|
||||
else if (handle_ptr->ds().stat(path.string(), stat) == Vfs::Directory_service::STAT_OK)
|
||||
handle_ptr->seek(stat.size);
|
||||
|
||||
return *handle_ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \throw Create_failed
|
||||
*/
|
||||
New_file(Directory &dir, Directory::Path const &path, bool append = false)
|
||||
:
|
||||
_ep(dir._ep), _alloc(dir._alloc), _fs(dir._fs),
|
||||
_handle(_init_handle(dir, path, append))
|
||||
{ }
|
||||
|
||||
~New_file()
|
||||
static void _sync(Vfs::Vfs_handle &handle, Entrypoint &ep)
|
||||
{
|
||||
while (_handle.fs().queue_sync(&_handle) == false)
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
while (handle.fs().queue_sync(&handle) == false)
|
||||
ep.wait_and_dispatch_one_io_signal();
|
||||
|
||||
for (bool sync_done = false; !sync_done; ) {
|
||||
|
||||
switch (_handle.fs().complete_sync(&_handle)) {
|
||||
switch (handle.fs().complete_sync(&handle)) {
|
||||
|
||||
case Vfs::File_io_service::SYNC_QUEUED:
|
||||
break;
|
||||
@ -755,14 +737,12 @@ class Genode::New_file : Noncopyable
|
||||
}
|
||||
|
||||
if (!sync_done)
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
ep.wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
_handle.ds().close(&_handle);
|
||||
}
|
||||
|
||||
enum class Append_result { OK, WRITE_ERROR };
|
||||
|
||||
Append_result append(char const *src, size_t size)
|
||||
static Append_result _append(Vfs::Vfs_handle &handle, Entrypoint &ep,
|
||||
char const *src, size_t size)
|
||||
{
|
||||
bool write_error = false;
|
||||
|
||||
@ -777,7 +757,7 @@ class Genode::New_file : Noncopyable
|
||||
|
||||
using Write_result = Vfs::File_io_service::Write_result;
|
||||
|
||||
switch (_handle.fs().write(&_handle, src, remaining_bytes,
|
||||
switch (handle.fs().write(&handle, src, remaining_bytes,
|
||||
out_count)) {
|
||||
|
||||
case Write_result::WRITE_ERR_AGAIN:
|
||||
@ -795,7 +775,7 @@ class Genode::New_file : Noncopyable
|
||||
out_count = min((Vfs::file_size)remaining_bytes, out_count);
|
||||
remaining_bytes -= (size_t)out_count;
|
||||
src += out_count;
|
||||
_handle.advance_seek(out_count);
|
||||
handle.advance_seek(out_count);
|
||||
break;
|
||||
};
|
||||
}
|
||||
@ -803,7 +783,7 @@ class Genode::New_file : Noncopyable
|
||||
stalled = true; }
|
||||
|
||||
if (stalled)
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
ep.wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
return write_error ? Append_result::WRITE_ERROR
|
||||
: Append_result::OK;
|
||||
@ -811,6 +791,81 @@ class Genode::New_file : Noncopyable
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Utility for appending data to an existing file via the Genode VFS library
|
||||
*/
|
||||
class Genode::Append_file : public Writeable_file
|
||||
{
|
||||
private:
|
||||
|
||||
Entrypoint &_ep;
|
||||
Vfs::Vfs_handle &_handle;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \throw Create_failed
|
||||
*/
|
||||
Append_file(Directory &dir, Directory::Path const &path)
|
||||
:
|
||||
_ep(dir._ep),
|
||||
_handle(_init_handle(dir, path))
|
||||
{
|
||||
Vfs::Directory_service::Stat stat { };
|
||||
if (_handle.ds().stat(path.string(), stat) == Vfs::Directory_service::STAT_OK)
|
||||
_handle.seek(stat.size);
|
||||
}
|
||||
|
||||
~Append_file()
|
||||
{
|
||||
_sync(_handle, _ep);
|
||||
_handle.ds().close(&_handle);
|
||||
}
|
||||
|
||||
Append_result append(char const *src, size_t size) {
|
||||
return _append(_handle, _ep, src, size); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Utility for writing data to a new file via the Genode VFS library
|
||||
*/
|
||||
class Genode::New_file : public Writeable_file
|
||||
{
|
||||
private:
|
||||
|
||||
Entrypoint &_ep;
|
||||
Vfs::Vfs_handle &_handle;
|
||||
|
||||
public:
|
||||
|
||||
using Writeable_file::Append_result;
|
||||
using Writeable_file::Create_failed;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \throw Create_failed
|
||||
*/
|
||||
New_file(Directory &dir, Directory::Path const &path)
|
||||
:
|
||||
_ep(dir._ep),
|
||||
_handle(_init_handle(dir, path))
|
||||
{ _handle.fs().ftruncate(&_handle, 0); }
|
||||
|
||||
~New_file()
|
||||
{
|
||||
_sync(_handle, _ep);
|
||||
_handle.ds().close(&_handle);
|
||||
}
|
||||
|
||||
Append_result append(char const *src, size_t size) {
|
||||
return _append(_handle, _ep, src, size); }
|
||||
};
|
||||
|
||||
|
||||
class Genode::Watcher
|
||||
{
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user