XRootD
Loading...
Searching...
No Matches
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
36
37#include "XrdOuc/XrdOucCache.hh"
38#include "XrdOuc/XrdOucECMsg.hh"
40
45
46/******************************************************************************/
47/* G l o b a l s */
48/******************************************************************************/
49
50namespace XrdPosixGlobals
51{
52extern XrdOucCache *theCache;
53extern thread_local XrdOucECMsg ecMsg;
54}
55
56using 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)
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)
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
135ssize_t XrdPosixExtra::pgRead (int fildes, void* buffer,
136 off_t offset, size_t rdlen,
137 std::vector<uint32_t>& csvec,
138 uint64_t opts,
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
199ssize_t XrdPosixExtra::pgWrite(int fildes, void* buffer,
200 off_t offset, size_t wrlen,
201 std::vector<uint32_t>& csvec,
202 uint64_t opts,
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
273int 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
struct myOpts opts
virtual int Fcntl(XrdOucCacheOp::Code opc, const std::string &args, std::string &resp)
static const uint64_t forceCS
virtual int pgRead(char *buff, long long offs, int rdlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0)
virtual int pgWrite(char *buff, long long offs, int wrlen, std::vector< uint32_t > &csvec, uint64_t opts=0, int *csfix=0)
int SetErrno(int ecc, int ret=-1, const char *alt=0)
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 const uint64_t forceCS
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
XrdOucECMsg ecMsg
static XrdPosixFile * File(int fildes, bool glk=false)
XrdOucECMsg ecMsg
XrdOucCache * theCache
Code
XRootD query request codes.
@ FSInfo
Query op-dependant file information on FS path.