//------------------------------------------------------------------------------ // File: FuseServer/Flush.cc // Author: Andreas-Joachim Peters - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2019 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #include #include #include "mgm/FuseServer/Flush.hh" #include "common/Logging.hh" #include "mgm/XrdMgmOfs.hh" EOSMGMNAMESPACE_BEGIN //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void FuseServer::Flush::beginFlush(uint64_t id, std::string client) { eos_static_info("ino=%016x client=%s", id, client.c_str()); XrdSysMutexHelper lock(this); flush_info_t finfo(client); flushmap[id][client].Add(finfo); } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void FuseServer::Flush::endFlush(uint64_t id, std::string client) { eos_static_info("ino=%016x client=%s", id, client.c_str()); XrdSysMutexHelper lock(this); flush_info_t finfo(client); if (flushmap[id][client].Remove(finfo)) { flushmap[id].erase(client); if (!flushmap[id].size()) { flushmap.erase(id); } } } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ bool FuseServer::Flush::hasFlush(uint64_t id) { // this function takes maximum 255ms and waits for a flush to be removed // this function might block a client connection/thread for the given time bool has = false; size_t delay = 1; for (size_t i = 0 ; i < 8; ++i) { { XrdSysMutexHelper lock(this); has = validateFlush(id); } if (!has) { return false; } std::this_thread::sleep_for(std::chrono::milliseconds(delay)); delay *= 2; } return true; } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ bool FuseServer::Flush::validateFlush(uint64_t id) { bool has = false; if (flushmap.count(id)) { for (auto it = flushmap[id].begin(); it != flushmap[id].end();) { if (eos::common::Timing::GetAgeInNs(&it->second.ftime) < 0) { has = true; ++it; } else { it = flushmap[id].erase(it); } } if (!flushmap[id].size()) { flushmap.erase(id); } } return has; } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void FuseServer::Flush::expireFlush() { XrdSysMutexHelper lock(this); for (auto it = flushmap.begin(); it != flushmap.end();) { for (auto fit = it->second.begin(); fit != it->second.end();) { if (eos::common::Timing::GetAgeInNs(&fit->second.ftime) < 0) { ++fit; } else { fit = it->second.erase(fit); } } if (!it->second.size()) { it = flushmap.erase(it); } else { ++it; } } } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void FuseServer::Flush::Print(std::string& out) { XrdSysMutexHelper lock(this); for (auto it = flushmap.begin(); it != flushmap.end(); ++it) { for (auto fit = it->second.begin(); fit != it->second.end(); ++fit) { long long valid = eos::common::Timing::GetAgeInNs(&fit->second.ftime); char formatline[4096]; snprintf(formatline, sizeof(formatline), "flush : ino : %016lx client : %-8s valid=%.02f sec\n", it->first, fit->first.c_str(), 1.0 * valid / 1000000000.0); out += formatline; } } } EOSMGMNAMESPACE_END