CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
XrdFile.cc
Go to the documentation of this file.
4 #include <vector>
5 
7  : m_client (0),
8  m_offset (0),
9  m_close (false)
10 {}
11 
12 XrdFile::XrdFile (const char *name,
13  int flags /* = IOFlags::OpenRead */,
14  int perms /* = 066 */)
15  : m_client (0),
16  m_offset (0),
17  m_close (false)
18 { open (name, flags, perms); }
19 
20 XrdFile::XrdFile (const std::string &name,
21  int flags /* = IOFlags::OpenRead */,
22  int perms /* = 066 */)
23  : m_client (0),
24  m_offset (0),
25  m_close (false)
26 { open (name.c_str (), flags, perms); }
27 
29 {
30  if (m_close)
31  edm::LogError("XrdFileError")
32  << "Destructor called on XROOTD file '" << m_name
33  << "' but the file is still open";
34 }
35 
37 void
38 XrdFile::create (const char *name,
39  bool exclusive /* = false */,
40  int perms /* = 066 */)
41 {
42  open (name,
44  | (exclusive ? IOFlags::OpenExclusive : 0)),
45  perms);
46 }
47 
48 void
49 XrdFile::create (const std::string &name,
50  bool exclusive /* = false */,
51  int perms /* = 066 */)
52 {
53  open (name.c_str (),
55  | (exclusive ? IOFlags::OpenExclusive : 0)),
56  perms);
57 }
58 
59 void
60 XrdFile::open (const std::string &name,
61  int flags /* = IOFlags::OpenRead */,
62  int perms /* = 066 */)
63 { open (name.c_str (), flags, perms); }
64 
65 void
66 XrdFile::open (const char *name,
67  int flags /* = IOFlags::OpenRead */,
68  int perms /* = 066 */)
69 {
70  m_name = name;
71 
72  // Actual open
73  if ((name == 0) || (*name == 0))
74  throw cms::Exception("XrdFile::open()")
75  << "Cannot open a file without a name";
76 
77  if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0)
78  throw cms::Exception("XrdFile::open()")
79  << "Must open file '" << name << "' at least for read or write";
80 
81  // If I am already open, close old file first
82  if (m_client && m_close)
83  close();
84  else
85  abort();
86 
87  // Translate our flags to system flags
88  int openflags = 0;
89 
90  if (flags & IOFlags::OpenWrite)
91  openflags |= kXR_open_updt;
92  else if (flags & IOFlags::OpenRead)
93  openflags |= kXR_open_read;
94 
95  if (flags & IOFlags::OpenAppend)
96  throw cms::Exception("XrdFile::open()")
97  << "Opening file '" << name << "' in append mode not supported";
98 
99  if (flags & IOFlags::OpenCreate)
100  {
101  if (! (flags & IOFlags::OpenExclusive))
102  openflags |= kXR_delete;
103  openflags |= kXR_new;
104  openflags |= kXR_mkpath;
105  }
106 
107  if ((flags & IOFlags::OpenTruncate) && (flags & IOFlags::OpenWrite))
108  openflags |= kXR_delete;
109 
110  m_client = new XrdClient(name);
111  if (! m_client->Open(perms, openflags)
112  || m_client->LastServerResp()->status != kXR_ok)
113  throw cms::Exception("XrdFile::open()")
114  << "XrdClient::Open(name='" << name
115  << "', flags=0x" << std::hex << openflags
116  << ", permissions=0" << std::oct << perms << std::dec
117  << ") => error '" << m_client->LastServerError()->errmsg
118  << "' (errno=" << m_client->LastServerError()->errnum << ")";
119 
120  if (! m_client->Stat(&m_stat))
121  throw cms::Exception("XrdFile::open()")
122  << "XrdClient::Stat(name='" << name
123  << ") => error '" << m_client->LastServerError()->errmsg
124  << "' (errno=" << m_client->LastServerError()->errnum << ")";
125 
126  m_offset = 0;
127  m_close = true;
128  edm::LogInfo("XrdFileInfo") << "Opened " << m_name;
129 }
130 
131 void
133 {
134  if (! m_client)
135  {
136  edm::LogError("XrdFileError")
137  << "XrdFile::close(name='" << m_name
138  << "') called but the file is not open";
139  m_close = false;
140  return;
141  }
142 
143  if (! m_client->Close())
144  edm::LogWarning("XrdFileWarning")
145  << "XrdFile::close(name='" << m_name
146  << "') failed with error '" << m_client->LastServerError()->errmsg
147  << "' (errno=" << m_client->LastServerError()->errnum << ")";
148  delete m_client;
149  m_client = 0;
150 
151  m_close = false;
152  m_offset = 0;
153  memset(&m_stat, 0, sizeof (m_stat));
154  edm::LogInfo("XrdFileInfo") << "Closed " << m_name;
155 }
156 
157 void
159 {
160  delete m_client;
161  m_client = 0;
162  m_close = false;
163  m_offset = 0;
164  memset(&m_stat, 0, sizeof (m_stat));
165 }
166 
168 IOSize
169 XrdFile::read (void *into, IOSize n)
170 {
171  if (n > 0x7fffffff)
172  throw cms::Exception("XrdFile::read()")
173  << "XrdFile::read(name='" << m_name << "', n=" << n
174  << ") too many bytes, limit is 0x7fffffff";
175 
176  int s = m_client->Read(into, m_offset, n);
177  if (s < 0)
178  throw cms::Exception("XrdFile::read()")
179  << "XrdClient::Read(name='" << m_name
180  << "', offset=" << m_offset << ", n=" << n
181  << ") failed with error '" << m_client->LastServerError()->errmsg
182  << "' (errno=" << m_client->LastServerError()->errnum << ")";
183  m_offset += s;
184  return s;
185 }
186 
187 IOSize
189 {
190  if (n > 0x7fffffff)
191  throw cms::Exception("XrdFile::read()")
192  << "XrdFile::read(name='" << m_name << "', n=" << n
193  << ") exceeds read size limit 0x7fffffff";
194 
195  int s = m_client->Read(into, pos, n);
196  if (s < 0)
197  throw cms::Exception("XrdFile::read()")
198  << "XrdClient::Read(name='" << m_name
199  << "', offset=" << m_offset << ", n=" << n
200  << ") failed with error '" << m_client->LastServerError()->errmsg
201  << "' (errno=" << m_client->LastServerError()->errnum << ")";
202  return s;
203 }
204 
205 IOSize
207 {
208  // Note that the XROOTD and our interfaces do not match.
209  // XROOTD expects readv() into a single monolithic buffer
210  // from multiple file locations, whereas we expect scatter
211  // gather buffers read from a single file location.
212  //
213  // We work around this mismatch for now by issuing a cache
214  // read on the background, and then individual reads.
216  std::vector<long long> offsets (n);
217  std::vector<int> lengths (n);
218  for (IOSize i = 0; i < n; ++i)
219  {
220  IOSize len = into[i].size();
221  if (len > 0x7fffffff)
222  throw cms::Exception("XrdFile::readv()")
223  << "XrdFile::readv(name='" << m_name << "')[" << i
224  << "].size=" << len << " exceeds read size limit 0x7fffffff";
225  offsets[i] = pos;
226  lengths[i] = len;
227  pos += len;
228  }
229 
230  // Prefetch into the cache (if any).
231  if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0)
232  throw cms::Exception("XrdFile::readv()")
233  << "XrdClient::ReadV(name='" << m_name
234  << "') failed with error '" << m_client->LastServerError()->errmsg
235  << "' (errno=" << m_client->LastServerError()->errnum << ")";
236 
237  // Issue actual reads.
238  IOSize total = 0;
239  for (IOSize i = 0; i < n; ++i)
240  {
241  int s = m_client->Read(into[i].data(), offsets[i], lengths[i]);
242  if (s < 0)
243  {
244  if (i > 0)
245  break;
246  throw cms::Exception("XrdFile::readv()")
247  << "XrdClient::Read(name='" << m_name
248  << "', offset=" << offsets[i] << ", n=" << lengths[i]
249  << ") failed with error '" << m_client->LastServerError()->errmsg
250  << "' (errno=" << m_client->LastServerError()->errnum << ")";
251  }
252  total += s;
253  m_offset += s;
254  }
255 
256  return total;
257 }
258 
259 IOSize
261 {
262  // See comments in readv() above.
263  std::vector<long long> offsets (n);
264  std::vector<int> lengths (n);
265  for (IOSize i = 0; i < n; ++i)
266  {
267  IOSize len = into[i].size();
268  if (len > 0x7fffffff)
269  throw cms::Exception("XrdFile::readv()")
270  << "XrdFile::readv(name='" << m_name << "')[" << i
271  << "].size=" << len << " exceeds read size limit 0x7fffffff";
272  offsets[i] = into[i].offset();
273  lengths[i] = len;
274  }
275 
276  // Prefetch into the cache (if any).
277  if (m_client->ReadV(0, &offsets[0], &lengths[0], n) < 0)
278  throw cms::Exception("XrdFile::readv()")
279  << "XrdClient::ReadV(name='" << m_name
280  << "') failed with error '" << m_client->LastServerError()->errmsg
281  << "' (errno=" << m_client->LastServerError()->errnum << ")";
282 
283  // Issue actual reads.
284  IOSize total = 0;
285  for (IOSize i = 0; i < n; ++i)
286  {
287  int s = m_client->Read(into[i].data(), offsets[i], lengths[i]);
288  if (s < 0)
289  {
290  if (i > 0)
291  break;
292  throw cms::Exception("XrdFile::readv()")
293  << "XrdClient::Read(name='" << m_name
294  << "', offset=" << offsets[i] << ", n=" << lengths[i]
295  << ") failed with error '" << m_client->LastServerError()->errmsg
296  << "' (errno=" << m_client->LastServerError()->errnum << ")";
297  }
298  total += s;
299  }
300 
301  return total;
302 }
303 
304 IOSize
305 XrdFile::write (const void *from, IOSize n)
306 {
307  if (n > 0x7fffffff)
308  throw cms::Exception("XrdFile::write()")
309  << "XrdFile::write(name='" << m_name << "', n=" << n
310  << ") too many bytes, limit is 0x7fffffff";
311 
312  ssize_t s = m_client->Write(from, m_offset, n);
313  if (s < 0)
314  throw cms::Exception("XrdFile::write()")
315  << "XrdFile::write(name='" << m_name << "', n=" << n
316  << ") failed with error '" << m_client->LastServerError()->errmsg
317  << "' (errno=" << m_client->LastServerError()->errnum << ")";
318 
319  m_offset += s;
320  if (m_offset > m_stat.size)
321  m_stat.size = m_offset;
322 
323  return s;
324 }
325 
326 IOSize
328 {
329  if (n > 0x7fffffff)
330  throw cms::Exception("XrdFile::write()")
331  << "XrdFile::write(name='" << m_name << "', n=" << n
332  << ") too many bytes, limit is 0x7fffffff";
333 
334  ssize_t s = m_client->Write(from, pos, n);
335  if (s < 0)
336  throw cms::Exception("XrdFile::write()")
337  << "XrdFile::write(name='" << m_name << "', n=" << n
338  << ") failed with error '" << m_client->LastServerError()->errmsg
339  << "' (errno=" << m_client->LastServerError()->errnum << ")";
340 
341  if (pos + s > m_stat.size)
342  m_stat.size = pos + s;
343 
344  return s;
345 }
346 
347 bool
349 {
350  XReqErrorType r = kOK;
351  for (IOSize i = 0; i < n && r == kOK; ++i)
352  r = m_client->Read_Async(what[i].offset(), what[i].size());
353  return r == kOK;
354 }
355 
359 IOOffset
361 {
362  if (! m_client)
363  throw cms::Exception("XrdFile::position()")
364  << "XrdFile::position() called on a closed file";
365 
366  switch (whence)
367  {
368  case SET:
369  m_offset = offset;
370  break;
371 
372  case CURRENT:
373  m_offset += offset;
374  break;
375 
376  case END:
377  m_offset = m_stat.size + offset;
378  break;
379 
380  default:
381  throw cms::Exception("XrdFile::position()")
382  << "XrdFile::position() called with incorrect 'whence' parameter";
383  }
384 
385  if (m_offset < 0)
386  m_offset = 0;
387  if (m_offset > m_stat.size)
388  m_stat.size = m_offset;
389 
390  return m_offset;
391 }
392 
393 void
395 {
396  throw cms::Exception("XrdFile::resize()")
397  << "XrdFile::resize(name='" << m_name << "') not implemented";
398 }
virtual void resize(IOOffset size)
Definition: XrdFile.cc:394
int i
Definition: DBlmapReader.cc:9
virtual void close(void)
Definition: XrdFile.cc:132
XrdClientStatInfo m_stat
Definition: XrdFile.h:53
virtual void create(const char *name, bool exclusive=false, int perms=0666)
Definition: XrdFile.cc:38
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
bool m_close
Definition: XrdFile.h:54
IOOffset m_offset
Definition: XrdFile.h:52
Relative
Definition: Storage.h:11
virtual bool prefetch(const IOPosBuffer *what, IOSize n)
Definition: XrdFile.cc:348
XrdFile(void)
Definition: XrdFile.cc:6
virtual IOOffset position(void) const
Definition: Storage.cc:95
virtual IOSize readv(IOBuffer *into, IOSize n)
Definition: XrdFile.cc:206
int read(void)
Definition: IOInput.cc:54
unsigned int offset(bool)
XrdClient * m_client
Definition: XrdFile.h:51
IOOffset offset(void) const
Definition: IOPosBuffer.h:50
IOSize size(void) const
Definition: IOBuffer.h:50
std::string m_name
Definition: XrdFile.h:55
static std::string from(" from ")
IOSize size(void) const
Definition: IOPosBuffer.h:60
~XrdFile(void)
Definition: XrdFile.cc:28
int64_t IOOffset
Definition: IOTypes.h:19
size_t IOSize
Definition: IOTypes.h:14
string s
Definition: asciidump.py:422
virtual void open(const char *name, int flags=IOFlags::OpenRead, int perms=0666)
Definition: XrdFile.cc:66
virtual IOSize write(const void *from, IOSize n)
Definition: XrdFile.cc:305
virtual void abort(void)
Definition: XrdFile.cc:158