Loading include/config.hpp +5 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ constexpr auto use_ctime = false; constexpr auto use_mtime = false; constexpr auto use_link_cnt = false; constexpr auto use_blocks = false; // metadata logic // Check for existence of file metadata before create. This done on RocksDB // level constexpr auto create_exist_check = true; } // namespace metadata namespace rpc { Loading include/daemon/backend/exceptions.hpp +5 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,11 @@ public: explicit NotFoundException(const std::string& s) : DBException(s){}; }; class ExistsException : public DBException { public: explicit ExistsException(const std::string& s) : DBException(s){}; }; } // namespace metadata } // namespace gkfs Loading include/daemon/backend/metadata/db.hpp +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ public: static inline void throw_rdb_status_excpt(const rdb::Status& s); MetadataDB(const std::string& path); explicit MetadataDB(const std::string& path); std::string get(const std::string& key) const; Loading @@ -45,6 +45,9 @@ public: void put(const std::string& key, const std::string& val); void put_no_exist(const std::string& key, const std::string& val); void remove(const std::string& key); Loading src/client/gkfs_functions.cpp +50 −50 Original line number Diff line number Diff line Loading @@ -128,49 +128,50 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { errno = ENOTSUP; return -1; } bool exists = true; auto md = gkfs::util::get_metadata(path); if(!md) { if(errno == ENOENT) { exists = false; } else { LOG(ERROR, "Error while retriving stat to file"); return -1; } } if(!exists) { if(!(flags & O_CREAT)) { // file doesn't exists and O_CREAT was not set errno = ENOENT; return -1; } /*** CREATION ***/ assert(flags & O_CREAT); // metadata pointer assigned during create or stat std::shared_ptr<gkfs::metadata::Metadata> md = nullptr; if(flags & O_CREAT) { if(flags & O_DIRECTORY) { LOG(ERROR, "O_DIRECTORY use with O_CREAT. NOT SUPPORTED"); errno = ENOTSUP; return -1; } // no access check required here. If one is using our FS they have the // permissions. if(gkfs_create(path, mode | S_IFREG)) { LOG(ERROR, "Error creating non-existent file: '{}'", strerror(errno)); int err = gkfs_create(path, mode | S_IFREG); if(err) { if(errno == EEXIST) { // file exists, O_CREAT was set if(flags & O_EXCL) { // File exists and O_EXCL & O_CREAT was set errno = EEXIST; return -1; } // 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); } else { /* File already exists */ if(flags & O_EXCL) { // File exists and O_EXCL was set errno = EEXIST; LOG(ERROR, "Error creating file: '{}'", strerror(errno)); return -1; } } else { // file was successfully created. Add to filemap return CTX->file_map()->add( std::make_shared<gkfs::filemap::OpenFile>(path, flags)); } } else { 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"); return -1; } } } assert(md); #ifdef HAS_SYMLINKS if(md->is_link()) { Loading @@ -197,7 +198,6 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { return -1; } } } return CTX->file_map()->add( std::make_shared<gkfs::filemap::OpenFile>(path, flags)); Loading src/daemon/backend/metadata/db.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ extern "C" { namespace gkfs::metadata { /** * Called when the daemon is started: Connects to the KV store * @param path where KV store data is stored */ MetadataDB::MetadataDB(const std::string& path) : path(path) { // Optimize RocksDB. This is the easiest way to get RocksDB to perform well options.IncreaseParallelism(); Loading @@ -41,6 +46,12 @@ MetadataDB::MetadataDB(const std::string& path) : path(path) { this->db.reset(rdb_ptr); } /** * Exception wrapper on Status object. Throws NotFoundException if * s.IsNotFound(), general DBException otherwise * @param RocksDB status * @throws DBException */ void MetadataDB::throw_rdb_status_excpt(const rdb::Status& s) { assert(!s.ok()); Loading @@ -52,6 +63,12 @@ MetadataDB::throw_rdb_status_excpt(const rdb::Status& s) { } } /** * Gets a KV store value for a key * @param key * @return value * @throws DBException on failure, NotFoundException if entry doesn't exist */ std::string MetadataDB::get(const std::string& key) const { std::string val; Loading @@ -62,6 +79,12 @@ MetadataDB::get(const std::string& key) const { return val; } /** * Puts an entry into the KV store * @param key * @param val * @throws DBException on failure */ void MetadataDB::put(const std::string& key, const std::string& val) { assert(gkfs::path::is_absolute(key)); Loading @@ -74,6 +97,25 @@ MetadataDB::put(const std::string& key, const std::string& val) { } } /** * Puts an entry into the KV store if it doesn't exist. This function does not * use a mutex. * @param key * @param val * @throws DBException on failure, ExistException if entry already exists */ void MetadataDB::put_no_exist(const std::string& key, const std::string& val) { if(exists(key)) throw ExistsException(key); put(key, val); } /** * Removes an entry from the KV store * @param key * @throws DBException on failure, NotFoundException if entry doesn't exist */ void MetadataDB::remove(const std::string& key) { auto s = db->Delete(write_opts, key); Loading @@ -82,6 +124,12 @@ MetadataDB::remove(const std::string& key) { } } /** * checks for existence of an entry * @param key * @return true if exists * @throws DBException on failure */ bool MetadataDB::exists(const std::string& key) { std::string val; Loading @@ -101,7 +149,7 @@ MetadataDB::exists(const std::string& key) { * @param old_key * @param new_key * @param val * @return * @throws DBException on failure, NotFoundException if entry doesn't exist */ void MetadataDB::update(const std::string& old_key, const std::string& new_key, Loading @@ -116,6 +164,14 @@ MetadataDB::update(const std::string& old_key, const std::string& new_key, } } /** * Increases only the size part of the metadentry via a RocksDB Operand * Operation. E.g., called before a write() call * @param key * @param size * @param append * @throws DBException on failure */ void MetadataDB::increase_size(const std::string& key, size_t size, bool append) { auto uop = IncreaseSizeOperand(size, append); Loading @@ -125,6 +181,13 @@ MetadataDB::increase_size(const std::string& key, size_t size, bool append) { } } /** * Decreases only the size part of the metadentry via a RocksDB Operand * Operation E.g., called before a truncate() call * @param key * @param size * @throws DBException on failure */ void MetadataDB::decrease_size(const std::string& key, size_t size) { auto uop = DecreaseSizeOperand(size); Loading Loading @@ -254,6 +317,12 @@ MetadataDB::iterate_all() { } } /** * Called when RocksDB connection is established. * Used for setting KV store settings * see here: https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide * @param options */ void MetadataDB::optimize_rocksdb_options(rdb::Options& options) { options.max_successive_merges = 128; Loading Loading
include/config.hpp +5 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ constexpr auto use_ctime = false; constexpr auto use_mtime = false; constexpr auto use_link_cnt = false; constexpr auto use_blocks = false; // metadata logic // Check for existence of file metadata before create. This done on RocksDB // level constexpr auto create_exist_check = true; } // namespace metadata namespace rpc { Loading
include/daemon/backend/exceptions.hpp +5 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,11 @@ public: explicit NotFoundException(const std::string& s) : DBException(s){}; }; class ExistsException : public DBException { public: explicit ExistsException(const std::string& s) : DBException(s){}; }; } // namespace metadata } // namespace gkfs Loading
include/daemon/backend/metadata/db.hpp +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ public: static inline void throw_rdb_status_excpt(const rdb::Status& s); MetadataDB(const std::string& path); explicit MetadataDB(const std::string& path); std::string get(const std::string& key) const; Loading @@ -45,6 +45,9 @@ public: void put(const std::string& key, const std::string& val); void put_no_exist(const std::string& key, const std::string& val); void remove(const std::string& key); Loading
src/client/gkfs_functions.cpp +50 −50 Original line number Diff line number Diff line Loading @@ -128,49 +128,50 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { errno = ENOTSUP; return -1; } bool exists = true; auto md = gkfs::util::get_metadata(path); if(!md) { if(errno == ENOENT) { exists = false; } else { LOG(ERROR, "Error while retriving stat to file"); return -1; } } if(!exists) { if(!(flags & O_CREAT)) { // file doesn't exists and O_CREAT was not set errno = ENOENT; return -1; } /*** CREATION ***/ assert(flags & O_CREAT); // metadata pointer assigned during create or stat std::shared_ptr<gkfs::metadata::Metadata> md = nullptr; if(flags & O_CREAT) { if(flags & O_DIRECTORY) { LOG(ERROR, "O_DIRECTORY use with O_CREAT. NOT SUPPORTED"); errno = ENOTSUP; return -1; } // no access check required here. If one is using our FS they have the // permissions. if(gkfs_create(path, mode | S_IFREG)) { LOG(ERROR, "Error creating non-existent file: '{}'", strerror(errno)); int err = gkfs_create(path, mode | S_IFREG); if(err) { if(errno == EEXIST) { // file exists, O_CREAT was set if(flags & O_EXCL) { // File exists and O_EXCL & O_CREAT was set errno = EEXIST; return -1; } // 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); } else { /* File already exists */ if(flags & O_EXCL) { // File exists and O_EXCL was set errno = EEXIST; LOG(ERROR, "Error creating file: '{}'", strerror(errno)); return -1; } } else { // file was successfully created. Add to filemap return CTX->file_map()->add( std::make_shared<gkfs::filemap::OpenFile>(path, flags)); } } else { 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"); return -1; } } } assert(md); #ifdef HAS_SYMLINKS if(md->is_link()) { Loading @@ -197,7 +198,6 @@ gkfs_open(const std::string& path, mode_t mode, int flags) { return -1; } } } return CTX->file_map()->add( std::make_shared<gkfs::filemap::OpenFile>(path, flags)); Loading
src/daemon/backend/metadata/db.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ extern "C" { namespace gkfs::metadata { /** * Called when the daemon is started: Connects to the KV store * @param path where KV store data is stored */ MetadataDB::MetadataDB(const std::string& path) : path(path) { // Optimize RocksDB. This is the easiest way to get RocksDB to perform well options.IncreaseParallelism(); Loading @@ -41,6 +46,12 @@ MetadataDB::MetadataDB(const std::string& path) : path(path) { this->db.reset(rdb_ptr); } /** * Exception wrapper on Status object. Throws NotFoundException if * s.IsNotFound(), general DBException otherwise * @param RocksDB status * @throws DBException */ void MetadataDB::throw_rdb_status_excpt(const rdb::Status& s) { assert(!s.ok()); Loading @@ -52,6 +63,12 @@ MetadataDB::throw_rdb_status_excpt(const rdb::Status& s) { } } /** * Gets a KV store value for a key * @param key * @return value * @throws DBException on failure, NotFoundException if entry doesn't exist */ std::string MetadataDB::get(const std::string& key) const { std::string val; Loading @@ -62,6 +79,12 @@ MetadataDB::get(const std::string& key) const { return val; } /** * Puts an entry into the KV store * @param key * @param val * @throws DBException on failure */ void MetadataDB::put(const std::string& key, const std::string& val) { assert(gkfs::path::is_absolute(key)); Loading @@ -74,6 +97,25 @@ MetadataDB::put(const std::string& key, const std::string& val) { } } /** * Puts an entry into the KV store if it doesn't exist. This function does not * use a mutex. * @param key * @param val * @throws DBException on failure, ExistException if entry already exists */ void MetadataDB::put_no_exist(const std::string& key, const std::string& val) { if(exists(key)) throw ExistsException(key); put(key, val); } /** * Removes an entry from the KV store * @param key * @throws DBException on failure, NotFoundException if entry doesn't exist */ void MetadataDB::remove(const std::string& key) { auto s = db->Delete(write_opts, key); Loading @@ -82,6 +124,12 @@ MetadataDB::remove(const std::string& key) { } } /** * checks for existence of an entry * @param key * @return true if exists * @throws DBException on failure */ bool MetadataDB::exists(const std::string& key) { std::string val; Loading @@ -101,7 +149,7 @@ MetadataDB::exists(const std::string& key) { * @param old_key * @param new_key * @param val * @return * @throws DBException on failure, NotFoundException if entry doesn't exist */ void MetadataDB::update(const std::string& old_key, const std::string& new_key, Loading @@ -116,6 +164,14 @@ MetadataDB::update(const std::string& old_key, const std::string& new_key, } } /** * Increases only the size part of the metadentry via a RocksDB Operand * Operation. E.g., called before a write() call * @param key * @param size * @param append * @throws DBException on failure */ void MetadataDB::increase_size(const std::string& key, size_t size, bool append) { auto uop = IncreaseSizeOperand(size, append); Loading @@ -125,6 +181,13 @@ MetadataDB::increase_size(const std::string& key, size_t size, bool append) { } } /** * Decreases only the size part of the metadentry via a RocksDB Operand * Operation E.g., called before a truncate() call * @param key * @param size * @throws DBException on failure */ void MetadataDB::decrease_size(const std::string& key, size_t size) { auto uop = DecreaseSizeOperand(size); Loading Loading @@ -254,6 +317,12 @@ MetadataDB::iterate_all() { } } /** * Called when RocksDB connection is established. * Used for setting KV store settings * see here: https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide * @param options */ void MetadataDB::optimize_rocksdb_options(rdb::Options& options) { options.max_successive_merges = 128; Loading