Loading lfs/src/classes/rpc_data.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,22 @@ void RPCData::rpc_srv_lookup_id(hg_id_t rpc_srv_lookup_id) { RPCData::rpc_srv_lookup_id_ = rpc_srv_lookup_id; } hg_id_t RPCData::rpc_srv_remove_dentry_id() const { return rpc_srv_remove_dentry_id_; } void RPCData::rpc_srv_remove_dentry_id(hg_id_t rpc_srv_remove_dentry_id) { RPCData::rpc_srv_remove_dentry_id_ = rpc_srv_remove_dentry_id; } hg_id_t RPCData::rpc_srv_remove_mdata_id() const { return rpc_srv_remove_mdata_id_; } void RPCData::rpc_srv_remove_mdata_id(hg_id_t rpc_srv_remove_mdata_id) { RPCData::rpc_srv_remove_mdata_id_ = rpc_srv_remove_mdata_id; } Loading lfs/src/classes/rpc_data.hpp +9 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ private: hg_id_t rpc_srv_create_mdata_id_; hg_id_t rpc_srv_attr_id_; hg_id_t rpc_srv_lookup_id_; hg_id_t rpc_srv_remove_dentry_id_; hg_id_t rpc_srv_remove_mdata_id_; public: Loading Loading @@ -106,6 +108,13 @@ public: void rpc_srv_lookup_id(hg_id_t rpc_srv_lookup_id); hg_id_t rpc_srv_remove_dentry_id() const; void rpc_srv_remove_dentry_id(hg_id_t rpc_srv_remove_dentry_id); hg_id_t rpc_srv_remove_mdata_id() const; void rpc_srv_remove_mdata_id(hg_id_t rpc_srv_remove_mdata_id); }; Loading lfs/src/fuse_ops/file.cpp +34 −17 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "../adafs_ops/access.hpp" #include "../adafs_ops/io.hpp" #include "../rpc/client/c_metadata.hpp" #include "../rpc/client/c_dentry.hpp" using namespace std; Loading Loading @@ -220,6 +221,7 @@ void adafs_ll_create(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t fuse_ino_t new_inode; err = rpc_send_create_dentry(recipient, parent, name, f_mode, new_inode); if (err == 0) { recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(new_inode).str()); err = rpc_send_create_mdata(recipient, uid, gid, f_mode, new_inode); if (err == 0) { fep.ino = new_inode; Loading Loading @@ -307,33 +309,48 @@ void adafs_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t */ void adafs_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char* name) { ADAFS_DATA->spdlogger()->debug("adafs_ll_unlink() enter: parent_inode {} name {}", parent, name); fuse_ino_t inode; fuse_ino_t del_inode; int err; // XXX errorhandling /* * 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 */ if (ADAFS_DATA->host_size() > 1) { auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (recipient == ADAFS_DATA->host_id()) { // local // Remove denty returns <err, inode_of_dentry> pair tie(err, inode) = remove_dentry(parent, name); tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { fuse_reply_err(req, err); return; } // Remove inode err = remove_all_metadata(inode); err = remove_all_metadata(del_inode); } else { // remote err = rpc_send_remove_dentry(recipient, parent, name, del_inode); if (err == 0) { recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(del_inode).str()); err = rpc_send_remove_mdata(recipient, del_inode); } } } else { // local // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { fuse_reply_err(req, err); return; } // Remove inode err = remove_all_metadata(del_inode); } /* 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 */ // XXX delete data blocks (asynchronously) fuse_reply_err(req, 0); fuse_reply_err(req, err); } /** Loading lfs/src/rpc/client/c_dentry.cpp +101 −1 Original line number Diff line number Diff line Loading @@ -56,3 +56,103 @@ int rpc_send_lookup(const size_t recipient, const fuse_ino_t parent, const char* err = 1; return err; } int rpc_send_create_dentry(const size_t recipient, const fuse_ino_t parent, const string& name, const mode_t mode, fuse_ino_t& new_inode) { hg_handle_t handle; hg_addr_t svr_addr = HG_ADDR_NULL; rpc_create_dentry_in_t in; rpc_create_dentry_out_t out; auto err = 0; // fill in in.parent_inode = static_cast<uint64_t>(parent); in.filename = name.c_str(); in.mode = static_cast<uint32_t>(mode); // TODO HG_ADDR_T is never freed atm. Need to change LRUCache if (!RPC_DATA->get_addr_by_hostid(recipient, svr_addr)) { ADAFS_DATA->spdlogger()->error("server address not resolvable for host id {}", recipient); return 1; } auto ret = HG_Create(RPC_DATA->client_hg_context(), svr_addr, RPC_DATA->rpc_srv_create_dentry_id(), &handle); if (ret != HG_SUCCESS) { ADAFS_DATA->spdlogger()->error("creating handle FAILED"); return 1; } int send_ret = HG_FALSE; for (int i = 0; i < max_retries; ++i) { send_ret = margo_forward_timed(RPC_DATA->client_mid(), handle, &in, 15000); if (send_ret == HG_SUCCESS) { break; } } if (send_ret == HG_SUCCESS) { /* decode response */ ret = HG_Get_output(handle, &out); ADAFS_DATA->spdlogger()->debug("Got response inode: {}", out.inode); new_inode = static_cast<fuse_ino_t>(out.inode); /* clean up resources consumed by this rpc */ HG_Free_output(handle, &out); } else { ADAFS_DATA->spdlogger()->error("RPC send_create_dentry (timed out)"); } in.filename = nullptr; // XXX temporary. If this is not done free input crashes because of invalid pointer?! HG_Free_input(handle, &in); HG_Destroy(handle); if (new_inode == INVALID_INODE) err = 1; return err; } int rpc_send_remove_dentry(const size_t recipient, const fuse_ino_t parent, const string& name, fuse_ino_t& del_inode) { hg_handle_t handle; hg_addr_t svr_addr = HG_ADDR_NULL; rpc_remove_dentry_in_t in; rpc_remove_dentry_out_t out; auto err = 0; // fill in in.parent_inode = static_cast<uint64_t>(parent); in.filename = name.c_str(); // TODO HG_ADDR_T is never freed atm. Need to change LRUCache if (!RPC_DATA->get_addr_by_hostid(recipient, svr_addr)) { ADAFS_DATA->spdlogger()->error("server address not resolvable for host id {}", recipient); return 1; } auto ret = HG_Create(RPC_DATA->client_hg_context(), svr_addr, RPC_DATA->rpc_srv_remove_dentry_id(), &handle); if (ret != HG_SUCCESS) { ADAFS_DATA->spdlogger()->error("creating handle FAILED"); return 1; } int send_ret = HG_FALSE; for (int i = 0; i < max_retries; ++i) { send_ret = margo_forward_timed(RPC_DATA->client_mid(), handle, &in, 15000); if (send_ret == HG_SUCCESS) { break; } } if (send_ret == HG_SUCCESS) { /* decode response */ ret = HG_Get_output(handle, &out); ADAFS_DATA->spdlogger()->debug("Got response deleted inode: {}", out.del_inode); del_inode = static_cast<fuse_ino_t>(out.del_inode); /* clean up resources consumed by this rpc */ HG_Free_output(handle, &out); } else { ADAFS_DATA->spdlogger()->error("RPC send_remove_dentry (timed out)"); } in.filename = nullptr; // XXX temporary. If this is not done free input crashes because of invalid pointer?! HG_Free_input(handle, &in); HG_Destroy(handle); if (del_inode == INVALID_INODE) err = 1; return err; } lfs/src/rpc/client/c_dentry.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -9,5 +9,11 @@ int rpc_send_lookup(const size_t recipient, const fuse_ino_t parent, const char* name, fuse_ino_t& inode); int rpc_send_create_dentry(const size_t recipient, const fuse_ino_t parent, const std::string& name, const mode_t mode, fuse_ino_t& new_inode); int rpc_send_remove_dentry(const size_t recipient, const fuse_ino_t parent, const std::string& name, fuse_ino_t& del_inode); #endif //LFS_C_DENTRY_HPP Loading
lfs/src/classes/rpc_data.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,22 @@ void RPCData::rpc_srv_lookup_id(hg_id_t rpc_srv_lookup_id) { RPCData::rpc_srv_lookup_id_ = rpc_srv_lookup_id; } hg_id_t RPCData::rpc_srv_remove_dentry_id() const { return rpc_srv_remove_dentry_id_; } void RPCData::rpc_srv_remove_dentry_id(hg_id_t rpc_srv_remove_dentry_id) { RPCData::rpc_srv_remove_dentry_id_ = rpc_srv_remove_dentry_id; } hg_id_t RPCData::rpc_srv_remove_mdata_id() const { return rpc_srv_remove_mdata_id_; } void RPCData::rpc_srv_remove_mdata_id(hg_id_t rpc_srv_remove_mdata_id) { RPCData::rpc_srv_remove_mdata_id_ = rpc_srv_remove_mdata_id; } Loading
lfs/src/classes/rpc_data.hpp +9 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ private: hg_id_t rpc_srv_create_mdata_id_; hg_id_t rpc_srv_attr_id_; hg_id_t rpc_srv_lookup_id_; hg_id_t rpc_srv_remove_dentry_id_; hg_id_t rpc_srv_remove_mdata_id_; public: Loading Loading @@ -106,6 +108,13 @@ public: void rpc_srv_lookup_id(hg_id_t rpc_srv_lookup_id); hg_id_t rpc_srv_remove_dentry_id() const; void rpc_srv_remove_dentry_id(hg_id_t rpc_srv_remove_dentry_id); hg_id_t rpc_srv_remove_mdata_id() const; void rpc_srv_remove_mdata_id(hg_id_t rpc_srv_remove_mdata_id); }; Loading
lfs/src/fuse_ops/file.cpp +34 −17 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "../adafs_ops/access.hpp" #include "../adafs_ops/io.hpp" #include "../rpc/client/c_metadata.hpp" #include "../rpc/client/c_dentry.hpp" using namespace std; Loading Loading @@ -220,6 +221,7 @@ void adafs_ll_create(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t fuse_ino_t new_inode; err = rpc_send_create_dentry(recipient, parent, name, f_mode, new_inode); if (err == 0) { recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(new_inode).str()); err = rpc_send_create_mdata(recipient, uid, gid, f_mode, new_inode); if (err == 0) { fep.ino = new_inode; Loading Loading @@ -307,33 +309,48 @@ void adafs_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t */ void adafs_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char* name) { ADAFS_DATA->spdlogger()->debug("adafs_ll_unlink() enter: parent_inode {} name {}", parent, name); fuse_ino_t inode; fuse_ino_t del_inode; int err; // XXX errorhandling /* * 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 */ if (ADAFS_DATA->host_size() > 1) { auto recipient = RPC_DATA->get_rpc_node(RPC_DATA->get_dentry_hashable(parent, name)); if (recipient == ADAFS_DATA->host_id()) { // local // Remove denty returns <err, inode_of_dentry> pair tie(err, inode) = remove_dentry(parent, name); tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { fuse_reply_err(req, err); return; } // Remove inode err = remove_all_metadata(inode); err = remove_all_metadata(del_inode); } else { // remote err = rpc_send_remove_dentry(recipient, parent, name, del_inode); if (err == 0) { recipient = RPC_DATA->get_rpc_node(fmt::FormatInt(del_inode).str()); err = rpc_send_remove_mdata(recipient, del_inode); } } } else { // local // Remove denty returns <err, inode_of_dentry> pair tie(err, del_inode) = remove_dentry(parent, name); if (err != 0) { fuse_reply_err(req, err); return; } // Remove inode err = remove_all_metadata(del_inode); } /* 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 */ // XXX delete data blocks (asynchronously) fuse_reply_err(req, 0); fuse_reply_err(req, err); } /** Loading
lfs/src/rpc/client/c_dentry.cpp +101 −1 Original line number Diff line number Diff line Loading @@ -56,3 +56,103 @@ int rpc_send_lookup(const size_t recipient, const fuse_ino_t parent, const char* err = 1; return err; } int rpc_send_create_dentry(const size_t recipient, const fuse_ino_t parent, const string& name, const mode_t mode, fuse_ino_t& new_inode) { hg_handle_t handle; hg_addr_t svr_addr = HG_ADDR_NULL; rpc_create_dentry_in_t in; rpc_create_dentry_out_t out; auto err = 0; // fill in in.parent_inode = static_cast<uint64_t>(parent); in.filename = name.c_str(); in.mode = static_cast<uint32_t>(mode); // TODO HG_ADDR_T is never freed atm. Need to change LRUCache if (!RPC_DATA->get_addr_by_hostid(recipient, svr_addr)) { ADAFS_DATA->spdlogger()->error("server address not resolvable for host id {}", recipient); return 1; } auto ret = HG_Create(RPC_DATA->client_hg_context(), svr_addr, RPC_DATA->rpc_srv_create_dentry_id(), &handle); if (ret != HG_SUCCESS) { ADAFS_DATA->spdlogger()->error("creating handle FAILED"); return 1; } int send_ret = HG_FALSE; for (int i = 0; i < max_retries; ++i) { send_ret = margo_forward_timed(RPC_DATA->client_mid(), handle, &in, 15000); if (send_ret == HG_SUCCESS) { break; } } if (send_ret == HG_SUCCESS) { /* decode response */ ret = HG_Get_output(handle, &out); ADAFS_DATA->spdlogger()->debug("Got response inode: {}", out.inode); new_inode = static_cast<fuse_ino_t>(out.inode); /* clean up resources consumed by this rpc */ HG_Free_output(handle, &out); } else { ADAFS_DATA->spdlogger()->error("RPC send_create_dentry (timed out)"); } in.filename = nullptr; // XXX temporary. If this is not done free input crashes because of invalid pointer?! HG_Free_input(handle, &in); HG_Destroy(handle); if (new_inode == INVALID_INODE) err = 1; return err; } int rpc_send_remove_dentry(const size_t recipient, const fuse_ino_t parent, const string& name, fuse_ino_t& del_inode) { hg_handle_t handle; hg_addr_t svr_addr = HG_ADDR_NULL; rpc_remove_dentry_in_t in; rpc_remove_dentry_out_t out; auto err = 0; // fill in in.parent_inode = static_cast<uint64_t>(parent); in.filename = name.c_str(); // TODO HG_ADDR_T is never freed atm. Need to change LRUCache if (!RPC_DATA->get_addr_by_hostid(recipient, svr_addr)) { ADAFS_DATA->spdlogger()->error("server address not resolvable for host id {}", recipient); return 1; } auto ret = HG_Create(RPC_DATA->client_hg_context(), svr_addr, RPC_DATA->rpc_srv_remove_dentry_id(), &handle); if (ret != HG_SUCCESS) { ADAFS_DATA->spdlogger()->error("creating handle FAILED"); return 1; } int send_ret = HG_FALSE; for (int i = 0; i < max_retries; ++i) { send_ret = margo_forward_timed(RPC_DATA->client_mid(), handle, &in, 15000); if (send_ret == HG_SUCCESS) { break; } } if (send_ret == HG_SUCCESS) { /* decode response */ ret = HG_Get_output(handle, &out); ADAFS_DATA->spdlogger()->debug("Got response deleted inode: {}", out.del_inode); del_inode = static_cast<fuse_ino_t>(out.del_inode); /* clean up resources consumed by this rpc */ HG_Free_output(handle, &out); } else { ADAFS_DATA->spdlogger()->error("RPC send_remove_dentry (timed out)"); } in.filename = nullptr; // XXX temporary. If this is not done free input crashes because of invalid pointer?! HG_Free_input(handle, &in); HG_Destroy(handle); if (del_inode == INVALID_INODE) err = 1; return err; }
lfs/src/rpc/client/c_dentry.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -9,5 +9,11 @@ int rpc_send_lookup(const size_t recipient, const fuse_ino_t parent, const char* name, fuse_ino_t& inode); int rpc_send_create_dentry(const size_t recipient, const fuse_ino_t parent, const std::string& name, const mode_t mode, fuse_ino_t& new_inode); int rpc_send_remove_dentry(const size_t recipient, const fuse_ino_t parent, const std::string& name, fuse_ino_t& del_inode); #endif //LFS_C_DENTRY_HPP