Loading include/client/preload_util.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ to_underlying(E e) { return static_cast<typename std::underlying_type<E>::type>(e); } std::shared_ptr<gkfs::metadata::Metadata> std::optional<gkfs::metadata::Metadata> get_metadata(const std::string& path, bool follow_links = false); int Loading src/client/gkfs_functions.cpp +40 −31 Original line number Diff line number Diff line Loading @@ -118,8 +118,8 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { errno = ENOTSUP; return -1; } // metadata pointer assigned during create or stat std::shared_ptr<gkfs::metadata::Metadata> md = nullptr; // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { if(flags & O_DIRECTORY) { LOG(ERROR, "O_DIRECTORY use with O_CREAT. NOT SUPPORTED"); Loading @@ -139,7 +139,14 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { } // file exists, O_CREAT was set O_EXCL wasnt, so function does // not fail this case is actually undefined as per `man 2 open` md = gkfs::util::get_metadata(path); auto md_ = gkfs::util::get_metadata(path); if(!md_) { LOG(ERROR, "Could not get metadata after creating file '{}': '{}'", path, strerror(errno)); return -1; } md = md_.value(); } else { LOG(ERROR, "Error creating file: '{}'", strerror(errno)); return -1; Loading @@ -150,40 +157,40 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { std::make_shared<gkfs::filemap::OpenFile>(path, flags)); } } else { md = gkfs::util::get_metadata(path); if(!md) { auto md_ = gkfs::util::get_metadata(path); if(!md_) { if(errno == ENOENT) { // file doesn't exists and O_CREAT was not set return -1; } else { LOG(ERROR, "Error stating existing file"); LOG(ERROR, "Error stating existing file '{}'", path); return -1; } } md = md_.value(); } assert(md); #ifdef HAS_SYMLINKS if(md->is_link()) { if(md.is_link()) { if(flags & O_NOFOLLOW) { LOG(WARNING, "Symlink found and O_NOFOLLOW flag was specified"); errno = ELOOP; return -1; } return gkfs_open(md->target_path(), mode, flags); return gkfs_open(md.target_path(), mode, flags); } #endif if(S_ISDIR(md->mode())) { if(S_ISDIR(md.mode())) { return gkfs_opendir(path); } /*** Regular file exists ***/ assert(S_ISREG(md->mode())); assert(S_ISREG(md.mode())); if((flags & O_TRUNC) && ((flags & O_RDWR) || (flags & O_WRONLY))) { if(gkfs_truncate(path, md->size(), 0)) { if(gkfs_truncate(path, md.size(), 0)) { LOG(ERROR, "Error truncating file"); return -1; } Loading Loading @@ -247,8 +254,10 @@ gkfs_remove(const std::string& path) { if(!md) { return -1; } bool has_data = S_ISREG(md->mode()) && (md->size() != 0); auto err = gkfs::rpc::forward_remove(path, !has_data, md->size()); gkfs::metadata::Metadata md{attr.value()}; bool has_data = S_ISREG(md.mode()) && (md.size() != 0); auto err = gkfs::rpc::forward_remove(path, !has_data, md.size()); if(err) { errno = err; return -1; Loading @@ -268,7 +277,6 @@ int gkfs_access(const std::string& path, const int mask, bool follow_links) { auto md = gkfs::util::get_metadata(path, follow_links); if(!md) { errno = ENOENT; return -1; } return 0; Loading @@ -288,7 +296,7 @@ gkfs_stat(const string& path, struct stat* buf, bool follow_links) { if(!md) { return -1; } gkfs::util::metadata_to_stat(path, *md, *buf); gkfs::util::metadata_to_stat(path, md.value(), *buf); return 0; } Loading @@ -315,7 +323,7 @@ gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, struct stat tmp {}; gkfs::util::metadata_to_stat(path, *md, tmp); gkfs::util::metadata_to_stat(path, md.value(), tmp); buf->stx_mask = 0; buf->stx_blksize = tmp.st_blksize; Loading Loading @@ -539,7 +547,8 @@ gkfs_truncate(const std::string& path, off_t length) { if(!md) { return -1; } auto size = md->size(); auto size = md.value().size(); if(static_cast<unsigned long>(length) > size) { LOG(DEBUG, "Length is greater then file size: {} > {}", length, size); errno = EINVAL; Loading Loading @@ -852,12 +861,12 @@ gkfs_pread_ws(int fd, void* buf, size_t count, off64_t offset) { */ int gkfs_opendir(const std::string& path) { auto md = gkfs::util::get_metadata(path); if(!md) { return -1; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(DEBUG, "Path is not a directory"); errno = ENOTDIR; return -1; Loading @@ -883,11 +892,10 @@ int gkfs_rmdir(const std::string& path) { auto md = gkfs::util::get_metadata(path); if(!md) { LOG(DEBUG, "Path '{}' does not exist: ", path); errno = ENOENT; LOG(DEBUG, "Error: Path '{}' err code '{}' ", path, strerror(errno)); return -1; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(DEBUG, "Path '{}' is not a directory", path); errno = ENOTDIR; return -1; Loading Loading @@ -1079,8 +1087,8 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { * So that application know we don't support link to directory. */ auto target_md = gkfs::util::get_metadata(target_path, false); if(target_md != nullptr) { auto trg_mode = target_md->mode(); if(target_md) { auto trg_mode = target_md.value().mode(); if(!(S_ISREG(trg_mode) || S_ISLNK(trg_mode))) { assert(S_ISDIR(trg_mode)); LOG(DEBUG, "Target path is a directory. Not supported"); Loading @@ -1094,11 +1102,12 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { } auto link_md = gkfs::util::get_metadata(path, false); if(link_md != nullptr) { if(link_md) { LOG(DEBUG, "Link exists: '{}'", path); errno = EEXIST; return -1; } auto err = gkfs::rpc::forward_mk_symlink(path, target_path); if(err) { errno = err; Loading @@ -1121,25 +1130,25 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { int gkfs_readlink(const std::string& path, char* buf, int bufsize) { auto md = gkfs::util::get_metadata(path, false); if(md == nullptr) { if(!md) { LOG(DEBUG, "Named link doesn't exist"); return -1; } if(!(md->is_link())) { if(!(md.value().is_link())) { LOG(DEBUG, "The named file is not a symbolic link"); errno = EINVAL; return -1; } int path_size = md->target_path().size() + CTX->mountdir().size(); int path_size = md.value().target_path().size() + CTX->mountdir().size(); if(path_size >= bufsize) { LOG(WARNING, "Destination buffer size is too short: {} < {}, {} ", bufsize, path_size, md->target_path()); bufsize, path_size, md.value().target_path()); errno = ENAMETOOLONG; return -1; } CTX->mountdir().copy(buf, CTX->mountdir().size()); std::strcpy(buf + CTX->mountdir().size(), md->target_path().c_str()); std::strcpy(buf + CTX->mountdir().size(), md.value().target_path().c_str()); return path_size; } Loading src/client/hooks.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -615,11 +615,12 @@ hook_chdir(const char* path) { if(internal) { // path falls in our namespace auto md = gkfs::util::get_metadata(rel_path); if(md == nullptr) { LOG(ERROR, "{}() path does not exists", __func__); return -ENOENT; if(!md) { LOG(ERROR, "{}() path {} errno {}", __func__, path, errno); return -errno; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(ERROR, "{}() path is not a directory", __func__); return -ENOTDIR; } Loading src/client/preload_util.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -165,20 +165,21 @@ load_hostfile(const std::string& path) { namespace gkfs::util { /** * Retrieve metadata from daemon * Retrieve metadata from daemon and return Metadata object * errno may be set * @param path * @param follow_links * @return shared_ptr for metadata, nullptr else * @return Metadata */ std::shared_ptr<gkfs::metadata::Metadata> optional<gkfs::metadata::Metadata> get_metadata(const string& path, bool follow_links) { std::string attr; auto err = gkfs::rpc::forward_stat(path, attr); if(err) { errno = err; return nullptr; return {}; } #ifdef HAS_SYMLINKS if(follow_links) { Loading @@ -187,15 +188,16 @@ get_metadata(const string& path, bool follow_links) { err = gkfs::rpc::forward_stat(md.target_path(), attr); if(err) { errno = err; return nullptr; return {}; } md = gkfs::metadata::Metadata{attr}; } } #endif return make_shared<gkfs::metadata::Metadata>(attr); return gkfs::metadata::Metadata{attr}; } /** * Converts the Metadata object into a stat struct, which is needed by Linux * @param path Loading Loading
include/client/preload_util.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ to_underlying(E e) { return static_cast<typename std::underlying_type<E>::type>(e); } std::shared_ptr<gkfs::metadata::Metadata> std::optional<gkfs::metadata::Metadata> get_metadata(const std::string& path, bool follow_links = false); int Loading
src/client/gkfs_functions.cpp +40 −31 Original line number Diff line number Diff line Loading @@ -118,8 +118,8 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { errno = ENOTSUP; return -1; } // metadata pointer assigned during create or stat std::shared_ptr<gkfs::metadata::Metadata> md = nullptr; // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { if(flags & O_DIRECTORY) { LOG(ERROR, "O_DIRECTORY use with O_CREAT. NOT SUPPORTED"); Loading @@ -139,7 +139,14 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { } // file exists, O_CREAT was set O_EXCL wasnt, so function does // not fail this case is actually undefined as per `man 2 open` md = gkfs::util::get_metadata(path); auto md_ = gkfs::util::get_metadata(path); if(!md_) { LOG(ERROR, "Could not get metadata after creating file '{}': '{}'", path, strerror(errno)); return -1; } md = md_.value(); } else { LOG(ERROR, "Error creating file: '{}'", strerror(errno)); return -1; Loading @@ -150,40 +157,40 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { std::make_shared<gkfs::filemap::OpenFile>(path, flags)); } } else { md = gkfs::util::get_metadata(path); if(!md) { auto md_ = gkfs::util::get_metadata(path); if(!md_) { if(errno == ENOENT) { // file doesn't exists and O_CREAT was not set return -1; } else { LOG(ERROR, "Error stating existing file"); LOG(ERROR, "Error stating existing file '{}'", path); return -1; } } md = md_.value(); } assert(md); #ifdef HAS_SYMLINKS if(md->is_link()) { if(md.is_link()) { if(flags & O_NOFOLLOW) { LOG(WARNING, "Symlink found and O_NOFOLLOW flag was specified"); errno = ELOOP; return -1; } return gkfs_open(md->target_path(), mode, flags); return gkfs_open(md.target_path(), mode, flags); } #endif if(S_ISDIR(md->mode())) { if(S_ISDIR(md.mode())) { return gkfs_opendir(path); } /*** Regular file exists ***/ assert(S_ISREG(md->mode())); assert(S_ISREG(md.mode())); if((flags & O_TRUNC) && ((flags & O_RDWR) || (flags & O_WRONLY))) { if(gkfs_truncate(path, md->size(), 0)) { if(gkfs_truncate(path, md.size(), 0)) { LOG(ERROR, "Error truncating file"); return -1; } Loading Loading @@ -247,8 +254,10 @@ gkfs_remove(const std::string& path) { if(!md) { return -1; } bool has_data = S_ISREG(md->mode()) && (md->size() != 0); auto err = gkfs::rpc::forward_remove(path, !has_data, md->size()); gkfs::metadata::Metadata md{attr.value()}; bool has_data = S_ISREG(md.mode()) && (md.size() != 0); auto err = gkfs::rpc::forward_remove(path, !has_data, md.size()); if(err) { errno = err; return -1; Loading @@ -268,7 +277,6 @@ int gkfs_access(const std::string& path, const int mask, bool follow_links) { auto md = gkfs::util::get_metadata(path, follow_links); if(!md) { errno = ENOENT; return -1; } return 0; Loading @@ -288,7 +296,7 @@ gkfs_stat(const string& path, struct stat* buf, bool follow_links) { if(!md) { return -1; } gkfs::util::metadata_to_stat(path, *md, *buf); gkfs::util::metadata_to_stat(path, md.value(), *buf); return 0; } Loading @@ -315,7 +323,7 @@ gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, struct stat tmp {}; gkfs::util::metadata_to_stat(path, *md, tmp); gkfs::util::metadata_to_stat(path, md.value(), tmp); buf->stx_mask = 0; buf->stx_blksize = tmp.st_blksize; Loading Loading @@ -539,7 +547,8 @@ gkfs_truncate(const std::string& path, off_t length) { if(!md) { return -1; } auto size = md->size(); auto size = md.value().size(); if(static_cast<unsigned long>(length) > size) { LOG(DEBUG, "Length is greater then file size: {} > {}", length, size); errno = EINVAL; Loading Loading @@ -852,12 +861,12 @@ gkfs_pread_ws(int fd, void* buf, size_t count, off64_t offset) { */ int gkfs_opendir(const std::string& path) { auto md = gkfs::util::get_metadata(path); if(!md) { return -1; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(DEBUG, "Path is not a directory"); errno = ENOTDIR; return -1; Loading @@ -883,11 +892,10 @@ int gkfs_rmdir(const std::string& path) { auto md = gkfs::util::get_metadata(path); if(!md) { LOG(DEBUG, "Path '{}' does not exist: ", path); errno = ENOENT; LOG(DEBUG, "Error: Path '{}' err code '{}' ", path, strerror(errno)); return -1; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(DEBUG, "Path '{}' is not a directory", path); errno = ENOTDIR; return -1; Loading Loading @@ -1079,8 +1087,8 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { * So that application know we don't support link to directory. */ auto target_md = gkfs::util::get_metadata(target_path, false); if(target_md != nullptr) { auto trg_mode = target_md->mode(); if(target_md) { auto trg_mode = target_md.value().mode(); if(!(S_ISREG(trg_mode) || S_ISLNK(trg_mode))) { assert(S_ISDIR(trg_mode)); LOG(DEBUG, "Target path is a directory. Not supported"); Loading @@ -1094,11 +1102,12 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { } auto link_md = gkfs::util::get_metadata(path, false); if(link_md != nullptr) { if(link_md) { LOG(DEBUG, "Link exists: '{}'", path); errno = EEXIST; return -1; } auto err = gkfs::rpc::forward_mk_symlink(path, target_path); if(err) { errno = err; Loading @@ -1121,25 +1130,25 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) { int gkfs_readlink(const std::string& path, char* buf, int bufsize) { auto md = gkfs::util::get_metadata(path, false); if(md == nullptr) { if(!md) { LOG(DEBUG, "Named link doesn't exist"); return -1; } if(!(md->is_link())) { if(!(md.value().is_link())) { LOG(DEBUG, "The named file is not a symbolic link"); errno = EINVAL; return -1; } int path_size = md->target_path().size() + CTX->mountdir().size(); int path_size = md.value().target_path().size() + CTX->mountdir().size(); if(path_size >= bufsize) { LOG(WARNING, "Destination buffer size is too short: {} < {}, {} ", bufsize, path_size, md->target_path()); bufsize, path_size, md.value().target_path()); errno = ENAMETOOLONG; return -1; } CTX->mountdir().copy(buf, CTX->mountdir().size()); std::strcpy(buf + CTX->mountdir().size(), md->target_path().c_str()); std::strcpy(buf + CTX->mountdir().size(), md.value().target_path().c_str()); return path_size; } Loading
src/client/hooks.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -615,11 +615,12 @@ hook_chdir(const char* path) { if(internal) { // path falls in our namespace auto md = gkfs::util::get_metadata(rel_path); if(md == nullptr) { LOG(ERROR, "{}() path does not exists", __func__); return -ENOENT; if(!md) { LOG(ERROR, "{}() path {} errno {}", __func__, path, errno); return -errno; } if(!S_ISDIR(md->mode())) { if(!S_ISDIR(md.value().mode())) { LOG(ERROR, "{}() path is not a directory", __func__); return -ENOTDIR; } Loading
src/client/preload_util.cpp +8 −6 Original line number Diff line number Diff line Loading @@ -165,20 +165,21 @@ load_hostfile(const std::string& path) { namespace gkfs::util { /** * Retrieve metadata from daemon * Retrieve metadata from daemon and return Metadata object * errno may be set * @param path * @param follow_links * @return shared_ptr for metadata, nullptr else * @return Metadata */ std::shared_ptr<gkfs::metadata::Metadata> optional<gkfs::metadata::Metadata> get_metadata(const string& path, bool follow_links) { std::string attr; auto err = gkfs::rpc::forward_stat(path, attr); if(err) { errno = err; return nullptr; return {}; } #ifdef HAS_SYMLINKS if(follow_links) { Loading @@ -187,15 +188,16 @@ get_metadata(const string& path, bool follow_links) { err = gkfs::rpc::forward_stat(md.target_path(), attr); if(err) { errno = err; return nullptr; return {}; } md = gkfs::metadata::Metadata{attr}; } } #endif return make_shared<gkfs::metadata::Metadata>(attr); return gkfs::metadata::Metadata{attr}; } /** * Converts the Metadata object into a stat struct, which is needed by Linux * @param path Loading