From 98f41fe4d29e344fe710bb85fcc906c1cecda795 Mon Sep 17 00:00:00 2001 From: Andrew Hanushevsky Date: Wed, 9 Oct 2019 07:50:41 -0700 Subject: [PATCH] [Server] Add default implementation for pgRead and pgWrite. --- src/XrdSfs/XrdSfsInterface.cc | 75 +++++++++++++++++++++++++++++++---- src/XrdSfs/XrdSfsInterface.hh | 10 ++--- 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/XrdSfs/XrdSfsInterface.cc b/src/XrdSfs/XrdSfsInterface.cc index acf2a22e08a..a36d77a282a 100644 --- a/src/XrdSfs/XrdSfsInterface.cc +++ b/src/XrdSfs/XrdSfsInterface.cc @@ -27,9 +27,19 @@ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ +#include "XrdOuc/XrdOucCRC.hh" #include "XrdSfs/XrdSfsAio.hh" #include "XrdSfs/XrdSfsInterface.hh" +/******************************************************************************/ +/* S t a t i c S y m b o l s */ +/******************************************************************************/ + +namespace +{ +static const XrdSfsFileOffset pgSize = XrdSfsPageSize; +} + /******************************************************************************/ /* p g R e a d */ /******************************************************************************/ @@ -39,10 +49,29 @@ XrdSfsXferSize XrdSfsFile::pgRead(XrdSfsFileOffset offset, XrdSfsXferSize rdlen, uint32_t *csvec, bool verify) -{(void)offset; (void)buffer; (void)rdlen; - (void)csvec; (void)verify; - error.setErrInfo(ENOTSUP, "Not supported."); - return SFS_ERROR; +{ + XrdSfsXferSize bytes; + +// Make sure the offset is on a 4K boundary and the size if a multiple of +// 4k as well (we use simple and for this). +// + if ((offset & ~pgSize) || (rdlen & ~XrdSfsPageSize)) + {error.setErrInfo(EINVAL,"Offset or readlen not a multiple of pagesize."); + return SFS_ERROR; + } + +// Read the data into the buffer +// + bytes = read(offset, buffer, rdlen); + +// Calculate checksums if so wanted +// + if (bytes > 0 && csvec) + XrdOucCRC::Calc32C((void *)buffer, rdlen, csvec, XrdSfsPageSize); + +// All done +// + return bytes; } /******************************************************************************/ @@ -66,10 +95,40 @@ XrdSfsXferSize XrdSfsFile::pgWrite(XrdSfsFileOffset offset, XrdSfsXferSize wrlen, uint32_t *csvec, bool verify) -{(void)offset; (void)buffer; (void)wrlen; - (void)csvec; (void)verify; - error.setErrInfo(ENOTSUP, "Not supported."); - return SFS_ERROR; +{ +// Make sure the offset is on a 4K boundary +// + if (offset & ~pgSize) + {error.setErrInfo(EINVAL,"Offset or readlen not a multiple of pagesize."); + return SFS_ERROR; + } + +// If a virtual end of file marker is set, make sure we are not trying to +// write past it. +// + if (pgwrEOF && (offset+wrlen) > pgwrEOF) + {error.setErrInfo(ESPIPE,"Attempt to write past virtual EOF."); + return SFS_ERROR; + } + +// If this is a short write then establish the virtual eof +// + if (wrlen & ~XrdSfsPageSize) pgwrEOF = (offset + wrlen) & ~pgSize; + +// If we have a checksum vector and verify is on, make sure the data +// in the buffer corresponds to he checksums. +// + if (csvec && verify) + {int pgErr; + if (!XrdOucCRC::Ver32C((void *)buffer,wrlen,csvec,XrdSfsPageSize,pgErr)) + {error.setErrInfo(EDOM,"Checksum error."); + return SFS_ERROR; + } + } + +// Now just return the result of a plain write +// + return write(offset, buffer, wrlen); } /******************************************************************************/ diff --git a/src/XrdSfs/XrdSfsInterface.hh b/src/XrdSfs/XrdSfsInterface.hh index 51ffad35797..b3f7d4fc62c 100644 --- a/src/XrdSfs/XrdSfsInterface.hh +++ b/src/XrdSfs/XrdSfsInterface.hh @@ -738,7 +738,7 @@ virtual void setXio(XrdSfsXio *xioP) { (void)xioP; } XrdSfsFile(const char *user=0, int MonID=0) : error(*(new XrdOucErrInfo(user, MonID))) - {lclEI = &error;} + {lclEI = &error; pgwrEOF = 0;} //----------------------------------------------------------------------------- //! Constructor for plugins that wrap another SFS plugin. This constructor @@ -749,7 +749,7 @@ virtual void setXio(XrdSfsXio *xioP) { (void)xioP; } //----------------------------------------------------------------------------- XrdSfsFile(XrdSfsFile &wrapF) - : error(wrapF.error), lclEI(0) {} + : error(wrapF.error), lclEI(0), pgwrEOF(0) {} //----------------------------------------------------------------------------- //! Constructor for base plugins that predefined an error object. This is a @@ -759,7 +759,7 @@ virtual void setXio(XrdSfsXio *xioP) { (void)xioP; } //----------------------------------------------------------------------------- XrdSfsFile(XrdOucErrInfo &eInfo) - : error(eInfo), lclEI(0) {} + : error(eInfo), lclEI(0), pgwrEOF(0) {} //----------------------------------------------------------------------------- //! Destructor @@ -768,8 +768,8 @@ virtual void setXio(XrdSfsXio *xioP) { (void)xioP; } virtual ~XrdSfsFile() {if (lclEI) delete lclEI;} private: -XrdOucErrInfo* lclEI; - +XrdOucErrInfo* lclEI; +XrdSfsFileOffset pgwrEOF; }; // class XrdSfsFile /******************************************************************************/