#ifndef __SFS_INTERFACE_H__ #define __SFS_INTERFACE_H__ /******************************************************************************/ /* */ /* X r d S f s I n t e r f a c e . h h */ /* */ /* (c) 2018 by the Board of Trustees of the Leland Stanford, Jr., University */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include // For strlcpy() #include #include #include #include #include "XrdOuc/XrdOucErrInfo.hh" #include "XrdOuc/XrdOucIOVec.hh" #include "XrdOuc/XrdOucSFVec.hh" #include "XrdSfs/XrdSfsGPFile.hh" #include "XrdSys/XrdSysPageSize.hh" /******************************************************************************/ /* O p e n M o d e s */ /******************************************************************************/ #define SFS_O_RDONLY 0 // open read/only #define SFS_O_WRONLY 1 // open write/only #define SFS_O_RDWR 2 // open read/write #define SFS_O_CREAT 0x00000100 // used for file creation #define SFS_O_TRUNC 0x00000200 // used for file truncation #define SFS_O_MULTIW 0x00000400 // used for multi-write locations #define SFS_O_NOTPC 0x00000800 // used to suppress TPC opens #define SFS_O_DIRLIST 0x00010000 // used for locate only #define SFS_O_POSC 0x00100000 // persist on successful close #define SFS_O_FORCE 0x00200000 // used for locate only #define SFS_O_HNAME 0x00400000 // used for locate only #define SFS_O_LOCAL 0x00800000 // used for locate only (local cmd) #define SFS_O_NOWAIT 0x01000000 // do not impose operational delays #define SFS_O_RAWIO 0x02000000 // allow client-side decompression #define SFS_O_RESET 0x04000000 // Reset any cached information #define SFS_O_REPLICA 0x08000000 // Open for replication // The following flag may be set in the access mode arg for open() & mkdir() // Note that on some systems mode_t is 16-bits so we use a careful value! // #define SFS_O_MKPTH 0x00004000 // Make directory path if missing // The following options are here to provide a uniform clustering interface. // They may be passed through open/locate/stat, as applicable. // #define SFS_O_LOCATE 0x10000000 // This request generated by locate() #define SFS_O_STAT 0x20000000 // This request generated by stat() #define SFS_O_META 0x40000000 // This request generated by metaop /******************************************************************************/ /* D e f i n e s */ /******************************************************************************/ // Common fctl command values (0 to 255) // #define SFS_FCTL_GETFD 1 // Return file descriptor if possible #define SFS_FCTL_STATV 2 // Return visa information #define SFS_FCTL_SPEC1 3 // Return implementation defined information #define SFS_SFIO_FDVAL 0x80000000 // Use SendData() method GETFD response value // Common fsctl command values (0 to 255) // #define SFS_FSCTL_CMD 255 #define SFS_FSCTL_LOCATE 1 // Locate a file #define SFS_FSCTL_STATFS 2 // Return FS data #define SFS_FSCTL_STATLS 3 // Return LS data #define SFS_FSCTL_STATXA 4 // Return XA data #define SFS_FSCTL_STATCC 5 // Return Cluster Config status #define SFS_FSCTL_PLUGIN 8 // Return Implementation Dependent Data #define SFS_FSCTL_PLUGIO 16 // Return Implementation Dependent Data #define SFS_FSCTL_PLUGXC 32 // Perform cache oriented operation // Return values for integer & XrdSfsXferSize returning XrdSfs methods // #define SFS_STALL 1 // Return value -> Seconds to stall client #define SFS_OK 0 // ErrInfo code -> All is well #define SFS_ERROR -1 // ErrInfo code -> Error occurred #define SFS_REDIRECT -256 // ErrInfo code -> Port number to redirect to #define SFS_STARTED -512 // ErrInfo code -> Estimated seconds to completion #define SFS_DATA -1024 // ErrInfo code -> Length of data #define SFS_DATAVEC -2048 // ErrInfo code -> Num iovec elements in msgbuff // The following macros are used for dealing with special local paths // #define SFS_LCLPRFX "/=/" #define SFS_LCLPLEN 3 #define SFS_LCLPATH(x) !strncmp(x, SFS_LCLPRFX, SFS_LCLPLEN) #define SFS_LCLPRFY "/=" #define SFS_LCLROOT(x) !strncmp(x, SFS_LCLPRFX, SFS_LCLPLEN-1) \ && (*(x+SFS_LCLPLEN-1) == '/' || *(x+SFS_LCLPLEN-1) == 0) /******************************************************************************/ /* S t r u c t u r e s & T y p e d e f s */ /******************************************************************************/ typedef long long XrdSfsFileOffset; typedef int XrdSfsFileOpenMode; typedef int XrdSfsMode; typedef int XrdSfsXferSize; enum XrdSfsFileExistence { XrdSfsFileExistNo, XrdSfsFileExistIsFile, XrdSfsFileExistIsDirectory, XrdSfsFileExistIsOffline, XrdSfsFileExistIsOther }; //------------------------------------------------ #define Prep_PRTY0 0 #define Prep_PRTY1 1 #define Prep_PRTY2 2 #define Prep_PRTY3 3 #define Prep_PMASK 3 #define Prep_SENDAOK 4 #define Prep_SENDERR 8 #define Prep_SENDACK 12 #define Prep_WMODE 16 #define Prep_STAGE 32 #define Prep_COLOC 64 #define Prep_FRESH 128 #define Prep_CANCEL 256 #define Prep_QUERY 512 #define Prep_EVICT 1024 class XrdOucTList; struct XrdSfsFSctl //!< SFS_FSCTL_PLUGIN/PLUGIO/PLUGXC parms { const char *Arg1; //!< PLUGINO, PLUGION, PLUGXC int Arg1Len; //!< Length int Arg2Len; //!< Length or -count of args in extension union{ const char *Arg2; //!< PLUGIN opaque string const char **ArgP; //!< PLUGXC argument list extension }; }; struct XrdSfsPrep //!< Prepare parameters { char *reqid; //!< Request ID char *notify; //!< Notification path or 0 int opts; //!< Prep_xxx XrdOucTList *paths; //!< List of paths XrdOucTList *oinfo; //!< 1-to-1 correspondence of opaque info }; /******************************************************************************/ /* F o r w a r d D e c l a r a t i o n s */ /******************************************************************************/ class XrdOucEnv; class XrdSecEntity; struct XrdSfsFACtl; /******************************************************************************/ /* O b j e c t W r a p p i n g G u i d e */ /******************************************************************************/ /* The XrdSfsDirectory and XrdSfsFile objects can be wrapped. Wraping can be used to add functionality. The process is common and pretty muche rote. There is only one caveat: all wrappers must use the same XrdOucErrInfo object. This is because the ErrInfo object contains client parameters that are used to control how things are done to be backward compatible. Newer client can then use more efficient internal processing. The SFS provides two ways to make sure the same ErrInfo object is used by all objects in the wrapped chain. Forward propagation (the one typically used) and backward propagation (used in certain unusual cases). In forward mode, the ErrInfo object of the last object in the chain is propagated to the front of the chain. In backward mode the reverse happens. Let's assume the following scenarion. Object-A wraps object-B (the object here can be directory or file object). In forward mode weneed to create objects in reverse order (bottom to top) which is typically what you would do anyway as you need to capture the pinter to the object your wrapping. So, using newFile() as an example where sfsP points to the Interface being wrapped: XrdSfsFile *newFile(const char *user, int MonID) { XrdSfsFile *wrapped_file = sfsP->newFile(user, MonID); if (!wrapped_file) return 0; return new mySfsFile(wrapped_file,...); } class mySfsFile : public XrdSfsFile {public: mySfsFile(XrdSfsFile *wrapped_file,...) : XrdSfsFile(*wrapped_file) {....} .... }; Notice we are allocating the wrapped file ahead of the wrapper so that the wrapper can use the ErrInfo object of the wrapped file. In backward mode we want to use the ErrInfo object of the front-most wrapper for all wrappers after it. This mechanism is far more complicated due to error handling requirements. However, it's useful when a wrapped object is not necessarily instantiated to accomplish the needs of the wrapper. An example of this is the newFile and newDir implementations for XrdSsi where wrapped object creation is subject to the resource name. */ /******************************************************************************/ /* X r d S f s D i r e c t o r y */ /******************************************************************************/ //------------------------------------------------------------------------------ //! The XrdSfsDirectory object is returned by XrdSfsFileSystem::newFile() when //! the caller wants to be able to perform directory oriented operations. //------------------------------------------------------------------------------ class XrdSfsDirectory { public: //----------------------------------------------------------------------------- //! The error object is used to return details whenever something other than //! SFS_OK is returned from the methods in this class, when noted. //----------------------------------------------------------------------------- XrdOucErrInfo &error; //----------------------------------------------------------------------------- //! Open a directory. //! //! @param path - Pointer to the path of the directory to be opened. //! @param client - Client's identify (see common description). //! @param opaque - path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, ir SFS_STALL //----------------------------------------------------------------------------- virtual int open(const char *path, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Get the next directory entry. //! //! @return A null terminated string with the directory name. Normally, "." //! ".." are not returned. If a null pointer is returned then if this //! is due to an error, error.code should contain errno. Otherwise, //! error.code should contain zero to indicate that no more entries //! exist (i.e. end of list). See autoStat() for additional caveats. //----------------------------------------------------------------------------- virtual const char *nextEntry() = 0; //----------------------------------------------------------------------------- //! Close the directory. //! //! @return One of SFS_OK or SFS_ERROR //----------------------------------------------------------------------------- virtual int close() = 0; //----------------------------------------------------------------------------- //! Get the directory path. //! //! @return Null terminated string of the path used in open(). //----------------------------------------------------------------------------- virtual const char *FName() = 0; //----------------------------------------------------------------------------- //! Set the stat() buffer where stat information is to be placed corresponding //! to the directory entry returned by nextEntry(). //! //! @return If supported, SFS_OK should be returned. If not supported, then //! SFS_ERROR should be returned with error.code set to ENOTSUP. //! //! @note: When autoStat() is in effect, directory entries that have been //! deleted from the target directory are quietly skipped. //----------------------------------------------------------------------------- virtual int autoStat(struct stat *buf); //----------------------------------------------------------------------------- //! Constructor (user and MonID are the ones passed to newDir()!). This //! constructor should only be used by base plugins. Plugins that wrap an //! SfsDirectory should use the second version of the constructor shown below. //! //! @param user - Text identifying the client responsible for this call. //! The pointer may be null if identification is missing. //! @param MonID - The monitoring identifier assigned to this and all //! future requests using the returned object. //----------------------------------------------------------------------------- XrdSfsDirectory(const char *user=0, int MonID=0) : error(*(new XrdOucErrInfo(user, MonID))) {lclEI = &error;} //----------------------------------------------------------------------------- //! Constructor for plugins that wrap another SfsDirectory. This constructor //! inherits the error object from a wrapped SfsDirectory object so that only //! one identical error object exists for all directory objects in the chain. //! //! @param wrapD - Reference to the directory object being wrapped. //----------------------------------------------------------------------------- XrdSfsDirectory(XrdSfsDirectory &wrapD) : error(wrapD.error), lclEI(0) {} //----------------------------------------------------------------------------- //! Constructor for base plugins that predefined an error object. This is a //! convenience constructor for base plugins only. //! //! @param eInfo - Reference to the error object to use. //----------------------------------------------------------------------------- XrdSfsDirectory(XrdOucErrInfo &eInfo) : error(eInfo), lclEI(0) {} //----------------------------------------------------------------------------- //! Destructor //----------------------------------------------------------------------------- virtual ~XrdSfsDirectory() {if (lclEI) delete lclEI;} private: XrdOucErrInfo* lclEI; }; // class XrdSfsDirectory /******************************************************************************/ /* X r d S f s F i l e */ /******************************************************************************/ //------------------------------------------------------------------------------ //! The XrdSfsFile object is returned by XrdSfsFileSystem::newFile() when //! the caller wants to be able to perform file oriented operations. //------------------------------------------------------------------------------ class XrdSfsAio; class XrdSfsDio; class XrdSfsXio; class XrdSfsFile { public: //----------------------------------------------------------------------------- //! The error object is used to return details whenever something other than //! SFS_OK is returned from the methods in this class, when noted. //----------------------------------------------------------------------------- XrdOucErrInfo &error; //----------------------------------------------------------------------------- //! Open a file. //! //! @param fileName - Pointer to the path of the file to be opened. //! @param openMode - Flags indicating how the open is to be handled. //! SFS_O_CREAT create the file //! SFS_O_MKPTH Make directory path if missing //! SFS_O_NOWAIT do not impose operational delays //! SFS_O_NOTPC do not allow TPC operation //! SFS_O_POSC persist only on successful close //! SFS_O_RAWIO allow client-side decompression //! SFS_O_RDONLY open read/only //! SFS_O_RDWR open read/write //! SFS_O_REPLICA Open for replication //! SFS_O_RESET Reset any cached information //! SFS_O_TRUNC truncate existing file to zero length //! SFS_O_WRONLY open write/only //! @param createMode - The file's mode if it will be created. //! @param client - Client's identify (see common description). //! @param opaque - path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED //----------------------------------------------------------------------------- virtual int open(const char *fileName, XrdSfsFileOpenMode openMode, mode_t createMode, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Create, delete, query, rollback a file checkpoint or perform an action. //! //! @param act - The operation to be performed (see cpAct enum below). //! @param range - Use and requirement vary by function: //! cpCreate - Create a new checkpoint, one must not exist. //! Parameters ignored, not applicable. //! cpDelete - Delete an existing checkpoint, one must exist. //! Parameters ignored, not applicable. //! cpQuery - Where result is to be returned: //! range[0].offset - Amount currently in use. //! range[0].length - Maximum total length //! cpRestore - Restore data from checkpoint and delete it. //! Parameters ignored, not applicable. //! cpTrunc - Offset target for truncation. //! range[0].offset - Offset for truncations. //! cpWrite - Offset/lengths of the file to be checkpointed. //! The checkpoint must exist via previous cpCreate. //! @param n - Number of elements in range. Applies only to cpWrite. //! //! @return One of SFS_OK or SFS_ERROR only. //----------------------------------------------------------------------------- enum cpAct {cpCreate=0, //!< Create a checkpoint, one must not be active. cpDelete, //!< Delete an existing checkpoint cpRestore, //!< Restore an active checkpoint and delete it. cpQuery, //!< Return checkpoint limits cpTrunc, //!< Truncate a file within checkpoint. cpWrite //!< Add data to an existing checkpoint. }; virtual int checkpoint(cpAct act, struct iov *range=0, int n=0); //----------------------------------------------------------------------------- //! Close the file. //! //! @return One of SFS_OK or SFS_ERROR. //----------------------------------------------------------------------------- virtual int close() = 0; //----------------------------------------------------------------------------- //! Execute a special operation on the file (version 1) //! //! @param cmd - The operation to be performed (see below). //! SFS_FCTL_GETFD Return file descriptor if possible //! SFS_FCTL_STATV Reserved for future use. //! @param args - specific arguments to cmd //! SFS_FCTL_GETFD Set to zero. //! @param eInfo - The object where error info or results are to be returned. //! This is legacy and the error onject may be used as well. //! //! @return If an error occurs or the operation is not support, SFS_ERROR //! should be returned with error.code set to errno. Otherwise, //! SFS_FCTL_GETFD error.code holds the real file descriptor number //! If the value is negative, sendfile() is not used. //! If the value is SFS_SFIO_FDVAL then the SendData() //! method is used for future read requests. //----------------------------------------------------------------------------- virtual int fctl(const int cmd, const char *args, XrdOucErrInfo &eInfo) = 0; //----------------------------------------------------------------------------- //! Execute a special operation on the file (version 2) //! //! @param cmd - The operation to be performed: //! SFS_FCTL_SPEC1 Perform implementation defined action //! @param alen - Length of data pointed to by args. //! @param args - Data sent with request, zero if alen is zero. //! @param client - Client's identify (see common description). //! //! @return SFS_OK a null response is sent. //! @return SFS_DATA error.code length of the data to be sent. //! error.message contains the data to be sent. //! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL. //----------------------------------------------------------------------------- virtual int fctl(const int cmd, int alen, const char *args, const XrdSecEntity *client = 0); //----------------------------------------------------------------------------- //! Get the file path. //! //! @return Null terminated string of the path used in open(). //----------------------------------------------------------------------------- virtual const char *FName() = 0; //----------------------------------------------------------------------------- //! Get file's memory mapping if one exists (memory mapped files only). //! //! @param Addr - Place where the starting memory address is returned. //! @param Size - Place where the file's size is returned. //! //! @return SFS_OK when the file is memory mapped or any other code otherwise. //----------------------------------------------------------------------------- virtual int getMmap(void **Addr, off_t &Size) = 0; //----------------------------------------------------------------------------- //! Options for pgRead() and pgWrite() as noted below. //----------------------------------------------------------------------------- static const uint64_t Verify = 0x8000000000000000ULL; //!< all: Verify checksums //----------------------------------------------------------------------------- //! Read file pages into a buffer and return corresponding checksums. //! //! @param offset - The offset where the read is to start. It may be //! unaligned with certain caveats relative to csvec. //! @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 XrdSfsPage::Size bytes. //! @param csvec - A vector of entries to be filled with the cooresponding //! CRC32C checksum for each page. However, if the offset is //! unaligned, then csvec[0] contains the crc for the page //! fragment that brings it to alignment for csvec[1]. //! It must be sized to hold all aligned XrdSys::Pagesize //! crc's plus additional ones for leading and ending page //! fragments, if any. //! @param opts - Processing options (see above). //! //! @return >= 0 The number of bytes that placed in buffer. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize pgRead(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize rdlen, uint32_t *csvec, uint64_t opts=0); //----------------------------------------------------------------------------- //! Read file pages and checksums using asynchronous I/O. //! //! @param aioparm - Pointer to async I/O object controlling the I/O. //! @param opts - Processing options (see above). //! //! @return SFS_OK Request accepted and will be scheduled. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual int pgRead(XrdSfsAio *aioparm, uint64_t opts=0); //----------------------------------------------------------------------------- //! Write file pages into a file with corresponding checksums. //! //! @param offset - The offset where the write is to start. It may be //! unaligned with certain caveats relative to csvec. //! @param buffer - pointer to buffer containing the bytes to write. //! @param wrlen - The number of bytes to write. If amount is not an //! integral number of XrdSys::PageSize bytes, then this must //! be the last write to the file at or above the offset. //! @param csvec - A vector which contains the corresponding CRC32 checksum //! for each page or page fragment. If offset is unaligned //! then csvec[0] is the crc of the leading fragment to //! align the subsequent full page who's crc is in csvec[1]. //! It must be sized to hold all aligned XrdSys::Pagesize //! crc's plus additional ones for leading and ending page //! fragments, if any. //! @param opts - Processing options (see above). //! //! @return >= 0 The number of bytes written. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize pgWrite(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize wrlen, uint32_t *csvec, uint64_t opts=0); //----------------------------------------------------------------------------- //! Write file pages and checksums using asynchronous I/O. //! //! @param aioparm - Pointer to async I/O object controlling the I/O. //! @param opts - Processing options (see above). //! //! @return SFS_OK Request accepted and will be scheduled. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual int pgWrite(XrdSfsAio *aioparm, uint64_t opts=0); //----------------------------------------------------------------------------- //! Preread file blocks into the file system cache. //! //! @param offset - The offset where the read is to start. //! @param size - The number of bytes to pre-read. //! //! @return >= 0 The number of bytes that will be pre-read. //! @return SFS_ERROR File could not be preread, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize read(XrdSfsFileOffset offset, XrdSfsXferSize size) = 0; //----------------------------------------------------------------------------- //! Read file bytes into a buffer. //! //! @param offset - The offset where the read is to start. //! @param buffer - pointer to buffer where the bytes are to be placed. //! @param size - The number of bytes to read. //! //! @return >= 0 The number of bytes that placed in buffer. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize read(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize size) = 0; //----------------------------------------------------------------------------- //! Read file bytes using asynchronous I/O. //! //! @param aioparm - Pointer to async I/O object controlling the I/O. //! //! @return SFS_OK Request accepted and will be scheduled. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual int read(XrdSfsAio *aioparm) = 0; //----------------------------------------------------------------------------- //! Given an array of read requests (size rdvCnt), read them from the file //! and place the contents consecutively in the provided buffer. A dumb default //! implementation is supplied but should be replaced to increase performance. //! //! @param readV pointer to the array of read requests. //! @param rdvCnt the number of elements in readV. //! //! @return >=0 The numbe of bytes placed into the buffer. //! @return SFS_ERROR File could not be read, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize readv(XrdOucIOVec *readV, int rdvCnt); //----------------------------------------------------------------------------- //! Send file bytes via a XrdSfsDio sendfile object to a client (optional). //! //! @param sfDio - Pointer to the sendfile object for data transfer. //! @param offset - The offset where the read is to start. //! @param size - The number of bytes to read and send. //! //! @return SFS_ERROR File not read, error object has reason. //! @return SFS_OK Either data has been successfully sent via sfDio or no //! data has been sent and a normal read() should be issued. //----------------------------------------------------------------------------- virtual int SendData(XrdSfsDio *sfDio, XrdSfsFileOffset offset, XrdSfsXferSize size); //----------------------------------------------------------------------------- //! Write file bytes from a buffer. //! //! @param offset - The offset where the write is to start. //! @param buffer - pointer to buffer where the bytes reside. //! @param size - The number of bytes to write. //! //! @return >= 0 The number of bytes that were written. //! @return SFS_ERROR File could not be written, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize write(XrdSfsFileOffset offset, const char *buffer, XrdSfsXferSize size) = 0; //----------------------------------------------------------------------------- //! Write file bytes using asynchronous I/O. //! //! @param aioparm - Pointer to async I/O object controlling the I/O. //! //! @return 0 Request accepted and will be scheduled. //! @return !0 Request not accepted, returned value is errno. //----------------------------------------------------------------------------- virtual int write(XrdSfsAio *aioparm) = 0; //----------------------------------------------------------------------------- //! Given an array of write requests (size wdvcnt), write them to the file //! from the provided associated buffer. A dumb default implementation is //! supplied but should be replaced to increase performance. //! //! @param writeV pointer to the array of write requests. //! @param wdvCnt the number of elements in writeV. //! //! @return >=0 The total number of bytes written to the file. //! @return SFS_ERROR File could not be written, error holds the reason. //----------------------------------------------------------------------------- virtual XrdSfsXferSize writev(XrdOucIOVec *writeV, int wdvCnt); //----------------------------------------------------------------------------- //! Return state information on the file. //! //! @param buf - Pointer to the structure where info it to be returned. //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL. When SFS_OK //! is returned, buf must hold stat information. //----------------------------------------------------------------------------- virtual int stat(struct stat *buf) = 0; //----------------------------------------------------------------------------- //! Make sure all outstanding data is actually written to the file (sync). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED //----------------------------------------------------------------------------- virtual int sync() = 0; //----------------------------------------------------------------------------- //! Make sure all outstanding data is actually written to the file (async). //! //! @return SFS_OK Request accepted and will be scheduled. //! @return SFS_ERROR Request could not be accepted, return error has reason. //----------------------------------------------------------------------------- virtual int sync(XrdSfsAio *aiop) = 0; //----------------------------------------------------------------------------- //! Truncate the file. //! //! @param fsize - The size that the file is to have. //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int truncate(XrdSfsFileOffset fsize) = 0; //----------------------------------------------------------------------------- //! Get compression information for the file. //! //! @param cxtype - Place where the compression algorithm name is to be placed //! @param cxrsz - Place where the compression page size is to be returned //! //! @return One of the valid SFS return codes described above. If the file //! is not compressed or an error is returned, cxrsz must be set to 0. //----------------------------------------------------------------------------- virtual int getCXinfo(char cxtype[4], int &cxrsz) = 0; //----------------------------------------------------------------------------- //! Enable exchange buffer I/O for write calls. //! //! @param xioP - Pointer to the XrdSfsXio object to be used for buffer exchanges. //----------------------------------------------------------------------------- virtual void setXio(XrdSfsXio *xioP) { (void)xioP; } //----------------------------------------------------------------------------- //! Constructor (user and MonID are the ones passed to newFile()!). This //! constructor should only be used by base plugins. Plugins that wrap an //! SfsFile should use the second version of the constructor shown below. //! //! @param user - Text identifying the client responsible for this call. //! The pointer may be null if identification is missing. //! @param MonID - The monitoring identifier assigned to this and all //! future requests using the returned object. //----------------------------------------------------------------------------- XrdSfsFile(const char *user=0, int MonID=0) : error(*(new XrdOucErrInfo(user, MonID))) {lclEI = &error; pgwrEOF = 0;} //----------------------------------------------------------------------------- //! Constructor for plugins that wrap another SFS plugin. This constructor //! inherits the error object from a wrapped XrdSfsFile object so that only //! one identical error object exists for all file objects in the chain. //! //! @param wrapF - Reference to the file object being wrapped. //----------------------------------------------------------------------------- XrdSfsFile(XrdSfsFile &wrapF) : error(wrapF.error), lclEI(0), pgwrEOF(0) {} //----------------------------------------------------------------------------- //! Constructor for base plugins that predefined an error object. This is a //! convenience constructor for base plugins only. //! //! @param eInfo - Reference to the error object to use. //----------------------------------------------------------------------------- XrdSfsFile(XrdOucErrInfo &eInfo) : error(eInfo), lclEI(0), pgwrEOF(0) {} //----------------------------------------------------------------------------- //! Destructor //----------------------------------------------------------------------------- virtual ~XrdSfsFile() {if (lclEI) delete lclEI;} private: XrdOucErrInfo* lclEI; XrdSfsFileOffset pgwrEOF; }; // class XrdSfsFile /******************************************************************************/ /* X r d S f s F i l e S y s t e m */ /******************************************************************************/ //----------------------------------------------------------------------------- //! Common parameters: Many of the methods have certain common parameters. //! These are documented here to avoid lengthy duplicate descriptions. //! //! @param eInfo - The object where error info or results are to be returned. //! For errors, you should return information as follows: //! SFS_OK eInfo may contain results, as described in //! specified method description that follows. //! SFS_ERROR eInfo.code - errno number //! eInfo.message - error message text //! SFS_REDIRECT eInfo.code - target port number //! eInfo.message - target host address/name //! SFS_STALL eInfo.code - expected seconds to stall //! eInfo.message - reason for the delay //! SFS_STARTED eInfo.code - expected seconds to completion //! eInfo.message - reason for the delay //! SFS_DATA eInfo.code - length of data in message //! eInfo.message - the request data //! //! @param client - Pointer to the client's identity information or nil if //! the identity is not known. //! //! @param opaque - Pointer to the CGI information associated with Path or //! nil if there is no opaque information. //----------------------------------------------------------------------------- class XrdSfsFileSystem { public: //----------------------------------------------------------------------------- //! Obtain a new director object to be used for future directory requests. //! //! @param user - Text identifying the client responsible for this call. //! The pointer may be null if identification is missing. //! @param MonID - The monitoring identifier assigned to this and all //! future requests using the returned object. //! //! @return pointer- Pointer to an XrdSfsDirectory object. //! @return nil - Insufficient memory to allocate an object. //----------------------------------------------------------------------------- virtual XrdSfsDirectory *newDir(char *user=0, int MonID=0) = 0; //----------------------------------------------------------------------------- //! Obtain a new wrapped directory object to be used for future requests. //! //! @param eInfo - Reference to the error object to be used by the new //! directory object. Note that an implementation is supplied //! for compatibility purposes but it returns a nil pointer //! which is considered to be a failure. You must supply an //! implementation for this to work correctly. //! //! @return pointer- Pointer to an XrdSfsDirectory object. //! @return nil - Insufficient memory to allocate an object. //----------------------------------------------------------------------------- virtual XrdSfsDirectory *newDir(XrdOucErrInfo &eInfo) {(void)eInfo; return 0;} //----------------------------------------------------------------------------- //! Obtain a new file object to be used for a future file requests. //! //! @param user - Text identifying the client responsible for this call. //! The pointer may be null if identification is missing. //! @param MonID - The monitoring identifier assigned to this and all //! future requests using the returned object. //! //! @return pointer- Pointer to an XrdSfsFile object. //! @return nil - Insufficient memory to allocate an object. //----------------------------------------------------------------------------- virtual XrdSfsFile *newFile(char *user=0, int MonID=0) = 0; //----------------------------------------------------------------------------- //! Obtain a new wrapped file object to be used for a future requests. //! //! @param eInfo - Reference to the error object to be used by the new file //! object. Note that an implementation is supplied for //! compatibility purposes but it returns a nil pointer //! which is considered to be a failure. You must supply an //! implementation for this to work correctly. //! //! @return pointer- Pointer to an XrdSfsFile object. //! @return nil - Insufficient memory to allocate an object. //----------------------------------------------------------------------------- virtual XrdSfsFile *newFile(XrdOucErrInfo &eInfo) {(void)eInfo; return 0;} //----------------------------------------------------------------------------- //! Obtain checksum information for a file. //! //! @param Func - The checksum operation to be performed: //! csCalc - (re)calculate and return the checksum value //! csGet - return the existing checksum value, if any //! csSize - return the size of the checksum value that //! corresponds to csName (path may be null). //! @param csName - The name of the checksum value wanted. //! @param path - Pointer to the path of the file in question. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, or SFS_REDIRECT. When SFS_OK is returned, //! eInfo should contain results, as follows: //! csCalc/csGet eInfo.message - null terminated string with the //! checksum value in ASCII hex. //! csSize eInfo.code - size of binary checksum value. //----------------------------------------------------------------------------- enum csFunc {csCalc = 0, csGet, csSize}; virtual int chksum( csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0); //----------------------------------------------------------------------------- //! Change file mode settings. //! //! @param path - Pointer to the path of the file in question. //! @param mode - The new file mode setting. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT or SFS_STALL //----------------------------------------------------------------------------- virtual int chmod(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Notify filesystem that a client has connected. //! //! @param client - Client's identify (see common description). //----------------------------------------------------------------------------- virtual void Connect(const XrdSecEntity *client = 0) { (void)client; } //----------------------------------------------------------------------------- //! Notify filesystem that a client has disconnected. //! //! @param client - Client's identify (see common description). //----------------------------------------------------------------------------- virtual void Disc(const XrdSecEntity *client = 0) {(void)client;} //----------------------------------------------------------------------------- //! Notify filesystem about implmentation dependent environment. This method //! may be called only once, if at all, right after obtaining this object. //! //! @param envP - Pointer to environmental information. //----------------------------------------------------------------------------- virtual void EnvInfo(XrdOucEnv *envP) {(void)envP;} //----------------------------------------------------------------------------- //! Return directory/file existence information (short stat). //! //! @param path - Pointer to the path of the file/directory in question. //! @param eFlag - Where the results are to be returned. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED //! When SFS_OK is returned, eFlag must be properly set, as follows: //! XrdSfsFileExistNo - path does not exist //! XrdSfsFileExistIsFile - path refers to an online file //! XrdSfsFileExistIsDirectory - path refers to an online directory //! XrdSfsFileExistIsOffline - path refers to an offline file //! XrdSfsFileExistIsOther - path is neither a file nor directory //----------------------------------------------------------------------------- virtual int exists(const char *path, XrdSfsFileExistence &eFlag, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Perform a filesystem extended attribute function. //! //! @param faReq - pointer to the request object (see XrdSfsFAttr.hh). If the //! pointer is nill, simply return whether or not extended //! attributes are supported. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! //! @return SFS_OK a null response is sent. //! @return SFS_DATA error.code length of the data to be sent. //! error.message contains the data to be sent. //! @return SFS_STARTED Operation started result will be returned via callback. //! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL. //----------------------------------------------------------------------------- virtual int FAttr( XrdSfsFACtl *faReq, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0); //----------------------------------------------------------------------------- //! Obtain file system feature set. //! //! @return The bit-wise feature set (i.e. supported or configured). //! See include file XrdSfsFlags.hh for actual bit values. //----------------------------------------------------------------------------- uint64_t Features() {return FeatureSet;} //----------------------------------------------------------------------------- //! Perform a filesystem control operation (version 2) //! //! @param cmd - The operation to be performed: //! SFS_FSCTL_PLUGIN Return Implementation Dependent Data v1 //! SFS_FSCTL_PLUGIO Return Implementation Dependent Data v2 //! @param args - Arguments specific to cmd. //! SFS_FSCTL_PLUGIN path and opaque information. //! SFS_FSCTL_PLUGIO Unscreened argument string. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! //! @return SFS_OK a null response is sent. //! SFS_DATA error.code length of the data to be sent. //! error.message contains the data to be sent. //! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL. //----------------------------------------------------------------------------- virtual int FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0); //----------------------------------------------------------------------------- //! Perform a filesystem control operation (version 1) //! //! @param cmd - The operation to be performed: //! SFS_FSCTL_LOCATE Locate a file or file servers //! SFS_FSCTL_STATCC Return cluster config status //! SFS_FSCTL_STATFS Return physical filesystem information //! SFS_FSCTL_STATLS Return logical filesystem information //! SFS_FSCTL_STATXA Return extended attributes //! @param args - Arguments specific to cmd. //! SFS_FSCTL_LOCATE args points to the path to be located //! "" path is the first exported path //! "*" return all current servers //! "*/" return servers exporting path //! o/w return servers having the path //! SFS_FSCTL_STATFS Path in the filesystem in question. //! SFS_FSCTL_STATLS Path in the filesystem in question. //! SFS_FSCTL_STATXA Path of the file whose xattr is wanted. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! //! @return SFS_OK a null response is sent. //! @return SFS_DATA error.code length of the data to be sent. //! error.message contains the data to be sent. //! @return SFS_STARTED Operation started result will be returned via callback. //! Valid only for for SFS_FSCTL_LOCATE, SFS_FSCTL_STATFS, and //! SFS_FSCTL_STATXA //! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL. //----------------------------------------------------------------------------- virtual int fsctl(const int cmd, const char *args, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0) = 0; //----------------------------------------------------------------------------- //! Return maximum checkpoint size. //! //! @return Maximum size of a checkpoint. //----------------------------------------------------------------------------- virtual int getChkPSize() {return 0;} //----------------------------------------------------------------------------- //! Return statistical information. //! //! @param buff - Pointer to the buffer where results are to be returned. //! Statistics should be in standard XML format. If buff is //! nil then only maximum size information is wanted. //! @param blen - The length available in buff. //! //! @return Number of bytes placed in buff. When buff is nil, the maximum //! number of bytes that could have been placed in buff. //----------------------------------------------------------------------------- virtual int getStats(char *buff, int blen) = 0; //----------------------------------------------------------------------------- //! Get version string. //! //! @return The version string. Normally this is the XrdVERSION value. //----------------------------------------------------------------------------- virtual const char *getVersion() = 0; //----------------------------------------------------------------------------- //! Perform a third party file transfer or cancel one. //! //! @param gpAct - What to do as one of the enums listed below. //! @param gpReq - reference tothe object describing the request. This object //! is also used communicate the request status. //! @param eInfo - The object where error info or results are to be returned. //! @param client - Client's identify (see common description). //! //! @return SFS_OK Request accepted (same as SFS_STARTED). Otherwise, one of //! SFS_ERROR, SFS_REDIRECT, or SFS_STALL. //----------------------------------------------------------------------------- enum gpfFunc {gpfCancel=0, //!< Cancel this request gpfGet, //!< Perform a file retrieval gpfPut //!< Perform a file push }; virtual int gpFile( gpfFunc &gpAct, XrdSfsGPFile &gpReq, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0); //----------------------------------------------------------------------------- //! Create a directory. //! //! @param path - Pointer to the path of the directory to be created. //! @param mode - The directory mode setting. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int mkdir(const char *path, XrdSfsMode mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Prepare a file for future processing. //! //! @param pargs - The preapre arguments. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int prepare( XrdSfsPrep &pargs, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0) = 0; //----------------------------------------------------------------------------- //! Remove a file. //! //! @param path - Pointer to the path of the file to be removed. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int rem(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Remove a directory. //! //! @param path - Pointer to the path of the directory to be removed. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - Path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int remdir(const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Rename a file or directory. //! //! @param oPath - Pointer to the path to be renamed. //! @param nPath - Pointer to the path oPath is to have. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaqueO - oPath's CGI information (see common description). //! @param opaqueN - nPath's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int rename(const char *oPath, const char *nPath, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaqueO = 0, const char *opaqueN = 0) = 0; //----------------------------------------------------------------------------- //! Return state information on a file or directory. //! //! @param Name - Pointer to the path in question. //! @param buf - Pointer to the structure where info it to be returned. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED //! When SFS_OK is returned, buf must contain stat information. //----------------------------------------------------------------------------- virtual int stat(const char *Name, struct stat *buf, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Return mode information on a file or directory. //! //! @param path - Pointer to the path in question. //! @param mode - Where full mode information is to be returned. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED //! When SFS_OK is returned, mode must contain mode information. If //! the mode is -1 then it is taken as an offline file. //----------------------------------------------------------------------------- virtual int stat(const char *path, mode_t &mode, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Truncate a file. //! //! @param path - Pointer to the path of the file to be truncated. //! @param fsize - The size that the file is to have. //! @param eInfo - The object where error info is to be returned. //! @param client - Client's identify (see common description). //! @param opaque - path's CGI information (see common description). //! //! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL //----------------------------------------------------------------------------- virtual int truncate(const char *path, XrdSfsFileOffset fsize, XrdOucErrInfo &eInfo, const XrdSecEntity *client = 0, const char *opaque = 0) = 0; //----------------------------------------------------------------------------- //! Constructor and Destructor //----------------------------------------------------------------------------- XrdSfsFileSystem(); virtual ~XrdSfsFileSystem() {} protected: uint64_t FeatureSet; //!< Adjust features at initialization }; /******************************************************************************/ /* F i l e S y s t e m I n s t a n t i a t o r */ /******************************************************************************/ //----------------------------------------------------------------------------- /*! When building a shared library plugin, the following "C" entry point must exist in the library: @param nativeFS - the filesystem that would have been used. You may return this pointer if you wish. @param Logger - The message logging object to be used for messages. @param configFn - pointer to the path of the configuration file. If nil there is no configuration file. @param envP - Pointer to the environment containing implementation specific information. @return Pointer to the file system object to be used or nil if an error occurred. extern "C" {XrdSfsFileSystem *XrdSfsGetFileSystem2(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *envP); } */ typedef XrdSfsFileSystem *(*XrdSfsFileSystem2_t)(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *envP); //----------------------------------------------------------------------------- /*! The old-style entry-point is still supported as a fallback. Should the version '2' entry point is not found, the system attempts to use the version '1' entry point. extern "C" {XrdSfsFileSystem *XrdSfsGetFileSystem(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn); } */ typedef XrdSfsFileSystem *(*XrdSfsFileSystem_t) (XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn); //------------------------------------------------------------------------------ /*! Specify the compilation version. Additionally, you *should* declare the xrootd version you used to compile your plug-in. The plugin manager automatically checks for compatibility. Declare it as follows: #include "XrdVersion.hh" XrdVERSIONINFO(XrdSfsGetFileSystem,); where is a 1- to 15-character unquoted name identifying your plugin. */ //------------------------------------------------------------------------------ #endif