Loading lfs/.gitignore +0 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,3 @@ cmake-build-debug/ cmake-build-release/ playground/ # Configurations # ################## src/configure.hpp lfs/src/adafs_ops/dentry_ops.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ pair<int, fuse_ino_t> do_lookup(const fuse_ino_t p_inode, const string& name) { int create_dentry(const fuse_ino_t p_inode, const fuse_ino_t inode, const string& name, mode_t mode) { // XXX check later if we need to check if dentry of father already exists // put dentry for key, value return db_put_dentry(db_build_dentry_key(p_inode, name), db_build_dentry_value(inode, mode)) ? 0 : 1; return db_put_dentry(db_build_dentry_key(p_inode, name), db_build_dentry_value(inode, mode)) ? 0 : EIO; } /** Loading lfs/src/adafs_ops/mdata_ops.cpp +161 −41 Original line number Diff line number Diff line Loading @@ -4,32 +4,44 @@ #include "mdata_ops.hpp" #include "dentry_ops.hpp" #include "../rpc/client/c_dentry.hpp" #include "../rpc/client/c_metadata.hpp" using namespace std; // TODO error handling. int write_all_metadata(const Metadata& md) { auto inode_key = fmt::FormatInt(md.inode_no()).str(); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks()); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks())) return EIO; return 0; } Loading Loading @@ -68,18 +80,28 @@ int read_all_metadata(Metadata& md, const fuse_ino_t inode) { * @return err */ int remove_all_metadata(const fuse_ino_t inode) { // TODO error handling auto inode_key = fmt::FormatInt(inode).str(); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map))); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)))) return EIO; return 0; } Loading Loading @@ -179,7 +201,7 @@ int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode } /** * Creates a new node (file or directory) in the file system. Fills given fuse_entry_param. This function is only called locally * Creates a new node (file or directory) in the file system. Fills given fuse_entry_param. * @param req * @param fep * @param parent Loading @@ -187,18 +209,116 @@ int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode * @param mode * @return err */ int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const string& name, const uid_t uid, const gid_t gid, int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const char* name, const uid_t uid, const gid_t gid, mode_t mode) { // create inode number auto new_inode = Util::generate_inode_no(); // // create inode number // auto new_inode = Util::generate_inode_no(); // // create dentry // create_dentry(parent, new_inode, name, mode); // // create metadata and fill fuse entry param // init_metadata_fep(fep, new_inode, uid, gid, mode); int err; // create new inode number fuse_ino_t new_inode = Util::generate_inode_no(); if (ADAFS_DATA->host_size() > 1) { // multiple node operation auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (ADAFS_DATA->is_local_op(recipient)) { // local dentry create err = create_dentry(parent, new_inode, name, mode); } else { // remote dentry create err = rpc_send_create_dentry(recipient, parent, name, mode, new_inode); } if (err != 0) { // failure in dentry creation ADAFS_DATA->spdlogger()->error("Failed to create a dentry"); return err; } // calculate recipient again for new inode because it could hash somewhere else recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(new_inode).str()); if (ADAFS_DATA->is_local_op(recipient)) { // local metadata init err = init_metadata_fep(fep, new_inode, uid, gid, mode); } else { // remote metadata init err = rpc_send_create_mdata(recipient, uid, gid, mode, new_inode); if (err == 0) { // Because we don't want to return the metadata init values through the RPC // we just set dummy values here with the most important bits fep.ino = new_inode; fep.attr.st_ino = new_inode; fep.attr.st_mode = mode; fep.attr.st_blocks = 0; fep.attr.st_gid = gid; fep.attr.st_uid = uid; fep.attr.st_nlink = 0; fep.attr.st_size = 0; fep.entry_timeout = 1.0; fep.attr_timeout = 1.0; } else { // TODO remove created dentry } } } else { //local single node operation // XXX check permissions (omittable), should create node be atomic? // create dentry create_dentry(parent, new_inode, name, mode); err = create_dentry(parent, new_inode, name, mode); if (err != 0) { // failure in dentry creation ADAFS_DATA->spdlogger()->error("Failed to create a dentry"); return err; } // create metadata and fill fuse entry param init_metadata_fep(fep, new_inode, uid, gid, mode); err = init_metadata_fep(fep, new_inode, uid, gid, mode); } if (err != 0) ADAFS_DATA->spdlogger()->error("Failed to create metadata"); // TODO remove created dentry return 0; return err; } int remove_node(fuse_ino_t parent, const char* name) { fuse_ino_t del_inode; int err; if (ADAFS_DATA->host_size() > 1) { // multiple node operation auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (ADAFS_DATA->is_local_op(recipient)) { // local dentry removal // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); } else { // remote dentry removal err = rpc_send_remove_dentry(recipient, parent, name, del_inode); } if (err != 0) { ADAFS_DATA->spdlogger()->error("Failed to remove dentry"); return err; } // recalculate recipient for metadata removal recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(del_inode).str()); if (ADAFS_DATA->is_local_op(recipient)) { // local metadata removal err = remove_all_metadata(del_inode); } else { // remote metadata removal err = rpc_send_remove_mdata(recipient, del_inode); } } else { // single node local operation // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { ADAFS_DATA->spdlogger()->error("Failed to remove dentry"); return err; } // Remove inode err = remove_all_metadata(del_inode); } if (err != 0) ADAFS_DATA->spdlogger()->error("Failed to remove metadata"); /* TODO really consider if this is even required in a distributed setup, I'd argue: No * XXX consider the whole lookup count functionality. We need something like a hashtable here, which marks the file * for removal. If forget is then called, the file should be really removed. (see forget comments) * Any fuse comments that increment the lookup count will show the file as deleted after unlink and before/after forget. * symlinks, hardlinks, devices, pipes, etc all work differently with forget and unlink */ return err; } lfs/src/adafs_ops/mdata_ops.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ int init_metadata_fep(struct fuse_entry_param& fep, const fuse_ino_t inode, cons int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode_t mode); int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const string& name, const uid_t uid, const gid_t gid, int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const char* name, const uid_t uid, const gid_t gid, mode_t mode); int remove_node(fuse_ino_t parent, const char* name); #endif //FS_METADATA_OPS_H lfs/src/db/db_ops.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -87,14 +87,14 @@ void db_get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) { } } pair<bool, fuse_ino_t> db_delete_dentry_get_inode(const fuse_ino_t p_inode, const string& name) { pair<int, fuse_ino_t> db_delete_dentry_get_inode(const fuse_ino_t p_inode, const string& name) { auto key = db_build_dentry_key(p_inode, name); auto db = ADAFS_DATA->rdb(); string val; db->Get(ReadOptions(), key, &val); auto pos = val.find("_"); return make_pair(db->Delete(ADAFS_DATA->rdb_write_options(), key).ok() ? 0 : 1, return make_pair(db->Delete(ADAFS_DATA->rdb_write_options(), key).ok() ? 0 : EIO, static_cast<fuse_ino_t>(stoul(val.substr(0, pos)))); } Loading Loading
lfs/.gitignore +0 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,3 @@ cmake-build-debug/ cmake-build-release/ playground/ # Configurations # ################## src/configure.hpp
lfs/src/adafs_ops/dentry_ops.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ pair<int, fuse_ino_t> do_lookup(const fuse_ino_t p_inode, const string& name) { int create_dentry(const fuse_ino_t p_inode, const fuse_ino_t inode, const string& name, mode_t mode) { // XXX check later if we need to check if dentry of father already exists // put dentry for key, value return db_put_dentry(db_build_dentry_key(p_inode, name), db_build_dentry_value(inode, mode)) ? 0 : 1; return db_put_dentry(db_build_dentry_key(p_inode, name), db_build_dentry_value(inode, mode)) ? 0 : EIO; } /** Loading
lfs/src/adafs_ops/mdata_ops.cpp +161 −41 Original line number Diff line number Diff line Loading @@ -4,32 +4,44 @@ #include "mdata_ops.hpp" #include "dentry_ops.hpp" #include "../rpc/client/c_dentry.hpp" #include "../rpc/client/c_metadata.hpp" using namespace std; // TODO error handling. int write_all_metadata(const Metadata& md) { auto inode_key = fmt::FormatInt(md.inode_no()).str(); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size()); db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks()); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size())) return EIO; if (!db_put_mdata(db_build_mdata_key( inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks())) return EIO; return 0; } Loading Loading @@ -68,18 +80,28 @@ int read_all_metadata(Metadata& md, const fuse_ino_t inode) { * @return err */ int remove_all_metadata(const fuse_ino_t inode) { // TODO error handling auto inode_key = fmt::FormatInt(inode).str(); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map))); db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map))); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::atime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mtime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::ctime)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::uid)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::gid)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::mode)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::link_count)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::size)>(md_field_map)))) return EIO; if (!db_delete_mdata(db_build_mdata_key(inode_key, std::get<to_underlying(Md_fields::blocks)>(md_field_map)))) return EIO; return 0; } Loading Loading @@ -179,7 +201,7 @@ int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode } /** * Creates a new node (file or directory) in the file system. Fills given fuse_entry_param. This function is only called locally * Creates a new node (file or directory) in the file system. Fills given fuse_entry_param. * @param req * @param fep * @param parent Loading @@ -187,18 +209,116 @@ int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode * @param mode * @return err */ int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const string& name, const uid_t uid, const gid_t gid, int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const char* name, const uid_t uid, const gid_t gid, mode_t mode) { // create inode number auto new_inode = Util::generate_inode_no(); // // create inode number // auto new_inode = Util::generate_inode_no(); // // create dentry // create_dentry(parent, new_inode, name, mode); // // create metadata and fill fuse entry param // init_metadata_fep(fep, new_inode, uid, gid, mode); int err; // create new inode number fuse_ino_t new_inode = Util::generate_inode_no(); if (ADAFS_DATA->host_size() > 1) { // multiple node operation auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (ADAFS_DATA->is_local_op(recipient)) { // local dentry create err = create_dentry(parent, new_inode, name, mode); } else { // remote dentry create err = rpc_send_create_dentry(recipient, parent, name, mode, new_inode); } if (err != 0) { // failure in dentry creation ADAFS_DATA->spdlogger()->error("Failed to create a dentry"); return err; } // calculate recipient again for new inode because it could hash somewhere else recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(new_inode).str()); if (ADAFS_DATA->is_local_op(recipient)) { // local metadata init err = init_metadata_fep(fep, new_inode, uid, gid, mode); } else { // remote metadata init err = rpc_send_create_mdata(recipient, uid, gid, mode, new_inode); if (err == 0) { // Because we don't want to return the metadata init values through the RPC // we just set dummy values here with the most important bits fep.ino = new_inode; fep.attr.st_ino = new_inode; fep.attr.st_mode = mode; fep.attr.st_blocks = 0; fep.attr.st_gid = gid; fep.attr.st_uid = uid; fep.attr.st_nlink = 0; fep.attr.st_size = 0; fep.entry_timeout = 1.0; fep.attr_timeout = 1.0; } else { // TODO remove created dentry } } } else { //local single node operation // XXX check permissions (omittable), should create node be atomic? // create dentry create_dentry(parent, new_inode, name, mode); err = create_dentry(parent, new_inode, name, mode); if (err != 0) { // failure in dentry creation ADAFS_DATA->spdlogger()->error("Failed to create a dentry"); return err; } // create metadata and fill fuse entry param init_metadata_fep(fep, new_inode, uid, gid, mode); err = init_metadata_fep(fep, new_inode, uid, gid, mode); } if (err != 0) ADAFS_DATA->spdlogger()->error("Failed to create metadata"); // TODO remove created dentry return 0; return err; } int remove_node(fuse_ino_t parent, const char* name) { fuse_ino_t del_inode; int err; if (ADAFS_DATA->host_size() > 1) { // multiple node operation auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (ADAFS_DATA->is_local_op(recipient)) { // local dentry removal // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); } else { // remote dentry removal err = rpc_send_remove_dentry(recipient, parent, name, del_inode); } if (err != 0) { ADAFS_DATA->spdlogger()->error("Failed to remove dentry"); return err; } // recalculate recipient for metadata removal recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(del_inode).str()); if (ADAFS_DATA->is_local_op(recipient)) { // local metadata removal err = remove_all_metadata(del_inode); } else { // remote metadata removal err = rpc_send_remove_mdata(recipient, del_inode); } } else { // single node local operation // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { ADAFS_DATA->spdlogger()->error("Failed to remove dentry"); return err; } // Remove inode err = remove_all_metadata(del_inode); } if (err != 0) ADAFS_DATA->spdlogger()->error("Failed to remove metadata"); /* TODO really consider if this is even required in a distributed setup, I'd argue: No * XXX consider the whole lookup count functionality. We need something like a hashtable here, which marks the file * for removal. If forget is then called, the file should be really removed. (see forget comments) * Any fuse comments that increment the lookup count will show the file as deleted after unlink and before/after forget. * symlinks, hardlinks, devices, pipes, etc all work differently with forget and unlink */ return err; }
lfs/src/adafs_ops/mdata_ops.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ int init_metadata_fep(struct fuse_entry_param& fep, const fuse_ino_t inode, cons int init_metadata(const fuse_ino_t inode, const uid_t uid, const gid_t gid, mode_t mode); int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const string& name, const uid_t uid, const gid_t gid, int create_node(struct fuse_entry_param& fep, fuse_ino_t parent, const char* name, const uid_t uid, const gid_t gid, mode_t mode); int remove_node(fuse_ino_t parent, const char* name); #endif //FS_METADATA_OPS_H
lfs/src/db/db_ops.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -87,14 +87,14 @@ void db_get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) { } } pair<bool, fuse_ino_t> db_delete_dentry_get_inode(const fuse_ino_t p_inode, const string& name) { pair<int, fuse_ino_t> db_delete_dentry_get_inode(const fuse_ino_t p_inode, const string& name) { auto key = db_build_dentry_key(p_inode, name); auto db = ADAFS_DATA->rdb(); string val; db->Get(ReadOptions(), key, &val); auto pos = val.find("_"); return make_pair(db->Delete(ADAFS_DATA->rdb_write_options(), key).ok() ? 0 : 1, return make_pair(db->Delete(ADAFS_DATA->rdb_write_options(), key).ok() ? 0 : EIO, static_cast<fuse_ino_t>(stoul(val.substr(0, pos)))); } Loading