Loading...
Searching...
No Matches
XrdXrootdXeqPgrw.cc
Go to the documentation of this file.
/******************************************************************************/
/* */
/* X r d X r o o t d X e q P g r w . c c */
/* */
/* (c) 2020 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 <http://www.gnu.org/licenses/>. */
/* */
/* 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 <cctype>
#include <cstdio>
#include <sys/uio.h>
#include "XrdSfs/XrdSfsInterface.hh"
#include "XrdSys/XrdSysPlatform.hh"
#include "XProtocol/XProtocol.hh"
#include "Xrd/XrdBuffer.hh"
#include "Xrd/XrdLink.hh"
#include "XrdOuc/XrdOucCRC.hh"
#include "XrdOuc/XrdOucString.hh"
#include "XrdOuc/XrdOucPgrwUtils.hh"
#include "XrdXrootd/XrdXrootdAioFob.hh"
#include "XrdXrootd/XrdXrootdFile.hh"
#include "XrdXrootd/XrdXrootdMonFile.hh"
#include "XrdXrootd/XrdXrootdMonitor.hh"
#include "XrdXrootd/XrdXrootdPgrwAio.hh"
#include "XrdXrootd/XrdXrootdPgwCtl.hh"
#include "XrdXrootd/XrdXrootdPgwFob.hh"
#include "XrdXrootd/XrdXrootdProtocol.hh"
#include "XrdXrootd/XrdXrootdStats.hh"
#include "XrdXrootd/XrdXrootdTrace.hh"
#include "XrdXrootd/XrdXrootdXeq.hh"
/******************************************************************************/
/* G l o b a l s */
/******************************************************************************/
extern XrdSysTrace XrdXrootdTrace;
namespace
{
static const int pgPageSize = XrdProto::kXR_pgPageSZ;
static const int pgPageMask = XrdProto::kXR_pgPageSZ-1;
static const int pgUnitSize = XrdProto::kXR_pgUnitSZ;
}
namespace
{
static const int pgAioMin = XrdXrootdPgrwAio::aioSZ
+ XrdXrootdPgrwAio::aioSZ*8/10; // 1.8 of aiosz
static const int pgAioHalf= XrdXrootdPgrwAio::aioSZ/2;
}
/******************************************************************************/
/* d o _ P g C l o s e */
/******************************************************************************/
bool XrdXrootdProtocol::do_PgClose(XrdXrootdFile *fP, int &rc)
{
XrdXrootdPgwFob *fobP = fP->pgwFob;
int numErrs, numFixes, numLeft;
// Make sure we have a fob
//
if (!fobP) return true;
// Obtain the checksum status of this file and update statistics
//
numLeft = fobP->numOffs(&numErrs, &numFixes);
fP->Stats.pgUpdt(numErrs, numFixes, numLeft);
// If there are uncorrected checksum, indicate failure. These will be logged
// when the fob is deleted later on.
//
if (numLeft)
{char ebuff[128];
snprintf(ebuff,sizeof(ebuff),"%d uncorrected checksum errors",numLeft);
rc = Response.Send(kXR_ChkSumErr, ebuff);
return false;
}
// All is well
//
return true;
}
/******************************************************************************/
/* d o _ P g R e a d */
/******************************************************************************/
int XrdXrootdProtocol::do_PgRead()
{
int pathID;
XrdXrootdFHandle fh(Request.pgread.fhandle);
numReads++;
// Unmarshall the data
//
IO.IOLen = ntohl(Request.pgread.rlen);
n2hll(Request.pgread.offset, IO.Offset);
// Perform a sanity check on the length
//
if (IO.IOLen <= 0)
return Response.Send(kXR_ArgInvalid, "Read length is invalid");
// Find the file object
//
if (!FTab || !(IO.File = FTab->Get(fh.handle)))
return Response.Send(kXR_FileNotOpen,
"pgread does not refer to an open file");
// Now handle the optional pathid and reqflags arguments.
//
IO.Flags = 0;
if (!Request.header.dlen) pathID = 0;
else {ClientPgReadReqArgs *rargs=(ClientPgReadReqArgs *)(argp->buff);
pathID = static_cast<int>(rargs->pathid);
if (Request.header.dlen > 1)
IO.Flags = static_cast<unsigned short>(rargs->reqflags);
}
// Trace this
//
TRACEP(FSIO,pathID<<" pgread "<<IO.IOLen<<'@'<<IO.Offset
<<" fn=" <<IO.File->FileKey);
// If we are monitoring, insert a read entry
//
if (Monitor.InOut())
Monitor.Agent->Add_rd(IO.File->Stats.FileID, Request.pgread.rlen,
Request.pgread.offset);
// Do statistics. They will not always be accurate because we may not be
// able to fully complete the I/O from the file. Note that we also count
// the checksums which a questionable practice.
//
IO.File->Stats.pgrOps(IO.IOLen, (IO.Flags & XrdProto::kXR_pgRetry) != 0);
// Use synchronous reads unless async I/O is allowed, the read size is
// sufficient, and there are not too many async operations in flight.
//
if (IO.File->AsyncMode && IO.IOLen >= pgAioMin
&& IO.Offset+IO.IOLen <= IO.File->Stats.fSize+pgAioHalf
&& linkAioReq < as_maxperlnk && srvrAioOps < as_maxpersrv
&& !(IO.Flags & XrdProto::kXR_pgRetry))
{XrdXrootdProtocol *pP;
XrdXrootdPgrwAio *aioP;
int rc;
if (!pathID) pP = this;
else {if (!(pP = VerifyStream(rc, pathID, false))) return rc;
if (pP->linkAioReq >= as_maxperlnk) pP = 0;
}
if (pP && (aioP = XrdXrootdPgrwAio::Alloc(pP, Response, IO.File)))
{if (!IO.File->aioFob) IO.File->aioFob = new XrdXrootdAioFob;
aioP->Read(IO.Offset, IO.IOLen);
return 0;
}
SI->AsyncRej++;
}
// See if an alternate path is required, offload the read
//
if (pathID) return do_Offload(&XrdXrootdProtocol::do_PgRIO, pathID);
// Now do the read on the main path
//
return do_PgRIO();
}
/******************************************************************************/
/* d o _ P g R I O */
/******************************************************************************/
// IO.File = file to be read
// IO.Offset = Offset at which to read
// IO.IOLen = Number of bytes to read from file and write to socket
int XrdXrootdProtocol::do_PgRIO()
{
// We restrict the maximum transfer size to generate no more than 1023 iovec
// elements where the first is used for the header.
//
static const int maxIOVZ = XrdSys::getIovMax();
static const int maxCSSZ = maxIOVZ/2 - 1;
static const int maxPGRD = maxCSSZ*pgPageSize; // 2,093,056 usually
static const int infoLen = sizeof(kXR_int64);
struct pgReadResponse
{ServerResponseStatus rsp;
kXR_int64 ofs;
} pgrResp;
XrdSfsFile *sfsP = IO.File->XrdSfsp;
uint64_t pgrOpts = 0;
int dlen, fLen, lLen, rc, xframt, Quantum;
uint32_t csVec[maxCSSZ];
struct iovec iov[maxIOVZ];
// Set flags, as needed
//
if (IO.Flags & XrdProto::kXR_pgRetry) pgrOpts |= XrdSfsFile::Verify;
// Preinitialize the header
//
pgrResp.rsp.bdy.requestid = kXR_pgread - kXR_1stRequest;
pgrResp.rsp.bdy.resptype = XrdProto::kXR_PartialResult;;
memset(pgrResp.rsp.bdy.reserved, 0, sizeof(pgrResp.rsp.bdy.reserved));
// Calculate the total pages in the read request. Note that the first and
// last pages may require short reads if they are not fully aligned.
//
int pgOff, rPages, rLen = IO.IOLen;
rPages = XrdOucPgrwUtils::csNum(IO.Offset, IO.IOLen) * pgPageSize;
// Compute the quantum.
//
Quantum = (maxPGRD > maxBuffsz ? maxBuffsz : maxPGRD);
if (rPages < Quantum) Quantum = rPages;
// Make sure we have a large enough buffer. We may need to adjust it downward
// due to reallocation rounding.
//
if (!argp || Quantum < halfBSize || Quantum > argp->bsize)
{if ((rc = getBuff(1, Quantum)) <= 0) return rc;}
else if (hcNow < hcNext) hcNow++;
if (argp->bsize > maxPGRD) Quantum = maxPGRD;
// Compute the number of iovec elements we need plus one for the header. The
// Quantum is gauranteed to be a multiple of pagesize now. Verify that this
// calculation was indeed correct to avoid overwriting the stack.
//
int items = Quantum / pgPageSize;
if (items > maxCSSZ)
return Response.Send(kXR_Impossible, "pgread logic error 1");
// Preinitialize the io vector for checksums and data (leave 1st element free).
//
uint32_t *csVP = csVec;
char *buff = argp->buff;
int i = 1, n = items * 2;
while(i < n)
{iov[i ].iov_base = csVP++;
iov[i++].iov_len = sizeof(uint32_t);
iov[i ].iov_base = buff;
iov[i++].iov_len = pgPageSize;
buff += pgPageSize;
}
// If this is an unaligned read, offset the unaligned segment in the buffer
// so that remaining pages are page-aligned. It will be reset when needed.
// We also calculate the actual length of the first read.
//
if ((pgOff = IO.Offset & pgPageMask))
{rLen = pgPageSize - pgOff;
buff = argp->buff + pgOff;
iov[2].iov_base = buff;
iov[2].iov_len = rLen;
rLen += Quantum - pgPageSize;
} else {
rLen = Quantum;
buff = argp->buff;
}
if (IO.IOLen < rLen) rLen = IO.IOLen;
// Now read all of the data. For each read we must recacalculate the number
// of iovec elements that we will use to send the data as fewer bytes may have
// been read. In fact, no bytes may have been read.
//
long long ioOffset = IO.Offset;
do {if ((xframt = sfsP->pgRead(IO.Offset, buff, rLen, csVec, pgrOpts)) <= 0)
break;
items = XrdOucPgrwUtils::csNum(IO.Offset, xframt, fLen, lLen);
iov[2].iov_len = fLen;
if (items > 1) iov[items<<1].iov_len = lLen;
if (xframt < rLen || xframt == IO.IOLen)
{pgrResp.rsp.bdy.resptype = XrdProto::kXR_FinalResult;
IO.IOLen = 0;
} else {
IO.IOLen -= xframt; IO.Offset += xframt;
rLen = (IO.IOLen < Quantum ? IO.IOLen : Quantum);
}
for (int i = 0; i < items; i++) csVec[i] = htonl(csVec[i]);
pgrResp.ofs = htonll(ioOffset);
// char trBuff[512];
// snprintf(trBuff, sizeof(trBuff), "Xeq PGR: %d@%lld (%lld)\n",
// xframt, ioOffset, ioOffset>>12);
// std::cerr<<trBuff<<std::flush;
dlen = xframt + (items * sizeof(uint32_t));
if ((rc = Response.Send(pgrResp.rsp, infoLen, iov, items*2+1, dlen)) < 0)
return rc;
if (pgOff)
{iov[2].iov_base = argp->buff;
iov[2].iov_len = pgPageSize;
buff = argp->buff;
pgOff = 0;
}
ioOffset = IO.Offset;
} while(IO.IOLen > 0);
// Determine why we ended here
//
if (xframt < 0) return fsError(xframt, 0, sfsP->error, 0, 0);
// Return no bytes if we were tricked into sending a partial result
//
if (pgrResp.rsp.bdy.resptype != XrdProto::kXR_FinalResult)
{pgrResp.rsp.bdy.resptype = XrdProto::kXR_FinalResult;
pgrResp.rsp.bdy.dlen = 0;
pgrResp.ofs = htonll(IO.Offset);
return Response.Send(pgrResp.rsp, infoLen);
}
return 0;
}
/******************************************************************************/
/* d o _ P g W r i t e */
/******************************************************************************/
int XrdXrootdProtocol::do_PgWrite()
{
XrdXrootdFHandle fh(Request.pgwrite.fhandle);
int pathID;
numWrites++;
// Unmarshall the data
//
IO.IOLen = Request.pgwrite.dlen;
n2hll(Request.pgwrite.offset, IO.Offset);
pathID = Request.pgwrite.pathid;
IO.Flags = static_cast<unsigned short>(Request.pgwrite.reqflags);
// Perform a sanity check on the length.
//
if (IO.IOLen <= (int)sizeof(kXR_unt32))
{Response.Send(kXR_ArgInvalid, "pgwrite length is invalid");
return Link->setEtext("pgwrite protocol violation");
}
// Validate pathid, at least as much as we need to. If it's wrong then we
// don't know where the data is and we just let it go.
//
if (pathID && (pathID >= maxStreams || !Stream[pathID]))
return Response.Send(kXR_ArgInvalid, "invalid path ID");
// Find the file object
//
if (!FTab || !(IO.File = FTab->Get(fh.handle)))
{IO.File = 0;
return do_WriteNone(pathID);
}
// If the file object does not have a pgWrite object, allocate one.
//
if (IO.File->pgwFob == 0) IO.File->pgwFob = new XrdXrootdPgwFob(IO.File);
// Trace this
//
TRACEP(FSIO, pathID<<" pgwrite "
<<(IO.Flags & XrdProto::kXR_pgRetry ? "retry " : "")
<<IO.IOLen<<'@'<<IO.Offset<<" fn=" <<IO.File->FileKey);
// Do statistics. They will not always be accurate because we may not be
// able to fully complete the I/O to the file. Note that we also count
// the checksums which a questionable practice.
//
IO.File->Stats.pgwOps(IO.IOLen, (IO.Flags & XrdProto::kXR_pgRetry) != 0);
// If we are monitoring, insert a write entry
//
if (Monitor.InOut())
Monitor.Agent->Add_wr(IO.File->Stats.FileID, Request.pgwrite.dlen,
Request.pgwrite.offset);
// See if an alternate path is required, offload the write
//
if (pathID) return do_Offload(&XrdXrootdProtocol::do_PgWIO, pathID);
// Now do the write on the main path
//
return do_PgWIO(true);
}
/******************************************************************************/
/* d o _ P g W A I O */
/******************************************************************************/
// IO.File = file to be written
// IO.Offset = Offset at which to write
// IO.IOLen = Number of bytes to read from socket
// IO.Flags = Flags associated with request
bool XrdXrootdProtocol::do_PgWAIO(int &rc)
{
XrdXrootdPgrwAio *aioP;
// Make sure the client is fast enough to do this
//
if (myStalls >= as_maxstalls)
{SI->AsyncRej++;
myStalls--;
return false;
}
// Allocate an aio request object
//
if (!(aioP = XrdXrootdPgrwAio::Alloc(this, Response, IO.File, pgwCtl)))
{SI->AsyncRej++;
return false;
}
// Issue the write request
//
rc = aioP->Write(IO.Offset, IO.IOLen);
return true;
}
/******************************************************************************/
/* d o _ P g W I O */
/******************************************************************************/
// IO.File = file to be written
// IO.Offset = Offset at which to write
// IO.IOLen = Number of bytes to read from socket
// IO.Flags = Flags associated with request
int XrdXrootdProtocol::do_PgWIO() {return do_PgWIO(true);}
int XrdXrootdProtocol::do_PgWIO(bool isFresh)
{
struct iovec *ioV;
XrdSfsFile *sfsP = IO.File->XrdSfsp;
const char *eMsg;
char *buff;
kXR_unt32 *csVec;
int n, rc, Quantum, iovLen, iovNum, csNum;
bool isRetry = (IO.Flags & XrdProto::kXR_pgRetry) != 0;
// Verify that we still have a control area and allocate a control object
// if we do not have one already. The object stays around until disconnect.
//
if (!IO.File->pgwFob)
return do_WriteNone(PathID, kXR_Impossible, "pgwrite logic error 1");
if (!pgwCtl) pgwCtl = new XrdXrootdPgwCtl(PathID);
// If this is the first entry then check if the request is eligible for async
// I/O or if this is a retry request which, of course, is not eligible.
//
if (isFresh)
{if (IO.File->AsyncMode && IO.IOLen >= pgAioMin
&& linkAioReq < as_maxperlnk && srvrAioOps < as_maxpersrv
&& !isRetry && do_PgWAIO(rc)) return rc;
if (isRetry && !do_PgWIORetry(rc)) return rc;
if (!do_PgWIOSetup(pgwCtl)) return -1;
}
// Either complete the current frame or start a new one. When we start a new
// one, the I/O will not return unless all of the data was successfully read.
// Hence, we update the length outstanding.
//
do{if (isFresh)
{if (!(ioV = pgwCtl->FrameInfo(iovNum, iovLen))) break;
IO.IOLen -= iovLen;
if ((rc = getData(this, "pgwrite", ioV, iovNum))) return rc;
}
// We now have all the data, get checksum and data information
//
if (!(csVec = pgwCtl->FrameInfo(csNum, buff, Quantum, argp)))
return do_WriteNone(PathID, kXR_Impossible, "pgwrite logic error 2");
// Convert checksums to host byte order
//
for (int i = 0; i < csNum; i++) csVec[i] = ntohl(csVec[i]);
// Verify the checksums
//
XrdOucPgrwUtils::dataInfo dInfo(buff, csVec, IO.Offset, Quantum);
off_t bado;
int badc;
bool aOK = true;
while(dInfo.count > 0 && !XrdOucPgrwUtils::csVer(dInfo, bado, badc))
{if ((eMsg = pgwCtl->boAdd(IO.File, bado, badc)))
return do_WriteNone(PathID, kXR_TooManyErrs, eMsg);
aOK = false;
}
// Write the data out. The callee is responsible for unaligned writes!
//
if ((rc = sfsP->pgWrite(IO.Offset, buff, Quantum, csVec)) <= 0)
{IO.EInfo[0] = rc; IO.EInfo[1] = 0;
return do_WriteNone();
}
// If this was a successful retry write, remove corrrected offset
//
if (aOK && IO.Flags & XrdProto::kXR_pgRetry)
IO.File->pgwFob->delOffs(IO.Offset, Quantum);
// Update offset and advance to next frame
//
IO.Offset += Quantum;
isFresh = true;
} while(pgwCtl->Advance());
// Return final result
//
buff = pgwCtl->boInfo(n);
return Response.Send(pgwCtl->resp, sizeof(pgwCtl->info), buff, n);
}
/******************************************************************************/
/* d o _ P g W I O R e t r y */
/******************************************************************************/
// IO.File = file to be written
// IO.Offset = Offset at which to write
// IO.IOLen = Number of bytes to read from socket
// IO.Flags = Flags associated with request
bool XrdXrootdProtocol::do_PgWIORetry(int &rc)
{
static const int csLen = sizeof(kXR_unt32);
bool isBad;
// Make sure the write does not cross a page bounday. For unaligned writes we
// can compute the exact length that we need. Otherwise, it can't be bigger
// than a unit's worth of data. Not precise but usually good enough.
//
if (IO.Offset & pgPageMask)
{int n = pgPageSize - (IO.Offset & pgPageMask);
isBad = IO.IOLen > (n + csLen);
} else isBad = IO.IOLen > pgUnitSize;
// Deep six the write if it violates retry rules.
//
if (isBad)
{rc = do_WriteNone(PathID, kXR_ArgInvalid,
"pgwrite retry of more than one page not allowed");
return false;
}
// Make sure that the offset is registered, if it is not, treat this as a
// regular write as this may have been a resend during write recovery.
//
if (!IO.File->pgwFob->hasOffs(IO.Offset, IO.IOLen - csLen))
{char buff[64];
snprintf(buff, sizeof(buff), "retry %d@%lld", IO.IOLen-csLen, IO.Offset);
eDest.Emsg("pgwRetry", buff, "not in error; fn=", IO.File->FileKey);
IO.Flags &= ~XrdProto::kXR_pgRetry;
}
// We can proceed with this write now.
//
return true;
}
/******************************************************************************/
/* d o _ P g w I O S e t u p */
/******************************************************************************/
// IO.File = file to be written
// IO.Offset = Offset at which to write
// IO.IOLen = Number of bytes to read from socket
// IO.Flags = Flags associated with request
bool XrdXrootdProtocol::do_PgWIOSetup(XrdXrootdPgwCtl *pgwCtl)
{
const char *eMsg;
int Quantum;
// Compute the minimum (4K) or maximum buffer size we will use.
//
if (IO.IOLen < XrdXrootdPgwCtl::maxBSize/2)
Quantum = (IO.IOLen < pgPageSize ? pgPageSize : IO.IOLen);
else Quantum = XrdXrootdPgwCtl::maxBSize;
// Make sure we have a large enough buffer
//
if (!argp || Quantum < halfBSize || argp->bsize < Quantum
|| argp->bsize > XrdXrootdPgwCtl::maxBSize)
{if (getBuff(0, Quantum) <= 0) return -1;}
else if (hcNow < hcNext) hcNow++;
// Do the setup. If it fails then either the client sent an incorrect stream
// of the header was corrupted. In either case, it doesn't matter as we can't
// depend on the information to clear the stream. So, we close the connection.
//
if ((eMsg = pgwCtl->Setup(argp, IO.Offset, IO.IOLen)))
{Response.Send(kXR_ArgInvalid, eMsg);
Link->setEtext("pgwrite protocol violation");
return false;
}
return true;
}
XProtocol.hh
kXR_ArgInvalid
@ kXR_ArgInvalid
Definition XProtocol.hh:990
kXR_Impossible
@ kXR_Impossible
Definition XProtocol.hh:1021
kXR_TooManyErrs
@ kXR_TooManyErrs
Definition XProtocol.hh:1023
kXR_ChkSumErr
@ kXR_ChkSumErr
Definition XProtocol.hh:1009
kXR_FileNotOpen
@ kXR_FileNotOpen
Definition XProtocol.hh:994
ClientPgReadReqArgs::pathid
kXR_char pathid
Definition XProtocol.hh:516
kXR_1stRequest
@ kXR_1stRequest
Definition XProtocol.hh:111
kXR_pgread
@ kXR_pgread
Definition XProtocol.hh:142
ClientPgReadReqArgs::reqflags
kXR_char reqflags
Definition XProtocol.hh:517
kXR_int64
long long kXR_int64
Definition XPtypes.hh:98
kXR_unt32
unsigned int kXR_unt32
Definition XPtypes.hh:90
XrdBuffer.hh
XrdXrootdTrace
XrdOucTrace * XrdXrootdTrace
Definition XrdFrmAdminMain.cc:96
XrdLink.hh
XrdOucCRC.hh
XrdOucPgrwUtils.hh
XrdOucString.hh
eMsg
#define eMsg(x)
Definition XrdSecsssAdmin.cc:53
XrdSfsInterface.hh
XrdSysPlatform.hh
XrdXrootdAioFob.hh
XrdXrootdFile.hh
XrdXrootdMonFile.hh
XrdXrootdMonitor.hh
XrdXrootdPgrwAio.hh
XrdXrootdPgwCtl.hh
XrdXrootdPgwFob.hh
XrdXrootdProtocol.hh
XrdXrootdStats.hh
XrdXrootdTrace.hh
TRACEP
#define TRACEP(act, x)
Definition XrdXrootdTrace.hh:63
XrdXrootdXeq.hh
XrdOucPgrwUtils::csVer
static bool csVer(dataInfo &dInfo, off_t &bado, int &badc)
Definition XrdOucPgrwUtils.cc:166
XrdOucPgrwUtils::csNum
static int csNum(off_t offs, int count)
Compute the required size of a checksum vector based on offset & length.
Definition XrdOucPgrwUtils.cc:109
XrdSfsFile::Verify
static const uint64_t Verify
Options for pgRead() and pgWrite() as noted below.
Definition XrdSfsInterface.hh:518
XrdSfsFile::error
XrdOucErrInfo & error
Definition XrdSfsInterface.hh:378
XrdSfsFile::pgRead
virtual XrdSfsXferSize pgRead(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize rdlen, uint32_t *csvec, uint64_t opts=0)
Definition XrdSfsInterface.cc:93
XrdSfsFile::pgWrite
virtual XrdSfsXferSize pgWrite(XrdSfsFileOffset offset, char *buffer, XrdSfsXferSize wrlen, uint32_t *csvec, uint64_t opts=0)
Definition XrdSfsInterface.cc:130
XrdSysTrace
Definition XrdSysTrace.hh:49
XrdXrootdFileStats::pgUpdt
void pgUpdt(int wErrs, int wFixd, int wUnc)
Definition XrdXrootdFileStats.hh:81
XrdXrootdFile
Definition XrdXrootdFile.hh:101
XrdXrootdFile::pgwFob
XrdXrootdPgwFob * pgwFob
Definition XrdXrootdFile.hh:118
XrdXrootdFile::Stats
XrdXrootdFileStats Stats
Definition XrdXrootdFile.hh:122
XrdXrootdPgrwAio::aioSZ
static const int aioSZ
Definition XrdXrootdPgrwAio.hh:55
XrdXrootdPgrwAio::Read
void Read(long long offs, int dlen) override
Definition XrdXrootdPgrwAio.cc:363
XrdXrootdPgrwAio::Alloc
static XrdXrootdPgrwAio * Alloc(XrdXrootdProtocol *protP, XrdXrootdResponse &resp, XrdXrootdFile *fP, XrdXrootdPgwBadCS *bcsP=0)
Definition XrdXrootdPgrwAio.cc:87
XrdXrootdPgrwAio::Write
int Write(long long offs, int dlen) override
Definition XrdXrootdPgrwAio.cc:544
XrdXrootdPgwCtl
Definition XrdXrootdPgwCtl.hh:42
XrdXrootdPgwCtl::maxBSize
static const int maxBSize
Definition XrdXrootdPgwCtl.hh:46
XrdXrootdPgwFob::numOffs
int numOffs(int *errs=0, int *fixs=0)
Definition XrdXrootdPgwFob.hh:70
XrdXrootdProtocol::SI
static XrdXrootdStats * SI
Definition XrdXrootdProtocol.hh:490
XrdXrootdProtocol::VerifyStream
XrdXrootdProtocol * VerifyStream(int &rc, int pID, bool lok=true)
Definition XrdXrootdProtocol.cc:975
XrdXrootdProtocol::Stream
XrdXrootdProtocol * Stream[maxStreams]
Definition XrdXrootdProtocol.hh:603
XrdXrootdProtocol::IO
XrdXrootd::IOParms IO
Definition XrdXrootdProtocol.hh:587
XrdXrootdProtocol::as_maxpersrv
static int as_maxpersrv
Definition XrdXrootdProtocol.hh:224
XrdXrootdProtocol::XrdXrootdProtocol
XrdXrootdProtocol()
Definition XrdXrootdProtocol.cc:259
XrdXrootdProtocol::Request
ClientRequest Request
Definition XrdXrootdProtocol.hh:635
XrdXrootdProtocol::pgwCtl
XrdXrootdPgwCtl * pgwCtl
Definition XrdXrootdProtocol.hh:550
XrdXrootdProtocol::FTab
XrdXrootdFileTable * FTab
Definition XrdXrootdProtocol.hh:514
XrdXrootdProtocol::eDest
static XrdSysError & eDest
Definition XrdXrootdProtocol.hh:404
XrdXrootdProtocol::getData
int getData(gdCallBack *gdcbP, const char *dtype, char *buff, int blen)
XrdXrootdProtocol::Monitor
XrdXrootdMonitor::User Monitor
Definition XrdXrootdProtocol.hh:515
XrdXrootdProtocol::myStalls
int myStalls
Definition XrdXrootdProtocol.hh:507
XrdXrootdProtocol::maxBuffsz
static int maxBuffsz
Definition XrdXrootdProtocol.hh:484
XrdXrootdProtocol::Link
XrdLink * Link
Definition XrdXrootdProtocol.hh:512
XrdXrootdProtocol::as_maxstalls
static int as_maxstalls
Definition XrdXrootdProtocol.hh:229
XrdXrootdProtocol::PathID
short PathID
Definition XrdXrootdProtocol.hh:615
XrdXrootdProtocol::as_maxperlnk
static int as_maxperlnk
Definition XrdXrootdProtocol.hh:222
XrdXrootdProtocol::Response
XrdXrootdResponse Response
Definition XrdXrootdProtocol.hh:636
XrdXrootdProtocol::hcNow
int hcNow
Definition XrdXrootdProtocol.hh:594
XrdXrootdProtocol::argp
XrdBuffer * argp
Definition XrdXrootdProtocol.hh:513
XrdXrootdProtocol::maxStreams
static const int maxStreams
Definition XrdXrootdProtocol.hh:218
XrdXrootdProtocol::hcNext
int hcNext
Definition XrdXrootdProtocol.hh:593
XrdXrootdProtocol::numWrites
int numWrites
Definition XrdXrootdProtocol.hh:497
XrdXrootdProtocol::srvrAioOps
static RAtomic_int srvrAioOps
Definition XrdXrootdProtocol.hh:176
XrdXrootdProtocol::numReads
int numReads
Definition XrdXrootdProtocol.hh:491
XrdXrootdProtocol::linkAioReq
RAtomic_int linkAioReq
Definition XrdXrootdProtocol.hh:545
XrdProto::kXR_pgUnitSZ
static const int kXR_pgUnitSZ
Definition XProtocol.hh:496
XrdProto::kXR_pgPageSZ
static const int kXR_pgPageSZ
Definition XProtocol.hh:494
XrdProto::kXR_PartialResult
@ kXR_PartialResult
Definition XProtocol.hh:1251
XrdProto::kXR_FinalResult
@ kXR_FinalResult
Definition XProtocol.hh:1250
XrdProto::kXR_pgRetry
static const int kXR_pgRetry
Definition XProtocol.hh:503
XrdSys::getIovMax
int getIovMax()
Definition XrdSysPlatform.cc:77