diff --git a/src/XrdFileCache/XrdFileCache.hh b/src/XrdFileCache/XrdFileCache.hh index f6009752adf..b1b7b6fbc74 100644 --- a/src/XrdFileCache/XrdFileCache.hh +++ b/src/XrdFileCache/XrdFileCache.hh @@ -242,6 +242,7 @@ public: void FileSyncDone(File*, bool high_debug); + XrdSysError* GetLog() { return &m_log; } XrdSysTrace* GetTrace() { return m_trace; } void ExecuteCommandUrl(const std::string& command_url); diff --git a/src/XrdFileCache/XrdFileCacheFile.cc b/src/XrdFileCache/XrdFileCacheFile.cc index 19bef489002..74fb6283688 100644 --- a/src/XrdFileCache/XrdFileCacheFile.cc +++ b/src/XrdFileCache/XrdFileCacheFile.cc @@ -40,7 +40,7 @@ using namespace XrdFileCache; namespace { -const int PREFETCH_MAX_ATTEMPTS = 10; +const int BLOCK_WRITE_MAX_ATTEMPTS = 4; Cache* cache() { return &Cache::GetInstance(); } @@ -811,36 +811,35 @@ int File::Read(IO *io, char* iUserBuff, long long iUserOff, int iUserSize) void File::WriteBlockToDisk(Block* b) { - int retval = 0; // write block buffer into disk file - long long offset = b->m_offset - m_offset; - long long size = (offset + m_cfi.GetBufferSize()) > m_fileSize ? (m_fileSize - offset) : m_cfi.GetBufferSize(); - int buffer_remaining = size; - int buffer_offset = 0; - int cnt = 0; - const char* buff = &b->m_buff[0]; - while ((buffer_remaining > 0) && // There is more to be written - (((retval = m_output->Write(buff, offset + buffer_offset, buffer_remaining)) != -1) - || (errno == EINTR))) // Write occurs without an error - { - buffer_remaining -= retval; - buff += retval; - cnt++; + long long offset = b->m_offset - m_offset; + long long size = (offset + m_cfi.GetBufferSize()) > m_fileSize ? (m_fileSize - offset) : m_cfi.GetBufferSize(); + const char *buff = &b->m_buff[0]; + + ssize_t retval = m_output->Write(buff, offset, size); - if (buffer_remaining) + if (retval < size) + { + if (retval < 0) { - TRACEF(Warning, "File::WriteToDisk() reattempt " << cnt << " writing missing " << buffer_remaining << " for block offset " << b->m_offset); + GetLog()->Emsg("File::WriteToDisk()", -retval, "write block to disk", GetLocalPath().c_str()); } - if (cnt > PREFETCH_MAX_ATTEMPTS) + else { - TRACEF(Error, "File::WriteToDisk() write block with off = " << b->m_offset <<" failed too manny attempts "); - return; + TRACEF(Error, "File::WriteToDisk() incomplete block write ret=" << retval << " (should be " << size << ")"); } + + XrdSysCondVarHelper _lck(m_downloadCond); + // XXXX MT - I suspect there might be a conrer case where block is not deallocated. + // Try to catch the case in debuggger. + dec_ref_count(b); + + return; } // set bit fetched - TRACEF(Dump, "File::WriteToDisk() success set bit for block " << b->m_offset << " size " << size); - int pfIdx = (b->m_offset - m_offset)/m_cfi.GetBufferSize(); + TRACEF(Dump, "File::WriteToDisk() success set bit for block " << b->m_offset << " size=" << size); + int pfIdx = (b->m_offset - m_offset) / m_cfi.GetBufferSize(); bool schedule_sync = false; { @@ -854,7 +853,6 @@ void File::WriteBlockToDisk(Block* b) // clLog()->Dump(XrdCl::AppMsg, "File::WriteToDisk() dec_ref_count %d %s", pfIdx, lPath()); dec_ref_count(b); - // set bit synced if (m_in_sync) { @@ -922,7 +920,8 @@ void File::dec_ref_count(Block* b) b->m_refcnt--; assert(b->m_refcnt >= 0); - // File::Read() can decrease ref count before waiting to be , prefetch starts with refcnt 0 + // File::Read() can decrease ref count before waiting for the block in case + // of an error. Prefetch starts with refcnt 0. if (b->m_refcnt == 0 && b->is_finished()) { free_block(b); @@ -932,7 +931,7 @@ void File::dec_ref_count(Block* b) void File::free_block(Block* b) { // Method always called under lock. - int i = b->m_offset/BufferSize(); + int i = b->m_offset / BufferSize(); TRACEF(Dump, "File::free_block block " << b << " idx = " << i); size_t ret = m_block_map.erase(i); if (ret != 1) @@ -1154,6 +1153,11 @@ float File::GetPrefetchScore() const return m_prefetchScore; } +XrdSysError* File::GetLog() +{ + return Cache::GetInstance().GetLog(); +} + XrdSysTrace* File::GetTrace() { return Cache::GetInstance().GetTrace(); diff --git a/src/XrdFileCache/XrdFileCacheFile.hh b/src/XrdFileCache/XrdFileCacheFile.hh index 1ad2b6943da..72717b7f468 100644 --- a/src/XrdFileCache/XrdFileCacheFile.hh +++ b/src/XrdFileCache/XrdFileCacheFile.hh @@ -205,7 +205,8 @@ public: std::string& GetLocalPath() { return m_filename; } - XrdSysTrace* GetTrace(); + XrdSysError* GetLog(); + XrdSysTrace* GetTrace(); long long GetFileSize() { return m_fileSize; }