Commit 405abc3a authored by Marc Vef's avatar Marc Vef
Browse files

Remove: Do not broadcast chunk removal to all nodes if file size == 0

This is an optimization for mdtest which shows very slow performance
in removing files, getting worse with an increasing number of nodes.
parent 78403696
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ int rpc_send_access(const std::string& path, int mask);

int rpc_send_stat(const std::string& path, std::string& attr);

int rpc_send_rm_node(const std::string& path);
int rpc_send_rm_node(const std::string& path, const bool remove_metadentry_only);

int rpc_send_update_metadentry(const std::string& path, const Metadentry& md, const MetadentryUpdateFlags& md_flags);

+5 −1
Original line number Diff line number Diff line
@@ -54,7 +54,11 @@ int adafs_mk_node(const std::string& path, const mode_t mode) {
 */
int adafs_rm_node(const std::string& path) {
    init_ld_env_if_needed();
    return rpc_send_rm_node(path);
    struct stat node_metadentry{};
    auto err = adafs_stat(path, &node_metadentry);
    if (err != 0)
        return -1;
    return rpc_send_rm_node(path, node_metadentry.st_size == 0);
}

int adafs_access(const std::string& path, const int mask) {
+14 −7
Original line number Diff line number Diff line
@@ -170,19 +170,26 @@ int rpc_send_stat(const std::string& path, string& attr) {
    return err;
}

int rpc_send_rm_node(const std::string& path) {
int rpc_send_rm_node(const std::string& path, const bool remove_metadentry_only) {
    hg_return_t ret;
    int err = 0; // assume we succeed
    // if metadentry should only removed only, send only 1 rpc to remove the metadata
    // else send an rpc to all hosts and thus broadcast chunk_removal.
    auto rpc_target_size = remove_metadentry_only ? static_cast<uint64_t>(1) : fs_config->host_size;

    ld_logger->debug("{}() Creating Mercury handles for all nodes ...", __func__);
    vector<hg_handle_t> rpc_handles(fs_config->host_size);
    vector<margo_request> rpc_waiters(fs_config->host_size);
    vector<rpc_rm_node_in_t> rpc_in(fs_config->host_size);
    vector<hg_handle_t> rpc_handles(rpc_target_size);
    vector<margo_request> rpc_waiters(rpc_target_size);
    vector<rpc_rm_node_in_t> rpc_in(rpc_target_size);
    // Send rpc to all nodes as all of them can have chunks for this path
    for (size_t i = 0; i < fs_config->host_size; i++) {
    for (size_t i = 0; i < rpc_target_size; i++) {
        // fill in
        rpc_in[i].path = path.c_str();
        // create handle
        // if only the metadentry needs to removed send one rpc to metadentry's responsible node
        if (remove_metadentry_only)
            ret = margo_create_wrap(ipc_rm_node_id, rpc_rm_node_id, path, rpc_handles[i], false);
        else
            ret = margo_create_wrap(ipc_rm_node_id, rpc_rm_node_id, i, rpc_handles[i], false);
        if (ret != HG_SUCCESS) {
            ld_logger->warn("{}() Unable to create Mercury handle", __func__);
@@ -201,7 +208,7 @@ int rpc_send_rm_node(const std::string& path) {
    }

    // Wait for RPC responses and then get response
    for (size_t i = 0; i < fs_config->host_size; i++) {
    for (size_t i = 0; i < rpc_target_size; i++) {
        // XXX We might need a timeout here to not wait forever for an output that never comes?
        ret = margo_wait(rpc_waiters[i]);
        if (ret != HG_SUCCESS) {