XRootD
XrdSfsNative.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d X f s N a t i v e . c c */
4 /* */
5 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <dirent.h>
33 #include <fcntl.h>
34 #include <memory.h>
35 #include <cstring>
36 #include <cstdio>
37 #include <cstdlib>
38 #include <sys/param.h>
39 #include <sys/stat.h>
40 
41 #include "XrdVersion.hh"
42 #include "XrdSys/XrdSysE2T.hh"
43 #include "XrdSys/XrdSysError.hh"
44 #include "XrdSys/XrdSysHeaders.hh"
45 #include "XrdSys/XrdSysLogger.hh"
46 #include "XrdSys/XrdSysPthread.hh"
48 #include "XrdSfs/XrdSfsAio.hh"
49 #include "XrdSfs/XrdSfsNative.hh"
50 
51 #ifdef AIX
52 #include <sys/mode.h>
53 #endif
54 
55 /******************************************************************************/
56 /* O S D i r e c t o r y H a n d l i n g I n t e r f a c e */
57 /******************************************************************************/
58 
59 #ifndef S_IAMB
60 #define S_IAMB 0x1FF
61 #endif
62 
63 /******************************************************************************/
64 /* G l o b a l O b j e c t s */
65 /******************************************************************************/
66 
67 XrdSysError *XrdSfsNative::eDest;
68 
69 /******************************************************************************/
70 /* U n i x F i l e S y s t e m I n t e r f a c e */
71 /******************************************************************************/
72 
73 class XrdSfsUFS
74 {
75 public:
76 
77 static int Chmod(const char *fn, mode_t mode) {return chmod(fn, mode);}
78 
79 static int Close(int fd) {return close(fd);}
80 
81 static int Mkdir(const char *fn, mode_t mode) {return mkdir(fn, mode);}
82 
83 static int Open(const char *path, int oflag, mode_t omode)
84  {return open(path, oflag, omode);}
85 
86 static int Rem(const char *fn) {return unlink(fn);}
87 
88 static int Remdir(const char *fn) {return rmdir(fn);}
89 
90 static int Rename(const char *ofn, const char *nfn) {return rename(ofn, nfn);}
91 
92 static int Statfd(int fd, struct stat *buf) {return fstat(fd, buf);}
93 
94 static int Statfn(const char *fn, struct stat *buf) {return stat(fn, buf);}
95 
96 static int Truncate(const char *fn, off_t flen) {return truncate(fn, flen);}
97 };
98 
99 /******************************************************************************/
100 /* C o n s t r u c t o r */
101 /******************************************************************************/
102 
104 {
105  eDest = ep;
106 }
107 
108 /******************************************************************************/
109 /* G e t F i l e S y s t e m */
110 /******************************************************************************/
111 
113  XrdSysLogger *lp)
114 {
115  static XrdSysError Eroute(lp, "XrdSfs");
116  static XrdSfsNative myFS(&Eroute);
117 
118  Eroute.Say("Copr. 2007 Stanford University/SLAC "
119  "sfs (Standard File System) v 9.0n");
120 
121  return &myFS;
122 }
123 
124 /******************************************************************************/
125 /* D i r e c t o r y O b j e c t I n t e r f a c e s */
126 /******************************************************************************/
127 /******************************************************************************/
128 /* o p e n */
129 /******************************************************************************/
130 
131 int XrdSfsNativeDirectory::open(const char *dir_path, // In
132  const XrdSecClientName *client, // In
133  const char *info) // In
134 /*
135  Function: Open the directory `path' and prepare for reading.
136 
137  Input: path - The fully qualified name of the directory to open.
138  cred - Authentication credentials, if any.
139  info - Opaque information, if any.
140 
141  Output: Returns SFS_OK upon success, otherwise SFS_ERROR.
142 */
143 {
144  static const char *epname = "opendir";
145 
146 // Verify that this object is not already associated with an open directory
147 //
148  if (dh) return
149  XrdSfsNative::Emsg(epname, error, EADDRINUSE,
150  "open directory", dir_path);
151 
152 // Set up values for this directory object
153 //
154  ateof = 0;
155  fname = strdup(dir_path);
156 
157 // Open the directory and get it's id
158 //
159  if (!(dh = opendir(dir_path))) return
160  XrdSfsNative::Emsg(epname,error,errno,"open directory",dir_path);
161 
162 // All done
163 //
164  return SFS_OK;
165 }
166 
167 /******************************************************************************/
168 /* n e x t E n t r y */
169 /******************************************************************************/
170 
172 /*
173  Function: Read the next directory entry.
174 
175  Input: None.
176 
177  Output: Upon success, returns the contents of the next directory entry as
178  a null terminated string. Returns a null pointer upon EOF or an
179  error. To differentiate the two cases, getErrorInfo will return
180  0 upon EOF and an actual error code (i.e., not 0) on error.
181 */
182 {
183  static const char *epname = "nextEntry";
184  struct dirent *rp;
185  int retc;
186 
187 // Lock the direcrtory and do any required tracing
188 //
189  if (!dh)
190  {XrdSfsNative::Emsg(epname,error,EBADF,"read directory",fname);
191  return (const char *)0;
192  }
193 
194 // Check if we are at EOF (once there we stay there)
195 //
196  if (ateof) return (const char *)0;
197 
198 // Read the next directory entry
199 //
200 #if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
201  errno = 0;
202  rp = readdir(dh);
203  if (!rp)
204  {if (!(retc = errno)) {ateof = 1; error.clear();}
205  else XrdSfsNative::Emsg(epname,error,retc,"read directory",fname);
206  d_pnt->d_name[0] = '\0';
207  return (const char *)0;
208  }
209  return (const char *)(rp->d_name);
210 #else
211  if ((retc = readdir_r(dh, d_pnt, &rp)))
212  {XrdSfsNative::Emsg(epname,error,retc,"read directory",fname);
213  d_pnt->d_name[0] = '\0';
214  return (const char *)0;
215  }
216 
217 // Check if we have reached end of file
218 //
219  if (!rp || !d_pnt->d_name[0])
220  {ateof = 1;
221  error.clear();
222  return (const char *)0;
223  }
224 
225 // Return the actual entry
226 //
227  return (const char *)(d_pnt->d_name);
228 #endif
229 }
230 
231 /******************************************************************************/
232 /* c l o s e */
233 /******************************************************************************/
234 
236 /*
237  Function: Close the directory object.
238 
239  Input: cred - Authentication credentials, if any.
240 
241  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
242 */
243 {
244  static const char *epname = "closedir";
245 
246 // Release the handle
247 //
248  if (dh && closedir(dh))
249  {XrdSfsNative::Emsg(epname, error, errno, "close directory", fname);
250  return SFS_ERROR;
251  }
252 
253 // Do some clean-up
254 //
255  if (fname) free(fname);
256  dh = (DIR *)0;
257  return SFS_OK;
258 }
259 
260 /******************************************************************************/
261 /* F i l e O b j e c t I n t e r f a c e s */
262 /******************************************************************************/
263 /******************************************************************************/
264 /* o p e n */
265 /******************************************************************************/
266 
267 int XrdSfsNativeFile::open(const char *path, // In
268  XrdSfsFileOpenMode open_mode, // In
269  mode_t Mode, // In
270  const XrdSecClientName *client, // In
271  const char *info) // In
272 /*
273  Function: Open the file `path' in the mode indicated by `open_mode'.
274 
275  Input: path - The fully qualified name of the file to open.
276  open_mode - One of the following flag values:
277  SFS_O_RDONLY - Open file for reading.
278  SFS_O_WRONLY - Open file for writing.
279  SFS_O_RDWR - Open file for update
280  SFS_O_CREAT - Create the file open in RDWR mode
281  SFS_O_TRUNC - Trunc the file open in RDWR mode
282  Mode - The Posix access mode bits to be assigned to the file.
283  These bits correspond to the standard Unix permission
284  bits (e.g., 744 == "rwxr--r--"). Mode may also conatin
285  SFS_O_MKPTH is the full path is to be created. The
286  agument is ignored unless open_mode = SFS_O_CREAT.
287  client - Authentication credentials, if any.
288  info - Opaque information to be used as seen fit.
289 
290  Output: Returns OOSS_OK upon success, otherwise SFS_ERROR is returned.
291 */
292 {
293  static const char *epname = "open";
294  const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
295  char *opname;
296  mode_t acc_mode = Mode & S_IAMB;
297  int retc, open_flag = 0;
298  struct stat buf;
299 
300 // Verify that this object is not already associated with an open file
301 //
302  if (oh >= 0)
303  return XrdSfsNative::Emsg(epname,error,EADDRINUSE,"open file",path);
304  fname = strdup(path);
305 
306 // Set the actual open mode
307 //
308  switch(open_mode & (SFS_O_RDONLY | SFS_O_WRONLY | SFS_O_RDWR))
309  {
310  case SFS_O_RDONLY: open_flag = O_RDONLY; break;
311  case SFS_O_WRONLY: open_flag = O_WRONLY; break;
312  case SFS_O_RDWR: open_flag = O_RDWR; break;
313  default: open_flag = O_RDONLY; break;
314  }
315 
316 // Prepare to create or open the file, as needed
317 //
318  if (open_mode & SFS_O_CREAT)
319  {open_flag = O_RDWR | O_CREAT | O_EXCL;
320  opname = (char *)"create";
321  if ((Mode & SFS_O_MKPTH) && (retc = XrdSfsNative::Mkpath(path,AMode,info)))
322  return XrdSfsNative::Emsg(epname,error,retc,"create path for",path);
323  } else if (open_mode & SFS_O_TRUNC)
324  {open_flag = O_RDWR | O_CREAT | O_TRUNC;
325  opname = (char *)"truncate";
326  } else opname = (char *)"open";
327 
328 // Open the file and make sure it is a file
329 //
330  if ((oh = XrdSfsUFS::Open(path, open_flag, acc_mode)) >= 0)
331  {do {retc = XrdSfsUFS::Statfd(oh, &buf);} while(retc && errno == EINTR);
332  if (!retc && !(buf.st_mode & S_IFREG))
333  {close(); oh = (buf.st_mode & S_IFDIR ? -EISDIR : -ENOTBLK);}
334  } else {
335  oh = -errno;
336  if (errno == EEXIST)
337  {do {retc = XrdSfsUFS::Statfn(path, &buf);}
338  while(retc && errno == EINTR);
339  if (!retc && (buf.st_mode & S_IFDIR)) oh = -EISDIR;
340  }
341  }
342 
343 // All done.
344 //
345  if (oh < 0) return XrdSfsNative::Emsg(epname, error, oh, opname, path);
346  return SFS_OK;
347 }
348 
349 /******************************************************************************/
350 /* c l o s e */
351 /******************************************************************************/
352 
354 /*
355  Function: Close the file object.
356 
357  Input: None
358 
359  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
360 */
361 {
362  static const char *epname = "close";
363 
364 // Release the handle and return
365 //
366  if (oh >= 0 && XrdSfsUFS::Close(oh))
367  return XrdSfsNative::Emsg(epname, error, errno, "close", fname);
368  oh = -1;
369  if (fname) {free(fname); fname = 0;}
370  return SFS_OK;
371 }
372 
373 /******************************************************************************/
374 /* f c t l */
375 /******************************************************************************/
376 
377 int XrdSfsNativeFile::fctl(const int cmd,
378  const char *args,
379  XrdOucErrInfo &out_error)
380 {
381 // See if we can do this
382 //
383  if (cmd == SFS_FCTL_GETFD)
384  {out_error.setErrCode(oh);
385  return SFS_OK;
386  }
387 
388 // We don't support this
389 //
390  out_error.setErrInfo(ENOTSUP, "fctl operation not supported");
391  return SFS_ERROR;
392 }
393 
394 /******************************************************************************/
395 /* r e a d */
396 /******************************************************************************/
397 
399  char *buff, // Out
400  XrdSfsXferSize blen) // In
401 /*
402  Function: Read `blen' bytes at `offset' into 'buff' and return the actual
403  number of bytes read.
404 
405  Input: offset - The absolute byte offset at which to start the read.
406  buff - Address of the buffer in which to place the data.
407  blen - The size of the buffer. This is the maximum number
408  of bytes that will be read from 'fd'.
409 
410  Output: Returns the number of bytes read upon success and SFS_ERROR o/w.
411 */
412 {
413  static const char *epname = "read";
414  XrdSfsXferSize nbytes;
415 
416 // Make sure the offset is not too large
417 //
418 #if _FILE_OFFSET_BITS!=64
419  if (offset > 0x000000007fffffff)
420  return XrdSfsNative::Emsg(epname, error, EFBIG, "read", fname);
421 #endif
422 
423 // Read the actual number of bytes
424 //
425  do { nbytes = pread(oh, (void *)buff, (size_t)blen, (off_t)offset); }
426  while(nbytes < 0 && errno == EINTR);
427 
428  if (nbytes < 0)
429  return XrdSfsNative::Emsg(epname, error, errno, "read", fname);
430 
431 // Return number of bytes read
432 //
433  return nbytes;
434 }
435 
436 /******************************************************************************/
437 /* r e a d v */
438 /******************************************************************************/
439 
441  int readCount) // In
442 /*
443  Function: Perform all the reads specified in the readV vector.
444 
445  Input: readV - A description of the reads to perform; includes the
446  absolute offset, the size of the read, and the buffer
447  to place the data into.
448  readCount - The size of the readV vector.
449 
450  Output: Returns the number of bytes read upon success and SFS_ERROR o/w.
451  If the number of bytes read is less than requested, it is considered
452  an error.
453 */
454 {
455  static const char *epname = "readv";
456  XrdSfsXferSize nbytes = 0;
457  ssize_t curCount;
458  int i;
459 
460  for (i=0; i<int(readCount); i++)
461  {do {curCount = pread(oh, (void *)readV[i].data, (size_t)readV[i].size, (off_t)readV[i].offset);}
462  while(curCount < 0 && errno == EINTR);
463 
464  if (curCount != readV[i].size)
465  {if (curCount > 0) errno = ESPIPE;
466  return XrdSfsNative::Emsg(epname, error, errno, "readv", fname);
467  }
468  nbytes += curCount;
469  }
470 
471  return nbytes;
472 }
473 
474 /******************************************************************************/
475 /* r e a d A I O */
476 /******************************************************************************/
477 
479 {
480 
481 // Execute this request in a synchronous fashion
482 //
483  aiop->Result = this->read((XrdSfsFileOffset)aiop->sfsAio.aio_offset,
484  (char *)aiop->sfsAio.aio_buf,
486  aiop->doneRead();
487  return 0;
488 }
489 
490 /******************************************************************************/
491 /* w r i t e */
492 /******************************************************************************/
493 
495  const char *buff, // In
496  XrdSfsXferSize blen) // In
497 /*
498  Function: Write `blen' bytes at `offset' from 'buff' and return the actual
499  number of bytes written.
500 
501  Input: offset - The absolute byte offset at which to start the write.
502  buff - Address of the buffer from which to get the data.
503  blen - The size of the buffer. This is the maximum number
504  of bytes that will be written to 'fd'.
505 
506  Output: Returns the number of bytes written upon success and SFS_ERROR o/w.
507 
508  Notes: An error return may be delayed until the next write(), close(), or
509  sync() call.
510 */
511 {
512  static const char *epname = "write";
513  XrdSfsXferSize nbytes;
514 
515 // Make sure the offset is not too large
516 //
517 #if _FILE_OFFSET_BITS!=64
518  if (offset > 0x000000007fffffff)
519  return XrdSfsNative::Emsg(epname, error, EFBIG, "write", fname);
520 #endif
521 
522 // Write the requested bytes
523 //
524  do { nbytes = pwrite(oh, (void *)buff, (size_t)blen, (off_t)offset); }
525  while(nbytes < 0 && errno == EINTR);
526 
527  if (nbytes < 0)
528  return XrdSfsNative::Emsg(epname, error, errno, "write", fname);
529 
530 // Return number of bytes written
531 //
532  return nbytes;
533 }
534 
535 /******************************************************************************/
536 /* w r i t e A I O */
537 /******************************************************************************/
538 
540 {
541 
542 // Execute this request in a synchronous fashion
543 //
544  aiop->Result = this->write((XrdSfsFileOffset)aiop->sfsAio.aio_offset,
545  (char *)aiop->sfsAio.aio_buf,
547  aiop->doneWrite();
548  return 0;
549 }
550 
551 /******************************************************************************/
552 /* s t a t */
553 /******************************************************************************/
554 
555 int XrdSfsNativeFile::stat(struct stat *buf) // Out
556 /*
557  Function: Return file status information
558 
559  Input: buf - The stat structiure to hold the results
560 
561  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
562 */
563 {
564  static const char *epname = "stat";
565 
566 // Execute the function
567 //
568  if (XrdSfsUFS::Statfd(oh, buf))
569  return XrdSfsNative::Emsg(epname, error, errno, "state", fname);
570 
571 // All went well
572 //
573  return SFS_OK;
574 }
575 
576 /******************************************************************************/
577 /* s y n c */
578 /******************************************************************************/
579 
581 /*
582  Function: Commit all unwritten bytes to physical media.
583 
584  Input: None
585 
586  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
587 */
588 {
589  static const char *epname = "sync";
590 
591 // Perform the function
592 //
593  if (fsync(oh))
594  return XrdSfsNative::Emsg(epname,error,errno,"synchronize",fname);
595 
596 // All done
597 //
598  return SFS_OK;
599 }
600 
601 /******************************************************************************/
602 /* s y n c A I O */
603 /******************************************************************************/
604 
606 {
607 
608 // Execute this request in a synchronous fashion
609 //
610  aiop->Result = this->sync();
611  aiop->doneWrite();
612  return 0;
613 }
614 
615 /******************************************************************************/
616 /* t r u n c a t e */
617 /******************************************************************************/
618 
620 /*
621  Function: Set the length of the file object to 'flen' bytes.
622 
623  Input: flen - The new size of the file.
624 
625  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
626 
627  Notes: If 'flen' is smaller than the current size of the file, the file
628  is made smaller and the data past 'flen' is discarded. If 'flen'
629  is larger than the current size of the file, a hole is created
630  (i.e., the file is logically extended by filling the extra bytes
631  with zeroes).
632 */
633 {
634  static const char *epname = "trunc";
635 
636 // Make sure the offset is not too larg
637 //
638  if (sizeof(off_t) < sizeof(flen) && flen > 0x000000007fffffff)
639  return XrdSfsNative::Emsg(epname, error, EFBIG, "truncate", fname);
640 
641 // Perform the function
642 //
643  if (ftruncate(oh, flen))
644  return XrdSfsNative::Emsg(epname, error, errno, "truncate", fname);
645 
646 // All done
647 //
648  return SFS_OK;
649 }
650 
651 /******************************************************************************/
652 /* F i l e S y s t e m O b j e c t I n t e r f a c e s */
653 /******************************************************************************/
654 /******************************************************************************/
655 /* c h m o d */
656 /******************************************************************************/
657 
658 int XrdSfsNative::chmod(const char *path, // In
659  XrdSfsMode Mode, // In
660  XrdOucErrInfo &error, // Out
661  const XrdSecClientName *client, // In
662  const char *info) // In
663 /*
664  Function: Change the mode on a file or directory.
665 
666  Input: path - Is the fully qualified name of the file to be removed.
667  einfo - Error information object to hold error details.
668  client - Authentication credentials, if any.
669  info - Opaque information, if any.
670 
671  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
672 */
673 {
674  static const char *epname = "chmod";
675  mode_t acc_mode = Mode & S_IAMB;
676 
677 // Perform the actual deletion
678 //
679  if (XrdSfsUFS::Chmod(path, acc_mode) )
680  return XrdSfsNative::Emsg(epname,error,errno,"change mode on",path);
681 
682 // All done
683 //
684  return SFS_OK;
685 }
686 
687 /******************************************************************************/
688 /* e x i s t s */
689 /******************************************************************************/
690 
691 int XrdSfsNative::exists(const char *path, // In
692  XrdSfsFileExistence &file_exists, // Out
693  XrdOucErrInfo &error, // Out
694  const XrdSecClientName *client, // In
695  const char *info) // In
696 /*
697  Function: Determine if file 'path' actually exists.
698 
699  Input: path - Is the fully qualified name of the file to be tested.
700  file_exists - Is the address of the variable to hold the status of
701  'path' when success is returned. The values may be:
702  XrdSfsFileExistsIsDirectory - file not found but path is valid.
703  XrdSfsFileExistsIsFile - file found.
704  XrdSfsFileExistsIsNo - neither file nor directory.
705  einfo - Error information object holding the details.
706  client - Authentication credentials, if any.
707  info - Opaque information, if any.
708 
709  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
710 
711  Notes: When failure occurs, 'file_exists' is not modified.
712 */
713 {
714  static const char *epname = "exists";
715  struct stat fstat;
716 
717 // Now try to find the file or directory
718 //
719  if (!XrdSfsUFS::Statfn(path, &fstat) )
720  { if (S_ISDIR(fstat.st_mode)) file_exists=XrdSfsFileExistIsDirectory;
721  else if (S_ISREG(fstat.st_mode)) file_exists=XrdSfsFileExistIsFile;
722  else file_exists=XrdSfsFileExistNo;
723  return SFS_OK;
724  }
725  if (errno == ENOENT)
726  {file_exists=XrdSfsFileExistNo;
727  return SFS_OK;
728  }
729 
730 // An error occurred, return the error info
731 //
732  return XrdSfsNative::Emsg(epname, error, errno, "locate", path);
733 }
734 
735 /******************************************************************************/
736 /* f s c t l */
737 /******************************************************************************/
738 
739 int XrdSfsNative::fsctl(const int cmd,
740  const char *args,
741  XrdOucErrInfo &out_error,
742  const XrdSecClientName *client)
743 {
744  out_error.setErrInfo(ENOTSUP, "Operation not supported.");
745  return SFS_ERROR;
746 }
747 
748 /******************************************************************************/
749 /* g e t V e r s i o n */
750 /******************************************************************************/
751 
752 const char *XrdSfsNative::getVersion() {return XrdVERSION;}
753 
754 /******************************************************************************/
755 /* m k d i r */
756 /******************************************************************************/
757 
758 int XrdSfsNative::mkdir(const char *path, // In
759  XrdSfsMode Mode, // In
760  XrdOucErrInfo &error, // Out
761  const XrdSecClientName *client, // In
762  const char *info) // In
763 /*
764  Function: Create a directory entry.
765 
766  Input: path - Is the fully qualified name of the file to be removed.
767  Mode - Is the POSIX mode setting for the directory. If the
768  mode contains SFS_O_MKPTH, the full path is created.
769  einfo - Error information object to hold error details.
770  client - Authentication credentials, if any.
771  info - Opaque information, if any.
772 
773  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
774 */
775 {
776  static const char *epname = "mkdir";
777  mode_t acc_mode = Mode & S_IAMB;
778 
779 // Create the path if it does not already exist
780 //
781  if (Mode & SFS_O_MKPTH) Mkpath(path, acc_mode, info);
782 
783 // Perform the actual deletion
784 //
785  if (XrdSfsUFS::Mkdir(path, acc_mode) )
786  return XrdSfsNative::Emsg(epname,error,errno,"create directory",path);
787 
788 // All done
789 //
790  return SFS_OK;
791 }
792 
793 /******************************************************************************/
794 /* M k p a t h */
795 /******************************************************************************/
796 /*
797  Function: Create a directory path
798 
799  Input: path - Is the fully qualified name of the new path.
800  mode - The new mode that each new directory is to have.
801  info - Opaque information, of any.
802 
803  Output: Returns 0 upon success and -errno upon failure.
804 */
805 
806 int XrdSfsNative::Mkpath(const char *path, mode_t mode, const char *info)
807 {
808  char actual_path[MAXPATHLEN], *local_path, *next_path;
809  unsigned int plen;
810  struct stat buf;
811 
812 // Extract out the path we should make
813 //
814  if (!(plen = strlen(path))) return -ENOENT;
815  if (plen >= sizeof(actual_path)) return -ENAMETOOLONG;
816  strcpy(actual_path, path);
817  if (actual_path[plen-1] == '/') actual_path[plen-1] = '\0';
818 
819 // Typically, the path exist. So, do a quick check before launching into it
820 //
821  if (!(local_path = rindex(actual_path, (int)'/'))
822  || local_path == actual_path) return 0;
823  *local_path = '\0';
824  if (!XrdSfsUFS::Statfn(actual_path, &buf)) return 0;
825  *local_path = '/';
826 
827 // Start creating directories starting with the root. Notice that we will not
828 // do anything with the last component. The caller is responsible for that.
829 //
830  local_path = actual_path+1;
831  while((next_path = index(local_path, int('/'))))
832  {*next_path = '\0';
833  if (XrdSfsUFS::Mkdir(actual_path,mode) && errno != EEXIST)
834  return -errno;
835  *next_path = '/';
836  local_path = next_path+1;
837  }
838 
839 // All done
840 //
841  return 0;
842 }
843 
844 /******************************************************************************/
845 /* r e m */
846 /******************************************************************************/
847 
848 int XrdSfsNative::rem(const char *path, // In
849  XrdOucErrInfo &error, // Out
850  const XrdSecClientName *client, // In
851  const char *info) // In
852 /*
853  Function: Delete a file from the namespace.
854 
855  Input: path - Is the fully qualified name of the file to be removed.
856  einfo - Error information object to hold error details.
857  client - Authentication credentials, if any.
858  info - Opaque information, if any.
859 
860  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
861 */
862 {
863  static const char *epname = "rem";
864 
865 // Perform the actual deletion
866 //
867  if (XrdSfsUFS::Rem(path) )
868  return XrdSfsNative::Emsg(epname, error, errno, "remove", path);
869 
870 // All done
871 //
872  return SFS_OK;
873 }
874 
875 /******************************************************************************/
876 /* r e m d i r */
877 /******************************************************************************/
878 
879 int XrdSfsNative::remdir(const char *path, // In
880  XrdOucErrInfo &error, // Out
881  const XrdSecClientName *client, // In
882  const char *info) // In
883 /*
884  Function: Delete a directory from the namespace.
885 
886  Input: path - Is the fully qualified name of the dir to be removed.
887  einfo - Error information object to hold error details.
888  client - Authentication credentials, if any.
889  info - Opaque information, if any.
890 
891  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
892 */
893 {
894  static const char *epname = "remdir";
895 
896 // Perform the actual deletion
897 //
898  if (XrdSfsUFS::Remdir(path) )
899  return XrdSfsNative::Emsg(epname, error, errno, "remove", path);
900 
901 // All done
902 //
903  return SFS_OK;
904 }
905 
906 /******************************************************************************/
907 /* r e n a m e */
908 /******************************************************************************/
909 
910 int XrdSfsNative::rename(const char *old_name, // In
911  const char *new_name, // In
912  XrdOucErrInfo &error, //Out
913  const XrdSecClientName *client, // In
914  const char *infoO, // In
915  const char *infoN) // In
916 /*
917  Function: Renames a file/directory with name 'old_name' to 'new_name'.
918 
919  Input: old_name - Is the fully qualified name of the file to be renamed.
920  new_name - Is the fully qualified name that the file is to have.
921  error - Error information structure, if an error occurs.
922  client - Authentication credentials, if any.
923  info - old_name opaque information, if any.
924  info - new_name opaque information, if any.
925 
926  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
927 */
928 {
929  static const char *epname = "rename";
930 
931 // Perform actual rename operation
932 //
933  if (XrdSfsUFS::Rename(old_name, new_name) )
934  return XrdSfsNative::Emsg(epname, error, errno, "rename", old_name);
935 
936 // All done
937 //
938  return SFS_OK;
939 }
940 
941 /******************************************************************************/
942 /* s t a t */
943 /******************************************************************************/
944 
945 int XrdSfsNative::stat(const char *path, // In
946  struct stat *buf, // Out
947  XrdOucErrInfo &error, // Out
948  const XrdSecClientName *client, // In
949  const char *info) // In
950 /*
951  Function: Get info on 'path'.
952 
953  Input: path - Is the fully qualified name of the file to be tested.
954  buf - The stat structiure to hold the results
955  error - Error information object holding the details.
956  client - Authentication credentials, if any.
957  info - Opaque information, if any.
958 
959  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
960 */
961 {
962  static const char *epname = "stat";
963 
964 // Execute the function
965 //
966  if (XrdSfsUFS::Statfn(path, buf) )
967  return XrdSfsNative::Emsg(epname, error, errno, "state", path);
968 
969 // All went well
970 //
971  return SFS_OK;
972 }
973 
974 /******************************************************************************/
975 /* t r u n c a t e */
976 /******************************************************************************/
977 
978 int XrdSfsNative::truncate(const char *path, // In
979  XrdSfsFileOffset flen, // In
980  XrdOucErrInfo &error, // Out
981  const XrdSecClientName *client, // In
982  const char *info) // In
983 /*
984  Function: Set the length of the file object to 'flen' bytes.
985 
986  Input: path - The path to the file.
987  flen - The new size of the file.
988  einfo - Error information object to hold error details.
989  client - Authentication credentials, if any.
990  info - Opaque information, if any.
991 
992  Output: Returns SFS_OK upon success and SFS_ERROR upon failure.
993 
994  Notes: If 'flen' is smaller than the current size of the file, the file
995  is made smaller and the data past 'flen' is discarded. If 'flen'
996  is larger than the current size of the file, a hole is created
997  (i.e., the file is logically extended by filling the extra bytes
998  with zeroes).
999 */
1000 {
1001  static const char *epname = "trunc";
1002 
1003 // Make sure the offset is not too larg
1004 //
1005  if (sizeof(off_t) < sizeof(flen) && flen > 0x000000007fffffff)
1006  return XrdSfsNative::Emsg(epname, error, EFBIG, "truncate", path);
1007 
1008 // Perform the function
1009 //
1010  if (XrdSfsUFS::Truncate(path, flen) )
1011  return XrdSfsNative::Emsg(epname, error, errno, "truncate", path);
1012 
1013 // All done
1014 //
1015  return SFS_OK;
1016 }
1017 
1018 /******************************************************************************/
1019 /* E m s g */
1020 /******************************************************************************/
1021 
1022 int XrdSfsNative::Emsg(const char *pfx, // Message prefix value
1023  XrdOucErrInfo &einfo, // Place to put text & error code
1024  int ecode, // The error code
1025  const char *op, // Operation being performed
1026  const char *target) // The target (e.g., fname)
1027 {
1028  const char *etext;
1029  char buffer[MAXPATHLEN+80];
1030 
1031 // Get the reason for the error
1032 //
1033  if (ecode < 0) ecode = -ecode;
1034  etext = XrdSysE2T(ecode);
1035 
1036 // Format the error message
1037 //
1038  snprintf(buffer,sizeof(buffer),"Unable to %s %s; %s", op, target, etext);
1039 
1040 // Print it out if debugging is enabled
1041 //
1042 #ifndef NODEBUG
1043  eDest->Emsg(pfx, buffer);
1044 #endif
1045 
1046 // Place the error message in the error object and return
1047 //
1048  einfo.setErrInfo(ecode, buffer);
1049 
1050  return SFS_ERROR;
1051 }
static XrdSysError eDest(0,"crypto_")
int truncate(const char *path, off_t offset)
ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
int stat(const char *path, struct stat *buf)
int ftruncate(int fildes, off_t offset)
struct dirent * readdir(DIR *dirp)
int open(const char *path, int oflag,...)
ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
int fstat(int fildes, struct stat *buf)
int unlink(const char *path)
int rename(const char *oldpath, const char *newpath)
int mkdir(const char *path, mode_t mode)
int fsync(int fildes)
int closedir(DIR *dirp)
int rmdir(const char *path)
DIR * opendir(const char *path)
#define close(a)
Definition: XrdPosix.hh:43
#define XrdSecClientName
int Mode
off_t aio_offset
Definition: XrdSfsAio.hh:49
size_t aio_nbytes
Definition: XrdSfsAio.hh:48
void * aio_buf
Definition: XrdSfsAio.hh:47
int XrdSfsMode
#define SFS_ERROR
XrdSfsFileExistence
@ XrdSfsFileExistIsFile
@ XrdSfsFileExistNo
@ XrdSfsFileExistIsDirectory
#define SFS_O_MKPTH
#define SFS_O_RDONLY
#define SFS_O_WRONLY
#define SFS_FCTL_GETFD
#define SFS_O_CREAT
#define SFS_O_RDWR
int XrdSfsFileOpenMode
#define SFS_OK
long long XrdSfsFileOffset
#define SFS_O_TRUNC
int XrdSfsXferSize
XrdSfsFileSystem * XrdSfsGetFileSystem(XrdSfsFileSystem *native_fs, XrdSysLogger *lp)
#define S_IAMB
Definition: XrdSfsNative.cc:60
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
void clear()
Reset data and error information to null. Any appenadges are released.
int setErrInfo(int code, const char *emsg)
int setErrCode(int code)
ssize_t Result
Definition: XrdSfsAio.hh:65
virtual void doneRead()=0
struct aiocb sfsAio
Definition: XrdSfsAio.hh:62
virtual void doneWrite()=0
XrdOucErrInfo & error
XrdOucErrInfo & error
const char * nextEntry()
int open(const char *dirName, const XrdSecClientName *client=0, const char *opaque=0)
XrdSfsXferSize readv(XrdOucIOVec *readV, int readCount)
int stat(struct stat *buf)
int open(const char *fileName, XrdSfsFileOpenMode openMode, mode_t createMode, const XrdSecClientName *client=0, const char *opaque=0)
XrdSfsXferSize write(XrdSfsFileOffset fileOffset, const char *buffer, XrdSfsXferSize buffer_size)
virtual int fctl(const int cmd, const char *args, XrdOucErrInfo &eInfo)=0
int read(XrdSfsFileOffset fileOffset, XrdSfsXferSize preread_sz)
int truncate(XrdSfsFileOffset fileOffset)
XrdSfsNative(XrdSysError *lp)
int rem(const char *path, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
int exists(const char *fileName, XrdSfsFileExistence &exists_flag, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
int truncate(const char *Name, XrdSfsFileOffset fileOffset, XrdOucErrInfo &out_error, const XrdSecEntity *client=0, const char *opaque=0)
int rename(const char *oldFileName, const char *newFileName, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaqueO=0, const char *opaqueN=0)
int fsctl(const int cmd, const char *args, XrdOucErrInfo &out_error, const XrdSecClientName *client=0)
static int Mkpath(const char *path, mode_t mode, const char *info=0)
int stat(const char *Name, struct stat *buf, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
int chmod(const char *Name, XrdSfsMode Mode, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
int remdir(const char *dirName, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
static int Emsg(const char *, XrdOucErrInfo &, int, const char *x, const char *y="")
const char * getVersion()
int mkdir(const char *dirName, XrdSfsMode Mode, XrdOucErrInfo &out_error, const XrdSecClientName *client=0, const char *opaque=0)
static int Mkdir(const char *fn, mode_t mode)
Definition: XrdSfsNative.cc:81
static int Rem(const char *fn)
Definition: XrdSfsNative.cc:86
static int Rename(const char *ofn, const char *nfn)
Definition: XrdSfsNative.cc:90
static int Truncate(const char *fn, off_t flen)
Definition: XrdSfsNative.cc:96
static int Open(const char *path, int oflag, mode_t omode)
Definition: XrdSfsNative.cc:83
static int Remdir(const char *fn)
Definition: XrdSfsNative.cc:88
static int Close(int fd)
Definition: XrdSfsNative.cc:79
static int Statfd(int fd, struct stat *buf)
Definition: XrdSfsNative.cc:92
static int Statfn(const char *fn, struct stat *buf)
Definition: XrdSfsNative.cc:94
static int Chmod(const char *fn, mode_t mode)
Definition: XrdSfsNative.cc:77
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141