XRootD
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 
44 #include "XrdPosix/XrdPosixFile.hh"
50 
51 #include "XrdSys/XrdSysError.hh"
52 #include "XrdSys/XrdSysPageSize.hh"
53 #include "XrdSys/XrdSysTimer.hh"
54 
55 /******************************************************************************/
56 /* S t a t i c M e m b e r s */
57 /******************************************************************************/
58 
59 namespace XrdPosixGlobals
60 {
61 extern XrdOucCache *theCache;
65 extern int ddInterval;
66 extern int ddMaxTries;
67 extern bool autoPGRD;
68 };
69 
70 namespace
71 {
72 XrdPosixFile *InitDDL()
73 {
74 pthread_t tid;
75 XrdSysThread::Run(&tid, XrdPosixFile::DelayedDestroy, 0, 0, "PosixFileDestroy");
76 return (XrdPosixFile *)0;
77 }
78 
79 std::string dsProperty("DataServer");
80 };
81 
86 
87 char *XrdPosixFile::sfSFX = 0;
88 short XrdPosixFile::sfSLN = 0;
89 bool XrdPosixFile::ddPosted = false;
90 int XrdPosixFile::ddNum = 0;
91 
92 /******************************************************************************/
93 /* L o c a l C l a s s e s */
94 /******************************************************************************/
95 
96 namespace
97 {
98 class pgioCB : public XrdOucCacheIOCB
99 {
100 public:
101 
102 void Done(int result)
103  {rc = result; pgSem.Post();}
104 
105 int Wait4PGIO() {pgSem.Wait(); return rc;}
106 
107  pgioCB(const char *who) : pgSem(0, who), rc(0) {}
108  ~pgioCB() {}
109 
110 private:
111 
112 XrdSysSemaphore pgSem;
113 int rc;
114 };
115 }
116 
117 /******************************************************************************/
118 /* C o n s t r u c t o r */
119 /******************************************************************************/
120 
121 XrdPosixFile::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;
132  if (!XrdPosixGlobals::theN2N || !XrdPosixGlobals::theCache) fPath = fOpen;
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 //
199 do{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)
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 //
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 
335 int XrdPosixFile::Fcntl(XrdOucCacheOp::Code opc, const std::string& args,
336  std::string& resp)
337 {
338  XrdCl::QueryCode::Code qCode;
339 
340 // Make sure we support the operation code
341 //
342  switch(opc)
343  {case XrdOucCacheOp::Code::QFinfo:
344  qCode = XrdCl::QueryCode::Code::FInfo;
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(
409  }
410 
411  return true;
412 }
413 
414 /******************************************************************************/
415 /* F s t a t */
416 /******************************************************************************/
417 
418 int 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 
477 const 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 
505 int 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 
559 int XrdPosixFile::pgWrite(char *buff,
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 
623 int 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 
647 void 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 
678 int 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 
711 void 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 
747 bool XrdPosixFile::Stat(XrdCl::XRootDStatus &Status, bool force)
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 {
775  myCtime = myMtime;
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 
826 int XrdPosixFile::Trunc(long long Offset)
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 
845 int 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 
860 void 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)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
std::string obfuscateAuth(const std::string &input)
#define DMSG(x, y)
#define DEBUGON
#define stat(a, b)
Definition: XrdPosix.hh:105
struct myOpts opts
Binary blob representation.
Definition: XrdClBuffer.hh:34
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
Definition: XrdClBuffer.hh:72
void Append(const char *buffer, uint32_t size)
Append data at the position pointed to by the append cursor.
Definition: XrdClBuffer.hh:164
uint32_t GetSize() const
Get the size of the message.
Definition: XrdClBuffer.hh:132
XRootDStatus VectorRead(const ChunkList &chunks, void *buffer, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:552
XRootDStatus PgRead(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:304
XRootDStatus Sync(ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:473
bool IsOpen() const
Check if the file is open.
Definition: XrdClFile.cc:962
XRootDStatus Fcntl(const Buffer &arg, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:694
XRootDStatus Truncate(uint64_t size, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:499
bool GetProperty(const std::string &name, std::string &value) const
Definition: XrdClFile.cc:994
XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:265
XRootDStatus Close(ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:210
XRootDStatus Stat(bool force, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:236
XRootDStatus PgWrite(uint64_t offset, uint32_t size, const void *buffer, std::vector< uint32_t > &cksums, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:439
XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, time_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:345
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)
virtual void Done(int result)=0
static const uint64_t forceCS
Definition: XrdOucCache.hh:215
virtual long long FSize()=0
struct XrdOucCacheStats::CacheStats X
void Count(long long &Dest)
void Set(XrdOucCacheStats &S)
static const int optRW
File is read/write (o/w read/only)
Definition: XrdOucCache.hh:555
virtual XrdOucCacheIO * Attach(XrdOucCacheIO *ioP, int opts=0)=0
XrdOucCacheStats Statistics
Definition: XrdOucCache.hh:740
static const int optFIS
File is structured (e.g. root file)
Definition: XrdOucCache.hh:554
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
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
XrdPosixPrepIO * PrepIO
Definition: XrdPosixFile.hh:66
int Read(char *Buff, long long Offs, int Len) override
static bool ddPosted
int Fstat(struct stat &buf) override
static int ddNum
const char * Origin()
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
Definition: XrdPosixFile.hh:67
XrdOucCacheIO * XCio
Definition: XrdPosixFile.hh:65
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)
Definition: XrdPosixMap.cc:62
static int Result(const XrdCl::XRootDStatus &Status, XrdOucECMsg &ecMsg, bool retneg1=false)
Definition: XrdPosixMap.cc:195
XrdOucECMsg ecMsg
void Count(long long &Dest)
static const char * P2L(const char *who, const char *inP, char *&relP, bool ponly=false)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void Snooze(int seconds)
Definition: XrdSysTimer.cc:168
std::vector< ChunkInfo > ChunkList
List of chunks.
XrdSysError Say
int Opts
Definition: XrdMpxStats.cc:58
XrdPosixStats Stats
Definition: XrdPosixFile.cc:64
XrdSysError * eDest
Definition: XrdPosixFile.cc:63
XrdOucCache * theCache
XrdOucName2Name * theN2N
Definition: XrdPosixFile.cc:62
Describe a data chunk for vector read.
Code
XRootD query request codes.
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:124
std::string ToString() const
Create a string representation.
Definition: XrdClStatus.cc:97