XRootD
Loading...
Searching...
No Matches
XrdSsiFileSess.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S s i F i l e S e s s . c c */
4/* */
5/* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <fcntl.h>
31#include <stddef.h>
32#include <cstdio>
33#include <cstring>
34#include <arpa/inet.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <sys/uio.h>
38
40
42#include "XrdOuc/XrdOucEnv.hh"
44#include "XrdOuc/XrdOucPList.hh"
45
47
48#include "XrdSfs/XrdSfsAio.hh"
49
55#include "XrdSsi/XrdSsiSfs.hh"
56#include "XrdSsi/XrdSsiStats.hh"
58#include "XrdSsi/XrdSsiTrace.hh"
59#include "XrdSsi/XrdSsiUtils.hh"
60
61#include "XrdSys/XrdSysE2T.hh"
62#include "XrdSys/XrdSysError.hh"
63
64/******************************************************************************/
65/* G l o b a l s */
66/******************************************************************************/
67
68namespace XrdSsi
69{
73extern XrdSsiStats Stats;
74extern XrdSysError Log;
75extern int respWT;
76extern int minRSZ;
77extern int maxRSZ;
78}
79
80using namespace XrdSsi;
81
82/******************************************************************************/
83/* L o c a l M a c r o s */
84/******************************************************************************/
85
86#define DUMPIT(x,y) XrdSsiUtils::b2x(x,y,hexBuff,sizeof(hexBuff),dotBuff)<<dotBuff
87
88/******************************************************************************/
89/* L o c a l C l a s s e s */
90/******************************************************************************/
91
92namespace
93{
94class nullCallBack : public XrdOucEICB
95{
96public:
97
98void Done(int &Result, XrdOucErrInfo *eInfo, const char *Path=0) {}
99
100int Same(unsigned long long arg1, unsigned long long arg2) {return 0;}
101
102 nullCallBack() {}
103virtual ~nullCallBack() {}
104};
105
106nullCallBack nullCB;
107};
108
109/******************************************************************************/
110/* S t a t i c M e m b e r s */
111/******************************************************************************/
112
113XrdSysMutex XrdSsiFileSess::arMutex;
114XrdSsiFileSess *XrdSsiFileSess::freeList = 0;
115int XrdSsiFileSess::freeNum = 0;
116int XrdSsiFileSess::freeNew = 0;
117int XrdSsiFileSess::freeMax = 100;
118int XrdSsiFileSess::freeAbs = 200;
119
120bool XrdSsiFileSess::authDNS = false;
121
122/******************************************************************************/
123/* A l l o c */
124/******************************************************************************/
125
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}
155
156/******************************************************************************/
157/* A t t n I n f o */
158/******************************************************************************/
159
161 unsigned int reqID)
162// Called with the request mutex locked!
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) rTab.Del(reqID, false);
230
231// Setup to have metadata actually sent to the requestor
232//
233 eInfo.setErrCode(ioN);
234 return doFin;
235}
236
237/******************************************************************************/
238/* c l o s e */
239/******************************************************************************/
240
241int XrdSsiFileSess::close(bool viaDel)
242/*
243 Function: Close the file object.
244
245 Input: None
246
247 Output: Always returns SFS_OK
248*/
249{
250 const char *epname = "close";
251
252// Do some debugging
253//
254 DEBUG((gigID ? gigID : "???") <<" del=" <<viaDel);
255
256// Collect statistics if this is a delete which implies a lost connection
257//
258 if (viaDel)
259 {int rCnt = rTab.Num();
260 if (rCnt) Stats.Bump(Stats.ReqFinForce, rCnt);
261 }
262
263// Run through all outstanding requests and comlete them
264//
265 rTab.Reset();
266
267// Free any in-progress buffers
268//
269 if (inProg)
270 {if (oucBuff) {oucBuff->Recycle(); oucBuff = 0;}
271 inProg = false;
272 }
273
274// Clean up storage
275//
276 isOpen = false;
277 return SFS_OK;
278}
279
280/******************************************************************************/
281/* f c t l */
282/******************************************************************************/
283
284int XrdSsiFileSess::fctl(const int cmd,
285 int alen,
286 const char *args,
287 const XrdSecEntity *client)
288{
289 static const char *epname = "fctl";
290 XrdSsiRRInfo *rInfo;
291 XrdSsiFileReq *rqstP;
292 unsigned int reqID;
293
294// If this isn't the special query, then return an error
295//
296 if (cmd != SFS_FCTL_SPEC1)
297 return XrdSsiUtils::Emsg(epname, ENOTSUP, "fctl", gigID, *eInfo);
298
299// Caller wishes to find out if a request is ready and wait if it is not
300//
301 if (!args || alen < (int)sizeof(XrdSsiRRInfo))
302 return XrdSsiUtils::Emsg(epname, EINVAL, "fctl", gigID, *eInfo);
303
304// Grab the request identifier
305//
306 rInfo = (XrdSsiRRInfo *)args;
307 reqID = rInfo->Id();
308
309// Do some debugging
310//
311 DEBUG(reqID <<':' <<gigID <<" query resp status");
312
313// Find the request
314//
315 if (!(rqstP = rTab.LookUp(reqID)))
316 return XrdSsiUtils::Emsg(epname, ESRCH, "fctl", gigID, *eInfo);
317
318// Check if a response is waiting for the caller
319//
320 if (rqstP->WantResponse(*eInfo))
321 {DEBUG(reqID <<':' <<gigID <<" resp ready");
323 return SFS_DATAVEC;
324 }
325
326// Put this client into callback state
327//
328 DEBUG(reqID <<':' <<gigID <<" resp not ready");
329 eInfo->setErrCB((XrdOucEICB *)rqstP);
330 eInfo->setErrInfo(respWT, "");
332 return SFS_STARTED;
333}
334
335/******************************************************************************/
336/* Private: I n i t */
337/******************************************************************************/
338
339void XrdSsiFileSess::Init(XrdOucErrInfo &einfo, const char *user, bool forReuse)
340{
341 tident = (user ? strdup(user) : strdup(""));
342 eInfo = &einfo;
343 gigID = 0;
344 fsUser = 0;
345 xioP = 0;
346 oucBuff = 0;
347 reqSize = 0;
348 reqLeft = 0;
349 isOpen = false;
350 inProg = false;
351 if (forReuse)
352 {eofVec.Reset();
353 rTab.Clear();
354 }
355}
356
357/******************************************************************************/
358/* Private: N e w R e q u e s t */
359/******************************************************************************/
360
361bool XrdSsiFileSess::NewRequest(unsigned int reqid,
362 XrdOucBuffer *oP,
364 int rSz)
365{
366 XrdSsiFileReq *reqP;
367
368// Allocate a new request object
369//
370 if (!(reqP=XrdSsiFileReq::Alloc(eInfo,&fileResource,this,gigID,tident,reqid)))
371 return false;
372
373// Add it to the table
374//
375 rTab.Add(reqP, reqid);
376
377// Activate the request
378//
379 inProg = false;
380 reqP->Activate(oP, bR, rSz);
381 return true;
382}
383
384/******************************************************************************/
385/* o p e n */
386/******************************************************************************/
387
388int XrdSsiFileSess::open(const char *path, // In
389 XrdOucEnv &theEnv, // In
390 XrdSfsFileOpenMode open_mode) // In
391/*
392 Function: Open the file `path' in the mode indicated by `open_mode'.
393
394 Input: path - The fully qualified name of the resource.
395 theEnv - Environmental information.
396 open_mode - It must contain only SFS_O_RDWR.
397
398 Output: Returns SFS_OK upon success, otherwise SFS_ERROR is returned.
399*/
400{
401 static const char *epname = "open";
403 const char *eText;
404 int eNum;
405
406// Verify that this object is not already associated with an open file
407//
408 if (isOpen)
409 return XrdSsiUtils::Emsg(epname, EADDRINUSE, "open session", path, *eInfo);
410
411// Make sure the open flag is correct (we now open this R/O so don't check)
412//
413// if (open_mode != SFS_O_RDWR)
414// return XrdSsiUtils::Emsg(epname, EPROTOTYPE, "open session", path, *eInfo);
415
416// Setup the file resource object
417//
418 fileResource.Init(path, theEnv, authDNS);
419
420// Notify the provider that we will be executing a request
421//
422 if (Service->Prepare(errInfo, fileResource))
423 {const char *usr = fileResource.rUser.c_str();
424 if (!(*usr)) gigID = strdup(path);
425 else {char gBuff[2048];
426 snprintf(gBuff, sizeof(gBuff), "%s:%s", usr, path);
427 gigID = strdup(gBuff);
428 }
429 DEBUG(gigID <<" prepared.");
430 isOpen = true;
431 return SFS_OK;
432 }
433
434// Get error information
435//
436 eText = errInfo.Get(eNum).c_str();
437 if (!eNum)
438 {eNum = ENOMSG; eText = "Provider returned invalid prepare response.";}
439
440// Decode the error
441//
442 switch(eNum)
443 {case EAGAIN:
444 if (!eText || !(*eText)) break;
445 eNum = errInfo.GetArg();
446 DEBUG(path <<" --> " <<eText <<':' <<eNum);
447 eInfo->setErrInfo(eNum, eText);
449 return SFS_REDIRECT;
450 break;
451 case EBUSY:
452 eNum = errInfo.GetArg();
453 if (!eText || !(*eText)) eText = "Provider is busy.";
454 DEBUG(path <<" dly " <<eNum <<' ' <<eText);
455 if (eNum <= 0) eNum = 1;
456 eInfo->setErrInfo(eNum, eText);
458 return eNum;
459 break;
460 default:
461 if (!eText || !(*eText)) eText = XrdSysE2T(eNum);
462 DEBUG(path <<" err " <<eNum <<' ' <<eText);
463 eInfo->setErrInfo(eNum, eText);
465 return SFS_ERROR;
466 break;
467 };
468
469// Something is quite wrong here
470//
471 Log.Emsg(epname, "Provider redirect returned no target host name!");
472 eInfo->setErrInfo(ENOMSG, "Server logic error");
474 return SFS_ERROR;
475}
476
477/******************************************************************************/
478/* r e a d */
479/******************************************************************************/
480
482 char *buff, // Out
483 XrdSfsXferSize blen) // In
484/*
485 Function: Read `blen' bytes at `offset' into 'buff' and return the actual
486 number of bytes read.
487
488 Input: offset - Contains request information.
489 buff - Address of the buffer in which to place the data.
490 blen - The size of the buffer. This is the maximum number
491 of bytes that will be returned.
492
493 Output: Returns the number of bytes read upon success and SFS_ERROR o/w.
494*/
495{
496 static const char *epname = "read";
497 XrdSsiRRInfo rInfo(offset);
498 XrdSsiFileReq *rqstP;
499 XrdSfsXferSize retval;
500 unsigned int reqID = rInfo.Id();
501 bool noMore = false;
502
503// Find the request object. If not there we may have encountered an eof
504//
505 if (!(rqstP = rTab.LookUp(reqID)))
506 {if (eofVec.IsSet(reqID))
507 {eofVec.UnSet(reqID);
508 return 0;
509 }
510 return XrdSsiUtils::Emsg(epname, ESRCH, "read", gigID, *eInfo);
511 }
512
513// Simply effect the read via the request object
514//
515 retval = rqstP->Read(noMore, buff, blen);
516
517// See if we just completed this request
518//
519 if (noMore)
520 {rqstP->Finalize();
521 rTab.Del(reqID);
522 eofVec.Set(reqID);
523 }
524
525// All done
526//
527 return retval;
528}
529
530/******************************************************************************/
531/* R e c y c l e */
532/******************************************************************************/
533
535{
536
537// Do an immediate reset on ourselves to avoid getting too many locks
538//
539 Reset();
540
541// Get a lock
542//
543 arMutex.Lock();
544
545// Check if we should place this on the free list or simply delete it
546//
547 if (freeNum < freeMax)
548 {nextFree = freeList;
549 freeList = this;
550 freeNum++;
551 arMutex.UnLock();
552 } else {
553 arMutex.UnLock();
554 delete this;
555 }
556}
557
558/******************************************************************************/
559/* Private: R e s e t */
560/******************************************************************************/
561
562void XrdSsiFileSess::Reset()
563{
564
565// Close this session
566//
567 if (isOpen) close(true);
568
569// Release other buffers
570//
571 if (tident) free(tident);
572 if (fsUser) free(fsUser);
573 if (gigID) free(gigID);
574}
575
576/******************************************************************************/
577/* S e n d D a t a */
578/******************************************************************************/
579
581 XrdSfsFileOffset offset,
582 XrdSfsXferSize size)
583{
584 static const char *epname = "SendData";
585 XrdSsiRRInfo rInfo(offset);
586 XrdSsiFileReq *rqstP;
587 unsigned int reqID = rInfo.Id();
588 int rc;
589
590// Find the request object
591//
592 if (!(rqstP = rTab.LookUp(reqID)))
593 return XrdSsiUtils::Emsg(epname, ESRCH, "send", gigID, *eInfo);
594
595// Simply effect the send via the request object
596//
597 rc = rqstP->Send(sfDio, size);
598
599// Determine how this ended
600//
601 if (rc > 0) rc = SFS_OK;
602 else {rqstP->Finalize();
603 rTab.Del(reqID);
604 }
605 return rc;
606}
607
608/******************************************************************************/
609/* t r u n c a t e */
610/******************************************************************************/
611
613/*
614 Function: Set the length of the file object to 'flen' bytes.
615
616 Input: flen - The new size of the file.
617
618 Output: Returns SFS_ERROR a this function is not supported.
619*/
620{
621 static const char *epname = "trunc";
622 XrdSsiFileReq *rqstP;
623 XrdSsiRRInfo rInfo(flen);
624 XrdSsiRRInfo::Opc reqXQ = rInfo.Cmd();
625 unsigned int reqID = rInfo.Id();
626
627// Find the request object. If not there we may have encountered an eof
628//
629 if (!(rqstP = rTab.LookUp(reqID)))
630 {if (eofVec.IsSet(reqID))
631 {eofVec.UnSet(reqID);
632 return 0;
633 }
634 return XrdSsiUtils::Emsg(epname, ESRCH, "cancel", gigID, *eInfo);
635 }
636
637// Process request (this can only be a cancel request)
638//
639 if (reqXQ != XrdSsiRRInfo::Can)
640 return XrdSsiUtils::Emsg(epname, ENOTSUP, "trunc", gigID, *eInfo);
641
642// Perform the cancellation
643//
644 DEBUG(reqID <<':' <<gigID <<" cancelled");
645 rqstP->Finalize();
646 rTab.Del(reqID);
647 return SFS_OK;
648}
649
650/******************************************************************************/
651/* w r i t e */
652/******************************************************************************/
653
655 const char *buff, // In
656 XrdSfsXferSize blen) // In
657/*
658 Function: Write `blen' bytes at `offset' from 'buff' and return the actual
659 number of bytes written.
660
661 Input: offset - The absolute byte offset at which to start the write.
662 buff - Address of the buffer from which to get the data.
663 blen - The size of the buffer. This is the maximum number
664 of bytes that will be written to 'fd'.
665
666 Output: Returns the number of bytes written upon success and SFS_ERROR o/w.
667
668 Notes: An error return may be delayed until the next write(), close(), or
669 sync() call.
670*/
671{
672 static const char *epname = "write";
673 XrdSsiRRInfo rInfo(offset);
674 unsigned int reqID = rInfo.Id();
675 int reqPass;
676
677// Check if we are reading a request segment and handle that. This assumes that
678// writes to different requests cannot be interleaved (which they can't be).
679//
680 if (inProg) return writeAdd(buff, blen, reqID);
681
682// Make sure this request does not refer to an active request
683//
684 if (rTab.LookUp(reqID))
685 return XrdSsiUtils::Emsg(epname, EADDRINUSE, "write", gigID, *eInfo);
686
687// The offset contains the actual size of the request, make sure it's OK. Note
688// that it can be zero and by convention the blen must be one if so.
689//
690 reqPass = reqSize = rInfo.Size();
691 if (reqSize < blen)
692 {if (reqSize || blen != 1)
693 return XrdSsiUtils::Emsg(epname, EPROTO, "write", gigID, *eInfo);
694 reqSize = 1;
695 } else if (reqSize < 0 || reqSize > maxRSZ)
696 return XrdSsiUtils::Emsg(epname, EFBIG, "write", gigID, *eInfo);
697
698// Indicate we are in the progress of collecting the request arguments
699//
700 inProg = true;
701 eofVec.UnSet(reqID);
702
703// Do some debugging
704//
705 DEBUG(reqID <<':' <<gigID <<" rsz=" <<reqSize <<" wsz=" <<blen);
706
707// If the complete request is here then grab the buffer, transfer ownership to
708// the request object, and then activate it for processing.
709//
710 if (reqSize == blen && xioP)
711 {XrdSfsXioHandle bRef = xioP->Claim(buff, reqSize, minRSZ);
712 if (!bRef)
713 {if (errno) Log.Emsg(epname,"Xio.Claim() failed;",XrdSysE2T(errno));}
714 else {if (!NewRequest(reqID, 0, bRef, reqPass))
715 return XrdSsiUtils::Emsg(epname,ENOMEM,"write xio",gigID,*eInfo);
716 return blen;
717 }
718 }
719
720// The full request is not present, so get a buffer to piece it together
721//
722 if (!(oucBuff = BuffPool->Alloc(reqSize)))
723 return XrdSsiUtils::Emsg(epname, ENOMEM, "write alloc", gigID, *eInfo);
724
725// Setup to buffer this
726//
727 reqLeft = reqSize - blen;
728 memcpy(oucBuff->Data(), buff, blen);
729 if (!reqLeft)
730 {oucBuff->SetLen(reqSize);
731
732 if (!NewRequest(reqID, oucBuff, 0, reqPass))
733 return XrdSsiUtils::Emsg(epname, ENOMEM, "write sfs", gigID, *eInfo);
734 oucBuff = 0;
735 } else oucBuff->SetLen(blen, blen);
736 return blen;
737}
738
739/******************************************************************************/
740/* Private: w r i t e A d d */
741/******************************************************************************/
742
743XrdSfsXferSize XrdSsiFileSess::writeAdd(const char *buff, // In
744 XrdSfsXferSize blen, // In
745 unsigned int rid)
746/*
747 Function: Add `blen' bytes from 'buff' to request and return the actual
748 number of bytes added.
749
750 Input: buff - Address of the buffer from which to get the data.
751 blen - The size of the buffer. This is the maximum number
752 of bytes that will be added.
753
754 Output: Returns the number of bytes added upon success and SFS_ERROR o/w.
755
756 Notes: An error return may be delayed until the next write(), close(), or
757 sync() call.
758*/
759{
760 static const char *epname = "writeAdd";
761 int dlen;
762
763// Make sure the caller is not exceeding the size stated on the first write
764//
765 if (blen > reqLeft)
766 return XrdSsiUtils::Emsg(epname, EFBIG, "writeAdd", gigID, *eInfo);
767
768// Append the bytes
769//
770 memcpy(oucBuff->Data(dlen), buff, blen);
771
772// Adjust how much we have left
773//
774 reqLeft -= blen;
775 DEBUG(rid <<':' <<gigID <<" rsz=" <<reqLeft <<" wsz=" <<blen);
776
777// If we have a complete request. Transfer the buffer ownership to the request
778// object and activate processing.
779//
780 if (!reqLeft)
781 {oucBuff->SetLen(reqSize);
782 if (!NewRequest(rid, oucBuff, 0, reqSize))
783 return XrdSsiUtils::Emsg(epname, ENOMEM, "write", gigID, *eInfo);
784 oucBuff = 0;
785 } else {
786 dlen += blen;
787 oucBuff->SetLen(dlen, dlen);
788 }
789
790// Return how much we appended
791//
792 return blen;
793}
#define tident
#define DEBUG(x)
#define EPNAME(x)
#define QTRACE(act)
#define close(a)
Definition XrdPosix.hh:48
bool Debug
XrdOucString Path
#define SFS_DATAVEC
#define SFS_ERROR
#define SFS_REDIRECT
#define SFS_STARTED
int XrdSfsFileOpenMode
#define SFS_FCTL_SPEC1
#define SFS_OK
long long XrdSfsFileOffset
int XrdSfsXferSize
class XrdBuffer * XrdSfsXioHandle
Definition XrdSfsXio.hh:46
#define DUMPIT(x, y)
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
XrdOucBuffer * Alloc(int sz)
char * Data() const
void Recycle()
Recycle the buffer. The buffer may be reused in the future.
void SetLen(int dataL, int dataO=0)
virtual void Done(int &Result, XrdOucErrInfo *eInfo, const char *Path=0)=0
virtual int Same(unsigned long long arg1, unsigned long long arg2)=0
char * getMsgBuff(int &mblen)
void setErrCB(XrdOucEICB *cb, unsigned long long cbarg=0)
int setErrInfo(int code, const char *emsg)
int setErrCode(int code)
void Bump(int &val)
virtual XrdSfsXioHandle Claim(const char *curBuff, int datasz, int minasz)=0
void Set(uint32_t bval)
Definition XrdSsiBVec.hh:39
void Reset()
Definition XrdSsiBVec.hh:55
bool IsSet(uint32_t bval)
Definition XrdSsiBVec.hh:44
void UnSet(uint32_t bval)
Definition XrdSsiBVec.hh:50
bool WantResponse(XrdOucErrInfo &eInfo)
XrdSfsXferSize Read(bool &done, char *buffer, XrdSfsXferSize blen)
int Send(XrdSfsDio *sfDio, XrdSfsXferSize size)
static XrdSsiFileReq * Alloc(XrdOucErrInfo *eP, XrdSsiFileResource *rP, XrdSsiFileSess *fP, const char *sn, const char *id, unsigned int rnum)
void Activate(XrdOucBuffer *oP, XrdSfsXioHandle bR, int rSz)
void Init(const char *path, XrdOucEnv &envP, bool aDNS)
int fctl(const int cmd, int alen, const char *args, const XrdSecEntity *client)
int open(const char *fileName, XrdOucEnv &theEnv, XrdSfsFileOpenMode openMode)
int close(bool viaDel=false)
XrdSfsXferSize write(XrdSfsFileOffset fileOffset, const char *buffer, XrdSfsXferSize buffer_size)
bool AttnInfo(XrdOucErrInfo &eInfo, const XrdSsiRespInfo *respP, unsigned int reqID)
XrdSfsXferSize read(XrdSfsFileOffset fileOffset, char *buffer, XrdSfsXferSize buffer_size)
int truncate(XrdSfsFileOffset fileOffset)
XrdOucErrInfo * errInfo()
int SendData(XrdSfsDio *sfDio, XrdSfsFileOffset offset, XrdSfsXferSize size)
static XrdSsiFileSess * Alloc(XrdOucErrInfo &einfo, const char *user)
void Size(unsigned int sz)
void Cmd(Opc cmd)
void Id(unsigned int id)
T * LookUp(uint64_t itemID)
void Add(T *item, uint64_t itemID)
void Del(uint64_t itemID, bool finit=false)
std::string rUser
-> Name of the resource user (nil if anonymous)
static const int MaxDirectXfr
virtual bool Prepare(XrdSsiErrInfo &eInfo, const XrdSsiResource &rDesc)
Prepare for processing subsequent resource request.
long long RspMDBytes
static int Emsg(const char *pfx, int ecode, const char *op, const char *path, XrdOucErrInfo &eDest)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSsiStats Stats
XrdSsiProvider * Provider
XrdOucBuffPool * BuffPool
XrdSsiService * Service
XrdSysError Log
static const int fullResp
static const int pendResp
int mdlen
Metadata length.
const char * mdata
-> Metadata about response.