XRootD
Loading...
Searching...
No Matches
XrdFfsPosix.cc File Reference
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <sys/types.h>
#include <sys/xattr.h>
#include <iostream>
#include <libgen.h>
#include <unistd.h>
#include <cstdlib>
#include <syslog.h>
#include "XrdFfs/XrdFfsPosix.hh"
#include "XrdPosix/XrdPosixXrootd.hh"
#include "XrdFfs/XrdFfsMisc.hh"
#include "XrdFfs/XrdFfsDent.hh"
#include "XrdFfs/XrdFfsQueue.hh"
#include "XrdCl/XrdClFileSystem.hh"
#include "XrdCl/XrdClFile.hh"
#include "XrdCl/XrdClURL.hh"
#include "XrdCl/XrdClXRootDResponses.hh"
Include dependency graph for XrdFfsPosix.cc:

Go to the source code of this file.

Classes

struct  XrdFfsPosixX_deleteall_args
struct  XrdFfsPosixX_readdirall_args
struct  XrdFfsPosixX_statall_args
struct  XrdFfsPosixX_statvfsall_args

Macros

#define _FILE_OFFSET_BITS   64
#define ENOATTR   ENODATA
#define MAXROOTURLLEN   1024

Functions

void XrdFfsPosix_clear_from_rdr_cache (const char *rdrurl)
int XrdFfsPosix_close (int fildes)
int XrdFfsPosix_closedir (DIR *dirp)
int XrdFfsPosix_deleteall (const char *rdrurl, const char *path, uid_t user_uid, mode_t st_mode)
int XrdFfsPosix_fsync (int fildes)
int XrdFfsPosix_ftruncate (int fildes, off_t offset)
long long XrdFfsPosix_getxattr (const char *path, const char *name, void *value, unsigned long long size)
off_t XrdFfsPosix_lseek (int fildes, off_t offset, int whence)
int XrdFfsPosix_mkdir (const char *path, mode_t mode)
int XrdFfsPosix_open (const char *path, int oflags, mode_t mode)
DIR * XrdFfsPosix_opendir (const char *path)
ssize_t XrdFfsPosix_pread (int fildes, void *buf, size_t nbyte, off_t offset)
ssize_t XrdFfsPosix_pwrite (int fildes, const void *buf, size_t nbyte, off_t offset)
ssize_t XrdFfsPosix_read (int fildes, void *buf, size_t nbyte)
struct dirent * XrdFfsPosix_readdir (DIR *dirp)
int XrdFfsPosix_readdirall (const char *rdrurl, const char *path, char ***direntarray, uid_t user_uid)
int XrdFfsPosix_rename (const char *oldpath, const char *newpath)
int XrdFfsPosix_renameall (const char *rdrurl, const char *from, const char *to, uid_t user_uid)
int XrdFfsPosix_rmdir (const char *path)
int XrdFfsPosix_rmdirall (const char *rdrurl, const char *path, uid_t user_uid)
int XrdFfsPosix_stat (const char *path, struct stat *buf)
int XrdFfsPosix_statall (const char *rdrurl, const char *path, struct stat *stbuf, uid_t user_uid)
int XrdFfsPosix_statvfsall (const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
int XrdFfsPosix_truncate (const char *path, off_t Size)
int XrdFfsPosix_truncateall (const char *rdrurl, const char *path, off_t size, uid_t user_uid)
int XrdFfsPosix_unlink (const char *path)
int XrdFfsPosix_unlinkall (const char *rdrurl, const char *path, uid_t user_uid)
ssize_t XrdFfsPosix_write (int fildes, const void *buf, size_t nbyte)
void * XrdFfsPosix_x_deleteall (void *x)
void * XrdFfsPosix_x_readdirall (void *x)
void * XrdFfsPosix_x_statall (void *x)
void * XrdFfsPosix_x_statvfsall (void *x)

Class Documentation

◆ XrdFfsPosixX_deleteall_args

struct XrdFfsPosixX_deleteall_args

Definition at line 248 of file XrdFfsPosix.cc.

Collaboration diagram for XrdFfsPosixX_deleteall_args:
Class Members
int * err
int * res
mode_t st_mode
char * url

◆ XrdFfsPosixX_readdirall_args

struct XrdFfsPosixX_readdirall_args

Definition at line 429 of file XrdFfsPosix.cc.

Collaboration diagram for XrdFfsPosixX_readdirall_args:
Class Members
struct XrdFfsDentnames ** dents
int * err
int * res
char * url

◆ XrdFfsPosixX_statall_args

struct XrdFfsPosixX_statall_args

Definition at line 743 of file XrdFfsPosix.cc.

Collaboration diagram for XrdFfsPosixX_statall_args:
Class Members
int * err
int * res
struct stat * stbuf
char * url

◆ XrdFfsPosixX_statvfsall_args

struct XrdFfsPosixX_statvfsall_args

Definition at line 611 of file XrdFfsPosix.cc.

Collaboration diagram for XrdFfsPosixX_statvfsall_args:
Class Members
int * err
short osscgroup
int * res
struct statvfs * stbuf
char * url

Macro Definition Documentation

◆ _FILE_OFFSET_BITS

#define _FILE_OFFSET_BITS   64

Definition at line 30 of file XrdFfsPosix.cc.

◆ ENOATTR

#define ENOATTR   ENODATA

Definition at line 41 of file XrdFfsPosix.cc.

◆ MAXROOTURLLEN

#define MAXROOTURLLEN   1024

Definition at line 64 of file XrdFfsPosix.cc.

Function Documentation

◆ XrdFfsPosix_clear_from_rdr_cache()

void XrdFfsPosix_clear_from_rdr_cache ( const char * rdrurl)

Definition at line 235 of file XrdFfsPosix.cc.

236{
237 int fd;
238 fd = XrdFfsPosix_open(rdrurl, O_CREAT | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
239 if ( fd != -1 )
240 {
242 XrdFfsPosix_unlink(rdrurl);
243 }
244}
int XrdFfsPosix_open(const char *path, int oflags, mode_t mode)
int XrdFfsPosix_unlink(const char *path)
int XrdFfsPosix_close(int fildes)

References XrdFfsPosix_close(), XrdFfsPosix_open(), and XrdFfsPosix_unlink().

Referenced by xrootdfs_mkdir(), and xrootdfs_rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_close()

int XrdFfsPosix_close ( int fildes)

Definition at line 127 of file XrdFfsPosix.cc.

128{
129 return XrdPosixXrootd::Close(fildes);
130}
static int Close(int fildes)
Close() conforms to POSIX.1-2001 close()

References XrdPosixXrootd::Close().

Referenced by XrdFfsPosix_clear_from_rdr_cache(), xrootdfs_create(), xrootdfs_mknod(), and xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_closedir()

int XrdFfsPosix_closedir ( DIR * dirp)

Definition at line 92 of file XrdFfsPosix.cc.

93{
94 return XrdPosixXrootd::Closedir(dirp);
95}
static int Closedir(DIR *dirp)
Closedir() conforms to POSIX.1-2001 closedir()

References XrdPosixXrootd::Closedir().

Referenced by XrdFfsPosix_x_readdirall(), and xrootdfs_readdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_deleteall()

int XrdFfsPosix_deleteall ( const char * rdrurl,
const char * path,
uid_t user_uid,
mode_t st_mode )

Definition at line 268 of file XrdFfsPosix.cc.

269{
270 int i, nurls, res;
271 char *newurls[XrdFfs_MAX_NUM_NODES];
272 int res_i[XrdFfs_MAX_NUM_NODES];
273 int errno_i[XrdFfs_MAX_NUM_NODES];
276
277 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
278
279 for (i = 0; i < nurls; i++)
280 {
281 errno_i[i] = 0;
282 strncat(newurls[i],path, MAXROOTURLLEN - strlen(newurls[i]) -1);
283 XrdFfsMisc_xrd_secsss_editurl(newurls[i], user_uid, 0);
284 args[i].url = newurls[i];
285 args[i].err = &errno_i[i];
286 args[i].res = &res_i[i];
287 args[i].st_mode = st_mode;
288#ifdef NOUSE_QUEUE
289 XrdFfsPosix_x_deleteall((void*) &args[i]);
290 }
291#else
292 jobs[i] = XrdFfsQueue_create_task(XrdFfsPosix_x_deleteall, (void**)(&args[i]), 0);
293 }
294 for (i = 0; i < nurls; i++)
295 {
296 XrdFfsQueue_wait_task(jobs[i]);
297 XrdFfsQueue_free_task(jobs[i]);
298 }
299#endif
300 res = -1;
301 errno = ENOENT;
302 for (i = 0; i < nurls; i++)
303 if (res_i[i] == 0)
304 {
305 res = 0;
306 errno = 0;
307 }
308 else if (res_i[i] != 0 && errno_i[i] == 125) // host is down
309 {
310 res = -1;
311 errno = ETIMEDOUT;
312 syslog(LOG_WARNING, "WARNING: unlink/rmdir(%s) failed (connection timeout)", newurls[i]);
313 break;
314 }
315 else if (res_i[i] != 0 && errno_i[i] != ENOENT)
316 {
317 res = -1;
318 errno = errno_i[i];
319 syslog(LOG_WARNING, "WARNING: unlink/rmdir(%s) failed (errno = %d)", newurls[i], errno);
320 break;
321 }
322
323 for (i = 0; i < nurls; i++)
324 free(newurls[i]);
325
326 return res;
327}
void XrdFfsMisc_xrd_secsss_editurl(char *url, uid_t user_uid, int *id)
int XrdFfsMisc_get_all_urls(const char *oldurl, char **newurls, const int nnodes)
#define MAXROOTURLLEN
Definition XrdFfsMisc.cc:62
#define XrdFfs_MAX_NUM_NODES
Definition XrdFfsMisc.hh:34
void * XrdFfsPosix_x_deleteall(void *x)
void XrdFfsQueue_free_task(struct XrdFfsQueueTasks *task)
struct XrdFfsQueueTasks * XrdFfsQueue_create_task(void *(*func)(void *), void **args, short initstat)
void XrdFfsQueue_wait_task(struct XrdFfsQueueTasks *task)

References XrdFfsQueueTasks::args, MAXROOTURLLEN, XrdFfsPosixX_deleteall_args::res, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_all_urls(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsPosix_x_deleteall(), and XrdFfsQueue_create_task().

Referenced by XrdFfsPosix_rmdirall(), and XrdFfsPosix_unlinkall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_fsync()

int XrdFfsPosix_fsync ( int fildes)

Definition at line 157 of file XrdFfsPosix.cc.

158{
159 return XrdPosixXrootd::Fsync(fildes);
160}
static int Fsync(int fildes)
Fsync() conforms to POSIX.1-2001 fsync()

References XrdPosixXrootd::Fsync().

Referenced by xrootdfs_fsync().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_ftruncate()

int XrdFfsPosix_ftruncate ( int fildes,
off_t offset )

Definition at line 172 of file XrdFfsPosix.cc.

173{
174 return XrdPosixXrootd::Ftruncate(fildes, offset);
175}
static int Ftruncate(int fildes, off_t offset)
Ftruncate() conforms to POSIX.1-2001 ftruncate()

References XrdPosixXrootd::Ftruncate().

Referenced by xrootdfs_ftruncate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_getxattr()

long long XrdFfsPosix_getxattr ( const char * path,
const char * name,
void * value,
unsigned long long size )

Definition at line 181 of file XrdFfsPosix.cc.

182{
183 int bufsize;
184 char xattrbuf[1024], nameclass[128], *namesubclass;
185 char *token, *key, *val;
186 char *lasts_xattr[256], *lasts_tokens[128];
187
188/*
189 Xrootd only support two names: xroot.space and xroot.xattr. We add support of xroot.space.*
190 such as xroot.space.oss.cgroup etc.
191 */
192 strncpy(nameclass, name, 11);
193 nameclass[11] = '\0';
194
195 if (strcmp(nameclass, "xroot.space") != 0 &&
196 strcmp(nameclass, "xroot.xattr") != 0 &&
197 strcmp(nameclass, "xroot.cksum") != 0)
198 {
199 errno = ENOATTR;
200 return -1;
201 }
202
203 bufsize = XrdPosixXrootd::Getxattr(path, nameclass, xattrbuf, size);
204 if (bufsize == -1) return -1;
205
206 if (strlen(name) > 11)
207 {
208 strcpy(nameclass, name);
209 namesubclass = &nameclass[12];
210 }
211 else /* xroot.space or xroot.xattr or xroot.cksum is provided. */
212 {
213 strcpy((char*)value, xattrbuf);
214 return bufsize;
215 }
216
217 token = strtok_r(xattrbuf, "&", lasts_xattr);
218 while ( token != NULL )
219 {
220 key = strtok_r(token, "=", lasts_tokens);
221 val = strtok_r(NULL, "=", lasts_tokens);
222 if (! strcmp(key, namesubclass))
223 {
224 strcpy((char*)value, val);
225 return strlen(val);
226 }
227 token = strtok_r(NULL, "&", lasts_xattr);
228 }
229 errno = ENOATTR;
230 return -1;
231}
#define ENOATTR
static long long Getxattr(const char *path, const char *name, void *value, unsigned long long size)

References ENOATTR, and XrdPosixXrootd::Getxattr().

Referenced by XrdFfsPosix_x_statvfsall(), xrootdfs_getxattr(), and xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_lseek()

off_t XrdFfsPosix_lseek ( int fildes,
off_t offset,
int whence )

Definition at line 132 of file XrdFfsPosix.cc.

133{
134 return XrdPosixXrootd::Lseek(fildes, (long long)offset, whence);
135}
static off_t Lseek(int fildes, off_t offset, int whence)
Lseek() conforms to POSIX.1-2001 lseek()

References XrdPosixXrootd::Lseek().

Referenced by xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_mkdir()

int XrdFfsPosix_mkdir ( const char * path,
mode_t mode )

Definition at line 97 of file XrdFfsPosix.cc.

98{
99 XrdCl::URL url(path);
100 std::string dir = url.GetPath();
101 XrdCl::LocationInfo *info = nullptr;
102 XrdCl::FileSystem fs(path);
103
104 XrdCl::XRootDStatus st = fs.DeepLocate("*", XrdCl::OpenFlags::PrefName, info );
105 std::unique_ptr<XrdCl::LocationInfo> ptr( info );
106
107 if( !st.IsOK() )
108 {
109 errno = ENOENT;
110 return -1;
111 }
112 std::string nodeUrl = "root://" + info->At(0).GetAddress() + "/" + dir;
113
114 return XrdPosixXrootd::Mkdir(nodeUrl.c_str(), mode);
115}
Send file/filesystem queries to an XRootD cluster.
const std::string & GetAddress() const
Get address.
Path location info.
Location & At(uint32_t index)
Get the location at index.
URL representation.
Definition XrdClURL.hh:31
static int Mkdir(const char *path, mode_t mode)
Mkdir() conforms to POSIX.1-2001 mkdir()
bool IsOK() const
We're fine.

References XrdCl::LocationInfo::At(), XrdCl::FileSystem::DeepLocate(), XrdCl::LocationInfo::Location::GetAddress(), XrdCl::URL::GetPath(), XrdCl::Status::IsOK(), XrdPosixXrootd::Mkdir(), and XrdCl::OpenFlags::PrefName.

Referenced by xrootdfs_mkdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_open()

int XrdFfsPosix_open ( const char * path,
int oflags,
mode_t mode )

Definition at line 122 of file XrdFfsPosix.cc.

123{
124 return XrdPosixXrootd::Open(path, oflags, mode);
125}
static int Open(const char *path, int oflag, mode_t mode=0, XrdPosixCallBack *cbP=0)

References XrdPosixXrootd::Open().

Referenced by XrdFfsPosix_clear_from_rdr_cache(), xrootdfs_do_create(), xrootdfs_open(), and xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_opendir()

DIR * XrdFfsPosix_opendir ( const char * path)

Definition at line 82 of file XrdFfsPosix.cc.

83{
84 return XrdPosixXrootd::Opendir(path);
85}
static DIR * Opendir(const char *path)
Opendir() conforms to POSIX.1-2001 opendir()

References XrdPosixXrootd::Opendir().

Referenced by XrdFfsPosix_x_readdirall(), and xrootdfs_readdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_pread()

ssize_t XrdFfsPosix_pread ( int fildes,
void * buf,
size_t nbyte,
off_t offset )

Definition at line 142 of file XrdFfsPosix.cc.

143{
144 return XrdPosixXrootd::Pread(fildes, buf, nbyte, (long long)offset);
145}
static ssize_t Pread(int fildes, void *buf, size_t nbyte, off_t offset)
Pread() conforms to POSIX.1-2001 pread()

References XrdPosixXrootd::Pread().

Referenced by XrdFfsWcache_pread(), and xrootdfs_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_pwrite()

ssize_t XrdFfsPosix_pwrite ( int fildes,
const void * buf,
size_t nbyte,
off_t offset )

Definition at line 152 of file XrdFfsPosix.cc.

153{
154 return XrdPosixXrootd::Pwrite(fildes, buf, nbyte, (long long) offset);
155}
static ssize_t Pwrite(int fildes, const void *buf, size_t nbyte, off_t offset)
Pwrite() conforms to POSIX.1-2001 pwrite()

References XrdPosixXrootd::Pwrite().

Referenced by XrdFfsWcache_flush(), and XrdFfsWcache_pwrite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_read()

ssize_t XrdFfsPosix_read ( int fildes,
void * buf,
size_t nbyte )

Definition at line 137 of file XrdFfsPosix.cc.

138{
139 return XrdPosixXrootd::Read(fildes, buf, nbyte);
140}
static ssize_t Read(int fildes, void *buf, size_t nbyte)
Read() conforms to POSIX.1-2001 read()

References XrdPosixXrootd::Read().

Here is the call graph for this function:

◆ XrdFfsPosix_readdir()

struct dirent * XrdFfsPosix_readdir ( DIR * dirp)

Definition at line 87 of file XrdFfsPosix.cc.

88{
89 return XrdPosixXrootd::Readdir(dirp);
90}
static struct dirent * Readdir(DIR *dirp)

References XrdPosixXrootd::Readdir().

Referenced by XrdFfsPosix_x_readdirall(), and xrootdfs_readdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_readdirall()

int XrdFfsPosix_readdirall ( const char * rdrurl,
const char * path,
char *** direntarray,
uid_t user_uid )

Definition at line 474 of file XrdFfsPosix.cc.

475{
476 int i, j, n, nents, nurls;
477 bool hasDirLock = false;
478
479 char *newurls[XrdFfs_MAX_NUM_NODES];
480 int res_i[XrdFfs_MAX_NUM_NODES];
481 int errno_i[XrdFfs_MAX_NUM_NODES];
482 struct XrdFfsDentnames *dir_i[XrdFfs_MAX_NUM_NODES] = {0};
485
486// for (i = 0; i < XrdFfs_MAX_NUM_NODES; i++)
487// dir_i[i] = NULL;
488
489 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
490/*
491 If a directory doesn't exist on any data server, it is better to return -1 with errno = ENOENT
492 than to return 0 with errno = 0. But this is difficult because it depends on correct returning
493 from XrdPosixXrootd::Opendir(). This has never been a problem for xrootdfs itself because FUSE
494 does stat() before readdir().
495
496 In the use case of XrdPssDir::Opendir(), it does expect this function to return -1/ENOENT. In
497 this use case the "rdrurl" contains the complete URL and "path" contains "" so "nurls" will be
498 zero if no data server has the directory. The following is a quick and dirty fix for this use
499 case. The orignal code was: if (nurls < 0) { errno = EACCES; return -1; }
500 */
501 if (nurls <= 0)
502 {
503 errno = (nurls == 0? ENOENT : EACCES);
504 return -1;
505 }
506
507 for (i = 0; i < nurls; i++)
508 {
509 errno_i[i] = 0;
510 strncat(newurls[i], path, MAXROOTURLLEN - strlen(newurls[i]) -1);
511 XrdFfsMisc_xrd_secsss_editurl(newurls[i], user_uid, 0);
512 args[i].url = newurls[i];
513 args[i].err = &errno_i[i];
514 args[i].res = &res_i[i];
515 args[i].dents = &dir_i[i];
516#ifdef NOUSE_QUEUE
517 XrdFfsPosix_x_readdirall((void*) &args[i]);
518 }
519#else
520 jobs[i] = XrdFfsQueue_create_task(XrdFfsPosix_x_readdirall, (void**)(&args[i]), 0);
521 }
522 for (i = 0; i < nurls; i++)
523 {
524 XrdFfsQueue_wait_task(jobs[i]);
525 XrdFfsQueue_free_task(jobs[i]);
526 }
527#endif
528
529 errno = 0;
530 for (i = 0; i < nurls; i++)
531 if (res_i[i] != 0 && errno_i[i] == 125) // when host i is down
532 {
533 errno = ETIMEDOUT;
534 syslog(LOG_WARNING, "WARNING: opendir(%s) failed (connection timeout)", newurls[i]);
535 break;
536 }
537
538 for (i = 0; i < nurls; i++)
539 free(newurls[i]);
540 for (i = 1; i < nurls; i++)
541 XrdFfsDent_names_join(&dir_i[i], &dir_i[i-1]);
542
543 char *last = NULL, **dnarraytmp;
544
545 n = XrdFfsDent_names_extract(&dir_i[nurls-1], &dnarraytmp);
546 *direntarray = (char **) malloc(sizeof(char*) * n);
547
548// note that dnarraytmp[] may contain redundant entries
549
550 nents = 0;
551 for (i = 0; i < n; i++)
552 {
553 // put DIR_LOCK to the last one to allow rm -rf to work...
554 //
555 if (! strcmp(dnarraytmp[i], "DIR_LOCK"))
556 {
557 hasDirLock = true;
558 continue;
559 }
560
561 if (i != 0) // can be used to filter out .lock .fail, etc.
562 {
563 char *tmp, *tmp_dot;
564 tmp = strdup(dnarraytmp[i]);
565 tmp_dot = tmp + strlen(tmp) - 5;
566
567 if (! strcmp(tmp_dot, ".lock") || ! strcmp(tmp_dot, ".fail")) // filter out .lock/.fail files
568 {
569 for (j = nents - 1; j >= 0; j--)
570 {
571 tmp_dot[0] = '\0';
572 if (! strcmp(tmp, (*direntarray)[j]))
573 {
574 tmp_dot[0] = '.';
575 free(tmp);
576 break;
577 }
578 }
579 if (j >= 0) continue; // found the file cooresponding to the .lock/.fail
580 }
581 free(tmp);
582 }
583
584 if (last == NULL || strcmp(last, dnarraytmp[i]) != 0)
585 {
586 last = dnarraytmp[i];
587 (*direntarray)[nents++] = strdup(dnarraytmp[i]);
588 }
589 }
590
591 for (i = 0; i < n; i++) free(dnarraytmp[i]); // do not mergo with the above because the above loop has 'break'.
592 free(dnarraytmp);
593
594/* inject this list into dent cache */
595
596 char *p;
597 p = strdup(path);
598 XrdFfsDent_cache_fill(p, direntarray, nents);
599 free(p);
600
601 if (hasDirLock) (*direntarray)[nents++] = strdup("DIR_LOCK");
602
603 return nents;
604}
void XrdFfsDent_names_join(struct XrdFfsDentnames **p, struct XrdFfsDentnames **n)
Definition XrdFfsDent.cc:78
int XrdFfsDent_cache_fill(char *dname, char ***dnarray, int nents)
int XrdFfsDent_names_extract(struct XrdFfsDentnames **p, char ***dnarray)
void * XrdFfsPosix_x_readdirall(void *x)

References XrdFfsQueueTasks::args, MAXROOTURLLEN, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_all_urls(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsPosix_x_readdirall(), and XrdFfsQueue_create_task().

Referenced by xrootdfs_readdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_rename()

int XrdFfsPosix_rename ( const char * oldpath,
const char * newpath )

Definition at line 167 of file XrdFfsPosix.cc.

168{
169 return XrdPosixXrootd::Rename(oldpath, newpath);
170}
static int Rename(const char *oldpath, const char *newpath)
Rename() conforms to POSIX.1-2001 rename()

References XrdPosixXrootd::Rename().

Referenced by XrdFfsPosix_renameall(), and xrootdfs_rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_renameall()

int XrdFfsPosix_renameall ( const char * rdrurl,
const char * from,
const char * to,
uid_t user_uid )

Definition at line 339 of file XrdFfsPosix.cc.

340{
341 int i, nurls, res, rval = 0;
342 struct stat stbuf;
343 char fromurl[1024], tourl[1024], *newurls[XrdFfs_MAX_NUM_NODES];
344
345 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
346 if (nurls < 0) rval = -1;
347
348 for (i = 0; i < nurls; i++)
349 {
350 errno = 0;
351
352 fromurl[0]='\0';
353 strcat(fromurl, newurls[i]);
354 strncat(fromurl, from, MAXROOTURLLEN - strlen(fromurl) -1);
355 tourl[0]='\0';
356 strcat(tourl, newurls[i]);
357 strncat(tourl, to, MAXROOTURLLEN - strlen(tourl) -1);
358
359 XrdFfsMisc_xrd_secsss_editurl(fromurl, user_uid, 0);
360 XrdFfsMisc_xrd_secsss_editurl(tourl, user_uid, 0);
361 res = (XrdFfsPosix_stat(fromurl, &stbuf));
362 if (res == 0)
363 {
364/* XrdFfsPosix_rename doesn't need this protection
365 newdir = strdup(tourl);
366 newdir = dirname(newdir);
367 if (XrdFfsPosix_stat(newdir, &stbuf) == -1)
368 XrdFfsPosix_mkdir(newdir, 0777);
369
370 free(newdir);
371*/
372 rval = XrdFfsPosix_rename(fromurl, tourl);
373 if (rval == -1)
374 {
375 syslog(LOG_WARNING, "WARNING: rename(%s, %s) failed (errno = %d)", fromurl, tourl, errno);
376 break;
377 }
378/* if a successful rename is followed by a failed one, will return failure (and leave both old and new files) for
379 user to investigate. */
380 }
381 }
382
383 for (i = 0; i < nurls; i++)
384 free(newurls[i]);
385
386 if (rval != 0 && errno == 0) errno = EIO;
387 return rval;
388}
int XrdFfsPosix_rename(const char *oldpath, const char *newpath)
int XrdFfsPosix_stat(const char *path, struct stat *buf)
#define stat(a, b)
Definition XrdPosix.hh:101

References MAXROOTURLLEN, stat, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_all_urls(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsPosix_rename(), and XrdFfsPosix_stat().

Referenced by xrootdfs_rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_rmdir()

int XrdFfsPosix_rmdir ( const char * path)

Definition at line 117 of file XrdFfsPosix.cc.

118{
119 return XrdPosixXrootd::Rmdir(path);
120}
static int Rmdir(const char *path)
Rmdir() conforms to POSIX.1-2001 rmdir()

References XrdPosixXrootd::Rmdir().

Referenced by XrdFfsPosix_x_deleteall(), and xrootdfs_rmdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_rmdirall()

int XrdFfsPosix_rmdirall ( const char * rdrurl,
const char * path,
uid_t user_uid )

Definition at line 334 of file XrdFfsPosix.cc.

335{
336 return XrdFfsPosix_deleteall(rdrurl, path, user_uid, S_IFDIR);
337}
int XrdFfsPosix_deleteall(const char *rdrurl, const char *path, uid_t user_uid, mode_t st_mode)

References XrdFfsPosix_deleteall().

Referenced by xrootdfs_rmdir().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_stat()

int XrdFfsPosix_stat ( const char * path,
struct stat * buf )

Definition at line 66 of file XrdFfsPosix.cc.

67{
68 int rc;
69 errno = 0;
70 rc = XrdPosixXrootd::Stat(path, buf);
71 if (rc == 0 && S_ISBLK(buf->st_mode)) /* If 'buf' come from HPSS, xrootd will return it as a block device! */
72 { /* So we re-mark it to a regular file */
73 buf->st_mode &= 0007777;
74 if ( buf->st_mode & S_IXUSR )
75 buf->st_mode |= S_IFDIR; /* a directory */
76 else
77 buf->st_mode |= S_IFREG; /* a file */
78 }
79 return rc;
80}
static int Stat(const char *path, struct stat *buf)
Stat() conforms to POSIX.1-2001 stat()

References XrdPosixXrootd::Stat(), and stat.

Referenced by XrdFfsMisc_get_current_url(), XrdFfsPosix_renameall(), XrdFfsPosix_statall(), XrdFfsPosix_truncateall(), XrdFfsPosix_x_statall(), xrootdfs_getattr(), xrootdfs_release(), and xrootdfs_rename().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_statall()

int XrdFfsPosix_statall ( const char * rdrurl,
const char * path,
struct stat * stbuf,
uid_t user_uid )

Definition at line 759 of file XrdFfsPosix.cc.

760{
761 int i, res, nurls;
762
763 char *newurls[XrdFfs_MAX_NUM_NODES];
764 int res_i[XrdFfs_MAX_NUM_NODES];
765 int errno_i[XrdFfs_MAX_NUM_NODES];
766 struct stat stbuf_i[XrdFfs_MAX_NUM_NODES];
769
770 char *p1, *p2, *dir, *file, rootpath[MAXROOTURLLEN];
771
772 rootpath[0] = '\0';
773 strncat(rootpath,rdrurl, MAXROOTURLLEN - strlen(rootpath) -1);
774 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
775 p1 = strdup(path);
776 p2 = strdup(path);
777 dir = dirname(p1);
778 file = basename(p2);
779
780// if task queue is too long, or if the stat() is from an ls -l command, the stat() against redirector
782 {
783 XrdFfsMisc_xrd_secsss_editurl(rootpath, user_uid, 0);
784 res = XrdFfsPosix_stat(rootpath, stbuf);
785// maybe a data server is down since the last _readdir()? in that case, continue
786// we also saw a case where redirectors report the file exist but meta redirector report
787// that the file doesn't exist, and we need to continue at here
788 if (res == 0)
789 {
790 free(p1);
791 free(p2);
792 return 0;
793 }
794 }
795 free(p1);
796 free(p2);
797
798 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
799
800 for (i = 0; i < nurls; i++)
801 {
802 strncat(newurls[i], path, MAXROOTURLLEN - strlen(path) -1);
803 XrdFfsMisc_xrd_secsss_editurl(newurls[i], user_uid, 0);
804 args[i].url = newurls[i];
805 args[i].res = &res_i[i];
806 args[i].err = &errno_i[i];
807 args[i].stbuf = &(stbuf_i[i]);
808#ifdef NOUSE_QUEUE
809 XrdFfsPosix_x_statall((void*) &args[i]);
810 }
811#else
812 jobs[i] = XrdFfsQueue_create_task(XrdFfsPosix_x_statall, (void**)(&args[i]), 0);
813 }
814 for (i = 0; i < nurls; i++)
815 {
816 XrdFfsQueue_wait_task(jobs[i]);
817 XrdFfsQueue_free_task(jobs[i]);
818 }
819#endif
820 res = -1;
821 errno = ENOENT;
822 for (i = 0; i < nurls; i++)
823 {
824 time_t max_mtime = 0;
825 if (res_i[i] == 0)
826 {
827 if (stbuf_i[i].st_mtime <= max_mtime) continue;
828 res = 0;
829 errno = 0;
830 memcpy((void*)stbuf, (void*)(&stbuf_i[i]), sizeof(struct stat));
831 break;
832 }
833 else if (res_i[i] != 0 && errno_i[i] == 125) // when host i is down
834 {
835 res = -1;
836 errno = ETIMEDOUT;
837 syslog(LOG_WARNING, "WARNING: stat(%s) failed (connection timeout)", newurls[i]);
838 }
839 }
840
841 for (i = 0; i < nurls; i++)
842 free(newurls[i]);
843
844 return res;
845}
int XrdFfsDent_cache_search(char *dname, char *dentname)
int XrdFfsMisc_get_number_of_data_servers()
void * XrdFfsPosix_x_statall(void *x)
unsigned int XrdFfsQueue_count_tasks()

References XrdFfsQueueTasks::args, MAXROOTURLLEN, XrdFfsPosixX_statall_args::res, stat, XrdFfs_MAX_NUM_NODES, XrdFfsDent_cache_search(), XrdFfsMisc_get_all_urls(), XrdFfsMisc_get_number_of_data_servers(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsPosix_stat(), XrdFfsPosix_x_statall(), XrdFfsQueue_count_tasks(), and XrdFfsQueue_create_task().

Referenced by xrootdfs_getattr().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_statvfsall()

int XrdFfsPosix_statvfsall ( const char * rdrurl,
const char * path,
struct statvfs * stbuf,
uid_t user_uid )

Definition at line 677 of file XrdFfsPosix.cc.

678{
679 int i, nurls;
680 short osscgroup;
681
682 char *newurls[XrdFfs_MAX_NUM_NODES];
683 int res_i[XrdFfs_MAX_NUM_NODES];
684 int errno_i[XrdFfs_MAX_NUM_NODES];
685 struct statvfs stbuf_i[XrdFfs_MAX_NUM_NODES];
688
689 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
690 if (nurls < 0)
691 {
692 errno = EACCES;
693 return -1;
694 }
695
696 if (strstr(path, "oss.cgroup") != NULL)
697 osscgroup = 1;
698 else
699 osscgroup = 0;
700 for (i = 0; i < nurls; i++)
701 {
702 strncat(newurls[i], path, MAXROOTURLLEN - strlen(newurls[i]) -1);
703// XrdFfsMisc_xrd_secsss_editurl(newurls[i], user_uid);
704 args[i].url = newurls[i];
705 args[i].res = &res_i[i];
706 args[i].err = &errno_i[i];
707 stbuf_i[i].f_bsize = stbuf->f_bsize;
708 args[i].stbuf = &(stbuf_i[i]);
709 args[i].osscgroup = osscgroup;
710#ifdef NOUSE_QUEUE
711 XrdFfsPosix_x_statvfsall((void*) &args[i]);
712 }
713#else
714 jobs[i] = XrdFfsQueue_create_task(XrdFfsPosix_x_statvfsall, (void**)(&args[i]), 0);
715 }
716 for (i = 0; i < nurls; i++)
717 {
718 XrdFfsQueue_wait_task(jobs[i]);
719 XrdFfsQueue_free_task(jobs[i]);
720 }
721#endif
722 /*
723 for statfs call, we don't care about return code and errno
724 */
725 stbuf->f_blocks = 0;
726 stbuf->f_bfree = 0;
727 stbuf->f_bavail = 0;
728 for (i = 0; i < nurls; i++)
729 {
730 stbuf->f_blocks += args[i].stbuf->f_blocks;
731 stbuf->f_bavail += args[i].stbuf->f_bavail;
732 stbuf->f_bfree += args[i].stbuf->f_bfree;
733 }
734
735 for (i = 0; i < nurls; i++)
736 free(newurls[i]);
737
738 return 0;
739}
void * XrdFfsPosix_x_statvfsall(void *x)
#define statvfs(a, b)
Definition XrdPosix.hh:105

References XrdFfsQueueTasks::args, MAXROOTURLLEN, XrdFfsPosixX_statvfsall_args::osscgroup, statvfs, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_all_urls(), XrdFfsPosix_x_statvfsall(), and XrdFfsQueue_create_task().

Referenced by xrootdfs_statfs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_truncate()

int XrdFfsPosix_truncate ( const char * path,
off_t Size )

Definition at line 176 of file XrdFfsPosix.cc.

177{
178 return XrdPosixXrootd::Truncate(path, Size);
179}
static int Truncate(const char *path, off_t offset)
Telldir() conforms to POSIX.1-2001 telldir()

References XrdPosixXrootd::Truncate().

Referenced by XrdFfsPosix_truncateall(), and xrootdfs_truncate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_truncateall()

int XrdFfsPosix_truncateall ( const char * rdrurl,
const char * path,
off_t size,
uid_t user_uid )

Definition at line 390 of file XrdFfsPosix.cc.

391{
392 int i, nurls, res, rval = 0;
393 struct stat stbuf;
394 char *newurls[XrdFfs_MAX_NUM_NODES];
395
396 nurls = XrdFfsMisc_get_all_urls(rdrurl, newurls, XrdFfs_MAX_NUM_NODES);
397 if (nurls < 0) rval = -1;
398
399 for (i = 0; i < nurls; i++)
400 {
401 errno = 0;
402 strncat(newurls[i],path, MAXROOTURLLEN - strlen(newurls[i]) -1);
403 XrdFfsMisc_xrd_secsss_editurl(newurls[i], user_uid, 0);
404 res = (XrdFfsPosix_stat(newurls[i], &stbuf));
405 if (res == 0)
406 {
407 if (S_ISREG(stbuf.st_mode))
408 rval = XrdFfsPosix_truncate(newurls[i], size);
409 else
410 rval = -1;
411 if (rval == -1)
412 {
413 syslog(LOG_WARNING, "WARNING: (f)truncate(%s) failed (errno = %d)", newurls[i], errno);
414 break;
415 }
416/* again, it will be messy if a successful truncate is followed by a failed one */
417 }
418 else if (errno != ENOENT)
419 rval = -1;
420 }
421
422 for (i = 0; i < nurls; i++)
423 free(newurls[i]);
424
425 if (rval != 0 && errno == 0) errno = EIO;
426 return rval;
427}
int XrdFfsPosix_truncate(const char *path, off_t Size)

References MAXROOTURLLEN, stat, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_all_urls(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsPosix_stat(), and XrdFfsPosix_truncate().

Referenced by xrootdfs_truncate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_unlink()

int XrdFfsPosix_unlink ( const char * path)

Definition at line 162 of file XrdFfsPosix.cc.

163{
164 return XrdPosixXrootd::Unlink(path);
165}
static int Unlink(const char *path)
Unlink() conforms to POSIX.1-2001 unlink()

References XrdPosixXrootd::Unlink().

Referenced by XrdFfsPosix_clear_from_rdr_cache(), XrdFfsPosix_x_deleteall(), and xrootdfs_unlink().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_unlinkall()

int XrdFfsPosix_unlinkall ( const char * rdrurl,
const char * path,
uid_t user_uid )

Definition at line 329 of file XrdFfsPosix.cc.

330{
331 return XrdFfsPosix_deleteall(rdrurl, path, user_uid, S_IFREG);
332}

References XrdFfsPosix_deleteall().

Referenced by xrootdfs_unlink().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_write()

ssize_t XrdFfsPosix_write ( int fildes,
const void * buf,
size_t nbyte )

Definition at line 147 of file XrdFfsPosix.cc.

148{
149 return XrdPosixXrootd::Write(fildes, buf, nbyte);
150}
static ssize_t Write(int fildes, const void *buf, size_t nbyte)
Write() conforms to POSIX.1-2001 write()

References XrdPosixXrootd::Write().

Referenced by xrootdfs_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_x_deleteall()

void * XrdFfsPosix_x_deleteall ( void * x)

Definition at line 255 of file XrdFfsPosix.cc.

256{
258
259 if (S_ISREG(args->st_mode))
260 *(args->res) = XrdFfsPosix_unlink(args->url);
261 else if (S_ISDIR(args->st_mode))
262 *(args->res) = XrdFfsPosix_rmdir(args->url);
263
264 *(args->err) = errno;
265 return NULL;
266}
int XrdFfsPosix_rmdir(const char *path)

References XrdFfsPosixX_deleteall_args::err, XrdFfsPosixX_deleteall_args::res, XrdFfsPosixX_deleteall_args::st_mode, XrdFfsPosixX_deleteall_args::url, XrdFfsPosix_rmdir(), and XrdFfsPosix_unlink().

Referenced by XrdFfsPosix_deleteall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_x_readdirall()

void * XrdFfsPosix_x_readdirall ( void * x)

Definition at line 445 of file XrdFfsPosix.cc.

446{
448 DIR *dp;
449 struct dirent *de;
450
451/*
452 Xrootd's Opendir will not return NULL even under some error. For instance,
453 when it is supposed to return ENOENT or ENOTDIR, it actually returns
454 EINPROGRESS (115), and DIR *dp will not be NULL.
455 */
456 dp = XrdFfsPosix_opendir(args->url);
457 if ( dp == NULL && errno != 0)
458 {
459 *(args->err) = errno;
460 *(args->res) = -1;
461 if (dp != NULL)
463 }
464 else
465 {
466 *(args->res) = 0;
467 while ((de = XrdFfsPosix_readdir(dp)) != NULL)
468 XrdFfsDent_names_add(args->dents, de->d_name);
470 }
471 return NULL;
472}
void XrdFfsDent_names_add(struct XrdFfsDentnames **p, char *name)
Definition XrdFfsDent.cc:56
DIR * XrdFfsPosix_opendir(const char *path)
struct dirent * XrdFfsPosix_readdir(DIR *dirp)
int XrdFfsPosix_closedir(DIR *dirp)
struct XrdFfsDentnames ** dents

References XrdFfsPosixX_readdirall_args::dents, XrdFfsPosixX_readdirall_args::err, XrdFfsPosixX_readdirall_args::res, XrdFfsPosixX_readdirall_args::url, XrdFfsDent_names_add(), XrdFfsPosix_closedir(), XrdFfsPosix_opendir(), and XrdFfsPosix_readdir().

Referenced by XrdFfsPosix_readdirall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_x_statall()

void * XrdFfsPosix_x_statall ( void * x)

Definition at line 750 of file XrdFfsPosix.cc.

751{
752 struct XrdFfsPosixX_statall_args *args = (struct XrdFfsPosixX_statall_args *)x;
753
754 *(args->res) = XrdFfsPosix_stat(args->url, args->stbuf);
755 *(args->err) = errno;
756 return (void *)0;
757}

References XrdFfsPosixX_statall_args::err, XrdFfsPosixX_statall_args::res, XrdFfsPosixX_statall_args::stbuf, XrdFfsPosixX_statall_args::url, and XrdFfsPosix_stat().

Referenced by XrdFfsPosix_statall().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ XrdFfsPosix_x_statvfsall()

void * XrdFfsPosix_x_statvfsall ( void * x)

Definition at line 619 of file XrdFfsPosix.cc.

620{
622 char xattr[256];
623 off_t oss_size;
624 long long llVal;
625
626 *(args->res) = XrdFfsPosix_getxattr(args->url, "xroot.space.oss.space", xattr, 256);
627 *(args->err) = errno;
628 sscanf((const char*)xattr, "%lld", &llVal);
629 oss_size = static_cast<off_t>(llVal);
630 args->stbuf->f_blocks = (fsblkcnt_t) (oss_size / args->stbuf->f_bsize);
631// sscanf((const char*)xattr, "%lld", &(args->stbuf->f_blocks));
632 if (*(args->res) == -1)
633 {
634 args->stbuf->f_blocks = 0;
635 args->stbuf->f_bavail = 0;
636 args->stbuf->f_bfree = 0;
637 return NULL;
638 }
639 *(args->res) = XrdFfsPosix_getxattr(args->url, "xroot.space.oss.free", xattr, 256);
640 *(args->err) = errno;
641 sscanf((const char*)xattr, "%lld", &llVal);
642 oss_size = static_cast<off_t>(llVal);
643 args->stbuf->f_bavail = (fsblkcnt_t) (oss_size / args->stbuf->f_bsize);
644// sscanf((const char*)xattr, "%lld", &(args->stbuf->f_bavail));
645 if (*(args->res) == -1)
646 {
647 args->stbuf->f_blocks = 0;
648 args->stbuf->f_bavail = 0;
649 args->stbuf->f_bfree = 0;
650 return NULL;
651 }
652
653/*
654 The relation of the output of df and stbuf->f_blocks, f_bfree and f_bavail is
655 Filesystem Size Used Avail Use% Mounted on
656 f_blocks f_blocks - f_bfree f_bavail
657
658 In the case of querying without oss.cgroup, f_bfree = f_bavail (e.g. Used is used space by all oss.space)
659 In the case of querying with oss.cgroup, Used is used space by the specified oss.space (oss_size/f_bsize) and
660 therefore f_bfree = f_blocks - oss_size / f_bsize (e.g. Used is oss_size / f_bsize)
661 */
662
663 if (args->osscgroup != 1)
664 args->stbuf->f_bfree = args->stbuf->f_bavail;
665 else
666 {
667 *(args->res) = XrdFfsPosix_getxattr(args->url, "xroot.space.oss.used", xattr, 256);
668 *(args->err) = errno;
669 sscanf((const char*)xattr, "%lld", &llVal);
670 oss_size = static_cast<off_t>(llVal);
671 args->stbuf->f_bfree = args->stbuf->f_blocks - (fsblkcnt_t) (oss_size / args->stbuf->f_bsize);
672// args->stbuf->f_bfree = args->stbuf->f_blocks - oss_size;
673 }
674 return NULL;
675}
long long XrdFfsPosix_getxattr(const char *path, const char *name, void *value, unsigned long long size)

References XrdFfsPosixX_statvfsall_args::err, XrdFfsPosixX_statvfsall_args::osscgroup, XrdFfsPosixX_statvfsall_args::res, XrdFfsPosixX_statvfsall_args::stbuf, XrdFfsPosixX_statvfsall_args::url, and XrdFfsPosix_getxattr().

Referenced by XrdFfsPosix_statvfsall().

Here is the call graph for this function:
Here is the caller graph for this function: