diff --git a/src/XrdFileCache/XrdFileCache.cc b/src/XrdFileCache/XrdFileCache.cc index a7b3ca57ea7..09b1c9cedac 100644 --- a/src/XrdFileCache/XrdFileCache.cc +++ b/src/XrdFileCache/XrdFileCache.cc @@ -168,6 +168,16 @@ int Cache::isAttached() void Cache::Detach(XrdOucCacheIO* io) { clLog()->Info(XrdCl::AppMsg, "Cache::Detach() %s", io->Path()); + std::map::iterator it = m_active.begin(); + while (it != m_active.end() ) + { + if (it->second.io == io) { + m_active.erase(it++); + } + else { + ++it; + } + } delete io; } @@ -265,6 +275,25 @@ Cache::RAMBlockReleased() m_RAMblocks_used--; } +//============================================================================== +//======================= File relinquish at process of dying =================== +//====================================================================== +File* Cache::GetFileForLocalPath(std::string path, IO* io) +{ + typedef std::map ActiveMap_t; + ActiveMap_t::iterator it = m_active.find(path); + if (it == m_active.end()) + { + return 0; + } + else { + File* file = it->second.file; + it->second.io->RelinquishFile(file); + return file; + } +} + + //============================================================================== //======================= PREFETCH =================================== @@ -306,7 +335,7 @@ Cache::DeRegisterPrefetchFile(File* file) // called from last line File::InitiateClose() m_prefetch_condVar.Lock(); - for (FileList::iterator it = m_prefetchList.begin(); it != m_prefetchList.end(); ++it) { + for (PrefetchList::iterator it = m_prefetchList.begin(); it != m_prefetchList.end(); ++it) { if (*it == file) { m_prefetchList.erase(it); break; diff --git a/src/XrdFileCache/XrdFileCache.hh b/src/XrdFileCache/XrdFileCache.hh index 1e19c1566d4..84489a7b889 100644 --- a/src/XrdFileCache/XrdFileCache.hh +++ b/src/XrdFileCache/XrdFileCache.hh @@ -186,13 +186,14 @@ namespace XrdFileCache XrdOss* GetOss() const { return m_output_fs; } XrdSysError& GetSysError() { return m_log; } - + + File* GetFileForLocalPath(std::string, IO*); private: bool ConfigParameters(std::string, XrdOucStream&); bool ConfigXeq(char *, XrdOucStream &); bool xdlib(XrdOucStream &); - static Cache *m_factory; //!< this object + static Cache *m_factory; //!< this object XrdSysError m_log; //!< XrdFileCache namespace logger XrdOucCacheStats m_stats; //!< @@ -222,6 +223,14 @@ namespace XrdFileCache WriteQ m_writeQ; + struct DiskNetIO + { + IO* io; + File* file; + }; + + std::map m_active; + // prefetching typedef std::vector PrefetchList; PrefetchList m_prefetchList; diff --git a/src/XrdFileCache/XrdFileCacheIO.hh b/src/XrdFileCache/XrdFileCacheIO.hh index a91d90d32f8..ff2fa866848 100644 --- a/src/XrdFileCache/XrdFileCacheIO.hh +++ b/src/XrdFileCache/XrdFileCacheIO.hh @@ -32,7 +32,9 @@ namespace XrdFileCache virtual int Write(char *Buffer, long long Offset, int Length) { errno = ENOTSUP; return -1; } - virtual void Update(XrdOucCacheIO2 &iocp) { m_io = &iocp; } + virtual void Update(XrdOucCacheIO2 &iocp) { m_io = &iocp; } + + virtual void RelinquishFile(File*) {} protected: XrdCl::Log* clLog() const { return XrdCl::DefaultEnv::GetLog(); } diff --git a/src/XrdFileCache/XrdFileCacheIOEntireFile.cc b/src/XrdFileCache/XrdFileCacheIOEntireFile.cc index ff2e6705322..bcd1fa053c4 100644 --- a/src/XrdFileCache/XrdFileCacheIOEntireFile.cc +++ b/src/XrdFileCache/XrdFileCacheIOEntireFile.cc @@ -44,11 +44,16 @@ IOEntireFile::IOEntireFile(XrdOucCacheIO2 *io, XrdOucCacheStats &stats, Cache & XrdCl::URL url(m_io->Path()); std::string fname = Cache::GetInstance().RefConfiguration().m_cache_dir + url.GetPath(); - struct stat st; - Fstat(st); - m_file = new File(io, fname, 0, st.st_size); + if (!Cache::GetInstance().GetFileForLocalPath(fname, this)) + { + struct stat st; + Fstat(st); + m_file = new File(io, fname, 0, st.st_size); + } } + + IOEntireFile::~IOEntireFile() { @@ -71,6 +76,12 @@ int IOEntireFile::Fstat(struct stat &sbuff) } } +void IOEntireFile::RelinquishFile(File* f) +{ + assert(m_file == f); + m_file = 0; +} + struct stat* IOEntireFile::getValidLocalStat(const char* path) { @@ -100,17 +111,21 @@ struct stat* IOEntireFile::getValidLocalStat(const char* path) bool IOEntireFile::ioActive() { - return m_file->InitiateClose(); + if (!m_file) + return false; + else + return m_file->InitiateClose(); } XrdOucCacheIO *IOEntireFile::Detach() { - m_statsGlobal.Add(m_file->GetStats()); - XrdOucCacheIO * io = m_io; - delete m_file; - m_file = 0; + if (m_file) { + m_statsGlobal.Add(m_file->GetStats()); + delete m_file; + m_file = 0; + } // This will delete us! m_cache.Detach(this); diff --git a/src/XrdFileCache/XrdFileCacheIOEntireFile.hh b/src/XrdFileCache/XrdFileCacheIOEntireFile.hh index cbd7de232a1..e3e8fe9f1a8 100644 --- a/src/XrdFileCache/XrdFileCacheIOEntireFile.hh +++ b/src/XrdFileCache/XrdFileCacheIOEntireFile.hh @@ -97,6 +97,7 @@ namespace XrdFileCache virtual int Fstat(struct stat &sbuff); + virtual void RelinquishFile(File*); private: File* m_file;