diff --git a/src/XrdChecksum.cc b/src/XrdChecksum.cc index 6691393..94481cb 100644 --- a/src/XrdChecksum.cc +++ b/src/XrdChecksum.cc @@ -195,6 +195,24 @@ int ChecksumManager::Set(const char *lfn, const char *cksname, const char *chksv return XrdCksManager::Set(pfn.c_str(), cks); } +int ChecksumManager::Del(const char *lfn, unsigned digests) +{ + std::string pfn = this->LFN2PFN(lfn); + auto del_digest = [&](const char *digest_name) { + std::string checksum_name = ATTR_PREFIX; + checksum_name += digest_name; + XrdSysXAttrActive->Del(checksum_name.c_str(), pfn.c_str()); + }; + + if (digests & ChecksumManager::CKSUM) del_digest("CKSUM"); + if (digests & ChecksumManager::ADLER32) del_digest("ADLER32"); + if (digests & ChecksumManager::CRC32) del_digest("CRC32"); + if (digests & ChecksumManager::MD5) del_digest("MD5"); + if (digests & ChecksumManager::CVMFS) del_digest("CVMFS"); + + return 0; +} + int ChecksumManager::Ver( const char *lfn, XrdCksData &Cks) { return XrdCksManager::Ver(lfn, Cks); @@ -243,4 +261,3 @@ std::string ChecksumManager::LFN2PFN(const char* lfn) { pfn = pfn_cstr; return pfn; } - diff --git a/src/XrdChecksum.hh b/src/XrdChecksum.hh index 147be22..308b1f3 100644 --- a/src/XrdChecksum.hh +++ b/src/XrdChecksum.hh @@ -109,6 +109,7 @@ public: int Set(const char *pfn, const ChecksumState &state); int Set(const char *pfn, const char *cksname, const char *chksvalue); + int Del(const char *pfn, unsigned digests); virtual ~ChecksumManager() {} @@ -140,4 +141,4 @@ private: -#endif \ No newline at end of file +#endif diff --git a/src/multiuser.cpp b/src/multiuser.cpp index 522cff3..39b75f7 100644 --- a/src/multiuser.cpp +++ b/src/multiuser.cpp @@ -173,20 +173,33 @@ int MultiuserFile::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv ssize_t MultiuserFile::Write(const void *buffer, off_t offset, size_t size) { + bool checksum_abandoned = false; if ((offset != m_nextoff) && m_state) { std::stringstream ss; - ss << "Out-of-order writes not supported while running checksum. " << m_fname; + ss << "Non-sequential write detected; disabling checksum calculation for " << m_fname; m_log.Emsg("Write", ss.str().c_str()); - return -ENOTSUP; + delete m_state; + m_state = NULL; + checksum_abandoned = true; } auto result = m_wrapped->Write(buffer, offset, size); - if (result >= 0) {m_nextoff += result;} - if (m_state) + if (result >= 0) + { + m_nextoff = offset + result; + } + if (checksum_abandoned && result > 0 && g_checksum_manager) + { + UserSentry sentry(m_client, m_log); + if (sentry.IsValid()) { + g_checksum_manager->Del(m_fname.c_str(), m_digests); + } + } + if (m_state && result > 0) { - m_state->Update(static_cast(buffer), size); + m_state->Update(static_cast(buffer), static_cast(result)); } return result; }