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());
|
_file_path = Directory::join(path, info.thread_name());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_dst_file.construct(root, _file_path, true);
|
_dst_file.construct(root, _file_path);
|
||||||
|
|
||||||
/* initialise packet header */
|
/* initialise packet header */
|
||||||
_packet_buffer.init_header(info);
|
_packet_buffer.init_header(info);
|
||||||
}
|
}
|
||||||
catch (New_file::Create_failed) {
|
catch (Append_file::Create_failed) {
|
||||||
error("Could not create file."); }
|
error("Could not create file."); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace Ctf {
|
|||||||
using namespace Trace_recorder;
|
using namespace Trace_recorder;
|
||||||
|
|
||||||
using Genode::Directory;
|
using Genode::Directory;
|
||||||
using Genode::New_file;
|
using Genode::Append_file;
|
||||||
|
|
||||||
using Buffer = Write_buffer<32*1024>;
|
using Buffer = Write_buffer<32*1024>;
|
||||||
|
|
||||||
@ -39,9 +39,9 @@ namespace Ctf {
|
|||||||
class Ctf::Writer : public Trace_recorder::Writer_base
|
class Ctf::Writer : public Trace_recorder::Writer_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Buffer &_packet_buffer;
|
Buffer &_packet_buffer;
|
||||||
Constructible<New_file> _dst_file { };
|
Constructible<Append_file> _dst_file { };
|
||||||
Directory::Path _file_path { };
|
Directory::Path _file_path { };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Writer(Genode::Registry<Writer_base> ®istry, Buffer &packet_buffer)
|
Writer(Genode::Registry<Writer_base> ®istry, Buffer &packet_buffer)
|
||||||
|
@ -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())
|
if (_header().empty())
|
||||||
return;
|
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);
|
error("Write error for ", path);
|
||||||
|
|
||||||
_header().reset();
|
_header().reset();
|
||||||
|
@ -35,14 +35,14 @@ void Writer::start_iteration(Directory &root,
|
|||||||
|
|
||||||
/* append to file */
|
/* append to file */
|
||||||
try {
|
try {
|
||||||
_dst_file.construct(root, _file_path, true);
|
_dst_file.construct(root, _file_path);
|
||||||
|
|
||||||
_interface_registry.clear();
|
_interface_registry.clear();
|
||||||
_buffer.clear();
|
_buffer.clear();
|
||||||
_buffer.append<Section_header_block>();
|
_buffer.append<Section_header_block>();
|
||||||
_empty_section = true;
|
_empty_section = true;
|
||||||
}
|
}
|
||||||
catch (New_file::Create_failed) {
|
catch (Append_file::Create_failed) {
|
||||||
error("Could not create file."); }
|
error("Could not create file."); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace Pcapng {
|
|||||||
using namespace Trace_recorder;
|
using namespace Trace_recorder;
|
||||||
|
|
||||||
using Genode::Directory;
|
using Genode::Directory;
|
||||||
using Genode::New_file;
|
using Genode::Append_file;
|
||||||
|
|
||||||
using Buffer = Write_buffer<32*1024>;
|
using Buffer = Write_buffer<32*1024>;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class Pcapng::Writer : public Trace_recorder::Writer_base
|
|||||||
Interface_registry &_interface_registry;
|
Interface_registry &_interface_registry;
|
||||||
Buffer &_buffer;
|
Buffer &_buffer;
|
||||||
Timestamp_calibrator const &_ts_calibrator;
|
Timestamp_calibrator const &_ts_calibrator;
|
||||||
Constructible<New_file> _dst_file { };
|
Constructible<Append_file> _dst_file { };
|
||||||
Directory::Path _file_path { };
|
Directory::Path _file_path { };
|
||||||
bool _empty_section { false };
|
bool _empty_section { false };
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ class Pcapng::Write_buffer
|
|||||||
return Append_ok();
|
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)
|
if (_total_length == 0)
|
||||||
return;
|
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);
|
error("Write error for ", path);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
@ -27,6 +27,8 @@ namespace Genode {
|
|||||||
struct File;
|
struct File;
|
||||||
class Readonly_file;
|
class Readonly_file;
|
||||||
class File_content;
|
class File_content;
|
||||||
|
class Writeable_file;
|
||||||
|
class Append_file;
|
||||||
class New_file;
|
class New_file;
|
||||||
class Watcher;
|
class Watcher;
|
||||||
template <typename>
|
template <typename>
|
||||||
@ -124,6 +126,8 @@ struct Genode::Directory : Noncopyable, Interface
|
|||||||
friend class Readonly_file;
|
friend class Readonly_file;
|
||||||
friend class Root_directory;
|
friend class Root_directory;
|
||||||
friend class Watcher;
|
friend class Watcher;
|
||||||
|
friend class Writeable_file;
|
||||||
|
friend class Append_file;
|
||||||
friend class New_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:
|
public:
|
||||||
|
|
||||||
struct Create_failed : Exception { };
|
struct Create_failed : Exception { };
|
||||||
|
|
||||||
private:
|
enum class Append_result { OK, WRITE_ERROR };
|
||||||
|
|
||||||
Entrypoint &_ep;
|
protected:
|
||||||
Allocator &_alloc;
|
|
||||||
Vfs::File_system &_fs;
|
|
||||||
Vfs::Vfs_handle &_handle;
|
|
||||||
|
|
||||||
Vfs::Vfs_handle &_init_handle(Directory &dir,
|
static Vfs::Vfs_handle &_init_handle(Directory &dir,
|
||||||
Directory::Path const &rel_path,
|
Directory::Path const &rel_path)
|
||||||
bool append)
|
|
||||||
{
|
{
|
||||||
/* create compound directory */
|
/* create compound directory */
|
||||||
{
|
{
|
||||||
@ -703,43 +704,24 @@ class Genode::New_file : Noncopyable
|
|||||||
|
|
||||||
Vfs::Vfs_handle *handle_ptr = nullptr;
|
Vfs::Vfs_handle *handle_ptr = nullptr;
|
||||||
Vfs::Directory_service::Open_result const res =
|
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)) {
|
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();
|
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;
|
return *handle_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
static void _sync(Vfs::Vfs_handle &handle, Entrypoint &ep)
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()
|
|
||||||
{
|
{
|
||||||
while (_handle.fs().queue_sync(&_handle) == false)
|
while (handle.fs().queue_sync(&handle) == false)
|
||||||
_ep.wait_and_dispatch_one_io_signal();
|
ep.wait_and_dispatch_one_io_signal();
|
||||||
|
|
||||||
for (bool sync_done = false; !sync_done; ) {
|
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:
|
case Vfs::File_io_service::SYNC_QUEUED:
|
||||||
break;
|
break;
|
||||||
@ -755,14 +737,12 @@ class Genode::New_file : Noncopyable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sync_done)
|
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 };
|
static Append_result _append(Vfs::Vfs_handle &handle, Entrypoint &ep,
|
||||||
|
char const *src, size_t size)
|
||||||
Append_result append(char const *src, size_t size)
|
|
||||||
{
|
{
|
||||||
bool write_error = false;
|
bool write_error = false;
|
||||||
|
|
||||||
@ -777,7 +757,7 @@ class Genode::New_file : Noncopyable
|
|||||||
|
|
||||||
using Write_result = Vfs::File_io_service::Write_result;
|
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)) {
|
out_count)) {
|
||||||
|
|
||||||
case Write_result::WRITE_ERR_AGAIN:
|
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);
|
out_count = min((Vfs::file_size)remaining_bytes, out_count);
|
||||||
remaining_bytes -= (size_t)out_count;
|
remaining_bytes -= (size_t)out_count;
|
||||||
src += out_count;
|
src += out_count;
|
||||||
_handle.advance_seek(out_count);
|
handle.advance_seek(out_count);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -803,7 +783,7 @@ class Genode::New_file : Noncopyable
|
|||||||
stalled = true; }
|
stalled = true; }
|
||||||
|
|
||||||
if (stalled)
|
if (stalled)
|
||||||
_ep.wait_and_dispatch_one_io_signal();
|
ep.wait_and_dispatch_one_io_signal();
|
||||||
}
|
}
|
||||||
return write_error ? Append_result::WRITE_ERROR
|
return write_error ? Append_result::WRITE_ERROR
|
||||||
: Append_result::OK;
|
: 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
|
class Genode::Watcher
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user