diff --git a/src/XrdOss/XrdOss.cc b/src/XrdOss/XrdOss.cc index 5fcdebe5ad1..20110dca014 100644 --- a/src/XrdOss/XrdOss.cc +++ b/src/XrdOss/XrdOss.cc @@ -169,7 +169,7 @@ int XrdOssDF::Fctl(int cmd, int alen, const char *args, char **resp) ssize_t XrdOssDF::pgRead(void *buffer, off_t offset, size_t rdlen, - uint32_t *csvec, + uint32_t *&csvec, uint64_t opts) { ssize_t bytes; @@ -185,7 +185,7 @@ ssize_t XrdOssDF::pgRead(void *buffer, // Calculate checksums if so wanted // - if (bytes > 0 && csvec) + if (bytes > 0) XrdOucCRC::Calc32C((void *)buffer, rdlen, csvec, pgSize); // All done @@ -200,7 +200,7 @@ int XrdOssDF::pgRead(XrdSfsAio *aioparm, uint64_t opts) aioparm->Result = this->pgRead((void *)aioparm->sfsAio.aio_buf, (off_t) aioparm->sfsAio.aio_offset, (size_t)aioparm->sfsAio.aio_nbytes, - aioparm->cksVec, opts); + aioparm->cksVec, opts); aioparm->doneRead(); return 0; } @@ -233,7 +233,7 @@ ssize_t XrdOssDF::pgWrite(void *buffer, // if (csvec && (opts & Verify)) {uint32_t valcs; - if (!XrdOucCRC::Ver32C((void *)buffer,wrlen,csvec,valcs,pgSize)) + if (!XrdOucCRC::Ver32C((void *)buffer, wrlen, csvec, valcs, pgSize)) return -EDOM; } @@ -249,7 +249,7 @@ int XrdOssDF::pgWrite(XrdSfsAio *aioparm, uint64_t opts) aioparm->Result = this->pgWrite((void *)aioparm->sfsAio.aio_buf, (off_t) aioparm->sfsAio.aio_offset, (size_t)aioparm->sfsAio.aio_nbytes, - aioparm->cksVec, opts); + aioparm->cksVec, opts); aioparm->doneWrite(); return 0; } diff --git a/src/XrdOss/XrdOss.hh b/src/XrdOss/XrdOss.hh index 27b074ab8d1..ebedd063bb9 100644 --- a/src/XrdOss/XrdOss.hh +++ b/src/XrdOss/XrdOss.hh @@ -76,7 +76,7 @@ virtual int getFD() {return -1;} virtual off_t getMmap(void **) {return 0;} virtual int isCompressed(char *cxidp=0) {(void)cxidp; return -EISDIR;} virtual int Open(const char *, int, mode_t, XrdOucEnv &) {return -EISDIR;} -virtual ssize_t pgRead (void*, off_t, size_t, uint32_t*, uint64_t); +virtual ssize_t pgRead (void*, off_t, size_t, uint32_t*&, uint64_t); virtual int pgRead (XrdSfsAio*, uint64_t); virtual ssize_t pgWrite(void*, off_t, size_t, uint32_t*, uint64_t); virtual int pgWrite(XrdSfsAio*, uint64_t); @@ -100,7 +100,9 @@ virtual ~XrdOssDF() {} // pgRead and pgWrite options as noted. // static const uint64_t -Verify = 0x8000000000000000ULL; //!< all: Verify checksums +Verify = 0x8000000000000000ULL; //!< all: Verify checksums +static const uint64_t +doCalc = 0x4000000000000000ULL; //!< pgw: Calculate checksums protected: diff --git a/src/XrdOuc/XrdOucCache.hh b/src/XrdOuc/XrdOucCache.hh index 382a58b5641..808e012b092 100644 --- a/src/XrdOuc/XrdOucCache.hh +++ b/src/XrdOuc/XrdOucCache.hh @@ -162,6 +162,104 @@ const char *Location() {return "";} virtual const char *Path() = 0; +//----------------------------------------------------------------------------- +//! Read file pages into a buffer and return corresponding checksums. +//! +//! @param buff pointer to buffer where the bytes are to be placed. +//! @param offs The offset where the read is to start. It must be +//! page aligned. +//! @param rdlen The number of bytes to read. The amount must be an +//! integral number of XrdSfsPageSize bytes. +//! @param csvec A vector of [rdlen/XrdSfsPageSize] entries which will be +//! filled with the corresponding CRC32C checksum for each page. +//! @param opts Processing options. +//! +//! @return >= 0 The number of bytes placed in buffer. +//! @return -errno File could not be read, return value is the reason. +//----------------------------------------------------------------------------- + +virtual int pgRead(char *buff, + long long offs, + int rdlen, + uint32_t *&csvec, + uint64_t opts=0); + +//----------------------------------------------------------------------------- +//! Read file pages and checksums using asynchronous I/O (default sync). +//! +//! @param iocb reference to the callback object that receives the result. All +//! results are returned via this object's Done() method. If the +//! caller holds any locks they must be recursive locks as the +//! callback may occur on the calling thread. +//! @param buff pointer to buffer where the bytes are to be placed. +//! @param offs The offset where the read is to start. It must be +//! page aligned. +//! @param rdlen The number of bytes to read. The amount must be an +//! integral number of XrdSfsPageSize bytes. +//! @param csvec A vector of [rdlen/XrdSfsPageSize] entries which will be +//! filled with the corresponding CRC32C checksum for each page. +//! @param opts Processing options. +//----------------------------------------------------------------------------- + +virtual void pgRead(XrdOucCacheIOCB &iocb, + char *buff, + long long offs, + int rdlen, + uint32_t *&csvec, + uint64_t opts=0) + {iocb.Done(pgRead(buff, offs, rdlen, csvec, opts));} + +//----------------------------------------------------------------------------- +//! Write file pages from a buffer and corresponding verified checksums. +//! +//! @param buff pointer to buffer holding the bytes to be written. +//! @param offs The offset where the write is to start. It must be +//! page aligned. +//! @param wrlen The number of bytes to write. The amount must be an +//! integral number of XrdSfsPageSize bytes except for the +//! page of the file. A short write prohibits writing past +//! offs+wrlen (i.e. it establishes an end of file). +//! @param csvec A vector of [rdlen/XrdSfsPageSize] entries that hold the +//! corresponding verified CRC32C checksum for each page. +//! @param opts Processing options. +//! +//! @return >= 0 The number of bytes written. +//! @return -errno File could not be written, returned value is the reason. +//----------------------------------------------------------------------------- + +virtual int pgWrite(char *buff, + long long offs, + int rdlen, + uint32_t *&csvec, + uint64_t opts=0); + +//----------------------------------------------------------------------------- +//! Write file pages and checksums using asynchronous I/O (default sync). +//! +//! @param iocb reference to the callback object that receives the result. All +//! results are returned via this object's Done() method. If the +//! caller holds any locks they must be recursive locks as the +//! callback may occur on the calling thread. +//! @param buff pointer to buffer holding the bytes to be written. +//! @param offs The offset where the write is to start. It must be +//! page aligned. +//! @param wrlen The number of bytes to write. The amount must be an +//! integral number of XrdSfsPageSize bytes except for the +//! page of the file. A short write prohibits writing past +//! offs+wrlen (i.e. it establishes an end of file). +//! @param csvec A vector of [rdlen/XrdSfsPageSize] entries that holds the +//! corresponding verified CRC32C checksum for each page. +//! @param opts Processing options. +//----------------------------------------------------------------------------- + +virtual void pgWrite(XrdOucCacheIOCB &iocb, + char *buff, + long long offs, + int wrlen, + uint32_t *&csvec, + uint64_t opts=0) + {iocb.Done(pgWrite(buff, offs, wrlen, csvec, opts));} + //------------------------------------------------------------------------------ //! Perform an asynchronous preread (may be ignored). //! @@ -198,12 +296,8 @@ struct aprParms virtual void Preread(aprParms &Parms) { (void)Parms; } //------------------------------------------------------------------------------ -//! Perform an asynchronous read (defaults to synchronous). +//! Perform an synchronous read. //! -//! @param iocb reference to the callback object that receives the result. All -//! results are returned via this object's Done() method. If the -//! caller holds any locks they must be recursive locks as the -//! callback may occur on the calling thread. //! @param buff pointer to the buffer to receive the results. The buffer must //! remain valid until the callback is invoked. //! @param offs the offset into the file. @@ -215,16 +309,25 @@ virtual void Preread(aprParms &Parms) { (void)Parms; } virtual int Read (char *buff, long long offs, int rlen) = 0; -virtual void Read (XrdOucCacheIOCB &iocb, char *buff, long long offs, int rlen) - {iocb.Done(Read(buff, offs, rlen));} - //------------------------------------------------------------------------------ -//! Perform an asynchronous vector read (defaults to synchronous). +//! Perform an asynchronous read (defaults to synchronous). //! //! @param iocb reference to the callback object that receives the result. All //! results are returned via this object's Done() method. If the //! caller holds any locks they must be recursive locks as the //! callback may occur on the calling thread. +//! @param buff pointer to the buffer to receive the results. The buffer must +//! remain valid until the callback is invoked. +//! @param offs the offset into the file. +//! @param rlen the number of bytes to read. +//------------------------------------------------------------------------------ + +virtual void Read (XrdOucCacheIOCB &iocb, char *buff, long long offs, int rlen) + {iocb.Done(Read(buff, offs, rlen));} + +//------------------------------------------------------------------------------ +//! Perform an synchronous vector read. +//! //! @param readV pointer to a vector of read requests. //! @param rnum the number of elements in the vector. //! @@ -232,29 +335,24 @@ virtual void Read (XrdOucCacheIOCB &iocb, char *buff, long long offs, int rlen) //! >=0 - ReadV succeeded, value is number of bytes read. //------------------------------------------------------------------------------ -virtual int ReadV(const XrdOucIOVec *readV, int rnum) - {int nbytes = 0, curCount = 0; - for (int i = 0; i < rnum; i++) - {curCount = Read(readV[i].data, - readV[i].offset, - readV[i].size); - if (curCount != readV[i].size) - return (curCount < 0 ? curCount : -ESPIPE); - nbytes += curCount; - } - return nbytes; - } - -virtual void ReadV(XrdOucCacheIOCB &iocb, const XrdOucIOVec *readV, int rnum) - {iocb.Done(ReadV(readV, rnum));} +virtual int ReadV(const XrdOucIOVec *readV, int rnum); //------------------------------------------------------------------------------ -//! Perform an asynchronous sync() operation (defaults to synchronous). +//! Perform an asynchronous vector read (defaults to synchronous). //! //! @param iocb reference to the callback object that receives the result. All //! results are returned via this object's Done() method. If the //! caller holds any locks they must be recursive locks as the //! callback may occur on the calling thread. +//! @param readV pointer to a vector of read requests. +//! @param rnum the number of elements in the vector. +//------------------------------------------------------------------------------ + +virtual void ReadV(XrdOucCacheIOCB &iocb, const XrdOucIOVec *readV, int rnum) + {iocb.Done(ReadV(readV, rnum));} + +//------------------------------------------------------------------------------ +//! Perform an synchronous sync() operation. //! //! @return <0 - Sync failed, value is -errno. //! =0 - Sync succeeded. @@ -262,8 +360,28 @@ virtual void ReadV(XrdOucCacheIOCB &iocb, const XrdOucIOVec *readV, int rnum) virtual int Sync() = 0; +//------------------------------------------------------------------------------ +//! Perform an asynchronous sync() operation (defaults to synchronous). +//! +//! @param iocb reference to the callback object that receives the result. All +//! results are returned via this object's Done() method. If the +//! caller holds any locks they must be recursive locks as the +//! callback may occur on the calling thread. +//------------------------------------------------------------------------------ + virtual void Sync(XrdOucCacheIOCB &iocb) {iocb.Done(Sync());} +//------------------------------------------------------------------------------ +//! Perform an synchronous trunc() operation. +//! +//! @param offs the size the file is have. +//! +//! @return <0 - Trunc failed, value is -errno. +//! =0 - Trunc succeeded. +//------------------------------------------------------------------------------ + +virtual int Trunc(long long offs) = 0; + //------------------------------------------------------------------------------ //! Perform an asynchronous trunc() operation (defaults to synchronous). //! @@ -277,8 +395,6 @@ virtual void Sync(XrdOucCacheIOCB &iocb) {iocb.Done(Sync());} //! =0 - Trunc succeeded. //------------------------------------------------------------------------------ -virtual int Trunc(long long offs) = 0; - virtual void Trunc(XrdOucCacheIOCB &iocb, long long offs) {iocb.Done(Trunc(offs));} @@ -297,12 +413,8 @@ virtual void Trunc(XrdOucCacheIOCB &iocb, long long offs) virtual void Update(XrdOucCacheIO &iocp) {} //------------------------------------------------------------------------------ -//! Perform an asynchronous write (defaults to synchronous). +//! Perform an synchronous write. //! -//! @param iocb reference to the callback object that receives the result. All -//! results are returned via this object's Done() method. If the -//! caller holds any locks they must be recursive locks as the -//! callback may occur on the calling thread. //! @param buff pointer to the buffer holding the contents. The buffer must //! remain valid until the callback is invoked. //! @param offs the offset into the file. @@ -314,9 +426,48 @@ virtual void Update(XrdOucCacheIO &iocp) {} virtual int Write(char *buff, long long offs, int wlen) = 0; +//------------------------------------------------------------------------------ +//! Perform an asynchronous write (defaults to synchronous). +//! +//! @param iocb reference to the callback object that receives the result. All +//! results are returned via this object's Done() method. If the +//! caller holds any locks they must be recursive locks as the +//! callback may occur on the calling thread. +//! @param buff pointer to the buffer holding the contents. The buffer must +//! remain valid until the callback is invoked. +//! @param offs the offset into the file. +//! @param wlen the number of bytes to write +//------------------------------------------------------------------------------ + virtual void Write(XrdOucCacheIOCB &iocb, char *buff, long long offs, int wlen) {iocb.Done(Write(buff, offs, wlen));} +//------------------------------------------------------------------------------ +//! Perform an synchronous vector write. +//! +//! @param writV pointer to a vector of write requests. +//! @param wnum the number of elements in the vector. +//! +//! @return < 0 - WriteV failed, value is -errno. +//! >=0 - WriteV succeeded, value is number of bytes written. +//------------------------------------------------------------------------------ + +virtual int WriteV(const XrdOucIOVec *writV, int wnum); + +//------------------------------------------------------------------------------ +//! Perform an asynchronous vector write (defaults to synchronous). +//! +//! @param iocb reference to the callback object that receives the result. All +//! results are returned via this object's Done() method. If the +//! caller holds any locks they must be recursive locks as the +//! callback may occur on the calling thread. +//! @param writV pointer to a vector of read requests. +//! @param wnum the number of elements in the vector. +//------------------------------------------------------------------------------ + +virtual void WriteV(XrdOucCacheIOCB &iocb, const XrdOucIOVec *writV, int wnum) + {iocb.Done(WriteV(writV, wnum));} + //------------------------------------------------------------------------------ //! Construct and Destructor //------------------------------------------------------------------------------ diff --git a/src/XrdSfs/XrdSfsInterface.cc b/src/XrdSfs/XrdSfsInterface.cc index 0eaa9b940a6..2208e5576cb 100644 --- a/src/XrdSfs/XrdSfsInterface.cc +++ b/src/XrdSfs/XrdSfsInterface.cc @@ -98,7 +98,7 @@ int XrdSfsFile::fctl(const int cmd, XrdSfsXferSize XrdSfsFile::pgRead(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize rdlen, - uint32_t *csvec, + uint32_t *&csvec, uint64_t opts) { XrdSfsXferSize bytes; @@ -117,7 +117,7 @@ XrdSfsXferSize XrdSfsFile::pgRead(XrdSfsFileOffset offset, // Calculate checksums if so wanted // - if (bytes > 0 && csvec) + if (bytes > 0) XrdOucCRC::Calc32C((void *)buffer, rdlen, csvec, XrdSfsPageSize); // All done @@ -144,7 +144,7 @@ XrdSfsXferSize XrdSfsFile::pgRead(XrdSfsAio *aioparm, uint64_t opts) XrdSfsXferSize XrdSfsFile::pgWrite(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize wrlen, - uint32_t *csvec, + uint32_t *&csvec, uint64_t opts) { // Make sure the offset is on a 4K boundary @@ -169,7 +169,7 @@ XrdSfsXferSize XrdSfsFile::pgWrite(XrdSfsFileOffset offset, // If we have a checksum vector and verify is on, make sure the data // in the buffer corresponds to he checksums. // - if (csvec && (opts & Verify)) + if (opts & Verify) {uint32_t valcs; if (XrdOucCRC::Ver32C((void *)buffer, wrlen, csvec, valcs, XrdSfsPageSize) >= 0) diff --git a/src/XrdSfs/XrdSfsInterface.hh b/src/XrdSfs/XrdSfsInterface.hh index f4223661a1f..d1d1ca5086c 100644 --- a/src/XrdSfs/XrdSfsInterface.hh +++ b/src/XrdSfs/XrdSfsInterface.hh @@ -501,9 +501,8 @@ Verify = 0x8000000000000000ULL; //!< all: Verify checksums //! @param buffer - pointer to buffer where the bytes are to be placed. //! @param rdlen - The number of bytes to read. The amount must be an //! integral number of XrdSfsPageSize bytes. -//! @param csvec - A vector of [rdlen/XrdSfsPageSize] entries which will be -//! filled with the corresponding CRC32C checksum for each -//! page. A nil pointer does not return the checksums. +//! @param csvec - A vector of [rdlen/XrdSfsPageSize] entries to be filled +//! with the corresponding CRC32C checksum for each page. //! @param opts - Processing options (see above). //! //! @return >= 0 The number of bytes that placed in buffer. @@ -513,7 +512,7 @@ Verify = 0x8000000000000000ULL; //!< all: Verify checksums virtual XrdSfsXferSize pgRead(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize rdlen, - uint32_t *csvec, + uint32_t *&csvec, uint64_t opts=0); //----------------------------------------------------------------------------- @@ -539,7 +538,6 @@ virtual int pgRead(XrdSfsAio *aioparm, uint64_t opts=0); //! be the last write to the file at or above the offset. //! @param csvec - A vector of [CEILING(wrlen/XrdSfsPageSize)] entries which //! contain the corresponding CRC32 checksum for each page. -//! A nil pointer causes the checksums to be computed. //! @param opts - Processing options (see above). //! //! @return >= 0 The number of bytes written. @@ -549,7 +547,7 @@ virtual int pgRead(XrdSfsAio *aioparm, uint64_t opts=0); virtual XrdSfsXferSize pgWrite(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize wrlen, - uint32_t *csvec, + uint32_t *&csvec, uint64_t opts=0); //----------------------------------------------------------------------------- diff --git a/src/XrdUtils.cmake b/src/XrdUtils.cmake index cd8ff36cf61..eedd44d4729 100644 --- a/src/XrdUtils.cmake +++ b/src/XrdUtils.cmake @@ -74,7 +74,7 @@ add_library( XrdOuc/XrdOucArgs.cc XrdOuc/XrdOucArgs.hh XrdOuc/XrdOucBackTrace.cc XrdOuc/XrdOucBackTrace.hh XrdOuc/XrdOucBuffer.cc XrdOuc/XrdOucBuffer.hh - XrdOuc/XrdOucCache.hh + XrdOuc/XrdOucCache.cc XrdOuc/XrdOucCache.hh XrdOuc/XrdOucCacheStats.hh XrdOuc/XrdOucCallBack.cc XrdOuc/XrdOucCallBack.hh XrdOuc/XrdOucCRC.cc XrdOuc/XrdOucCRC.hh