52#include "XrdVersion.hh"
75#include "oocx_CXFile.h"
104 const char *OssLib,
const char *OssParms,
114 if (urVer.vNum != myOssSys.
myVersion->vNum
124 if (!OssLib) {
if (myOssSys.
Init(
Logger, config_fn, envP))
return 0;
125 else return (
XrdOss *)&myOssSys;
132 "osslib", OssLib)))
return 0;
136 const char *epName1 =
"XrdOssGetStorageSystem";
138 const char *epName2 =
"?XrdOssGetStorageSystem2";
144 if (getOSS2) ossP = getOSS2((
XrdOss *)&myOssSys,
Logger, config_fn,
147 if (!getOSS1)
return 0;
148 ossP = getOSS1((
XrdOss *)&myOssSys,
Logger, config_fn, OssParms);
156 if (envP && strcmp(OssLib, myLib->
Path()))
157 envP->
Put(
"oss.lib", myLib->
Path());
172 XrdVersionInfo &urVer)
174 return XrdOssGetSS(logger, cfg_fn, 0, 0, 0, urVer);
216 if ((
int)strlen(oldp) >= blen)
return -ENAMETOOLONG;
223 if (!
lcl_N2N) {rc = 0;
return oldp;}
224 if ((rc = -(
lcl_N2N->lfn2pfn(oldp, newp, blen))))
return 0;
240 if (strlen(oldp) >= MAXPATHLEN)
return -ENAMETOOLONG;
257 if (strlen(oldp) >= MAXPATHLEN)
return -ENAMETOOLONG;
281 if (srcFile.
getFD() < 0)
284 if (ioctl(
fd, FICLONE, srcFile.
getFD())==-1)
295#if defined(FICLONERANGE)
303 {
struct file_clone_range fr;
304 fr.src_fd = seg.srcFD;
305 fr.src_offset = seg.srcOffs;
306 fr.src_length = seg.srcLen;
307 fr.dest_offset = seg.dstOffs;
308 if (ioctl(
fd, FICLONERANGE, &fr) == -1)
return -errno;
334 char actual_path[MAXPATHLEN+1], *local_path;
340 if ((retc =
lcl_N2N->lfn2pfn(path, actual_path,
sizeof(actual_path))))
342 else local_path = actual_path;
343 else local_path = (
char *)path;
347 return (chmod(local_path, mode) ? -errno :
XrdOssOK);
368 char actual_path[MAXPATHLEN+1], *local_path;
378 if ((retc =
lcl_N2N->lfn2pfn(path, actual_path,
sizeof(actual_path))))
380 else local_path = actual_path;
381 else local_path = (
char *)path;
386 if (mkpath && errno == ENOENT){
return Mkpath(local_path, mode);}
387 if (errno != EEXIST)
return -errno;
392 static const mode_t accBits = (S_IRWXU|S_IRWXG|S_IRWXO);
415 char local_path[MAXPATHLEN+1], *next_path;
416 int i = strlen(path);
420 strcpy(local_path, path);
424 while(i && local_path[--i] ==
'/') local_path[i] =
'\0';
425 if (!i)
return -ENOENT;
429 next_path = local_path;
430 while((next_path = index(next_path+1,
int(
'/'))))
432 if (
mkdir(local_path, mode) && errno != EEXIST)
return -errno;
438 if (
mkdir(local_path, mode) && errno != EEXIST)
return -errno;
458 static const char statfmt1[] =
"<stats id=\"oss\" v=\"2\">";
459 static const char statfmt2[] =
"</stats>";
460 static const int statflen =
sizeof(statfmt1) +
sizeof(statfmt2);
466 if (!buff)
return statflen +
getStats(0,0);
470 if (blen < statflen)
return 0;
471 strcpy(bp, statfmt1);
472 bp +=
sizeof(statfmt1)-1; blen -=
sizeof(statfmt1)-1;
481 if (blen >= (
int)
sizeof(statfmt2))
482 {strcpy(bp, statfmt2); bp += (
sizeof(statfmt2)-1);}
505 struct stat statbuff;
506 char actual_path[MAXPATHLEN+1], *local_path;
517 if ((retc =
lcl_N2N->lfn2pfn(path, actual_path,
sizeof(actual_path))))
519 else local_path = actual_path;
520 else local_path = (
char *)path;
524 if (lstat(local_path, &statbuff))
return -errno;
525 else if ((statbuff.st_mode & S_IFMT) == S_IFDIR)
return -EISDIR;
526 else if ((statbuff.st_mode & S_IFMT) == S_IFLNK)
528 if (
stat(local_path, &buff))
return -errno;
529 oldsz = buff.st_size;
530 }
else oldsz = statbuff.st_size;
534 if (
truncate(local_path, size))
return -errno;
560 char actual_path[MAXPATHLEN+1], *local_path, *remote_path;
569 unsigned long long pflags =
XrdOssSS->PathOpts(dir_path);
578 if ((retc =
XrdOssSS->lcl_N2N->lfn2pfn(dir_path, actual_path,
sizeof(actual_path))))
580 else local_path = actual_path;
581 else local_path = (
char *)dir_path;
586 if (!(dOpts & isStage) || (dOpts & noDread))
587 {
TRACE(
Opendir,
"lcl path " <<local_path <<
" (" <<dir_path <<
")");
588 if (!(lclfd = XrdSysFD_OpenDir(local_path)))
return -errno;
597 if ((retc =
XrdOssSS->rmt_N2N->lfn2rfn(dir_path, actual_path,
sizeof(actual_path))))
599 else remote_path = actual_path;
600 else remote_path = (
char *)dir_path;
602 TRACE(
Opendir,
"rmt path " << remote_path <<
" (" << dir_path <<
")");
619 if (!(mssfd =
XrdOssSS->MSS_Opendir(remote_path, retc)))
return retc;
656 {
strlcpy(buff, rp->d_name, blen);
658 if (Stat && fstatat(
fd, rp->d_name, Stat, 0))
659 {
if (errno != ENOENT)
return -errno;
666 *buff =
'\0'; ateof =
true;
673 {
if (ateof) *buff =
'\0';
674 else {*buff =
'.'; ateof =
true;}
680 return XrdOssSS->MSS_Readdir(mssfd, buff, blen);
706 if (!lclfd)
return -ENOTSUP;
737 if (retsz) *retsz = 0;
751 if (mssfd) {
if (!(retc =
XrdOssSS->MSS_Closedir(mssfd))) mssfd = 0;}
781 if (lclfd)
return -EALREADY;
782 if (alen != (
int)
sizeof(
int))
return -EINVAL;
784 memcpy(&newFD, args,
sizeof(
int));
786 do {retc =
fstat(newFD, &buf);}
while(retc && errno == EINTR);
787 if (retc)
return -errno;
789 if (!(lclfd = fdopendir(newFD)))
return -errno;
818 unsigned long long popts;
820 char actual_path[MAXPATHLEN+1], *local_path;
836 if ((retc =
XrdOssSS->lcl_N2N->lfn2pfn(path, actual_path,
sizeof(actual_path))))
838 else local_path = actual_path;
839 else local_path = (
char *)path;
843 if (((Oflag & O_ACCMODE) != O_RDONLY) && (popts &
XRDEXP_NOTRW))
851 if ( (
fd = (
int)Open_ufs(local_path, Oflag,
Mode, popts)) == -ENOENT
863 {
do {retc =
fstat(
fd, &buf);}
while(retc && errno == EINTR);
864 if (!retc && !(buf.st_mode & S_IFREG))
865 {
close(
fd);
fd = (buf.st_mode & S_IFDIR ? -EISDIR : -ENOTBLK);}
866 if ((Oflag & O_ACCMODE) != O_RDONLY)
870 FSize = -1; cacheP = 0;
872 }
else if (
fd == -EEXIST)
873 {
do {retc =
stat(local_path,&buf);}
while(retc && errno==EINTR);
874 if (!retc && (buf.st_mode & S_IFDIR))
fd = -EISDIR;
885 Info.Get(local_path,
fd);
918 do {retc =
fstat(
fd, &buf);}
while(retc && errno == EINTR);
919 if (cacheP && FSize != buf.st_size)
921 if (retsz) *retsz = buf.st_size;
926 if (cxobj) {
delete cxobj; cxobj = 0;}
928 fd = -1; FSize = -1; cacheP = 0;
950#if defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
951 posix_fadvise(
fd, offset, blen, POSIX_FADV_WILLNEED);
983 else retval = cxobj->Read((
char *)buff, blen, offset);
986 do { retval =
pread(
fd, buff, blen, offset); }
987 while(retval < 0 && errno == EINTR);
989 return (retval >= 0 ? retval : (ssize_t)-errno);
1011 ssize_t rdsz, totBytes = 0;
1016#if (defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))) && defined(HAVE_ATOMICS)
1018 long long begOff, endOff, begLst = -1, endLst = -1;
1027 if (readV[nPR].size > 0)
1030 rdsz = endOff - begOff + 1;
1031 if ((begOff > endLst || endOff < begLst)
1032 && rdsz < XrdOssSS->prBytes)
1033 {posix_fadvise(
fd, begOff, rdsz, POSIX_FADV_WILLNEED);
1034 TRACE(
Debug,
"fadvise(" <<
fd <<
',' <<begOff <<
',' <<rdsz <<
')');
1037 begLst = begOff; endLst = endOff;
1044 for (i = 0; i < n; i++)
1045 {
do {rdsz =
pread(
fd, readV[i].data, readV[i].size, readV[i].offset);}
1046 while(rdsz < 0 && errno == EINTR);
1047 if (rdsz < 0 || rdsz != readV[i].size)
1048 {totBytes = (rdsz < 0 ? -errno : -ESPIPE);
break;}
1050#if (defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))) && defined(HAVE_ATOMICS)
1051 if (nPR < n && readV[nPR].size > 0)
1054 rdsz = endOff - begOff + 1;
1055 if ((begOff > endLst || endOff < begLst)
1056 && rdsz <= XrdOssSS->prBytes)
1057 {posix_fadvise(
fd, begOff, rdsz, POSIX_FADV_WILLNEED);
1058 TRACE(
Debug,
"fadvise(" <<
fd <<
',' <<begOff <<
',' <<rdsz <<
')');
1060 begLst = begOff; endLst = endOff;
1068#if (defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))) && defined(HAVE_ATOMICS)
1097 if (cxobj) retval = cxobj->ReadRaw((
char *)buff, blen, offset);
1100 do { retval =
pread(
fd, buff, blen, offset); }
1101 while(retval < 0 && errno == EINTR);
1103 return (retval >= 0 ? retval : (ssize_t)-errno);
1130 do { retval =
pwrite(
fd, buff, blen, offset); }
1131 while(retval < 0 && errno == EINTR);
1133 if (retval < 0) retval = (retval == EBADF && cxobj ? -
XRDOSS_E8022 : -errno);
1170 const struct timeval *utArgs;
1174 if (alen !=
sizeof(
struct timeval)*2 || !args)
return -EINVAL;
1175 utArgs = (
const struct timeval *)args;
1176 if (futimes(
fd, utArgs))
return -errno;
1181 if (
fd >= 0)
return -EALREADY;
1182 if (alen != (
int)
sizeof(
int))
return -EINVAL;
1184 memcpy(&newFD, args,
sizeof(
int));
1186 do {retc =
fstat(newFD, &buf);}
while(retc && errno == EINTR);
1187 if (retc)
return -errno;
1189 FSize = buf.st_size;
1211#if defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
1214 posix_fadvise(
fd, 0, 0, POSIX_FADV_DONTNEED);
1268 if (mmFile)
return (addr ? mmFile->Export(addr) : 1);
1269 if (addr) *addr = 0;
1290 {cxidp[0] = cxid[0]; cxidp[1] = cxid[1];
1291 cxidp[2] = cxid[2]; cxidp[3] = cxid[3];
1319 off_t newlen = flen;
1321 if (
sizeof(newlen) <
sizeof(flen) && (flen>>31))
return -
XRDOSS_E8008;
1335int XrdOssFile::Open_ufs(
const char *path,
int Oflag,
int Mode,
1336 unsigned long long popts)
1341 char *ftype = (
char *)
" path=";
1356 do { myfd = XrdSysFD_Open(path, Oflag|O_LARGEFILE,
Mode);}
1357 while( myfd < 0 && errno == EINTR);
1366 bzero(&lock_args,
sizeof(lock_args));
1367 lock_args.l_type = F_RDLCK;
1368 fcntl(myfd, F_SETLKW, &lock_args);
1373 if (myfd < 0) myfd = -errno;
1375 else if ((popts & XRDEXP_COMPCHK)
1376 && oocx_CXFile::isCompressed(myfd, cxid, &cxpgsz))
1384 {
if (myfd < XrdOssSS->FDFence)
1387 else {
close(myfd); myfd = newfd;}
1392 if (attcx) {cxobj =
new oocx_CXFile;
1393 ftype = (
char *)
" CXpath=";
1394 if ((retc = cxobj->Attach(myfd, path)) < 0)
1395 {
close(myfd); myfd = retc;
delete cxobj; cxobj = 0;}
static XrdSysLogger Logger
XrdSysError OssEroute(0, "oss_")
XrdSysTrace OssTrace("oss")
XrdOss * XrdOssGetSS(XrdSysLogger *Logger, const char *config_fn, const char *OssLib, const char *OssParms, XrdOucEnv *envP, XrdVersionInfo &urVer)
XrdOss * XrdOssDefaultSS(XrdSysLogger *logger, const char *cfg_fn, XrdVersionInfo &urVer)
#define Check_RW(act, path, opname)
XrdOss *(* XrdOssGetStorageSystem2_t)(XrdOss *native_oss, XrdSysLogger *Logger, const char *config_fn, const char *parms, XrdOucEnv *envP)
XrdOss *(* XrdOssGetStorageSystem_t)(XrdOss *native_oss, XrdSysLogger *Logger, const char *config_fn, const char *parms)
The typedef that describes the XRdOssStatInfoInit external.
int fdatasync(int fildes)
#define pwrite(a, b, c, d)
#define pread(a, b, c, d)
static const char memKeep
static const char memLock
static XrdOssCache_FS * Find(const char *Path, int lklen=0)
static void Adjust(dev_t devid, off_t size)
static const uint16_t DF_isFile
Object is for a file.
XrdOssDF(const char *tid="", uint16_t dftype=0, int fdnum=-1)
static const int Fctl_utimes
static const uint16_t DF_isDir
Object is for a directory.
static const int Fctl_setFD
int StatRet(struct stat *buff)
int Opendir(const char *, XrdOucEnv &)
int Readdir(char *buff, int blen)
int Close(long long *retsz=0)
int Fctl(int cmd, int alen, const char *args, char **resp=0)
virtual int Close(long long *retsz=0)
int Clone(XrdOssDF &srcFile)
int isCompressed(char *cxidp=0)
ssize_t Read(off_t, size_t)
int Fctl(int cmd, int alen, const char *args, char **resp=0)
virtual int Open(const char *, int, mode_t, XrdOucEnv &)
off_t getMmap(void **addr)
void Flush()
Flush filesystem cached pages for this file (used for checksums).
ssize_t ReadV(XrdOucIOVec *readV, int)
int Ftruncate(unsigned long long)
ssize_t Write(const void *, off_t, size_t)
ssize_t ReadRaw(void *, off_t, size_t)
static XrdOssMioFile * Map(char *path, int fd, int opts)
static void Recycle(XrdOssMioFile *mp)
int GenRemotePath(const char *, char *)
int Configure(const char *, XrdSysError &, XrdOucEnv *envP)
int Init(XrdSysLogger *, const char *, XrdOucEnv *envP)
int getStats(char *buff, int blen)
int Mkdir(const char *, mode_t mode, int mkpath=0, XrdOucEnv *eP=0)
int Mkpath(const char *, mode_t mode)
int GenLocalPath(const char *, char *)
XrdOucName2Name * lcl_N2N
int Lfn2Pfn(const char *Path, char *buff, int blen)
XrdVersionInfo * myVersion
int Stat(const char *, struct stat *, int opts=0, XrdOucEnv *Env=0)
int Chmod(const char *, mode_t mode, XrdOucEnv *eP=0)
int Stats(char *bp, int bl)
int Truncate(const char *, unsigned long long Size, XrdOucEnv *eP=0)
XrdOucName2Name * rmt_N2N
virtual void EnvInfo(XrdOucEnv *envP)
char * Get(const char *varname)
void Put(const char *varname, const char *value)
void * Resolve(const char *symbl, int mcnt=1)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
static bool VerCmp(XrdVersionInfo &vInf1, XrdVersionInfo &vInf2, bool noMsg=false)