XRootD
Loading...
Searching...
No Matches
XrdPosixFile.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d P o s i x F i l e . c c */
4/* */
5/* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cerrno>
32#include <fcntl.h>
33#include <cstdio>
34#include <sys/time.h>
35#include <sys/param.h>
36#include <sys/resource.h>
37#include <sys/uio.h>
38#include <sys/stat.h>
39
50
51#include "XrdSys/XrdSysError.hh"
53#include "XrdSys/XrdSysTimer.hh"
54
55/******************************************************************************/
56/* S t a t i c M e m b e r s */
57/******************************************************************************/
58
59namespace XrdPosixGlobals
60{
61extern XrdOucCache *theCache;
65extern int ddInterval;
66extern int ddMaxTries;
67extern bool autoPGRD;
68};
69
70namespace
71{
72XrdPosixFile *InitDDL()
73{
74pthread_t tid;
75XrdSysThread::Run(&tid, XrdPosixFile::DelayedDestroy, 0, 0, "PosixFileDestroy");
76return (XrdPosixFile *)0;
77}
78
79std::string dsProperty("DataServer");
80};
81
86
87char *XrdPosixFile::sfSFX = 0;
88short XrdPosixFile::sfSLN = 0;
89bool XrdPosixFile::ddPosted = false;
91
92/******************************************************************************/
93/* L o c a l C l a s s e s */
94/******************************************************************************/
95
96namespace
97{
98class pgioCB : public XrdOucCacheIOCB
99{
100public:
101
102void Done(int result)
103 {rc = result; pgSem.Post();}
104
105int Wait4PGIO() {pgSem.Wait(); return rc;}
106
107 pgioCB(const char *who) : pgSem(0, who), rc(0) {}
108 ~pgioCB() {}
109
110private:
111
112XrdSysSemaphore pgSem;
113int rc;
114};
115}
116
117/******************************************************************************/
118/* C o n s t r u c t o r */
119/******************************************************************************/
120
121XrdPosixFile::XrdPosixFile(bool &aOK, const char *path, XrdPosixCallBack *cbP,
122 int Opts)
123 : XCio((XrdOucCacheIO *)this), PrepIO(0),
124 mySize(0), myAtime(0), myCtime(0), myMtime(0), myRdev(0),
125 myInode(0), myMode(0), theCB(cbP), fLoc(0), cOpt(0),
126 isStream(Opts & isStrm ? 1 : 0)
127{
128// Handle path generation. This is trickt as we may have two namespaces. One
129// for the origin and one for the cache.
130//
131 fOpen = strdup(path); aOK = true;
133 else if (!XrdPosixXrootPath::P2L("file",path,fPath)) aOK = false;
134 else if (!fPath) fPath = fOpen;
135
136// Check for structured file check
137//
138 if (sfSFX)
139 {int n = strlen(path);
140 if (n > sfSLN && !strcmp(sfSFX, path + n - sfSLN))
141 cOpt = XrdOucCache::optFIS;
142 }
143
144// Set cache update option
145//
146 if (Opts & isUpdt) cOpt |= XrdOucCache::optRW;
147}
148
149/******************************************************************************/
150/* D e s t r u c t o r */
151/******************************************************************************/
152
154{
155// Close the remote connection
156//
157 if (clFile.IsOpen())
159 XrdCl::XRootDStatus status = clFile.Close();
160 if (!status.IsOK())
162 }
163
164// Get rid of deferred open object
165//
166 if (PrepIO) delete PrepIO;
167
168// Free the path and location information
169//
170 if (fPath) free(fPath);
171 if (fOpen != fPath) free(fOpen);
172 if (fLoc) free(fLoc);
173}
174
175/******************************************************************************/
176/* D e l a y e d D e s t r o y */
177/******************************************************************************/
178
180{
181// Static function.
182// Called within a dedicated thread if there is a reference outstanding to the
183// file or the file cannot be closed in a clean fashion for some reason.
184//
185 EPNAME("DDestroy");
186
188 XrdCl::XRootDStatus Status;
189 std::string statusMsg;
190 const char *eTxt;
191 XrdPosixFile *fCurr, *fNext;
192 char buff[512], buff2[256];
193 static int ddNumLost = 0;
194 int ddCount, refNum;
195 bool doWait = false;
196
197// Wait for active I/O to complete
198//
199do{if (doWait)
201 doWait = false;
202 } else {
203 ddSem.Wait();
204 doWait = true;
205 continue;
206 }
207
208// Grab the delayed delete list
209//
210 ddMutex.Lock();
211 fNext=ddList; ddList=0; ddPosted=false; ddCount = ddNum; ddNum = 0;
212 ddMutex.UnLock();
213
214// Do some debugging
215//
216 DEBUG("DLY destroy of "<<ddCount<<" objects; "<<ddNumLost <<" already lost.");
217
218// Try to delete all the files on the list. If we exceeded the try limit,
219// remove the file from the list and let it sit forever.
220//
221 int nowLost = ddNumLost;
222 while((fCurr = fNext))
223 {fNext = fCurr->nextFile;
224 if (!(refNum = fCurr->Refs()))
225 {if (fCurr->Close(Status) || !fCurr->clFile.IsOpen())
226 {delete fCurr; ddCount--; continue;}
227 else {statusMsg = Status.ToString();
228 eTxt = statusMsg.c_str();
229 }
230 } else eTxt = 0;
231
232 if (fCurr->numTries > XrdPosixGlobals::ddMaxTries)
233 {ddNumLost++; ddCount--;
234 if (!eTxt)
235 {snprintf(buff2, sizeof(buff2), "in use %d", refNum);
236 eTxt = buff2;
237 }
238 if (Say)
239 {snprintf(buff, sizeof(buff), "%s timeout closing", eTxt);
240 Say->Emsg("DDestroy", buff, obfuscateAuth(fCurr->Origin()).c_str());
241 } else {
242 DMSG("DDestroy", eTxt <<" timeout closing " << obfuscateAuth(fCurr->Origin())
243 <<' ' <<ddNumLost <<" objects lost");
244 }
245 fCurr->nextFile = ddLost;
246 ddLost = fCurr;
247 } else {
248 fCurr->numTries++;
249 doWait = true;
250 ddMutex.Lock();
251 fCurr->nextFile = ddList; ddList = fCurr;
252 ddNum++; ddPosted = true;
253 ddMutex.UnLock();
254 }
255 }
256 if (Say && ddNumLost - nowLost >= 3)
257 {snprintf(buff, sizeof(buff), "%d objects deferred and %d lost.",
258 ddCount, ddNumLost);
259 Say->Emsg("DDestroy", buff);
260 } else {
261 DEBUG("DLY destroy end; "<<ddCount<<" objects deferred and "
262 <<ddNumLost <<" lost.");
263 }
264 if (XrdPosixGlobals::theCache && ddNumLost != nowLost)
265 XrdPosixGlobals::theCache->Statistics.Set(
266 (XrdPosixGlobals::theCache->Statistics.X.ClosedLost), ddNumLost);
267 } while(true);
268
269 return 0;
270}
271
272/******************************************************************************/
273
275{
276 EPNAME("DDestroyFP");
277 int ddCount;
278 bool doPost;
279
280// Count number of times this has happened (we should have a cache)
281//
283 XrdPosixGlobals::theCache->Statistics.Count(
284 (XrdPosixGlobals::theCache->Statistics.X.ClosDefers));
285
286// Place this file on the delayed delete list
287//
288 ddMutex.Lock();
289 fp->nextFile = ddList;
290 ddList = fp;
291 ddNum++; ddCount = ddNum;
292 if (ddPosted) doPost = false;
293 else {doPost = true;
294 ddPosted = true;
295 }
296 fp->numTries = 0;
297 ddMutex.UnLock();
298
299 if(DEBUGON) {
300 DEBUG("DLY destroy " << (doPost ? "post " : "has ") << ddCount
301 << " objects; added " << obfuscateAuth(fp->Origin()));
302 }
303 if (doPost) ddSem.Post();
304}
305
306/******************************************************************************/
307/* C l o s e */
308/******************************************************************************/
309
311{
312// If this is a deferred open, disable any future calls as we are ready to
313// shutdown this beast!
314//
315 if (PrepIO) PrepIO->Disable();
316
317// If we don't need to close the file, then return success. Otherwise, do the
318// actual close and return the status. We should have already been removed
319// from the file table at this point and should be unlocked.
320//
321 if (clFile.IsOpen())
323 Status = clFile.Close();
324 if (Status.IsOK()) return true;
326 return false;
327 }
328 return true;
329}
330
331/******************************************************************************/
332/* F c n t l */
333/******************************************************************************/
334
335int XrdPosixFile::Fcntl(XrdOucCacheOp::Code opc, const std::string& args,
336 std::string& resp)
337{
339
340// Make sure we support the operation code
341//
342 switch(opc)
345 break;
346 default: resp = "Unsupported operation code.";
347 return -ENOTSUP;
348 }
349
350// Convert argument to a client buffer
351//
352 uint32_t sz = args.size();
353 if (sz && args[0]) sz++;
354 XrdCl::Buffer theArgs(sz);
355 if (sz) theArgs.Append(args.c_str(), sz);
356
357// We only support the sync version of this, we may need to change that later
358//
359 XrdCl::Buffer* theResp = 0;
360 XrdCl::XRootDStatus Status;
361 Ref();
362 Status = clFile.Fcntl(qCode, theArgs, theResp);
363 unRef();
364
365// Check status, upon error we set errno and return -1
366//
367 if (!Status.IsOK())
368 {if (theResp) delete theResp;
369 return XrdPosixMap::Result(Status,ecMsg,true);
370 }
371
372// Construct the response.
373//
374 if (!theResp || !(sz = theResp->GetSize())) resp = "";
375 else resp.assign(theResp->GetBuffer(), sz);
376
377// All done
378//
379 if (theResp) delete theResp;
380 return 0;
381}
382
383/******************************************************************************/
384/* F i n a l i z e */
385/******************************************************************************/
386
388{
389 XrdOucCacheIO *ioP;
390
391// Indicate that we are at the start of the file
392//
393 currOffset = 0;
394
395// Complete initialization. If the stat() fails, the caller will unwind the
396// whole open process (ick). In the process get correct I/O vector.
397
398 if (!Status) ioP = (XrdOucCacheIO *)PrepIO;
399 else if (Stat(*Status)) ioP = (XrdOucCacheIO *)this;
400 else return false;
401
402// Setup the cache if it is to be used
403//
405 {XCio = XrdPosixGlobals::theCache->Attach(ioP, cOpt);
406 if (ioP == (XrdOucCacheIO *)PrepIO)
407 XrdPosixGlobals::theCache->Statistics.Add(
408 (XrdPosixGlobals::theCache->Statistics.X.OpenDefers), 1LL);
409 }
410
411 return true;
412}
413
414/******************************************************************************/
415/* F s t a t */
416/******************************************************************************/
417
418int XrdPosixFile::Fstat(struct stat &buf)
419{
420 long long theSize;
421
422// The size is treated differently here as it may come from a cache and may
423// actually trigger a file open if the open was deferred.
424//
425 theSize = XCio->FSize();
426 if (theSize < 0) return static_cast<int>(theSize);
427
428// Return what little we can
429//
431 buf.st_size = theSize;
432 buf.st_atime = myAtime;
433 buf.st_ctime = myCtime;
434 buf.st_mtime = myMtime;
435 buf.st_blocks = buf.st_size/512 + buf.st_size%512;
436 buf.st_ino = myInode;
437 buf.st_rdev = myRdev;
438 buf.st_mode = myMode;
439 return 0;
440}
441
442/******************************************************************************/
443/* H a n d l e R e s p o n s e */
444/******************************************************************************/
445
446// Note: This response handler is only used for async open requests!
447
449 XrdCl::AnyObject *response)
450{
451 XrdCl::XRootDStatus Status;
452 XrdPosixCallBack *xeqCB = theCB;
453 int rc = fdNum;
454
455// If no errors occurred, complete the open
456//
457 if (!(status->IsOK())) rc = XrdPosixMap::Result(*status,ecMsg,false);
458 else if (!Finalize(&Status)) rc = XrdPosixMap::Result( Status,ecMsg,false);
459
460// Issue XrdPosixCallBack callback with the correct result. Errors are indicated
461// by result set < 0 (typically -1) and errno set to the error number. In our
462// case, rc is -errno if an error occurred and that is what the callback gets.
463//
464 xeqCB->Complete(rc);
465
466// Finish up
467//
468 delete status;
469 delete response;
470 if (rc < 0) delete this;
471}
472
473/******************************************************************************/
474/* L o c a t i o n */
475/******************************************************************************/
476
477const char *XrdPosixFile::Location(bool refresh)
478{
479
480// If the file is not open, then we have no location
481//
482 if (!clFile.IsOpen()) return "";
483
484// If we have no location info, get it
485//
486 if (!fLoc || refresh)
487 {std::string currNode;
488 if (clFile.GetProperty(dsProperty, currNode))
489 {if (!fLoc || strcmp(fLoc, currNode.c_str()))
490 {if (fLoc) free(fLoc);
491 fLoc = strdup(currNode.c_str());
492 }
493 } else return "";
494 }
495
496// Return location information
497//
498 return fLoc;
499}
500
501/******************************************************************************/
502/* p g R e a d */
503/******************************************************************************/
504
505int XrdPosixFile::pgRead(char *buff,
506 long long offs,
507 int rlen,
508 std::vector<uint32_t> &csvec,
509 uint64_t opts,
510 int *csfix)
511{
512// Do a sync call using the async interface
513//
514 pgioCB pgrCB("Posix pgRead CB");
515 pgRead(pgrCB, buff, offs, rlen, csvec, opts, csfix);
516 return pgrCB.Wait4PGIO();
517}
518
519/******************************************************************************/
520
522 char *buff,
523 long long offs,
524 int rlen,
525 std::vector<uint32_t> &csvec,
526 uint64_t opts,
527 int *csfix)
528{
529 XrdCl::XRootDStatus Status;
530 XrdPosixFileRH *rhP;
531
532// Allocate callback object. Note the response handler may do additional post
533// processing.
534//
535 rhP = XrdPosixFileRH::Alloc(&iocb, this, offs, rlen, XrdPosixFileRH::isReadP);
536
537// Set the destination checksum vector
538//
539 if (csfix) *csfix = 0;
540 rhP->setCSVec(&csvec, csfix, (opts & XrdOucCacheIO::forceCS) != 0);
541
542// Issue read
543//
544 Ref();
545 Status = clFile.PgRead((uint64_t)offs,(uint32_t)rlen,buff,rhP);
546
547// Check status, upon error we pass -errno as the result.
548//
549 if (!Status.IsOK())
550 {rhP->Sched(XrdPosixMap::Result(Status, ecMsg, false));
551 unRef();
552 }
553}
554
555/******************************************************************************/
556/* p g W r i t e */
557/******************************************************************************/
558
560 long long offs,
561 int wlen,
562 std::vector<uint32_t> &csvec,
563 uint64_t opts,
564 int *csfix)
565{
566 XrdCl::XRootDStatus Status;
567
568// Preset checksum error count
569//
570 if (csfix) *csfix = 0;
571
572// Issue write and return appropriately. An error returns -1.
573//
574 Ref();
575 Status = clFile.PgWrite((uint64_t)offs, (uint32_t)wlen, buff, csvec);
576 unRef();
577
578 return (Status.IsOK() ? wlen : XrdPosixMap::Result(Status,ecMsg,true));
579}
580
581/******************************************************************************/
582
584 char *buff,
585 long long offs,
586 int wlen,
587 std::vector<uint32_t> &csvec,
588 uint64_t opts,
589 int *csfix)
590{
591 XrdCl::XRootDStatus Status;
592 XrdPosixFileRH *rhP;
593
594// Allocate callback object. Note that a pgWrite is essentially a normal write
595// as far as the response handler is concerned.
596//
597 rhP = XrdPosixFileRH::Alloc(&iocb,this,offs,wlen,XrdPosixFileRH::isWrite);
598
599// Set checksum info
600//
601 if (csfix)
602 {*csfix = 0;
603 rhP->setCSVec(0, csfix);
604 }
605
606// Issue write
607//
608 Ref();
609 Status = clFile.PgWrite((uint64_t)offs, (uint32_t)wlen, buff, csvec, rhP);
610
611// Check status, if error pass along -errno as the result.
612//
613 if (!Status.IsOK())
614 {rhP->Sched(XrdPosixMap::Result(Status,ecMsg,false));
615 unRef();
616 }
617}
618
619/******************************************************************************/
620/* R e a d */
621/******************************************************************************/
622
623int XrdPosixFile::Read (char *Buff, long long Offs, int Len)
624{
625 XrdCl::XRootDStatus Status;
626 uint32_t bytes;
627
628// Handle automatic pgread
629//
631 {pgioCB pgrCB("Posix pgRead CB");
632 Read(pgrCB, Buff, Offs, Len);
633 return pgrCB.Wait4PGIO();
634 }
635
636// Issue read and return appropriately.
637//
638 Ref();
639 Status = clFile.Read((uint64_t)Offs, (uint32_t)Len, Buff, bytes);
640 unRef();
641
642 return (Status.IsOK() ? (int)bytes : XrdPosixMap::Result(Status,ecMsg,false));
643}
644
645/******************************************************************************/
646
647void XrdPosixFile::Read (XrdOucCacheIOCB &iocb, char *buff, long long offs,
648 int rlen)
649{
650 XrdCl::XRootDStatus Status;
651 XrdPosixFileRH *rhP;
653 bool doPgRd = XrdPosixGlobals::autoPGRD;
654
655// Allocate correct callback object
656//
658 rhP = XrdPosixFileRH::Alloc(&iocb, this, offs, rlen, rhT);
659
660// Issue read
661//
662 Ref();
663 if (doPgRd) Status = clFile.PgRead((uint64_t)offs,(uint32_t)rlen,buff,rhP);
664 else Status = clFile.Read ((uint64_t)offs,(uint32_t)rlen,buff,rhP);
665
666// Check status. Upon error pass along -errno as the result.
667//
668 if (!Status.IsOK())
669 {rhP->Sched(XrdPosixMap::Result(Status, ecMsg, false));
670 unRef();
671 }
672}
673
674/******************************************************************************/
675/* R e a d V */
676/******************************************************************************/
677
678int XrdPosixFile::ReadV (const XrdOucIOVec *readV, int n)
679{
680 XrdCl::XRootDStatus Status;
681 XrdCl::ChunkList chunkVec;
682 XrdCl::VectorReadInfo *vrInfo = 0;
683 int nbytes = 0;
684
685// Copy in the vector (would be nice if we didn't need to do this)
686//
687 chunkVec.reserve(n);
688 for (int i = 0; i < n; i++)
689 {nbytes += readV[i].size;
690 chunkVec.push_back(XrdCl::ChunkInfo((uint64_t)readV[i].offset,
691 (uint32_t)readV[i].size,
692 (void *)readV[i].data
693 ));
694 }
695
696// Issue the readv. We immediately delete the vrInfo as w don't need it as a
697// readv will succeed only if actually read the number of bytes requested.
698//
699 Ref();
700 Status = clFile.VectorRead(chunkVec, (void *)0, vrInfo);
701 unRef();
702 delete vrInfo;
703
704// Return appropriate result (here we return -errno as the result)
705//
706 return (Status.IsOK() ? nbytes : XrdPosixMap::Result(Status, ecMsg, false));
707}
708
709/******************************************************************************/
710
711void XrdPosixFile::ReadV(XrdOucCacheIOCB &iocb, const XrdOucIOVec *readV, int n)
712{
713 XrdCl::XRootDStatus Status;
714 XrdCl::ChunkList chunkVec;
715 int nbytes = 0;
716
717// Copy in the vector (would be nice if we didn't need to do this)
718//
719 chunkVec.reserve(n);
720 for (int i = 0; i < n; i++)
721 {nbytes += readV[i].size;
722 chunkVec.push_back(XrdCl::ChunkInfo((uint64_t)readV[i].offset,
723 (uint32_t)readV[i].size,
724 (void *)readV[i].data
725 ));
726 }
727
728// Issue the readv.
729//
730 XrdPosixFileRH *rhp = XrdPosixFileRH::Alloc(&iocb, this, 0, nbytes,
732 Ref();
733 Status = clFile.VectorRead(chunkVec, (void *)0, rhp);
734
735// Return appropriate result
736//
737 if (!Status.IsOK())
738 {rhp->Sched(XrdPosixMap::Result(Status, ecMsg, false));
739 unRef();
740 }
741}
742
743/******************************************************************************/
744/* S t a t */
745/******************************************************************************/
746
748{
749 XrdCl::StatInfo *sInfo = 0;
750
751// Get the stat information from the open file
752//
753 Ref();
754 Status = clFile.Stat(force, sInfo);
755 if (!Status.IsOK())
756 {unRef();
757 delete sInfo;
758 return false;
759 }
760
761// Copy over the relevant fields, the stat structure must have been
762// properly pre-initialized.
763//
765 myMtime = static_cast<time_t>(sInfo->GetModTime());
766 mySize = static_cast<size_t>(sInfo->GetSize());
767 myInode = static_cast<ino_t>(strtoll(sInfo->GetId().c_str(), 0, 10));
768
769// If this is an extended stat then we can get some more info
770//
771 if (sInfo->ExtendedFormat())
772 {myCtime = static_cast<time_t>(sInfo->GetChangeTime());
773 myAtime = static_cast<time_t>(sInfo->GetAccessTime());
774 } else {
776 myAtime = time(0);
777 }
778
779// Delete our status information and return final result
780//
781 unRef();
782 delete sInfo;
783 return true;
784}
785
786/******************************************************************************/
787/* S y n c */
788/******************************************************************************/
789
791{
792 XrdCl::XRootDStatus Status;
793
794// Issue the Sync
795//
796 Ref();
797 Status = clFile.Sync();
798 unRef();
799
800// Return result
801//
802 return XrdPosixMap::Result(Status, ecMsg, false);
803}
804
805/******************************************************************************/
806
808{
809 XrdCl::XRootDStatus Status;
810 XrdPosixFileRH *rhp = XrdPosixFileRH::Alloc(&iocb, this, 0, 0,
812
813// Issue read
814//
815 Status = clFile.Sync(rhp);
816
817// Check status
818//
819 if (!Status.IsOK()) rhp->Sched(XrdPosixMap::Result(Status, ecMsg, false));
820}
821
822/******************************************************************************/
823/* T r u n c */
824/******************************************************************************/
825
827{
828 XrdCl::XRootDStatus Status;
829
830// Issue truncate request
831//
832 Ref();
833 Status = clFile.Truncate((uint64_t)Offset);
834 unRef();
835
836// Return results
837//
838 return XrdPosixMap::Result(Status,ecMsg,false);
839}
840
841/******************************************************************************/
842/* W r i t e */
843/******************************************************************************/
844
845int XrdPosixFile::Write(char *Buff, long long Offs, int Len)
846{
847 XrdCl::XRootDStatus Status;
848
849// Issue write and return appropriately
850//
851 Ref();
852 Status = clFile.Write((uint64_t)Offs, (uint32_t)Len, Buff);
853 unRef();
854
855 return (Status.IsOK() ? Len : XrdPosixMap::Result(Status,ecMsg,false));
856}
857
858/******************************************************************************/
859
860void XrdPosixFile::Write(XrdOucCacheIOCB &iocb, char *buff, long long offs,
861 int wlen)
862{
863 XrdCl::XRootDStatus Status;
864 XrdPosixFileRH *rhp = XrdPosixFileRH::Alloc(&iocb, this, offs, wlen,
866
867// Issue write
868//
869 Ref();
870 Status = clFile.Write((uint64_t)offs, (uint32_t)wlen, buff, rhp);
871
872// Check status
873//
874 if (!Status.IsOK())
875 {rhp->Sched(XrdPosixMap::Result(Status,ecMsg,false));
876 unRef();
877 }
878}
#define DEBUG(x)
#define EPNAME(x)
struct stat Stat
Definition XrdCks.cc:49
XrdOucPup XrdCmsParser::Pup & Say
std::string obfuscateAuth(const std::string &input)
#define DMSG(x, y)
#define DEBUGON
#define stat(a, b)
Definition XrdPosix.hh:101
struct myOpts opts
Binary blob representation.
void Append(const char *buffer, uint32_t size)
Append data at the position pointed to by the append cursor.
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
uint32_t GetSize() const
Get the size of the message.
bool IsOpen() const
Check if the file is open.
Definition XrdClFile.cc:962
Object stat info.
uint64_t GetChangeTime() const
Get change time (in seconds since epoch).
uint64_t GetSize() const
Get size (in bytes).
uint32_t GetFlags() const
Get flags.
bool ExtendedFormat() const
Has extended stat information.
const std::string & GetId() const
Get id.
uint64_t GetModTime() const
Get modification time (in seconds since epoch).
uint64_t GetAccessTime() const
Get change time (in seconds since epoch).
static const uint64_t forceCS
XrdOucCacheIO()
Construct and Destructor.
static const int optRW
File is read/write (o/w read/only).
static const int optFIS
File is structured (e.g. root file).
An abstract class to define a callback for Open() call.
virtual void Complete(int Result)=0
static void initStat(struct stat *buf)
void setCSVec(std::vector< uint32_t > *csv, int *csf, bool fcs=false)
void Sched(int result)
static XrdPosixFileRH * Alloc(XrdOucCacheIOCB *cbp, XrdPosixFile *fp, long long offs, int xResult, ioType typeIO)
XrdPosixFile(bool &aOK, const char *path, XrdPosixCallBack *cbP=0, int Opts=0)
static XrdSysSemaphore ddSem
static XrdSysMutex ddMutex
static char * sfSFX
const char * Origin()
int Write(char *Buff, long long Offs, int Len) override
int Fcntl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp) override
static const int isUpdt
int Sync() override
static XrdPosixFile * ddLost
static const int isStrm
XrdPosixPrepIO * PrepIO
int Read(char *Buff, long long Offs, int Len) override
static bool ddPosted
int Fstat(struct stat &buf) override
static int ddNum
int pgRead(char *buff, long long offs, int rdlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0) override
int Trunc(long long Offset) override
const char * Location(bool refresh=false) override
bool Stat(XrdCl::XRootDStatus &Status, bool force=false)
bool Close(XrdCl::XRootDStatus &Status)
static short sfSLN
XrdCl::File clFile
XrdOucCacheIO * XCio
static XrdPosixFile * ddList
long long Offset()
void HandleResponse(XrdCl::XRootDStatus *status, XrdCl::AnyObject *response) override
bool Finalize(XrdCl::XRootDStatus *Status)
int ReadV(const XrdOucIOVec *readV, int n) override
static void * DelayedDestroy(void *)
int pgWrite(char *buff, long long offs, int wrlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0) override
static mode_t Flags2Mode(dev_t *rdv, uint32_t flags)
static int Result(const XrdCl::XRootDStatus &Status, XrdOucECMsg &ecMsg, bool retneg1=false)
XrdOucECMsg ecMsg
static const char * P2L(const char *who, const char *inP, char *&relP, bool ponly=false)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Snooze(int seconds)
std::vector< ChunkInfo > ChunkList
List of chunks.
XrdPosixStats Stats
XrdSysError * eDest
XrdOucCache * theCache
XrdOucName2Name * theN2N
Describe a data chunk for vector read.
Code
XRootD query request codes.
@ FInfo
Query op-dependant file information on FD.
bool IsOK() const
We're fine.
std::string ToString() const
Create a string representation.