XRootD
XrdPosixExtra.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d P o s i x E x t r a . c c */
4 /* */
5 /* */
6 /* (c) 2021 by the Board of Trustees of the Leland Stanford, Jr., University */
7 /* All Rights Reserved */
8 /* Produced by Andrew Hanushevsky for Stanford University under contract */
9 /* DE-AC02-76-SFO0515 with the Department of Energy */
10 /* */
11 /* This file is part of the XRootD software suite. */
12 /* */
13 /* XRootD is free software: you can redistribute it and/or modify it under */
14 /* the terms of the GNU Lesser General Public License as published by the */
15 /* Free Software Foundation, either version 3 of the License, or (at your */
16 /* option) any later version. */
17 /* */
18 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21 /* License for more details. */
22 /* */
23 /* You should have received a copy of the GNU Lesser General Public License */
24 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26 /* */
27 /* The copyright holder's institutional names and contributor's names may not */
28 /* be used to endorse or promote products derived from this software without */
29 /* specific prior written permission of the institution or contributor. */
30 /* Modified by Frank Winklmeier to add the full Posix file system definition. */
31 /******************************************************************************/
32 
33 #include <cerrno>
34 
35 #include "XrdCl/XrdClFileSystem.hh"
36 
37 #include "XrdOuc/XrdOucCache.hh"
38 #include "XrdOuc/XrdOucECMsg.hh"
40 
44 #include "XrdPosix/XrdPosixFile.hh"
45 
46 /******************************************************************************/
47 /* G l o b a l s */
48 /******************************************************************************/
49 
50 namespace XrdPosixGlobals
51 {
52 extern XrdOucCache *theCache;
53 extern thread_local XrdOucECMsg ecMsg;
54 }
55 
56 using namespace XrdPosixGlobals;
57 
58 /******************************************************************************/
59 /* F c t l */
60 /******************************************************************************/
61 
63  const std::string& args, std::string& resp)
64 {
65  XrdPosixFile *fp;
66 
67 // Make s
68 
69 // Execute the request (this handles simple cases)
70 //
71  switch(opc)
72  {case XrdOucCacheOp::Code::QFinfo:
73  if (!(fp = XrdPosixObject::File(fildes)))
74  {resp = "Invalid file descriptor.";
75  return -1;
76  }
77  break;
78  default:
79  resp = "File operation not supported.";
80  errno = ENOTSUP;
81  return -1;
82  }
83 
84 // Execute the operation which may first hit the cache if we have one.
85 //
86  return fp->XCio->Fcntl(XrdOucCacheOp::Code::QFinfo, args, resp);
87 }
88 
89 /******************************************************************************/
90 /* F S c t l */
91 /******************************************************************************/
92 
94  const std::string& args, std::string& resp,
95  bool viaCache, bool viaRedir)
96 {
98 
99 // Make sure we support the operation
100 //
101  switch(opc)
102  {case XrdOucCacheOp::Code::QFSinfo:
103  clOp = XrdCl::QueryCode::Code::FSInfo;
104  break;
105  default:
106  resp = "Filesystem operation not supported.";
107  errno = ENOTSUP;
108  return -1;
109  }
110 
111 // Use cache, if possible and allowed, to handle this operation
112 //
113  if (viaCache && XrdPosixGlobals::theCache)
114  return XrdPosixGlobals::theCache->Fcntl(opc, args, resp);
115 
116 // We need to execute this at the endpoint described by args (i.e. a URL)
117 //
118  XrdPosixAdmin admin(args.c_str(),XrdPosixGlobals::ecMsg);
119 
120 // Stat the file first to allow vectoring of the request to the right server
121 // but do so only if caller wishes to use a redirect as opposed to sending
122 // the request to the actual redirector.
123 //
124  if (viaRedir && !admin.Stat()) return -1;
125 
126 // Return the actual retult
127 
128  return admin.Query(clOp, resp);
129 }
130 
131 /******************************************************************************/
132 /* p g R e a d */
133 /******************************************************************************/
134 
135 ssize_t XrdPosixExtra::pgRead (int fildes, void* buffer,
136  off_t offset, size_t rdlen,
137  std::vector<uint32_t>& csvec,
138  uint64_t opts,
139  XrdPosixCallBackIO* cbp)
140 {
141  XrdPosixFile *fp;
142  long long offs, bytes;
143  uint64_t fOpts;
144  int iosz;
145 
146 // Find the file object
147 //
148  if (!(fp = XrdPosixObject::File(fildes)))
149  {if (!cbp) return -1;
150  cbp->Complete(-1);
151  return 0;
152  }
153 
154 // Make sure the size is not too large
155 //
156  if (rdlen > (size_t)0x7fffffff)
157  {fp->UnLock();
158  errno = EOVERFLOW;
159  if (!cbp) return -1;
160  cbp->Complete(-1);
161  return 0;
162  }
163 
164 // Get the parameters
165 //
166  iosz = static_cast<int>(rdlen);
167  offs = static_cast<long long>(offset);
168  csvec.clear();
169  fOpts= (opts & forceCS ? XrdOucCacheIO::forceCS : 0);
170 
171 // Issue the read in the sync case
172 //
173  if (!cbp)
174  {bytes = fp->XCio->pgRead((char *)buffer, offs, (int)iosz, csvec, fOpts);
175  if (bytes < 0)
176  {fp->ecMsg.SetErrno(-bytes);
177  fp->UnLock();
178  return -1;
179  }
180  fp->UnLock();
181  return (ssize_t)bytes;
182  }
183 
184 // Handle the read in the async case
185 //
186  cbp->theFile = fp;
187  fp->Ref(); fp->UnLock();
188 
189 // Issue the read
190 //
191  fp->XCio->pgRead(*cbp, (char *)buffer, offs, (int)iosz, csvec, fOpts);
192  return 0;
193 }
194 
195 /******************************************************************************/
196 /* p g W r i t e */
197 /******************************************************************************/
198 
199 ssize_t XrdPosixExtra::pgWrite(int fildes, void* buffer,
200  off_t offset, size_t wrlen,
201  std::vector<uint32_t>& csvec,
202  uint64_t opts,
203  XrdPosixCallBackIO* cbp)
204 {
205  XrdPosixFile *fp;
206  long long offs;
207  int iosz, bytes;
208 
209 // Find the file object
210 //
211  if (!(fp = XrdPosixObject::File(fildes)))
212  {if (!cbp) return -1;
213  cbp->Complete(-1);
214  return 0;
215  }
216 
217 // Make sure the size is not too large
218 //
219  if (wrlen > (size_t)0x7fffffff)
220  {fp->UnLock();
221  errno = EOVERFLOW;
222  if (!cbp) return -1;
223  cbp->Complete(-1);
224  return 0;
225  }
226 
227 // Check if we need to generate checksums or verify that we have the right num.
228 //
229  if (csvec.size() == 0)
230  XrdOucPgrwUtils::csCalc((const char *)buffer, offset, wrlen, csvec);
231  else if (XrdOucPgrwUtils::csNum(offset, wrlen) != (int)csvec.size())
232  {fp->UnLock();
233  errno = EINVAL;
234  if (!cbp) return -1;
235  cbp->Complete(-1);
236  return 0;
237  }
238 
239 // Get the parameters
240 //
241  iosz = static_cast<int>(wrlen);
242  offs = static_cast<long long>(offset);
243 
244 // Sync: Issue the write
245 //
246  if (!cbp)
247  {bytes = fp->XCio->pgWrite((char *)buffer, offs, (int)iosz, csvec);
248  if (bytes < 0)
249  {fp->ecMsg.SetErrno(-bytes);
250  fp->UnLock();
251  return -1;
252  }
253  fp->UpdtSize(offs + iosz);
254  fp->UnLock();
255  return (ssize_t)bytes;
256  }
257 
258 // Async: Prepare for writing
259 //
260  cbp->theFile = fp;
261  fp->Ref(); fp->UnLock();
262 
263 // Issue the write
264 //
265  fp->XCio->pgWrite(*cbp, (char *)buffer, offs, (int)iosz, csvec);
266  return 0;
267 }
268 
269 /******************************************************************************/
270 /* P r e R e a d */
271 /******************************************************************************/
272 
273 int XrdPosixExtra::PreRead(int fildes, off_t offs, int size)
274 {
275  XrdPosixFile *fp;
276 
277 // Find the file object
278 //
279  if (!(fp = XrdPosixObject::File(fildes))) return -1;
280 
281 // We need to implement this
282 //
283  return 0;
284 }
285 
287 {
288  XrdPosixFile *fp;
289 
290 // Find the file object
291 //
292  if (!(fp = XrdPosixObject::File(fildes))) return -1;
293 
294 // We need to implement this so for now we just pretend this worked
295 //
296  return 0;
297 }
std::vector< XrdOucRange > XrdOucRangeList
Definition: XrdOucRange.hh:57
struct myOpts opts
virtual int Fcntl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp)
Definition: XrdOucCache.hh:148
static const uint64_t forceCS
Definition: XrdOucCache.hh:215
virtual int pgRead(char *buff, long long offs, int rdlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0)
Definition: XrdOucCache.cc:39
virtual int pgWrite(char *buff, long long offs, int wrlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0)
Definition: XrdOucCache.cc:68
virtual int Fcntl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp)
Definition: XrdOucCache.hh:572
int SetErrno(int ecc, int ret=-1, const char *alt=0)
Definition: XrdOucECMsg.cc:152
static void csCalc(const char *data, off_t offs, size_t count, uint32_t *csval)
static int csNum(off_t offs, int count)
Compute the required size of a checksum vector based on offset & length.
bool Stat(mode_t *flags=0, time_t *mtime=0)
int Query(XrdCl::QueryCode::Code reqCode, void *buff, int bsz)
virtual void Complete(ssize_t Result)=0
static int PreRead(int fildes, off_t offs, int size)
static int FSctl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp, bool viaCache=false, bool viaRedir=false)
static ssize_t pgWrite(int fildes, void *buffer, off_t offset, size_t wrlen, std::vector< uint32_t > &csvec, uint64_t opts=0, XrdPosixCallBackIO *cbp=0)
static ssize_t pgRead(int fildes, void *buffer, off_t offset, size_t rdlen, std::vector< uint32_t > &csvec, uint64_t opts=0, XrdPosixCallBackIO *cbp=0)
static int Fctl(int fildes, XrdOucCacheOp::Code opc, const std::string &args, std::string &resp)
void UpdtSize(size_t newsz)
XrdOucCacheIO * XCio
Definition: XrdPosixFile.hh:65
XrdOucECMsg ecMsg
static XrdPosixFile * File(int fildes, bool glk=false)
thread_local XrdOucECMsg ecMsg
XrdOucCache * theCache
Code
XRootD query request codes.