Skip to content

Commit

Permalink
Implement Fstat() at the cache level.
Browse files Browse the repository at this point in the history
  • Loading branch information
abh3 committed Jun 30, 2016
1 parent 3167795 commit 99dbf85
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 38 deletions.
19 changes: 17 additions & 2 deletions src/XrdOuc/XrdOucCache2.hh
Expand Up @@ -61,6 +61,21 @@ class XrdOucCacheIO2 : public virtual XrdOucCacheIO
{
public:

//------------------------------------------------------------------------------
//! Perform an fstat() operation (defaults to passthrough).
//!
//! @param sbuff reference to the stat buffer to be filled in. Only fields
//! st_size, st_blocks, st_mtime (st_atime and st_ctime may be
//! set to st_mtime), st_ino, and st_mode need to be set. All
//! other fields are preset and should not be changed.
//!
//! @return <0 - fstat failed, value is -errno.
//! =0 - fstat succeeded, sbuff holds stat information.
//! >0 - fstat could not be done, forward operation to next level.
//------------------------------------------------------------------------------

virtual int Fstat(struct stat &sbuff) {(void)sbuff; return 1;}

//------------------------------------------------------------------------------
//! Perform an asynchronous read (defaults to synchrnous).
//!
Expand Down Expand Up @@ -227,8 +242,8 @@ int Prepare(const char *url, int oflags, mode_t mode)
//! @param url pointer to the url whose stat information is wanted.
//! @param sbuff reference to the stat buffer to be filled in. Only fields
//! st_size, st_blocks, st_mtime (st_atime and st_ctime may be
//! set to st_mtime), st_ino, st_rdev, and st_mode need to be
//! set. All other fields should be set to zero.
//! set to st_mtime), st_ino, and st_mode need to be set. All
//! other fields are preset and should not be changed.
//!
//! @return <0 - Stat failed, value is -errno.
//! =0 - Stat succeeded, sbuff holds stat information.
Expand Down
2 changes: 2 additions & 0 deletions src/XrdPosix/XrdPosixCacheBC.hh
Expand Up @@ -53,6 +53,8 @@ XrdOucCacheIO2 *Detach() {XrdOucCacheIO2 *theCIO = cacheIO2;
virtual
long long FSize() {return cacheIO1->FSize();}

virtual int Fstat(struct stat &buf) {return cacheIO2->Fstat(buf);}

virtual
const char *Path() {return cacheIO1->Path();}

Expand Down
25 changes: 25 additions & 0 deletions src/XrdPosix/XrdPosixFile.cc
Expand Up @@ -248,6 +248,31 @@ bool XrdPosixFile::Finalize(XrdCl::XRootDStatus *Status)
return true;
}

/******************************************************************************/
/* F s t a t */
/******************************************************************************/

int XrdPosixFile::Fstat(struct stat &buf)
{
long long theSize;

// The size is treated differently here as it may come from a cache and may
// actually trigger a file open if the open was deferred.
//
theSize = XCio->FSize();
if (theSize < 0) return static_cast<int>(theSize);

// Return what little we can
//
buf.st_size = theSize;
buf.st_atime = buf.st_mtime = buf.st_ctime = myMtime;
buf.st_blocks = buf.st_size/512+1;
buf.st_ino = myInode;
buf.st_rdev = myRdev;
buf.st_mode = myMode;
return 0;
}

/******************************************************************************/
/* H a n d l e R e s p o n s e */
/******************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions src/XrdPosix/XrdPosixFile.hh
Expand Up @@ -92,6 +92,8 @@ static void DelayedDestroy(XrdPosixFile *fp);
return retSize;
}

int Fstat(struct stat &buf);

void HandleResponse(XrdCl::XRootDStatus *status,
XrdCl::AnyObject *response);

Expand Down
5 changes: 5 additions & 0 deletions src/XrdPosix/XrdPosixPrepIO.hh
Expand Up @@ -43,8 +43,13 @@ XrdOucCacheIO *Detach() {return this;} // Already defined

long long FSize() {return (Init() ? fileP->FSize() : openRC);}

int Fstat(struct stat &buf)
{return (Init() ? fileP->Fstat(buf) : openRC);}

bool ioActive() { return false; } // Already defined

int Open() {Init(); return openRC;}

const char *Path() {return fileP->Path();}

int Read (char *Buffer, long long Offset, int Length)
Expand Down
57 changes: 21 additions & 36 deletions src/XrdPosix/XrdPosixXrootd.cc
Expand Up @@ -294,7 +294,7 @@ int XrdPosixXrootd::endPoint(int FD, char *Buff, int Blen)
int XrdPosixXrootd::Fstat(int fildes, struct stat *buf)
{
XrdPosixFile *fp;
long long theSize;
int rc;

// Find the file object
//
Expand All @@ -306,40 +306,21 @@ int XrdPosixXrootd::Fstat(int fildes, struct stat *buf)

// Check if we can get the stat information from the cache.
//
if (myCache2)
{int rc = myCache2->Stat(fp->Path(), *buf);
if (rc <= 0)
{fp->UnLock();
if (!rc) return 0;
errno = -rc;
return -1;
}
}

// We need to trat getting the size separately as this file may still not be
// open. This gets resolved via the cache layer.
//
theSize = fp->XCio->FSize();
if (theSize < 0)
rc = fp->XCio->Fstat(*buf);
if (rc <= 0)
{fp->UnLock();
errno = static_cast<int>(-theSize);
if (!rc) return 0;
errno = -rc;
return -1;
}


// Return what little we can
//
buf->st_size = theSize;
buf->st_atime = buf->st_mtime = buf->st_ctime = fp->myMtime;
buf->st_blocks = buf->st_size/512+1;
buf->st_ino = fp->myInode;
buf->st_rdev = fp->myRdev;
buf->st_mode = fp->myMode;

// All done
// At this point we can call the file's Fstat() and if the file is not open
// it will be opened.
//
rc = fp->Fstat(*buf);
fp->UnLock();
return 0;
if (rc < 0) {errno = -rc; rc = -1;}
return rc;
}

/******************************************************************************/
Expand Down Expand Up @@ -445,13 +426,17 @@ off_t XrdPosixXrootd::Lseek(int fildes, off_t offset, int whence)
//
if (!(fp = XrdPosixObject::File(fildes))) return -1;

// Set the new offset
// Set the new offset. Note that SEEK_END requires that the file be opened.
// An open may occur by calling the FSize() method via the cache pointer.
//
if (whence == SEEK_SET) curroffset = fp->setOffset(offset);
else if (whence == SEEK_CUR) curroffset = fp->addOffset(offset);
else if (whence == SEEK_END)
curroffset = fp->setOffset(fp->FSize()+offset);
else return Fault(fp, EINVAL);
if (whence == SEEK_SET) curroffset = fp->setOffset(offset);
else if (whence == SEEK_CUR) curroffset = fp->addOffset(offset);
else if (whence == SEEK_END)
{curroffset = fp->XCio->FSize();
if (curroffset < 0) return Fault(fp,static_cast<int>(-curroffset));
curroffset = fp->setOffset(curroffset+offset);
}
else return Fault(fp, EINVAL);

// All done
//
Expand Down Expand Up @@ -1395,7 +1380,7 @@ void XrdPosixXrootd::initEnv(char *eData)
myParms.Options |= XrdOucCache::Serialized;
if (!(v1Cache = myCache->Create(myParms, &apParms)))
cerr <<"XrdPosix: " <<strerror(errno) <<" creating cache." <<endl;
else XrdPosixGlobals::theCache = myCache2 = new XrdPosixCacheBC(v1Cache);
else XrdPosixGlobals::theCache = new XrdPosixCacheBC(v1Cache);
}

/******************************************************************************/
Expand Down

0 comments on commit 99dbf85

Please sign in to comment.