XRootD
Loading...
Searching...
No Matches
XrdSsiFileSess Class Reference

#include <XrdSsiFileSess.hh>

Collaboration diagram for XrdSsiFileSess:

Public Member Functions

bool AttnInfo (XrdOucErrInfo &eInfo, const XrdSsiRespInfo *respP, unsigned int reqID)
int close (bool viaDel=false)
bool DeferFinalize (XrdSsiFileReq *req, uint64_t itemID)
void DeferredFinalizeDone (XrdSsiFileReq *req, uint64_t itemID)
XrdOucErrInfoerrInfo ()
int fctl (const int cmd, int alen, const char *args, const XrdSecEntity *client)
const char * FName ()
int open (const char *fileName, XrdOucEnv &theEnv, XrdSfsFileOpenMode openMode)
XrdSfsXferSize read (XrdSfsFileOffset fileOffset, char *buffer, XrdSfsXferSize buffer_size)
void Recycle ()
XrdSsiFileResourceResource ()
int SendData (XrdSfsDio *sfDio, XrdSfsFileOffset offset, XrdSfsXferSize size)
void setXio (XrdSfsXio *xP)
int truncate (XrdSfsFileOffset fileOffset)
XrdSfsXferSize write (XrdSfsFileOffset fileOffset, const char *buffer, XrdSfsXferSize buffer_size)

Static Public Member Functions

static XrdSsiFileSessAlloc (XrdOucErrInfo &einfo, const char *user)
static void SetAuthDNS ()

Detailed Description

Definition at line 46 of file XrdSsiFileSess.hh.

Member Function Documentation

◆ Alloc()

XrdSsiFileSess * XrdSsiFileSess::Alloc ( XrdOucErrInfo & einfo,
const char * user )
static

Definition at line 126 of file XrdSsiFileSess.cc.

127{
128 XrdSsiFileSess *fsP;
129
130// Get a lock
131//
132 arMutex.Lock();
133
134// Get either a reuseable object or a new one
135//
136 if ((fsP = freeList))
137 {freeNum--;
138 freeList = fsP->nextFree;
139 arMutex.UnLock();
140 fsP->Init(einfo, user, true);
141 } else {
142 freeNew++;
143 if (freeMax <= freeAbs && freeNew >= freeMax/2)
144 {freeMax += freeMax/2;
145 freeNew = 0;
146 }
147 arMutex.UnLock();
148 fsP = new XrdSsiFileSess(einfo, user);
149 }
150
151// Return the object
152//
153 return fsP;
154}

Referenced by XrdSsiFile::open().

Here is the caller graph for this function:

◆ AttnInfo()

bool XrdSsiFileSess::AttnInfo ( XrdOucErrInfo & eInfo,
const XrdSsiRespInfo * respP,
unsigned int reqID )

Definition at line 160 of file XrdSsiFileSess.cc.

163{
164 EPNAME("AttnInfo");
165 struct AttnResp {struct iovec ioV[4]; XrdSsiRRInfoAttn aHdr;};
166
167 AttnResp *attnResp;
168 char *mBuff;
169 int n, ioN = 2;
170 bool doFin;
171
172// If there is no data we can send back to the client in the attn response,
173// then simply reply with a short message to make the client come back.
174//
175 if (!respP->mdlen)
176 {if (respP->rType != XrdSsiRespInfo::isData
177 || respP->blen > XrdSsiResponder::MaxDirectXfr)
178 {eInfo.setErrInfo(0, "");
179 return false;
180 }
181 }
182
183// We will be constructing the response in the message buffer. This is
184// gauranteed to be big enough for our purposes so no need to check the size.
185//
186 mBuff = eInfo.getMsgBuff(n);
187
188// Initialize the response
189//
190 attnResp = (AttnResp *)mBuff;
191 memset(attnResp, 0, sizeof(AttnResp));
192 attnResp->aHdr.pfxLen = htons(sizeof(XrdSsiRRInfoAttn));
193
194// Fill out iovec to point to our header
195//
196//?attnResp->ioV[0].iov_len = sizeof(XrdSsiRRInfoAttn) + respP->mdlen;
197 attnResp->ioV[1].iov_base = mBuff+offsetof(struct AttnResp, aHdr);
198 attnResp->ioV[1].iov_len = sizeof(XrdSsiRRInfoAttn);
199
200// Fill out the iovec for the metadata if we have some
201//
202 if (respP->mdlen)
203 {attnResp->ioV[2].iov_base = (void *)respP->mdata;
204 attnResp->ioV[2].iov_len = respP->mdlen; ioN = 3;
205 attnResp->aHdr.mdLen = htonl(respP->mdlen);
207 if (QTRACE(Debug))
208 {char hexBuff[16],dotBuff[4];
209 DEBUG(reqID <<':' <<gigID <<' ' <<respP->mdlen <<" byte metadata (0x"
210 <<DUMPIT(respP->mdata,respP->mdlen) <<") sent.");
211 }
212 }
213
214// Check if we have actual data here as well and can send it along
215//
216 if (respP->rType == XrdSsiRespInfo::isData
217 && respP->blen+respP->mdlen <= XrdSsiResponder::MaxDirectXfr)
218 {if (respP->blen)
219 {attnResp->ioV[ioN].iov_base = (void *)respP->buff;
220 attnResp->ioV[ioN].iov_len = respP->blen; ioN++;
221 }
222 attnResp->aHdr.tag = XrdSsiRRInfoAttn::fullResp; doFin = true;
223 }
224 else {attnResp->aHdr.tag = XrdSsiRRInfoAttn::pendResp; doFin = false;}
225
226// If we sent the full response we must remove the request from the request
227// table as it will get finished off when the response is actually sent.
228//
229 if (doFin)
230 {XrdSsiRRTableItem<XrdSsiFileReq> rqstP;
231 if (!(rqstP = rTab.LookUp(reqID)))
232 {eInfo.setErrInfo(0, "");
233 return false;
234 }
235 attnFinCallBack.setReq(std::move(rqstP));
236 eInfo.setErrCB(&attnFinCallBack);
237 rTab.Del(reqID);
238 }
239
240// Setup to have metadata actually sent to the requestor
241//
242 eInfo.setErrCode(ioN);
243 return doFin;
244}
#define DEBUG(x)
#define EPNAME(x)
#define QTRACE(act)
bool Debug
#define DUMPIT(x, y)
void Bump(int &val)
static const int MaxDirectXfr
long long RspMDBytes
XrdSsiStats Stats
static const int fullResp
static const int pendResp
int mdlen
Metadata length.
const char * mdata
-> Metadata about response.

References DEBUG, Debug, DUMPIT, EPNAME, XrdSsiRRInfoAttn::fullResp, XrdSsiRespInfo::isData, XrdSsiResponder::MaxDirectXfr, XrdSsiRespInfo::mdata, XrdSsiRespInfo::mdlen, XrdSsiRRInfoAttn::pendResp, QTRACE, XrdSsiRespInfo::rType, and XrdSsi::Stats.

◆ close()

int XrdSsiFileSess::close ( bool viaDel = false)

Definition at line 250 of file XrdSsiFileSess.cc.

258{
259 const char *epname = "close";
260
261// Do some debugging
262//
263 DEBUG((gigID ? gigID : "???") <<" del=" <<viaDel);
264
265// Collect statistics if this is a delete which implies a lost connection
266//
267 if (viaDel)
268 {int rCnt = rTab.Num();
269 if (rCnt) Stats.Bump(Stats.ReqFinForce, rCnt);
270 }
271
272// Run through all outstanding requests and comlete them
273//
274 rTab.Reset();
275
276// Free any in-progress buffers
277//
278 if (inProg)
279 {if (oucBuff) {oucBuff->Recycle(); oucBuff = 0;}
280 inProg = false;
281 }
282
283// Clean up storage
284//
285 isOpen = false;
286 return SFS_OK;
287}
#define SFS_OK

References DEBUG, SFS_OK, and XrdSsi::Stats.

◆ DeferFinalize()

bool XrdSsiFileSess::DeferFinalize ( XrdSsiFileReq * req,
uint64_t itemID )
inline

Definition at line 56 of file XrdSsiFileSess.hh.

57 {return rTab.DeferFinalize(req,itemID);}

◆ DeferredFinalizeDone()

void XrdSsiFileSess::DeferredFinalizeDone ( XrdSsiFileReq * req,
uint64_t itemID )
inline

Definition at line 59 of file XrdSsiFileSess.hh.

60 {return rTab.DeferredFinalizeDone(req, itemID);}

◆ errInfo()

XrdOucErrInfo * XrdSsiFileSess::errInfo ( )
inline

Definition at line 62 of file XrdSsiFileSess.hh.

62{return eInfo;}

Referenced by open().

Here is the caller graph for this function:

◆ fctl()

int XrdSsiFileSess::fctl ( const int cmd,
int alen,
const char * args,
const XrdSecEntity * client )

Definition at line 293 of file XrdSsiFileSess.cc.

297{
298 static const char *epname = "fctl";
299 XrdSsiRRInfo *rInfo;
300 XrdSsiRRTableItem<XrdSsiFileReq> rqstP;
301 unsigned int reqID;
302
303// If this isn't the special query, then return an error
304//
305 if (cmd != SFS_FCTL_SPEC1)
306 return XrdSsiUtils::Emsg(epname, ENOTSUP, "fctl", gigID, *eInfo);
307
308// Caller wishes to find out if a request is ready and wait if it is not
309//
310 if (!args || alen < (int)sizeof(XrdSsiRRInfo))
311 return XrdSsiUtils::Emsg(epname, EINVAL, "fctl", gigID, *eInfo);
312
313// Grab the request identifier
314//
315 rInfo = (XrdSsiRRInfo *)args;
316 reqID = rInfo->Id();
317
318// Do some debugging
319//
320 DEBUG(reqID <<':' <<gigID <<" query resp status");
321
322// Find the request
323//
324 if (!(rqstP = rTab.LookUp(reqID)))
325 return XrdSsiUtils::Emsg(epname, ESRCH, "fctl", gigID, *eInfo);
326
327// Check if a response is waiting for the caller
328//
329 if (rqstP->WantResponse(*eInfo))
330 {DEBUG(reqID <<':' <<gigID <<" resp ready");
332 return SFS_DATAVEC;
333 }
334
335// Put this client into callback state
336//
337 DEBUG(reqID <<':' <<gigID <<" resp not ready");
338 fctlCallBack.setReq(std::move(rqstP));
339
340 eInfo->setErrCB(&fctlCallBack);
341 eInfo->setErrInfo(respWT, "");
343 return SFS_STARTED;
344}
#define SFS_DATAVEC
#define SFS_STARTED
#define SFS_FCTL_SPEC1
void Id(unsigned int id)
static int Emsg(const char *pfx, int ecode, const char *op, const char *path, XrdOucErrInfo &eDest)

References DEBUG, XrdSsiUtils::Emsg(), XrdSsiRRInfo::Id(), XrdSsi::respWT, SFS_DATAVEC, SFS_FCTL_SPEC1, SFS_STARTED, and XrdSsi::Stats.

Here is the call graph for this function:

◆ FName()

const char * XrdSsiFileSess::FName ( )
inline

Definition at line 71 of file XrdSsiFileSess.hh.

71{return gigID;}

◆ open()

int XrdSsiFileSess::open ( const char * fileName,
XrdOucEnv & theEnv,
XrdSfsFileOpenMode openMode )

Definition at line 403 of file XrdSsiFileSess.cc.

415{
416 static const char *epname = "open";
417 XrdSsiErrInfo errInfo;
418 const char *eText;
419 int eNum;
420
421// Verify that this object is not already associated with an open file
422//
423 if (isOpen)
424 return XrdSsiUtils::Emsg(epname, EADDRINUSE, "open session", path, *eInfo);
425
426// Make sure the open flag is correct (we now open this R/O so don't check)
427//
428// if (open_mode != SFS_O_RDWR)
429// return XrdSsiUtils::Emsg(epname, EPROTOTYPE, "open session", path, *eInfo);
430
431// Setup the file resource object
432//
433 fileResource.Init(path, theEnv, authDNS);
434
435// Notify the provider that we will be executing a request
436//
437 if (Service->Prepare(errInfo, fileResource))
438 {const char *usr = fileResource.rUser.c_str();
439 if (!(*usr)) gigID = strdup(path);
440 else {char gBuff[2048];
441 snprintf(gBuff, sizeof(gBuff), "%s:%s", usr, path);
442 gigID = strdup(gBuff);
443 }
444 DEBUG(gigID <<" prepared.");
445 isOpen = true;
446 return SFS_OK;
447 }
448
449// Get error information
450//
451 eText = errInfo.Get(eNum).c_str();
452 if (!eNum)
453 {eNum = ENOMSG; eText = "Provider returned invalid prepare response.";}
454
455// Decode the error
456//
457 switch(eNum)
458 {case EAGAIN:
459 if (!eText || !(*eText)) break;
460 eNum = errInfo.GetArg();
461 DEBUG(path <<" --> " <<eText <<':' <<eNum);
462 eInfo->setErrInfo(eNum, eText);
464 return SFS_REDIRECT;
465 break;
466 case EBUSY:
467 eNum = errInfo.GetArg();
468 if (!eText || !(*eText)) eText = "Provider is busy.";
469 DEBUG(path <<" dly " <<eNum <<' ' <<eText);
470 if (eNum <= 0) eNum = 1;
471 eInfo->setErrInfo(eNum, eText);
473 return eNum;
474 break;
475 default:
476 if (!eText || !(*eText)) eText = XrdSysE2T(eNum);
477 DEBUG(path <<" err " <<eNum <<' ' <<eText);
478 eInfo->setErrInfo(eNum, eText);
480 return SFS_ERROR;
481 break;
482 };
483
484// Something is quite wrong here
485//
486 Log.Emsg(epname, "Provider redirect returned no target host name!");
487 eInfo->setErrInfo(ENOMSG, "Server logic error");
489 return SFS_ERROR;
490}
#define SFS_ERROR
#define SFS_REDIRECT
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
XrdOucErrInfo * errInfo()
virtual bool Prepare(XrdSsiErrInfo &eInfo, const XrdSsiResource &rDesc)
Prepare for processing subsequent resource request.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSsiService * Service
XrdSysError Log

References DEBUG, XrdSsiUtils::Emsg(), errInfo(), XrdSsi::Log, XrdSsi::Service, SFS_ERROR, SFS_OK, SFS_REDIRECT, XrdSsi::Stats, and XrdSysE2T().

Here is the call graph for this function:

◆ read()

XrdSfsXferSize XrdSsiFileSess::read ( XrdSfsFileOffset fileOffset,
char * buffer,
XrdSfsXferSize buffer_size )

Definition at line 496 of file XrdSsiFileSess.cc.

510{
511 static const char *epname = "read";
512 XrdSsiRRInfo rInfo(offset);
513 XrdSsiRRTableItem<XrdSsiFileReq> rqstP;
514 XrdSfsXferSize retval;
515 unsigned int reqID = rInfo.Id();
516 bool noMore = false;
517
518// Find the request object. If not there we may have encountered an eof
519//
520 if (!(rqstP = rTab.LookUp(reqID)))
521 {if (eofVec.IsSet(reqID))
522 {eofVec.UnSet(reqID);
523 return 0;
524 }
525 return XrdSsiUtils::Emsg(epname, ESRCH, "read", gigID, *eInfo);
526 }
527
528// Simply effect the read via the request object
529//
530 retval = rqstP->Read(noMore, buff, blen);
531
532// See if we just completed this request
533//
534 if (noMore)
535 {rTab.DelFinalize(std::move(rqstP));
536 eofVec.Set(reqID);
537 }
538
539// All done
540//
541 return retval;
542}
int XrdSfsXferSize

References XrdSsiUtils::Emsg(), and XrdSsiRRInfo::Id().

Here is the call graph for this function:

◆ Recycle()

void XrdSsiFileSess::Recycle ( )

Definition at line 548 of file XrdSsiFileSess.cc.

549{
550
551// Do an immediate reset on ourselves to avoid getting too many locks
552//
553 Reset();
554
555// Get a lock
556//
557 arMutex.Lock();
558
559// Check if we should place this on the free list or simply delete it
560//
561 if (freeNum < freeMax)
562 {nextFree = freeList;
563 freeList = this;
564 freeNum++;
565 arMutex.UnLock();
566 } else {
567 arMutex.UnLock();
568 delete this;
569 }
570}

◆ Resource()

XrdSsiFileResource & XrdSsiFileSess::Resource ( )
inline

Definition at line 83 of file XrdSsiFileSess.hh.

83{return fileResource;}

◆ SendData()

int XrdSsiFileSess::SendData ( XrdSfsDio * sfDio,
XrdSfsFileOffset offset,
XrdSfsXferSize size )

Definition at line 594 of file XrdSsiFileSess.cc.

597{
598 static const char *epname = "SendData";
599 XrdSsiRRInfo rInfo(offset);
600 XrdSsiRRTableItem<XrdSsiFileReq> rqstP;
601 unsigned int reqID = rInfo.Id();
602 int rc;
603
604// Find the request object
605//
606 if (!(rqstP = rTab.LookUp(reqID)))
607 return XrdSsiUtils::Emsg(epname, ESRCH, "send", gigID, *eInfo);
608
609// Simply effect the send via the request object
610//
611 rc = rqstP->Send(sfDio, size);
612
613// Determine how this ended
614//
615 if (rc > 0) rc = SFS_OK;
616 else rTab.DelFinalize(std::move(rqstP));
617
618 return rc;
619}

References XrdSsiUtils::Emsg(), XrdSsiRRInfo::Id(), and SFS_OK.

Here is the call graph for this function:

◆ SetAuthDNS()

void XrdSsiFileSess::SetAuthDNS ( )
inlinestatic

Definition at line 89 of file XrdSsiFileSess.hh.

89{authDNS = true;}

◆ setXio()

void XrdSsiFileSess::setXio ( XrdSfsXio * xP)
inline

Definition at line 91 of file XrdSsiFileSess.hh.

91{xioP = xP;}

◆ truncate()

int XrdSsiFileSess::truncate ( XrdSfsFileOffset fileOffset)

Definition at line 625 of file XrdSsiFileSess.cc.

633{
634 static const char *epname = "trunc";
635 XrdSsiRRTableItem<XrdSsiFileReq> rqstP;
636 XrdSsiRRInfo rInfo(flen);
637 XrdSsiRRInfo::Opc reqXQ = rInfo.Cmd();
638 unsigned int reqID = rInfo.Id();
639
640// Find the request object. If not there we may have encountered an eof
641//
642 if (!(rqstP = rTab.LookUp(reqID)))
643 {if (eofVec.IsSet(reqID))
644 {eofVec.UnSet(reqID);
645 return 0;
646 }
647 return XrdSsiUtils::Emsg(epname, ESRCH, "cancel", gigID, *eInfo);
648 }
649
650// Process request (this can only be a cancel request)
651//
652 if (reqXQ != XrdSsiRRInfo::Can)
653 return XrdSsiUtils::Emsg(epname, ENOTSUP, "trunc", gigID, *eInfo);
654
655// Perform the cancellation
656//
657 DEBUG(reqID <<':' <<gigID <<" cancelled");
658 rTab.DelFinalize(std::move(rqstP));
659 return SFS_OK;
660}

References XrdSsiRRInfo::Can, XrdSsiRRInfo::Cmd(), DEBUG, XrdSsiUtils::Emsg(), XrdSsiRRInfo::Id(), and SFS_OK.

Here is the call graph for this function:

◆ write()

XrdSfsXferSize XrdSsiFileSess::write ( XrdSfsFileOffset fileOffset,
const char * buffer,
XrdSfsXferSize buffer_size )

Definition at line 666 of file XrdSsiFileSess.cc.

683{
684 static const char *epname = "write";
685 XrdSsiRRInfo rInfo(offset);
686 unsigned int reqID = rInfo.Id();
687 int reqPass;
688
689// Check if we are reading a request segment and handle that. This assumes that
690// writes to different requests cannot be interleaved (which they can't be).
691//
692 if (inProg) return writeAdd(buff, blen, reqID);
693
694// Make sure this request does not refer to an active request
695//
696 if (rTab.LookUp(reqID))
697 return XrdSsiUtils::Emsg(epname, EADDRINUSE, "write", gigID, *eInfo);
698
699// The offset contains the actual size of the request, make sure it's OK. Note
700// that it can be zero and by convention the blen must be one if so.
701//
702 reqPass = reqSize = rInfo.Size();
703 if (reqSize < blen)
704 {if (reqSize || blen != 1)
705 return XrdSsiUtils::Emsg(epname, EPROTO, "write", gigID, *eInfo);
706 reqSize = 1;
707 } else if (reqSize < 0 || reqSize > maxRSZ)
708 return XrdSsiUtils::Emsg(epname, EFBIG, "write", gigID, *eInfo);
709
710// Indicate we are in the progress of collecting the request arguments
711//
712 inProg = true;
713 eofVec.UnSet(reqID);
714
715// Do some debugging
716//
717 DEBUG(reqID <<':' <<gigID <<" rsz=" <<reqSize <<" wsz=" <<blen);
718
719// If the complete request is here then grab the buffer, transfer ownership to
720// the request object, and then activate it for processing.
721//
722 if (reqSize == blen && xioP)
723 {XrdSfsXioHandle bRef = xioP->Claim(buff, reqSize, minRSZ);
724 if (!bRef)
725 {if (errno) Log.Emsg(epname,"Xio.Claim() failed;",XrdSysE2T(errno));}
726 else {if (!NewRequest(reqID, 0, bRef, reqPass))
727 return XrdSsiUtils::Emsg(epname,ENOMEM,"write xio",gigID,*eInfo);
728 return blen;
729 }
730 }
731
732// The full request is not present, so get a buffer to piece it together
733//
734 if (!(oucBuff = BuffPool->Alloc(reqSize)))
735 return XrdSsiUtils::Emsg(epname, ENOMEM, "write alloc", gigID, *eInfo);
736
737// Setup to buffer this
738//
739 reqLeft = reqSize - blen;
740 memcpy(oucBuff->Data(), buff, blen);
741 if (!reqLeft)
742 {oucBuff->SetLen(reqSize);
743
744 if (!NewRequest(reqID, oucBuff, 0, reqPass))
745 return XrdSsiUtils::Emsg(epname, ENOMEM, "write sfs", gigID, *eInfo);
746 oucBuff = 0;
747 } else oucBuff->SetLen(blen, blen);
748 return blen;
749}
class XrdBuffer * XrdSfsXioHandle
Definition XrdSfsXio.hh:46
XrdOucBuffer * Alloc(int sz)
XrdOucBuffPool * BuffPool

References XrdSsi::BuffPool, DEBUG, XrdSsiUtils::Emsg(), XrdSsiRRInfo::Id(), XrdSsi::Log, XrdSsi::maxRSZ, XrdSsi::minRSZ, XrdSsiRRInfo::Size(), and XrdSysE2T().

Here is the call graph for this function:

The documentation for this class was generated from the following files: