37#include <sys/resource.h>
40#include "XrdVersion.hh"
103int XrdPosixXrootd::baseFD = 0;
104int XrdPosixXrootd::initDone = 0;
122 LfnPath(
const char *who,
const char *pURL,
bool ponly=
true)
125 ~LfnPath() {
if (relURL) free(relURL);}
165 if (!cbP)
return fp->
FDNum();
193 if (initDone) {myMutex.
UnLock();
return;}
204 if (*cfn ==
'+') {hush =
false; cfn++;}
205 else hush = (getenv(
"XRDPOSIX_DEBUG") == 0);
208 psxEnv->
Put(
"psx.Client",
"1");
209 XrdOucPsx psxConfig(&XrdVERSIONINFOVAR(XrdPosix), cfn, 0, psxEnv);
212 {std::cerr <<
"Posix: Unable to instantiate specified "
213 "configuration; program exiting!" <<std::endl;
249 if (!admin.
Stat(&stMode))
return -1;
253 if (amode & R_OK && !(stMode & S_IRUSR)) aOK = 0;
254 if (amode & W_OK && !(stMode & S_IWUSR)) aOK = 0;
255 if (amode & X_OK && !(stMode & S_IXUSR)) aOK = 0;
287 {
if ((ret = fP->
Close(Status))) {
delete fP; fP = 0;}
289 {std::string eTxt = Status.
ToString();
342 {fp->
UnLock();
return -ENOTCONN;}
346 std::string dataServer;
350 if (dataServer.size() >= (uint32_t)Blen)
351 {fp->
UnLock();
return -ENAMETOOLONG;}
355 strcpy(Buff, dataServer.c_str());
359 uPort = dataServerUrl.
GetPort();
394 rc = fp->
Fstat(*buf);
396 if (rc < 0) {errno = -rc; rc = -1;}
415 if ((rc = fp->
XCio->
Sync()) < 0)
return Fault(fp, -rc);
450 if ((rc = fp->
XCio->
Trunc(offset)) < 0)
return Fault(fp, -rc);
460#define ENOATTR ENOTSUP
464 void *value,
unsigned long long size)
468 int vsize =
static_cast<int>(size);
472 if (size == 0)
return 1024;
480 else {errno =
ENOATTR;
return -1;}
481 }
else {errno = EINVAL;
return -1;}
485 if (!admin.
Stat())
return -1;
489 return admin.
Query(reqCode, value, vsize);
499 long long curroffset;
508 if (whence == SEEK_SET) curroffset = fp->
setOffset(offset);
509 else if (whence == SEEK_CUR) curroffset = fp->
addOffset(offset);
510 else if (whence == SEEK_END)
512 if (curroffset < 0)
return Fault(fp,
static_cast<int>(-curroffset));
513 curroffset = fp->
setOffset(curroffset+offset);
515 else return Fault(fp, EINVAL);
539 if (!admin.
isOK())
return -1;
557 return Open(path, oflags, mode, cbP, 0);
569 bool aOK, isRO =
false;
573 if (oflags & (O_WRONLY | O_RDWR))
591 if (oflags & O_CREAT)
607 if (!aOK) {
delete fp;
return -1;}
614 if (infoP && isRO && OpenCache(*fp, *infoP))
620 if (rc > 0)
return OpenDefer(fp, cbP, XOflags, XOmode, oflags&
isStream);
627 if (!cbP) Status = fp->
clFile.
Open((std::string)path, XOflags, XOmode);
628 else Status = fp->
clFile.
Open((std::string)path, XOflags, XOmode,
636 if (
DEBUGON && rc != -ENOENT && rc != -ELOOP)
645 if (!(fp->AssignFD(oflags &
isStream)))
653 if (cbP) {errno = EINPROGRESS;
return -1;}
654 if (fp->Finalize(&Status))
return fp->FDNum();
685 (
int)
sizeof(
Info.cachePath),
689 {
Info.ffReady =
true;
690 DEBUG(
"File in cache url=" <<
Info.cacheURL);
696 Info.ffReady =
false;
727 if ((dirP = dP->
Open()))
return dirP;
744 long long offs, bytes;
754 if (nbyte > (
size_t)0x7fffffff)
755 return Fault(fp, EOVERFLOW,
"read size too large");
756 else iosz =
static_cast<int>(nbyte);
760 offs =
static_cast<long long>(offset);
761 bytes = fp->
XCio->
Read((
char *)buf, offs, (int)iosz);
762 if (bytes < 0)
return Fault(fp,-bytes,
"*");
767 return (ssize_t)bytes;
785 if (nbyte > (
size_t)0x7fffffff)
796 iosz =
static_cast<int>(nbyte);
797 offs =
static_cast<long long>(offset);
801 fp->
XCio->
Read(*cbp, (
char *)buf, offs, (int)iosz);
820 if (nbyte > (
size_t)0x7fffffff)
821 return Fault(fp,EOVERFLOW,
"write size too large");
822 else iosz =
static_cast<int>(nbyte);
826 offs =
static_cast<long long>(offset);
827 bytes = fp->
XCio->
Write((
char *)buf, offs, (int)iosz);
828 if (bytes < 0)
return Fault(fp,-bytes,
"*");
834 return (ssize_t)iosz;
852 if (nbyte > (
size_t)0x7fffffff)
863 iosz =
static_cast<int>(nbyte);
864 offs =
static_cast<long long>(offset);
868 fp->
XCio->
Write(*cbp, (
char *)buf, offs, (int)iosz);
887 if (nbyte > (
size_t)0x7fffffff)
return Fault(fp,EOVERFLOW);
888 else iosz =
static_cast<int>(nbyte);
893 if (bytes < 0)
return Fault(fp,-bytes);
899 return (ssize_t)bytes;
908 ssize_t bytes, totbytes = 0;
913 for (i = 0; i < iovcnt; i++)
914 {bytes =
Read(fildes,(
void *)
iov[i].iov_base,(
size_t)
iov[i].iov_len);
915 if (bytes > 0) totbytes += bytes;
916 else if (bytes < 0)
return -1;
940 if ((bytes = fp->
XCio->
ReadV(readV, n)) < 0)
return Fault(fp,-bytes);
975 dp32 = (
struct dirent *)dp64;
976 if ((
char*)dp32->d_name != (
char*)dp64->d_name)
977 {dp32->d_ino = dp64->d_ino;
978#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__GNU__) && !(defined(__FreeBSD_kernel__) && defined(__GLIBC__))
979 dp32->d_off = dp64->d_off;
982 dp32->d_type = dp64->d_type;
984 dp32->d_reclen = dp64->d_reclen;
985 strcpy(dp32->d_name, dp64->d_name);
1000 return (dirent64*)0;
1020 struct dirent **result)
1022 dirent64 *dp64 = 0, d64ent;
1025 if ((rc =
Readdir64_r(dirp, &d64ent, &dp64)) || !dp64)
1026 {*result = 0;
return rc;}
1028 entry->d_ino = dp64->d_ino;
1029#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__GNU__) && !(defined(__FreeBSD_kernel__) && defined(__GLIBC__))
1030 entry->d_off = dp64->d_off;
1033 entry->d_type = dp64->d_type;
1035 entry->d_reclen = dp64->d_reclen;
1036 strcpy(entry->d_name, dp64->d_name);
1042 struct dirent64 **result)
1053 if (!(*result = dP->
nextEntry(entry))) {rc = dP->
Status(); *result = 0;}
1054 else {rc = 0; *result = entry;}
1079 {LfnPath oldF(
"rename", oldpath);
1080 LfnPath newF(
"rename", newpath);
1081 if (!oldF.path || !newF.path)
return -1;
1088 return EcRename(oldpath, newpath, admin);
1122 if (!admin.
isOK())
return -1;
1127 {LfnPath rmd(
"rmdir", path);
1128 if (!rmd.path)
return -1;
1155 else if (loc < 0) loc = 0;
1171 if (!admin.
isOK())
return -1;
1180 {LfnPath statX(
"stat", path,
false);
1181 if (!statX.path)
return -1;
1184 if (rc < 0) {errno = -rc;
return -1;}
1190 return EcStat(path, buf, admin);
1192 if (!admin.
Stat(*buf))
return -1;
1207 if ((rc =
Statvfs(path, &myVfs)))
return rc;
1211 memset(buf, 0,
sizeof(
struct statfs));
1212 buf->f_bsize = myVfs.f_bsize;
1213 buf->f_blocks = myVfs.f_blocks;
1214 buf->f_bfree = myVfs.f_bfree;
1215 buf->f_files = myVfs.f_files;
1216 buf->f_ffree = myVfs.f_ffree;
1217#if defined(__APPLE__) || defined(__FreeBSD__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
1218 buf->f_iosize = myVfs.f_frsize;
1220 buf->f_frsize = myVfs.f_frsize;
1222#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
1223 buf->f_bavail = myVfs.f_bavail;
1225#if defined(__linux__) || defined(__GNU__)
1226 buf->f_namelen = myVfs.f_namemax;
1227#elif defined(__FreeBSD__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
1228 buf->f_namemax = myVfs.f_namemax;
1239 static const int szVFS =
sizeof(buf->f_bfree);
1240 static const long long max32 = 0x7fffffffLL;
1245 long long rwFree, ssFree, rwBlks;
1246 int rwNum, ssNum, rwUtil, ssUtil;
1250 if (!admin.
isOK())
return -1;
1260 rwNum =
static_cast<int>(vfsStat->
GetNodesRW());
1261 rwFree = (
long long)vfsStat->
GetFreeRW();
1270 if (rwUtil == 0) rwBlks = rwFree;
1271 else if (rwUtil >= 100) rwBlks = 0;
1272 else rwBlks = rwFree * (100 / (100 - rwUtil));
1273 if (ssUtil == 0) rwBlks += ssFree;
1274 else if (ssUtil < 100) rwBlks += ssFree * (100 / (100 - ssUtil));
1279 {
if (rwBlks > max32) rwBlks = max32;
1280 if (rwFree > max32) rwFree = max32;
1281 if (ssFree > max32) ssFree = max32;
1286 memset(buf, 0,
sizeof(
struct statvfs));
1287 buf->f_bsize = 1024*1024;
1288 buf->f_frsize = 1024*1024;
1289 buf->f_blocks =
static_cast<fsblkcnt_t
>(rwBlks);
1290 buf->f_bfree =
static_cast<fsblkcnt_t
>(rwFree + ssFree);
1291 buf->f_bavail =
static_cast<fsblkcnt_t
>(rwFree);
1292 buf->f_ffree = rwNum + ssNum;
1293 buf->f_favail = rwNum;
1294 buf->f_namemax = 255;
1295 buf->f_flag = (rwNum == 0 ? ST_RDONLY|ST_NOSUID : ST_NOSUID);
1328 uint64_t tSize =
static_cast<uint64_t
>(Size);
1332 if (!admin.
isOK())
return -1;
1337 {LfnPath trunc(
"truncate", path);
1338 if (!trunc.path)
return -1;
1359 if (!admin.
isOK())
return -1;
1364 {LfnPath remf(
"unlink", path);
1365 if (!remf.path)
return -1;
1372 return EcUnlink(path, admin);
1393 if (nbyte > (
size_t)0x7fffffff)
return Fault(fp,EOVERFLOW);
1394 else iosz =
static_cast<int>(nbyte);
1399 if (bytes < 0)
return Fault(fp,-bytes);
1405 return (ssize_t)iosz;
1414 ssize_t totbytes = 0;
1419 for (i = 0; i < iovcnt; i++)
1420 {
if (!
Write(fildes,(
void *)
iov[i].iov_base,(
size_t)
iov[i].iov_len))
1422 totbytes +=
iov[i].iov_len;
1439 if (!dirp)
return false;
1462 char *value,
int vsize)
1468 if (!admin.
Stat(0, &Mtime))
return -1;
1493 return ecmP->
Get(
emsg, reset);
1523 if (!admin.
Stat())
return -1;
1537int XrdPosixXrootd::Fault(
XrdPosixFile *fp,
int ecode,
const char *msg)
1547int XrdPosixXrootd::EcRename(
const char *oldpath,
const char *newpath,
1553 std::string file = url.GetPath();
1564 || queryResp->
ToString() ==
"server\n")
1566 if (queryResp)
delete queryResp;
1568 newUrl.GetPathWithParams()),
1572 if (queryResp)
delete queryResp;
1575 std::unique_ptr<XrdCl::LocationInfo> ptr( info );
1584 if ( ! S_ISREG(buf.st_mode))
1591 for(
size_t i = 0; i < info->
GetSize(); ++i )
1593 std::string url_i =
"root://" + info->
At(i).
GetAddress() +
"/" + file;
1596 newUrl.GetPathWithParams()),
1598 if (x != -ENOENT && rc != 0)
1600 if (admin_i)
delete admin_i;
1609int XrdPosixXrootd::EcStat(
const char *path,
struct stat *buf,
1613 std::string file = url.GetPath();
1617 std::vector<std::string> xattrkeys;
1618 std::vector<XrdCl::XAttr> xattrvals;
1619 xattrkeys.push_back(
"xrdec.strpver");
1620 xattrkeys.push_back(
"xrdec.filesize");
1628 || queryResp->
ToString() ==
"server\n")
1630 if (queryResp)
delete queryResp;
1631 if (!admin.
Stat(*buf))
1635 st = fs.GetXAttr(file, xattrkeys, xattrvals, 0);
1636 if (! xattrvals[0].value.empty())
1638 std::stringstream sstream0(xattrvals[0].value);
1639 sstream0 >> buf->st_mtime;
1640 std::stringstream sstream1(xattrvals[1].value);
1641 sstream1 >> buf->st_size;
1642 buf->st_blocks = (buf->st_size + 512)/512;
1648 if (queryResp)
delete queryResp;
1651 std::unique_ptr<XrdCl::LocationInfo> ptr( info );
1659 uint64_t verNumMax = 0;
1662 for(
size_t i = 0; i < info->
GetSize(); ++i )
1664 std::string url_i =
"root://" + info->
At(i).
GetAddress() +
"/" + file;
1667 if (admin_i->
Stat(buf_i))
1669 if (! S_ISREG(buf_i.st_mode))
1671 memcpy(buf, &buf_i,
sizeof(
struct stat));
1672 if (admin_i)
delete admin_i;
1677 if (verNumMax == 0) memcpy(buf, &buf_i,
sizeof(
struct stat));
1683 st = fs_i->
GetXAttr(file, xattrkeys, xattrvals, 0);
1684 if (! xattrvals[0].value.empty())
1686 std::stringstream sstream(xattrvals[0].value);
1689 if ( verNum > verNumMax )
1692 memcpy(buf, &buf_i,
sizeof(
struct stat));
1693 buf->st_mtime = verNumMax;
1694 std::stringstream sstream(xattrvals[1].value);
1695 sstream >> buf->st_size;
1696 buf->st_blocks = (buf->st_size + 512)/512;
1699 if (fs_i)
delete fs_i;
1701 if (admin_i)
delete admin_i;
1715int XrdPosixXrootd::EcUnlink(
const char *path,
XrdPosixAdmin &admin)
1718 std::string file = url.GetPath();
1728 || queryResp->
ToString() ==
"server\n")
1730 if (queryResp)
delete queryResp;
1735 if (queryResp)
delete queryResp;
1738 std::unique_ptr<XrdCl::LocationInfo> ptr( info );
1743 for(
size_t i = 0; i < info->
GetSize(); ++i )
1745 std::string url_i =
"root://" + info->
At(i).
GetAddress() +
"/" + file;
1750 if (x != -ENOENT && rc != 0)
1752 if (admin_i)
delete admin_i;
XrdVERSIONINFO(XrdPosix, XrdPosix)
int emsg(int rc, char *msg)
Binary blob representation.
void FromString(const std::string str)
Fill the buffer from a string.
std::string ToString() const
Convert the buffer to a string.
Send file/filesystem queries to an XRootD cluster.
XRootDStatus RmDir(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Mv(const std::string &source, const std::string &dest, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus Rm(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus GetXAttr(const std::string &path, const std::vector< std::string > &attrs, ResponseHandler *handler, uint16_t timeout=0)
XRootDStatus Truncate(const std::string &path, uint64_t size, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus MkDir(const std::string &path, MkDirFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
XRootDStatus StatVFS(const std::string &path, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
bool IsOpen() const
Check if the file is open.
XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
bool GetProperty(const std::string &name, std::string &value) const
const std::string & GetAddress() const
Get address.
uint32_t GetSize() const
Get number of locations.
Location & At(uint32_t index)
Get the location at index.
Handle an async response.
uint64_t GetFreeRW() const
Get size of the largest contiguous area of free r/w space (in MB)
uint64_t GetNodesStaging() const
Get number of nodes that can provide staging space.
uint8_t GetUtilizationStaging() const
Get percentage of the partition utilization represented by FreeStaging.
uint64_t GetFreeStaging() const
Get size of the largest contiguous area of free staging space (in MB)
uint8_t GetUtilizationRW() const
Get percentage of the partition utilization represented by FreeRW.
uint64_t GetNodesRW() const
Get number of nodes that can provide read/write space.
std::string GetPathWithParams() const
Get the path with params.
bool IsValid() const
Is the url valid.
int GetPort() const
Get the target port.
virtual int Read(char *buff, long long offs, int rlen)=0
virtual int Fstat(struct stat &sbuff)
virtual int Write(char *buff, long long offs, int wlen)=0
virtual long long FSize()=0
virtual bool Detach(XrdOucCacheIOCD &iocd)=0
virtual int Trunc(long long offs)=0
virtual int ReadV(const XrdOucIOVec *readV, int rnum)
virtual int Rename(const char *oldp, const char *newp)
virtual int Stat(const char *url, struct stat &sbuff)
virtual int Truncate(const char *path, off_t size)
virtual int Unlink(const char *path)
virtual int LocalFilePath(const char *url, char *buff=0, int blen=0, LFP_Reason why=ForAccess, bool forall=false)
virtual int Prepare(const char *url, int oflags, mode_t mode)
virtual int Rmdir(const char *dirp)
int Get(std::string &ecm, bool rst=true)
int SetErrno(int ecc, int retval=-1, const char *alt=0)
void Put(const char *varname, const char *value)
bool ClientConfig(const char *pfx, bool hush=false)
bool Stat(mode_t *flags=0, time_t *mtime=0)
int Query(XrdCl::QueryCode::Code reqCode, void *buff, int bsz)
virtual void Complete(ssize_t Result)=0
An abstract class to define a callback for Open() call.
virtual void Complete(int Result)=0
static void initStat(struct stat *buf)
static bool SetConfig(XrdOucPsx &parms)
static int dirNo(DIR *dirP)
dirent64 * nextEntry(dirent64 *dp=0)
void setOffset(long offset)
void UpdtSize(size_t newsz)
long long addOffset(long long offs, int updtSz=0)
int Fstat(struct stat &buf) override
bool Close(XrdCl::XRootDStatus &Status)
const char * Path() override
bool Finalize(XrdCl::XRootDStatus *Status)
long long setOffset(long long offs)
static void * DelayedDestroy(void *)
static int Result(const XrdCl::XRootDStatus &Status, XrdOucECMsg &ecMsg, bool retneg1=false)
static XrdCl::Access::Mode Mode2Access(mode_t mode)
bool AssignFD(bool isStream=false)
static XrdPosixDir * Dir(int fildes, bool glk=false)
static XrdPosixDir * ReleaseDir(int fildes)
static int Init(int numfd)
static XrdPosixFile * ReleaseFile(int fildes)
static bool Valid(int fd)
static XrdPosixFile * File(int fildes, bool glk=false)
void Count(long long &Dest)
static const char * P2L(const char *who, const char *inP, char *&relP, bool ponly=false)
static ssize_t Readv(int fildes, const struct iovec *iov, int iovcnt)
Readv() conforms to POSIX.1-2001 readv()
static ssize_t Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Pread() conforms to POSIX.1-2001 pread()
static int Closedir(DIR *dirp)
Closedir() conforms to POSIX.1-2001 closedir()
static void Seekdir(DIR *dirp, long loc)
Seekdir() conforms to POSIX.1-2001 seekdir()
static const int isStream
static int Stat(const char *path, struct stat *buf)
Stat() conforms to POSIX.1-2001 stat()
static int QueryChksum(const char *path, time_t &mtime, char *buff, int blen)
static int Mkdir(const char *path, mode_t mode)
Mkdir() conforms to POSIX.1-2001 mkdir()
static int Unlink(const char *path)
Unlink() conforms to POSIX.1-2001 unlink()
static int Rmdir(const char *path)
Rmdir() conforms to POSIX.1-2001 rmdir()
static void Rewinddir(DIR *dirp)
Rewinddir() conforms to POSIX.1-2001 rewinddir()
static void VRead(int fildes, const XrdOucIOVec *readV, int n, XrdPosixCallBackIO *cbp)
static int Rename(const char *oldpath, const char *newpath)
Rename() conforms to POSIX.1-2001 rename()
static int Close(int fildes)
Close() conforms to POSIX.1-2001 close()
static int Statvfs(const char *path, struct statvfs *buf)
Statvfs() conforms to POSIX.1-2001 statvfs()
static int endPoint(int FD, char *Buff, int Blen)
static ssize_t Write(int fildes, const void *buf, size_t nbyte)
Write() conforms to POSIX.1-2001 write()
static struct dirent * Readdir(DIR *dirp)
static int Readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
static ssize_t Writev(int fildes, const struct iovec *iov, int iovcnt)
Writev() conforms to POSIX.1-2001 writev()
static int QueryError(std::string &emsg, int fd=-1, bool reset=true)
static struct dirent64 * Readdir64(DIR *dirp)
XrdPosixXrootd(int maxfd=255, int maxdir=0, int maxthr=0)
static int Ftruncate(int fildes, off_t offset)
Ftruncate() conforms to POSIX.1-2001 ftruncate()
static long Telldir(DIR *dirp)
Telldir() conforms to POSIX.1-2001 telldir()
static bool isXrootdDir(DIR *dirp)
static int Access(const char *path, int amode)
Access() conforms to POSIX.1-2001 access()
static DIR * Opendir(const char *path)
Opendir() conforms to POSIX.1-2001 opendir()
static int Fsync(int fildes)
Fsync() conforms to POSIX.1-2001 fsync()
static long long Getxattr(const char *path, const char *name, void *value, unsigned long long size)
static long long QueryOpaque(const char *path, char *buff, int blen)
static int Statfs(const char *path, struct statfs *buf)
static int Readdir64_r(DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
static ssize_t Read(int fildes, void *buf, size_t nbyte)
Read() conforms to POSIX.1-2001 read()
static int Fstat(int fildes, struct stat *buf)
Fstat() conforms to POSIX.1-2001 fstat()
static off_t Lseek(int fildes, off_t offset, int whence)
Lseek() conforms to POSIX.1-2001 lseek()
static int Open(const char *path, int oflag, mode_t mode=0, XrdPosixCallBack *cbP=0)
static ssize_t Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Pwrite() conforms to POSIX.1-2001 pwrite()
static int Truncate(const char *path, off_t offset)
Telldir() conforms to POSIX.1-2001 telldir()
thread_local XrdOucECMsg ecMsg
XrdCl::DirListFlags::Flags dlFlag
@ MakePath
create the entire directory tree if it doesn't exist
Flags
Open flags, may be or'd when appropriate.
@ Read
Open only for reading.
@ Update
Open for reading and writing.
Code
XRootD query request codes.
@ OpaqueFile
Implementation dependent.
@ XAttr
Query file extended attributes.
@ Config
Query server configuration.
@ Checksum
Query file checksum.
@ Space
Query logical space stats.
bool IsOK() const
We're fine.
std::string ToString() const
Create a string representation.