1
0
mirror of https://github.com/falk-werner/webfuse synced 2024-10-27 20:34:10 +00:00

completed filesystem implemenation

This commit is contained in:
Falk Werner 2022-11-20 14:48:56 +01:00
parent 6f6555cc90
commit 2479a6c2d6
5 changed files with 169 additions and 36 deletions

View File

@ -1,5 +1,8 @@
#include "webfuse/filesystem.hpp" #include "webfuse/filesystem.hpp"
#include <errno.h> #include <errno.h>
#include <cstring>
#include <stdexcept>
namespace webfuse namespace webfuse
{ {
@ -56,8 +59,14 @@ int filesystem::readlink(std::string const & path, std::string & out)
try try
{ {
messagewriter req(message_type::readlink_req); messagewriter req(message_type::readlink_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; auto reader = proxy.perform(std::move(req));
int const result = reader.read_result();
if (0 == result)
{
out = reader.read_str();
}
return result;
} }
catch(...) catch(...)
{ {
@ -70,8 +79,10 @@ int filesystem::symlink(std::string const & target, std::string const & linkpath
try try
{ {
messagewriter req(message_type::symlink_req); messagewriter req(message_type::symlink_req);
proxy.perform(std::move(req)); req.write_str(target);
return -ENOENT; req.write_str(linkpath);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -84,8 +95,10 @@ int filesystem::link(std::string const & old_path, std::string const & new_path)
try try
{ {
messagewriter req(message_type::link_req); messagewriter req(message_type::link_req);
proxy.perform(std::move(req)); req.write_str(old_path);
return -ENOENT; req.write_str(new_path);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -98,8 +111,11 @@ int filesystem::rename(std::string const & old_path, std::string const & new_pat
try try
{ {
messagewriter req(message_type::rename_req); messagewriter req(message_type::rename_req);
proxy.perform(std::move(req)); req.write_str(old_path);
return -ENOENT; req.write_str(new_path);
req.write_rename_flags(flags);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -112,8 +128,10 @@ int filesystem::chmod(std::string const & path, mode_t mode)
try try
{ {
messagewriter req(message_type::chmod_req); messagewriter req(message_type::chmod_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_mode(mode);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -126,8 +144,11 @@ int filesystem::chown(std::string const & path, uid_t uid, gid_t gid)
try try
{ {
messagewriter req(message_type::chown_req); messagewriter req(message_type::chown_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_uid(uid);
req.write_gid(gid);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -140,8 +161,11 @@ int filesystem::truncate(std::string const & path, uint64_t size, uint64_t handl
try try
{ {
messagewriter req(message_type::truncate_req); messagewriter req(message_type::truncate_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_u64(size);
req.write_u64(handle);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -154,8 +178,11 @@ int filesystem::fsync(std::string const & path, bool is_datasync, uint64_t handl
try try
{ {
messagewriter req(message_type::fsync_req); messagewriter req(message_type::fsync_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_bool(is_datasync);
req.write_u64(handle);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -168,8 +195,15 @@ int filesystem::open(std::string const & path, int flags, uint64_t & handle)
try try
{ {
messagewriter req(message_type::open_req); messagewriter req(message_type::open_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_openflags(flags);
auto reader = proxy.perform(std::move(req));
int result = reader.read_result();
if (0 == result)
{
handle = reader.read_u64();
}
return result;
} }
catch(...) catch(...)
{ {
@ -182,8 +216,11 @@ int filesystem::mknod(std::string const & path, mode_t mode, dev_t rdev)
try try
{ {
messagewriter req(message_type::mknod_req); messagewriter req(message_type::mknod_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_mode(mode);
req.write_u64(rdev);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -196,8 +233,15 @@ int filesystem::create(std::string const & path, mode_t mode, uint64_t & handle)
try try
{ {
messagewriter req(message_type::create_req); messagewriter req(message_type::create_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_mode(mode);
auto reader = proxy.perform(std::move(req));
int result = reader.read_result();
if (0 == result)
{
handle = reader.read_u64();
}
return result;
} }
catch(...) catch(...)
{ {
@ -210,8 +254,10 @@ int filesystem::release(std::string const & path, uint64_t handle)
try try
{ {
messagewriter req(message_type::release_req); messagewriter req(message_type::release_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_u64(handle);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -224,8 +270,9 @@ int filesystem::unlink(std::string const & path)
try try
{ {
messagewriter req(message_type::unlink_req); messagewriter req(message_type::unlink_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -238,8 +285,25 @@ int filesystem::read(std::string const & path, char * buffer, size_t buffer_size
try try
{ {
messagewriter req(message_type::read_req); messagewriter req(message_type::read_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_u32(buffer_size);
req.write_u64(offset);
req.write_u64(handle);
auto reader = proxy.perform(std::move(req));
int result = reader.read_result();
if (result > 0)
{
std::string data = reader.read_bytes();
if (data.size() <= buffer_size)
{
memcpy(reinterpret_cast<void*>(buffer), reinterpret_cast<void const*>(data.data()), data.size());
}
else
{
throw std::runtime_error("invalid message");
}
}
return result;
} }
catch(...) catch(...)
{ {
@ -252,8 +316,12 @@ int filesystem::write(std::string const & path, char const * buffer, size_t buff
try try
{ {
messagewriter req(message_type::write_req); messagewriter req(message_type::write_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_data(buffer, buffer_size);
req.write_u64(offset);
req.write_u64(handle);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -266,8 +334,10 @@ int filesystem::mkdir(std::string const & path, mode_t mode)
try try
{ {
messagewriter req(message_type::mkdir_req); messagewriter req(message_type::mkdir_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; req.write_mode(mode);
auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -300,8 +370,9 @@ int filesystem::rmdir(std::string const & path)
try try
{ {
messagewriter req(message_type::rmdir_req); messagewriter req(message_type::rmdir_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; auto reader = proxy.perform(std::move(req));
return reader.read_result();
} }
catch(...) catch(...)
{ {
@ -314,8 +385,14 @@ int filesystem::statfs(std::string const & path, struct statvfs * statistics)
try try
{ {
messagewriter req(message_type::statfs_req); messagewriter req(message_type::statfs_req);
proxy.perform(std::move(req)); req.write_str(path);
return -ENOENT; auto reader = proxy.perform(std::move(req));
int result = reader.read_result();
if (0 == result)
{
reader.read_statistics(statistics);
}
return result;
} }
catch(...) catch(...)
{ {

View File

@ -55,6 +55,19 @@ void messagereader::read_attr(struct stat * attr)
attr->st_ctim.tv_nsec = static_cast<long>(read_u32()); attr->st_ctim.tv_nsec = static_cast<long>(read_u32());
} }
void messagereader::read_statistics(struct statvfs * statistics)
{
statistics->f_bsize = read_u64();
statistics->f_frsize = read_u64();
statistics->f_blocks = read_u64();
statistics->f_bfree = read_u64();
statistics->f_bavail = read_u64();
statistics->f_files = read_u64();
statistics->f_ffree = read_u64();
statistics->f_namemax = read_u64();
}
mode_t messagereader::read_mode() mode_t messagereader::read_mode()
{ {
filemode mode(read_u32()); filemode mode(read_u32());

View File

@ -3,6 +3,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/statvfs.h>
#include <unistd.h> #include <unistd.h>
#include <cinttypes> #include <cinttypes>
@ -24,6 +25,7 @@ public:
int read_result(); int read_result();
void read_attr(struct stat * attr); void read_attr(struct stat * attr);
void read_statistics(struct statvfs * statistics);
mode_t read_mode(); mode_t read_mode();
uint8_t read_u8(); uint8_t read_u8();

View File

@ -1,11 +1,16 @@
#include "webfuse/ws/messagewriter.hpp" #include "webfuse/ws/messagewriter.hpp"
#include "webfuse/filesystem/accessmode.hpp" #include "webfuse/filesystem/accessmode.hpp"
#include "webfuse/filesystem/filemode.hpp"
#include "webfuse/filesystem/openflags.hpp"
#include <libwebsockets.h> #include <libwebsockets.h>
namespace webfuse namespace webfuse
{ {
constexpr uint8_t const rename_noreplace = 0x01;
constexpr uint8_t const rename_exchange = 0x02;
messagewriter::messagewriter(message_type msg_type) messagewriter::messagewriter(message_type msg_type)
: id(0) : id(0)
, data(LWS_PRE) , data(LWS_PRE)
@ -125,6 +130,37 @@ void messagewriter::write_access_mode(int value)
write_i8(mode); write_i8(mode);
} }
void messagewriter::write_rename_flags(unsigned int value)
{
uint8_t flags = 0;
if (RENAME_NOREPLACE == (value & RENAME_NOREPLACE)) { flags |= rename_noreplace; }
if (RENAME_EXCHANGE == (value & RENAME_EXCHANGE )) { flags |= rename_exchange; }
write_u8(flags);
}
void messagewriter::write_mode(mode_t value)
{
filemode mode = filemode::from_mode(value);
write_u32(mode);
}
void messagewriter::write_uid(uid_t value)
{
write_u32(static_cast<uint32_t>(value));
}
void messagewriter::write_gid(gid_t value)
{
write_u32(static_cast<uint32_t>(value));
}
void messagewriter::write_openflags(int value)
{
openflags flags = openflags::from_int(value);
write_i32(flags);
}
unsigned char * messagewriter::get_data(size_t &size) unsigned char * messagewriter::get_data(size_t &size)
{ {

View File

@ -34,6 +34,11 @@ public:
void write_strings(std::vector<std::string> const & list); void write_strings(std::vector<std::string> const & list);
void write_access_mode(int value); void write_access_mode(int value);
void write_rename_flags(unsigned int value);
void write_mode(mode_t value);
void write_uid(uid_t value);
void write_gid(gid_t value);
void write_openflags(int value);
unsigned char * get_data(size_t &size); unsigned char * get_data(size_t &size);