XRootD
Loading...
Searching...
No Matches
XrdFfsXrootdfs.cc File Reference
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <stddef.h>
#include <fuse.h>
#include <fuse/fuse_opt.h>
#include <cctype>
#include <cstring>
#include <fcntl.h>
#include <dirent.h>
#include <cerrno>
#include <sys/time.h>
#include <pthread.h>
#include <pwd.h>
#include <libgen.h>
#include <syslog.h>
#include <signal.h>
#include <sys/xattr.h>
#include "XrdFfs/XrdFfsPosix.hh"
#include "XrdFfs/XrdFfsMisc.hh"
#include "XrdFfs/XrdFfsWcache.hh"
#include "XrdFfs/XrdFfsQueue.hh"
#include "XrdFfs/XrdFfsFsinfo.hh"
#include "XrdPosix/XrdPosixXrootd.hh"
+ Include dependency graph for XrdFfsXrootdfs.cc:

Go to the source code of this file.

Classes

struct  XROOTDFS
 

Macros

#define FUSE_USE_VERSION   26
 
#define MAXROOTURLLEN   1024
 

Enumerations

enum  {
  OPT_KEY_HELP ,
  OPT_KEY_SECSSS
}
 

Functions

int main (int argc, char *argv[])
 
void * XrdFfsMisc_logging_url_cache_pthread_create_cast (void *arg)
 
static int xrootdfs_access (const char *path, int mask)
 
static int xrootdfs_chmod (const char *path, mode_t mode)
 
static int xrootdfs_chown (const char *path, uid_t uid, gid_t gid)
 
static int xrootdfs_create (const char *path, mode_t mode, struct fuse_file_info *fi)
 
static int xrootdfs_do_create (const char *path, const char *url, int oflags, bool use_link_id, int *fd)
 
static int xrootdfs_fsync (const char *path, int isdatasync, struct fuse_file_info *fi)
 
static int xrootdfs_ftruncate (const char *path, off_t size, struct fuse_file_info *fi)
 
static int xrootdfs_getattr (const char *path, struct stat *stbuf)
 
static int xrootdfs_getxattr (const char *path, const char *name, char *value, size_t size)
 
static void * xrootdfs_init (struct fuse_conn_info *conn)
 
static int xrootdfs_link (const char *from, const char *to)
 
static int xrootdfs_listxattr (const char *path, char *list, size_t size)
 
static int xrootdfs_mkdir (const char *path, mode_t mode)
 
static int xrootdfs_mknod (const char *path, mode_t mode, dev_t rdev)
 
static int xrootdfs_open (const char *path, struct fuse_file_info *fi)
 
static int xrootdfs_opt_proc (void *data, const char *arg, int key, struct fuse_args *outargs)
 
static int xrootdfs_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
 
static int xrootdfs_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
 
static int xrootdfs_readlink (const char *path, char *buf, size_t size)
 
static int xrootdfs_release (const char *path, struct fuse_file_info *fi)
 
static int xrootdfs_removexattr (const char *path, const char *name)
 
static int xrootdfs_rename (const char *from, const char *to)
 
static int xrootdfs_rmdir (const char *path)
 
static int xrootdfs_setxattr (const char *path, const char *name, const char *value, size_t size, int flags)
 
void xrootdfs_sigusr1_handler (int sig)
 
static int xrootdfs_statfs (const char *path, struct statvfs *stbuf)
 
static int xrootdfs_symlink (const char *from, const char *to)
 
static int xrootdfs_truncate (const char *path, off_t size)
 
static int xrootdfs_unlink (const char *path)
 
static void xrootdfs_usage (const char *progname)
 
static int xrootdfs_utimens (const char *path, const struct timespec ts[2])
 
static int xrootdfs_write (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
 

Variables

int cwdfd
 
bool usingEC = false
 
struct XROOTDFS xrootdfs
 
static struct fuse_operations xrootdfs_oper
 
static struct fuse_opt xrootdfs_opts [14]
 

Class Documentation

◆ XROOTDFS

struct XROOTDFS

Definition at line 72 of file XrdFfsXrootdfs.cc.

+ Collaboration diagram for XROOTDFS:
Class Members
char * cns
char * daemon_user
char * fastls
int maxfd
int nworkers
bool ofsfwd
char * rdr
char * ssskeytab
char * urlcachelife

Macro Definition Documentation

◆ FUSE_USE_VERSION

#define FUSE_USE_VERSION   26

Definition at line 30 of file XrdFfsXrootdfs.cc.

◆ MAXROOTURLLEN

#define MAXROOTURLLEN   1024

Definition at line 70 of file XrdFfsXrootdfs.cc.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_KEY_HELP 
OPT_KEY_SECSSS 

Definition at line 89 of file XrdFfsXrootdfs.cc.

@ OPT_KEY_HELP
@ OPT_KEY_SECSSS

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 1314 of file XrdFfsXrootdfs.cc.

1315{
1343 xrootdfs_oper.removexattr = xrootdfs_removexattr;
1344
1345/* Define XrootdFS options */
1346 char **cmdline_opts;
1347
1348 if (getenv("XRDCL_EC")) usingEC = true;
1349
1350 cmdline_opts = (char **) malloc(sizeof(char*) * (argc -1 + 3));
1351 cmdline_opts[0] = argv[0];
1352 cmdline_opts[1] = strdup("-o");
1353 if (getenv("XROOTDFS_NO_ALLOW_OTHER") != NULL && ! strcmp(getenv("XROOTDFS_NO_ALLOW_OTHER"),"1") )
1354 {
1355 if (! usingEC)
1356 cmdline_opts[2] = strdup("fsname=xrootdfs,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5");
1357 else
1358 cmdline_opts[2] = strdup("fsname=xrootdfs,max_write=131072,attr_timeout=10,entry_timeout=0,negative_timeout=5");
1359 }
1360 else
1361 {
1362 if (! usingEC)
1363 cmdline_opts[2] = strdup("fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5");
1364 else
1365 cmdline_opts[2] = strdup("fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=0,negative_timeout=5");
1366 }
1367
1368 for (int i = 1; i < argc; i++)
1369 cmdline_opts[i+2] = argv[i];
1370
1371 struct fuse_args args = FUSE_ARGS_INIT(argc -1 + 3, cmdline_opts);
1372
1373 xrootdfs_opts[0].templ = "-h";
1374 xrootdfs_opts[0].offset = -1U;
1375 xrootdfs_opts[0].value = OPT_KEY_HELP;
1376
1377 xrootdfs_opts[1].templ = "-help";
1378 xrootdfs_opts[1].offset = -1U;
1379 xrootdfs_opts[1].value = OPT_KEY_HELP;
1380
1381 xrootdfs_opts[2].templ = "--help";
1382 xrootdfs_opts[2].offset = -1U;
1383 xrootdfs_opts[2].value = OPT_KEY_HELP;
1384
1385 xrootdfs_opts[3].templ = "rdr=%s";
1386 xrootdfs_opts[3].offset = offsetof(struct XROOTDFS, rdr);
1387 xrootdfs_opts[3].value = 0;
1388
1389 xrootdfs_opts[4].templ = "cns=%s";
1390 xrootdfs_opts[4].offset = offsetof(struct XROOTDFS, cns);
1391 xrootdfs_opts[4].value = 0;
1392
1393 xrootdfs_opts[5].templ = "fastls=%s";
1394 xrootdfs_opts[5].offset = offsetof(struct XROOTDFS, fastls);
1395 xrootdfs_opts[5].value = 0;
1396
1397 xrootdfs_opts[6].templ = "uid=%s";
1398 xrootdfs_opts[6].offset = offsetof(struct XROOTDFS, daemon_user);
1399 xrootdfs_opts[6].value = 0;
1400
1401 xrootdfs_opts[7].templ = "ofsfwd=%s";
1402 xrootdfs_opts[7].offset = offsetof(struct XROOTDFS, ofsfwd);
1403 xrootdfs_opts[7].value = 0;
1404
1405/* using "sss" security module. the actually location of the key is determined
1406 by shell enviornment variable XrdSecsssKT (or default locations). */
1407
1408/* The location of the key is not specified in command line. */
1409 xrootdfs_opts[8].templ = "sss";
1410 xrootdfs_opts[8].offset = -1U;
1411 xrootdfs_opts[8].value = OPT_KEY_SECSSS;
1412
1413/* The location of the key is specified in command line. */
1414 xrootdfs_opts[9].templ = "sss=%s";
1415 xrootdfs_opts[9].offset = offsetof(struct XROOTDFS, ssskeytab);
1416 xrootdfs_opts[9].value = 0;
1417
1418/* life time of the data server list */
1419 xrootdfs_opts[10].templ = "refreshdslist=%s";
1420 xrootdfs_opts[10].offset = offsetof(struct XROOTDFS, urlcachelife);
1421 xrootdfs_opts[10].value = 0;
1422
1423/* number of workers to handle parallel requests to data servers */
1424 xrootdfs_opts[11].templ = "nworkers=%d";
1425 xrootdfs_opts[11].offset = offsetof(struct XROOTDFS, nworkers);
1426 xrootdfs_opts[11].value = 0;
1427
1428/* number of virtual file descriptors */
1429 xrootdfs_opts[12].templ = "maxfd=%d";
1430 xrootdfs_opts[12].offset = offsetof(struct XROOTDFS, maxfd);
1431 xrootdfs_opts[12].value = 0;
1432
1433 xrootdfs_opts[13].templ = NULL;
1434
1435/* initialize struct xrootdfs */
1436// memset(&xrootdfs, 0, sizeof(xrootdfs));
1437 xrootdfs.rdr = NULL;
1438 xrootdfs.cns = NULL;
1439 xrootdfs.fastls = NULL;
1440 xrootdfs.daemon_user = NULL;
1441 xrootdfs.ofsfwd = false;
1442 xrootdfs.ssskeytab = NULL;
1443 xrootdfs.urlcachelife = strdup("3650d"); /* 10 years */
1444 xrootdfs.nworkers = 4;
1445 xrootdfs.maxfd = 8192;
1446
1447/* Get options from environment variables first */
1448 xrootdfs.rdr = getenv("XROOTDFS_RDRURL");
1449 xrootdfs.cns = getenv("XROOTDFS_CNSURL");
1450 xrootdfs.fastls = getenv("XROOTDFS_FASTLS");
1451// If this is defined, XrootdFS will setuid/setgid to this user at xrootdfs_init().
1452 xrootdfs.daemon_user = getenv("XROOTDFS_USER");
1453 if (getenv("XROOTDFS_OFSFWD") != NULL && ! strcmp(getenv("XROOTDFS_OFSFWD"),"1")) xrootdfs.ofsfwd = true;
1454 if (getenv("XROOTDFS_NWORKERS") != NULL) sscanf(getenv("XROOTDFS_NWORKERS"), "%d", &xrootdfs.nworkers);
1455 if (getenv("XROOTDFS_MAXFD") != NULL) sscanf(getenv("XROOTDFS_MAXFD"), "%d", &xrootdfs.maxfd);
1456
1457/* Parse XrootdFS options, will overwrite those defined in environment variables */
1458 fuse_opt_parse(&args, &xrootdfs, xrootdfs_opts, xrootdfs_opt_proc);
1459
1460/* make sure xrootdfs.rdr is specified */
1461 if (xrootdfs.rdr == NULL)
1462 {
1463 argc = 2;
1464 argv[1] = strdup("-h");
1465 struct fuse_args xargs = FUSE_ARGS_INIT(argc, argv);
1466 fuse_opt_parse(&xargs, &xrootdfs, xrootdfs_opts, xrootdfs_opt_proc);
1467 }
1468
1469/* convert xroot://... to root://... */
1470 if (xrootdfs.rdr != NULL && xrootdfs.rdr[0] == 'x') xrootdfs.rdr += 1;
1471 if (xrootdfs.cns != NULL && xrootdfs.cns[0] == 'x') xrootdfs.cns += 1;
1472/*
1473 XROOTDFS_OFSFWD (ofs.fwd (and ofs.fwd 3way) on rm, rmdir, mv, truncate.
1474 if this is not defined, XrootdFS will go to CNS and each data server
1475 and do the work.
1476
1477 If CNS is not defined, we have to set ofsfwd to false, or we will not be able to
1478 get a return status of rm, rmdir, mv and truncate.
1479 */
1480 if (xrootdfs.cns == NULL) xrootdfs.ofsfwd = false;
1481
1482 if (xrootdfs.ssskeytab != NULL)
1483 {
1484 setenv("XROOTDFS_SECMOD", "sss", 1);
1485 setenv("XrdSecsssKT", xrootdfs.ssskeytab, 1);
1486 }
1487
1488 if (xrootdfs.maxfd < 2048) xrootdfs.maxfd = 2048;
1489
1490 signal(SIGUSR1,xrootdfs_sigusr1_handler);
1491
1492 cwdfd = open(".",O_RDONLY);
1493 umask(0);
1494
1495 return fuse_main(args.argc, args.argv, &xrootdfs_oper, NULL);
1496}
static int xrootdfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
static int xrootdfs_mknod(const char *path, mode_t mode, dev_t rdev)
static int xrootdfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
static int xrootdfs_release(const char *path, struct fuse_file_info *fi)
static int xrootdfs_link(const char *from, const char *to)
static int xrootdfs_getxattr(const char *path, const char *name, char *value, size_t size)
char * fastls
static struct fuse_opt xrootdfs_opts[14]
static int xrootdfs_fsync(const char *path, int isdatasync, struct fuse_file_info *fi)
static int xrootdfs_symlink(const char *from, const char *to)
int cwdfd
bool usingEC
static int xrootdfs_rmdir(const char *path)
void xrootdfs_sigusr1_handler(int sig)
static int xrootdfs_open(const char *path, struct fuse_file_info *fi)
static int xrootdfs_access(const char *path, int mask)
static int xrootdfs_utimens(const char *path, const struct timespec ts[2])
struct XROOTDFS xrootdfs
static int xrootdfs_create(const char *path, mode_t mode, struct fuse_file_info *fi)
static int xrootdfs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags)
char * urlcachelife
static int xrootdfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
char * ssskeytab
static int xrootdfs_removexattr(const char *path, const char *name)
static int xrootdfs_readlink(const char *path, char *buf, size_t size)
static int xrootdfs_truncate(const char *path, off_t size)
static int xrootdfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
static struct fuse_operations xrootdfs_oper
static int xrootdfs_rename(const char *from, const char *to)
static int xrootdfs_listxattr(const char *path, char *list, size_t size)
static void * xrootdfs_init(struct fuse_conn_info *conn)
static int xrootdfs_mkdir(const char *path, mode_t mode)
static int xrootdfs_chown(const char *path, uid_t uid, gid_t gid)
static int xrootdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
char * daemon_user
static int xrootdfs_getattr(const char *path, struct stat *stbuf)
static int xrootdfs_unlink(const char *path)
static int xrootdfs_statfs(const char *path, struct statvfs *stbuf)
static int xrootdfs_chmod(const char *path, mode_t mode)
#define open
Definition XrdPosix.hh:76

References XROOTDFS::cns, cwdfd, XROOTDFS::daemon_user, XROOTDFS::fastls, XROOTDFS::maxfd, XROOTDFS::nworkers, XROOTDFS::ofsfwd, open, OPT_KEY_HELP, OPT_KEY_SECSSS, XROOTDFS::rdr, XROOTDFS::ssskeytab, XROOTDFS::urlcachelife, usingEC, xrootdfs, xrootdfs_access(), xrootdfs_chmod(), xrootdfs_chown(), xrootdfs_create(), xrootdfs_fsync(), xrootdfs_ftruncate(), xrootdfs_getattr(), xrootdfs_getxattr(), xrootdfs_init(), xrootdfs_link(), xrootdfs_listxattr(), xrootdfs_mkdir(), xrootdfs_mknod(), xrootdfs_open(), xrootdfs_oper, xrootdfs_opt_proc(), xrootdfs_opts, xrootdfs_read(), xrootdfs_readdir(), xrootdfs_readlink(), xrootdfs_release(), xrootdfs_removexattr(), xrootdfs_rename(), xrootdfs_rmdir(), xrootdfs_setxattr(), xrootdfs_sigusr1_handler(), xrootdfs_statfs(), xrootdfs_symlink(), xrootdfs_truncate(), xrootdfs_unlink(), xrootdfs_utimens(), and xrootdfs_write().

+ Here is the call graph for this function:

◆ XrdFfsMisc_logging_url_cache_pthread_create_cast()

void * XrdFfsMisc_logging_url_cache_pthread_create_cast ( void *  arg)

Definition at line 1234 of file XrdFfsXrootdfs.cc.

1235{
1236 XrdFfsMisc_logging_url_cache( reinterpret_cast<char*>( arg ) );
1237 return 0;
1238}
void XrdFfsMisc_logging_url_cache(const char *url)

References XrdFfsMisc_logging_url_cache().

Referenced by xrootdfs_sigusr1_handler().

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

◆ xrootdfs_access()

static int xrootdfs_access ( const char *  path,
int  mask 
)
static

Definition at line 283 of file XrdFfsXrootdfs.cc.

284{
285/*
286 int res;
287 res = access(path, mask);
288 if (res == -1)
289 return -errno;
290*/
291 return 0;
292}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_chmod()

static int xrootdfs_chmod ( const char *  path,
mode_t  mode 
)
static

Definition at line 674 of file XrdFfsXrootdfs.cc.

675{
676/*
677 int res;
678
679 res = chmod(path, mode);
680 if (res == -1)
681 return -errno;
682*/
683 return 0;
684}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_chown()

static int xrootdfs_chown ( const char *  path,
uid_t  uid,
gid_t  gid 
)
static

Definition at line 686 of file XrdFfsXrootdfs.cc.

687{
688/*
689 int res;
690
691 res = lchown(path, uid, gid);
692 if (res == -1)
693 return -errno;
694*/
695 return 0;
696}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_create()

static int xrootdfs_create ( const char *  path,
mode_t  mode,
struct fuse_file_info *  fi 
)
static

Definition at line 443 of file XrdFfsXrootdfs.cc.

453{
454 int res, fd;
455 if (!S_ISREG(mode))
456 return -EPERM;
457 if (usingEC)
458 res = xrootdfs_do_create(path, xrootdfs.rdr, O_CREAT | O_WRONLY | O_EXCL, true, &fd);
459 else
460 res = xrootdfs_do_create(path, xrootdfs.rdr, O_CREAT | O_WRONLY, true, &fd);
461 if (res < 0) return res;
462 fi->fh = fd;
463 XrdFfsWcache_create(fd, fi->flags); // Unlike mknod and like open, prepare wcache.
464 if (xrootdfs.cns != NULL)
465 {
466 xrootdfs_do_create(path, xrootdfs.cns, O_CREAT | O_EXCL, false, &fd);
468 }
469 return res;
470}
int XrdFfsPosix_close(int fildes)
int XrdFfsWcache_create(int fd, int flags)
static int xrootdfs_do_create(const char *path, const char *url, int oflags, bool use_link_id, int *fd)

References XROOTDFS::cns, XROOTDFS::rdr, usingEC, XrdFfsPosix_close(), XrdFfsWcache_create(), xrootdfs, and xrootdfs_do_create().

Referenced by main().

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

◆ xrootdfs_do_create()

static int xrootdfs_do_create ( const char *  path,
const char *  url,
int  oflags,
bool  use_link_id,
int *  fd 
)
static

Definition at line 371 of file XrdFfsXrootdfs.cc.

382{
383 int res, link_id;
384 int *p_link_id = NULL;
385 char rootpath[MAXROOTURLLEN] = "";
386
387 if (use_link_id)
388 p_link_id = &link_id;
389
390 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, p_link_id);
391 strncat(rootpath, url, MAXROOTURLLEN - strlen(rootpath) - 1);
392 strncat(rootpath, path, MAXROOTURLLEN - strlen(rootpath) - 1);
393
394 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, p_link_id);
395 res = XrdFfsPosix_open(rootpath, oflags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
396 if (res == -1)
397 return -errno;
398 if (fd != NULL)
399 *fd = res;
400 return 0;
401}
void XrdFfsMisc_xrd_secsss_register(uid_t user_uid, gid_t user_gid, int *id)
void XrdFfsMisc_xrd_secsss_editurl(char *url, uid_t user_uid, int *id)
int XrdFfsPosix_open(const char *path, int oflags, mode_t mode)
#define MAXROOTURLLEN

References MAXROOTURLLEN, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), and XrdFfsPosix_open().

Referenced by xrootdfs_create(), and xrootdfs_mknod().

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

◆ xrootdfs_fsync()

static int xrootdfs_fsync ( const char *  path,
int  isdatasync,
struct fuse_file_info *  fi 
)
static

Definition at line 1026 of file XrdFfsXrootdfs.cc.

1028{
1029 int fd;
1030
1031 fd = (int) fi->fh;
1034 return 0;
1035}
int XrdFfsPosix_fsync(int fildes)
ssize_t XrdFfsWcache_flush(int fd)

References XrdFfsPosix_fsync(), and XrdFfsWcache_flush().

Referenced by main().

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

◆ xrootdfs_ftruncate()

static int xrootdfs_ftruncate ( const char *  path,
off_t  size,
struct fuse_file_info *  fi 
)
static

Definition at line 699 of file XrdFfsXrootdfs.cc.

701{
702 int fd, res;
703// char rootpath[1024];
704
705 fd = (int) fi->fh;
707 res = XrdFfsPosix_ftruncate(fd, size);
708 if (res == -1)
709 return -errno;
710
711/*
712 There is no need to update the size of the CNS shadow file now. That
713 should be updated when the file is closed
714
715 if (xrootdfs.cns != NULL)
716 {
717 rootpath[0]='\0';
718 strcat(rootpath,xrootdfs.cns);
719 strcat(rootpath,path);
720
721 res = XrdFfsPosix_truncate(rootpath, size);
722 if (res == -1)
723 return -errno;
724 }
725*/
726 return 0;
727}
int XrdFfsPosix_ftruncate(int fildes, off_t offset)

References XrdFfsPosix_ftruncate(), and XrdFfsWcache_flush().

Referenced by main().

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

◆ xrootdfs_getattr()

static int xrootdfs_getattr ( const char *  path,
struct stat stbuf 
)
static

Definition at line 166 of file XrdFfsXrootdfs.cc.

167{
168// int res, fd;
169 int res;
170 char rootpath[MAXROOTURLLEN];
171// uid_t user_uid, uid;
172// gid_t user_gid, gid;
173
174// user_uid = fuse_get_context()->uid;
175// uid = getuid();
176
177// user_gid = fuse_get_context()->gid;
178// gid = getgid();
179
180 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
181
182 rootpath[0]='\0';
183/*
184 if (xrootdfs.cns != NULL && xrootdfs.fastls != NULL)
185 strcat(rootpath,xrootdfs.cns);
186 else
187 strcat(rootpath,xrootdfs.rdr);
188 strcat(rootpath,path);
189
190// setegid(fuse_get_context()->gid);
191// seteuid(fuse_get_context()->uid);
192
193 res = XrdFfsPosix_stat(rootpath, stbuf);
194*/
195
196 if (xrootdfs.cns != NULL && xrootdfs.fastls != NULL)
197 {
198 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
199 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
200 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
201 res = XrdFfsPosix_stat(rootpath, stbuf);
202 }
203 else
204 res = XrdFfsPosix_statall(xrootdfs.rdr, path, stbuf, fuse_get_context()->uid);
205
206// seteuid(getuid());
207// setegid(getgid());
208
209// stbuf->st_uid = user_uid;
210// stbuf->st_gid = user_gid;
211
212 if (res == 0)
213 {
214 if (S_ISREG(stbuf->st_mode))
215 {
216/*
217 By adding the following 'if' block, 'xrootdfs.fastls = RDR' will force XrootdFS to check
218 with redirector for file status info (not directory).
219
220 Some applicatios such as SRM may do extensive file or directory existence checking.
221 These applications can't tolerant slow responding on file or directory info (if
222 don't exist). They also expect correct file size. For this type of application, we
223 can set 'xrootdfs.fastls = RDR'.
224
225 Allowing multi-thread may solve this problem. However, XrootdFS crashs under some
226 situation, and we have to add -s (single thread) option when runing XrootdFS.
227 */
228 if (xrootdfs.cns != NULL && xrootdfs.fastls != NULL && strcmp(xrootdfs.fastls,"RDR") == 0)
229 {
230 rootpath[0]='\0';
231 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
232 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
233 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
234 XrdFfsPosix_stat(rootpath, stbuf);
235// stbuf->st_uid = user_uid;
236// stbuf->st_gid = user_gid;
237 }
238 stbuf->st_mode |= 0666;
239 stbuf->st_mode &= 0772777; /* remove sticky bit and suid bit */
240 stbuf->st_blksize = 32768; /* unfortunately, it is ignored, see include/fuse.h */
241 return 0;
242 }
243 else if (S_ISDIR(stbuf->st_mode))
244 {
245 stbuf->st_mode |= 0777;
246 stbuf->st_mode &= 0772777; /* remove sticky bit and suid bit */
247 return 0;
248 }
249 else
250 return -EIO;
251 }
252 else if (res == -1 && xrootdfs.cns != NULL && xrootdfs.fastls != NULL)
253 return -errno;
254 else if (xrootdfs.cns == NULL)
255 return -errno;
256 else
257 {
258 rootpath[0]='\0';
259 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
260 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
261 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
262 res = XrdFfsPosix_stat(rootpath, stbuf);
263// stbuf->st_uid = user_uid;
264// stbuf->st_gid = user_gid;
265 if (res == -1)
266 return -errno;
267 else
268 {
269 if (S_ISREG(stbuf->st_mode))
270 return -ENOENT;
271 else if (S_ISDIR(stbuf->st_mode))
272 {
273 stbuf->st_mode |= 0777;
274 stbuf->st_mode &= 0772777;
275 return 0;
276 }
277 else
278 return -EIO;
279 }
280 }
281}
int XrdFfsPosix_statall(const char *rdrurl, const char *path, struct stat *stbuf, uid_t user_uid)
int XrdFfsPosix_stat(const char *path, struct stat *buf)

References XROOTDFS::cns, XROOTDFS::fastls, MAXROOTURLLEN, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_stat(), XrdFfsPosix_statall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_getxattr()

static int xrootdfs_getxattr ( const char *  path,
const char *  name,
char *  value,
size_t  size 
)
static

Definition at line 1071 of file XrdFfsXrootdfs.cc.

1073{
1074 int xattrlen;
1075 char rootpath[MAXROOTURLLEN]="";
1076 char rooturl[MAXROOTURLLEN]="";
1077
1078 if (!strcmp(name,"xroot.url"))
1079 {
1080 errno = 0;
1081 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
1082 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
1083
1084// XrdFfsMisc_get_current_url(rootpath, rooturl);
1085 strcpy(rooturl, rootpath);
1086
1087 if (size == 0)
1088 return strlen(rooturl);
1089 else if (size > strlen(rooturl)) // check the size to make sure strcat(value, rooturl) is safe
1090 {
1091 size = strlen(rooturl);
1092 if (size != 0)
1093 {
1094 value[0] = '\0';
1095 strcat(value, rooturl);
1096 }
1097 return size;
1098 }
1099 else
1100 {
1101 errno = ERANGE;
1102 return -1;
1103 }
1104 }
1105 else if (!strcmp(name, "xrootdfs.fs.dataserverlist"))
1106 {
1107 char *hostlist;
1108
1109 hostlist = (char*) malloc(sizeof(char) * XrdFfs_MAX_NUM_NODES * 256);
1111
1112 if (size == 0)
1113 {
1114 xattrlen = strlen(hostlist);
1115 free(hostlist);
1116 return xattrlen;
1117 }
1118 else if (size > strlen(hostlist))
1119 {
1120 size = strlen(hostlist);
1121 if (size != 0)
1122 {
1123 value[0] = '\0';
1124 strcat(value, hostlist);
1125 }
1126 free(hostlist);
1127 return size;
1128 }
1129 else
1130 {
1131 errno = ERANGE;
1132 free(hostlist);
1133 return -1;
1134 }
1135 }
1136 else if (!strcmp(name, "xrootdfs.fs.nworkers"))
1137 {
1138 char nworkers[7];
1139 int n;
1141 sprintf(nworkers, "%d", n);
1142
1143 if (size == 0)
1144 return strlen(nworkers);
1145 else if (size > strlen(nworkers))
1146 {
1147 size = strlen(nworkers);
1148 if (size != 0)
1149 {
1150 value[0] = '\0';
1151 strcat(value, nworkers);
1152 }
1153 return size;
1154 }
1155 else
1156 {
1157 errno = ERANGE;
1158 return -1;
1159 }
1160 }
1161 else if (!strcmp(name, "xrootdfs.file.permission"))
1162 {
1163 char xattr[256]="";
1164 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
1165 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
1166
1167 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
1168 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
1169
1170 xattrlen = XrdFfsPosix_getxattr(rootpath, "xroot.xattr.ofs.ap", xattr, 255);
1171 if (size == 0)
1172 return xattrlen;
1173 else if (size > (size_t)xattrlen)
1174 {
1175 strncpy(value, xattr, size);
1176 size = xattrlen;
1177 value[size] = '\0';
1178 return size;
1179 }
1180 else
1181 {
1182 errno = ERANGE;
1183 return -1;
1184 }
1185 }
1186
1187 if (xrootdfs.cns != NULL)
1188 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
1189 else
1190 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
1191 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
1192
1193 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
1194 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
1195 xattrlen = XrdFfsPosix_getxattr(rootpath, name, value, size);
1196 if (xattrlen == -1)
1197 return -errno;
1198 else
1199 return xattrlen;
1200}
int XrdFfsMisc_get_list_of_data_servers(char *list)
#define XrdFfs_MAX_NUM_NODES
Definition XrdFfsMisc.hh:34
long long XrdFfsPosix_getxattr(const char *path, const char *name, void *value, unsigned long long size)
int XrdFfsQueue_count_workers()

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::rdr, XrdFfs_MAX_NUM_NODES, XrdFfsMisc_get_list_of_data_servers(), XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_getxattr(), XrdFfsQueue_count_workers(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_init()

static void * xrootdfs_init ( struct fuse_conn_info *  conn)
static

Definition at line 93 of file XrdFfsXrootdfs.cc.

94{
95 struct passwd pw, *pwp;
96 char *pwbuf;
97 size_t pwbuflen;
98
99 struct rlimit rl;
100 rl.rlim_cur = RLIM_INFINITY;
101 rl.rlim_max = RLIM_INFINITY;
102 setrlimit(RLIMIT_CORE, &rl); // attemp to enable core dump
103
104 pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
105 pwbuf = (char*)malloc(pwbuflen + 1);
106
107 if (xrootdfs.daemon_user != NULL)
108 {
109 int i, len;
110 len = strlen(xrootdfs.daemon_user);
111 for (i=0; i<len; i++) // daemon_user can be both string name or uid
112 {
113 if (isdigit(xrootdfs.daemon_user[i]) == 0)
114 {
115 getpwnam_r(xrootdfs.daemon_user, &pw, pwbuf, pwbuflen, &pwp);
116 break;
117 }
118 }
119 if (i == len) getpwuid_r(atoi(xrootdfs.daemon_user), &pw, pwbuf, pwbuflen, &pwp);
120 if( setgid((gid_t)pw.pw_gid) != 0 )
121 syslog( LOG_ERR, "ERROR: Unable to set gid to %d", pw.pw_gid );
122 if( setuid((uid_t)pw.pw_uid) != 0 )
123 syslog( LOG_ERR, "ERROR: Unable to set uid to %d", pw.pw_uid );
124#if defined(__linux__)
125 prctl(PR_SET_DUMPABLE, 1); // enable core dump after setuid/setgid
126#endif
127 }
128 free(pwbuf);
129
130/* put Xrootd related initialization calls here, after fuse daemonize itself. */
134
135 char *next, *savptr;
136 next = strtok_r(strdup(xrootdfs.rdr), "//", &savptr);
137 next = strtok_r(NULL, "//", &savptr);
138 char exportpath[1024];
139 while ((next = strtok_r(NULL, "//", &savptr)) != NULL)
140 {
141 strcat(exportpath, "/");
142 strcat(exportpath, next);
143 }
144 setenv("XRDEXPORTS", exportpath, 1);
145/*
146 From FAQ:
147 Miscellaneous threads should be started from the init() method.
148 Threads started before fuse_main() will exit when the process goes
149 into the background.
150*/
151
152#ifndef NOUSE_QUEUE
154
155 syslog(LOG_INFO, "INFO: Starting %d workers", XrdFfsQueue_count_workers());
156#else
157 syslog(LOG_INFO, "INFO: Not compiled to use task queue");
158#endif
159
160 if (fchdir(cwdfd)) {};
161 close(cwdfd);
162
163 return NULL;
164}
void XrdFfsMisc_xrd_init(const char *rdrurl, const char *urlcachelife, int startQueue)
int XrdFfsQueue_create_workers(int n)
void XrdFfsWcache_init(int basefd, int maxfd)
#define close(a)
Definition XrdPosix.hh:48
POSIX interface to XRootD with some extensions, as noted.

References close, cwdfd, XROOTDFS::daemon_user, XrdPosixXrootd::fdOrigin(), XROOTDFS::maxfd, XROOTDFS::nworkers, XROOTDFS::rdr, XROOTDFS::urlcachelife, XrdFfsMisc_xrd_init(), XrdFfsQueue_count_workers(), XrdFfsQueue_create_workers(), XrdFfsWcache_init(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_link()

static int xrootdfs_link ( const char *  from,
const char *  to 
)
static

Definition at line 662 of file XrdFfsXrootdfs.cc.

663{
664/*
665 int res;
666
667 res = link(from, to);
668 if (res == -1)
669 return -errno;
670*/
671 return -EMLINK;
672}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_listxattr()

static int xrootdfs_listxattr ( const char *  path,
char *  list,
size_t  size 
)
static

Definition at line 1202 of file XrdFfsXrootdfs.cc.

1203{
1204/*
1205 int res = llistxattr(path, list, size);
1206 if (res == -1)
1207 return -errno;
1208 return res;
1209*/
1210 return 0;
1211}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_mkdir()

static int xrootdfs_mkdir ( const char *  path,
mode_t  mode 
)
static

Definition at line 472 of file XrdFfsXrootdfs.cc.

473{
474 int res;
475 char rootpath[1024];
476/*
477 Posix Mkdir() fails on the current version of Xrootd, 20071101-0808p1
478 So we avoid doing that. This is fixed in CVS head version.
479*/
480/*
481 if CNS is defined, only mkdir() on CNS. Otherwise, mkdir() on redirector
482 */
483 rootpath[0]='\0';
484
485 if (xrootdfs.cns != NULL)
486 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
487 else
488 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
489
490 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
491
492 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
493 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
494
495 res = XrdFfsPosix_mkdir(rootpath, mode);
496 if (res == 0) return 0;
497/*
498 now we are here either because there is either a race to create the directory, or the redirector
499 incorrectly cached a non-existing one (see _mknod() for more explaitation)
500
501 the following code try to clear the redirector cache. In the case of two racing mkdir(), it doesn't
502 care which one will success/fail.
503*/
505
506 res = XrdFfsPosix_mkdir(rootpath, mode);
507 return ((res == -1)? -errno : 0);
508}
void XrdFfsPosix_clear_from_rdr_cache(const char *rdrurl)
int XrdFfsPosix_mkdir(const char *path, mode_t mode)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_clear_from_rdr_cache(), XrdFfsPosix_mkdir(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_mknod()

static int xrootdfs_mknod ( const char *  path,
mode_t  mode,
dev_t  rdev 
)
static

Definition at line 403 of file XrdFfsXrootdfs.cc.

415{
416 int res, fd;
417 if (!S_ISREG(mode))
418 return -EPERM;
419/*
420 Around May 2008, the O_EXCL was added to the _open(). No reason was given. It is removed again
421 due to the following reason (the situation that redirector thinks a file exist while it doesn't):
422
423 1. FUSE will use _getattr to determine file status. _mknod() will be called only if _getattr()
424 determined that the file does not exist.
425 2. In the case that rootd security is enabled, if a user create a file at an unauthorized path
426 (and fail), redirector thinks the files exist but it actually does't exist (enabling security
427 on redirector doesn't seems to help. An authorized user won't be able to create the same file
428 until the redirector forgets about it.
429
430 res = XrdFfsPosix_open(rootpath, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
431*/
432 res = xrootdfs_do_create(path, xrootdfs.rdr, O_CREAT | O_WRONLY, false, &fd);
433 if (res < 0) return res;
435 if (xrootdfs.cns != NULL)
436 {
437 xrootdfs_do_create(path, xrootdfs.cns, O_CREAT | O_EXCL, false, &fd);
439 }
440 return res;
441}

References XROOTDFS::cns, XROOTDFS::rdr, XrdFfsPosix_close(), xrootdfs, and xrootdfs_do_create().

Referenced by main().

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

◆ xrootdfs_open()

static int xrootdfs_open ( const char *  path,
struct fuse_file_info *  fi 
)
static

Definition at line 782 of file XrdFfsXrootdfs.cc.

789{
790 int fd, lid = 1;
791 char rootpath[MAXROOTURLLEN]="";
792 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
793 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
794
795 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, &lid);
796 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, &lid);
797 fd = XrdFfsPosix_open(rootpath, fi->flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
798 if (fd == -1)
799 return -errno;
800
801 fi->fh = fd;
802 // be careful, 0 means error for this function
803 if (XrdFfsWcache_create(fi->fh, fi->flags))
804 return 0;
805 else
806 return -errno;
807}

References MAXROOTURLLEN, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_open(), XrdFfsWcache_create(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_opt_proc()

static int xrootdfs_opt_proc ( void *  data,
const char *  arg,
int  key,
struct fuse_args *  outargs 
)
static

Definition at line 1289 of file XrdFfsXrootdfs.cc.

1290{
1291 (void) data;
1292 (void) outargs;
1293
1294// printf("hellow key %d arg %s\n", key, arg);
1295 switch (key) {
1296 case FUSE_OPT_KEY_OPT:
1297 return 1;
1298 case FUSE_OPT_KEY_NONOPT:
1299 return 1;
1300 case OPT_KEY_SECSSS:
1301 setenv("XROOTDFS_SECMOD", "sss", 1);
1302 return 0;
1303 case OPT_KEY_HELP:
1304 xrootdfs_usage(outargs->argv[0]);
1305 fuse_opt_add_arg(outargs, "-ho");
1306 fuse_main(outargs->argc, outargs->argv, &xrootdfs_oper, NULL);
1307 exit(1);
1308 default:
1309 return(-1);
1310 ;
1311 }
1312}
static void xrootdfs_usage(const char *progname)

References OPT_KEY_HELP, OPT_KEY_SECSSS, xrootdfs_oper, and xrootdfs_usage().

Referenced by main().

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

◆ xrootdfs_read()

static int xrootdfs_read ( const char *  path,
char *  buf,
size_t  size,
off_t  offset,
struct fuse_file_info *  fi 
)
static

!! TO DO: Remove offset test once XrdClEC read regression is fixed

Definition at line 809 of file XrdFfsXrootdfs.cc.

811{
812 int fd;
813 int res;
814
815 fd = (int) fi->fh;
816 if ((fi->flags & O_ACCMODE) == O_RDWR) XrdFfsWcache_flush(fd);
817
818 if (usingEC)
819 {
820 struct stat stbuf;
821 XrdPosixXrootd::Fstat(fd, &stbuf); // Silly but does not seem to hurt performance
822 off_t fsize = stbuf.st_size;
823
825 if ( offset >= fsize )
826 return 0;
827
828 size = (size_t)(fsize - offset) > size ? size : fsize - offset;
829 // Restrict the use of read cache to O_DIRECT use case
830 // See comment in XRdFfsWcache_pread()
831 if ( ((fi->flags & O_ACCMODE) != O_RDWR) && (fi->flags & O_DIRECT) )
832 res = XrdFfsWcache_pread(fd, buf, size, offset);
833 else
834 res = XrdFfsPosix_pread(fd, buf, size, offset);
835 }
836 else
837 res = XrdFfsPosix_pread(fd, buf, size, offset);
838
839 if (res == -1)
840 res = -errno;
841
842 return res;
843}
#define O_DIRECT
Definition XrdCrc32c.cc:51
ssize_t XrdFfsPosix_pread(int fildes, void *buf, size_t nbyte, off_t offset)
ssize_t XrdFfsWcache_pread(int fd, char *buf, size_t len, off_t offset)
#define stat(a, b)
Definition XrdPosix.hh:101
static int Fstat(int fildes, struct stat *buf)
Fstat() conforms to POSIX.1-2001 fstat()

References XrdPosixXrootd::Fstat(), O_DIRECT, stat, usingEC, XrdFfsPosix_pread(), XrdFfsWcache_flush(), and XrdFfsWcache_pread().

Referenced by main().

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

◆ xrootdfs_readdir()

static int xrootdfs_readdir ( const char *  path,
void *  buf,
fuse_fill_dir_t  filler,
off_t  offset,
struct fuse_file_info *  fi 
)
static

Definition at line 308 of file XrdFfsXrootdfs.cc.

310{
311 DIR *dp;
312 struct dirent *de;
313
314 (void) offset;
315 (void) fi;
316
317 char rootpath[MAXROOTURLLEN];
318
319 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
320/*
321 if CNS server is not defined, there is no way to list files in a directory
322 because we don't know the data nodes
323*/
324 if (xrootdfs.cns != NULL)
325 {
326 rootpath[0]='\0';
327 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
328 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
329
330 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
331 dp = XrdFfsPosix_opendir(rootpath);
332 if (dp == NULL)
333 return -errno;
334
335 while ((de = XrdFfsPosix_readdir(dp)) != NULL)
336 {
337/*
338 struct stat st;
339 memset(&st, 0, sizeof(st));
340 st.st_ino = de->d_ino;
341 st.st_mode = de->d_type << 12;
342 */
343 if (filler(buf, de->d_name, NULL, 0))
344 break;
345 }
347 return 0;
348 }
349 else /* if there is no CNS, try collect dirents from all known data servers. */
350 {
351 int i, n;
352 char **dnarray = NULL;
353
354 n = XrdFfsPosix_readdirall(xrootdfs.rdr, path, &dnarray, fuse_get_context()->uid);
355
356 for (i = 0; i < n; i++)
357 if (filler(buf, dnarray[i], NULL, 0)) break;
358
359/*
360 this loop should not be merged with the above loop because all members of
361 dnarray[] should be freed, or there will be memory leak.
362 */
363 for (i = 0; i < n; i++)
364 free(dnarray[i]);
365 free(dnarray);
366
367 return -errno;
368 }
369}
DIR * XrdFfsPosix_opendir(const char *path)
struct dirent * XrdFfsPosix_readdir(DIR *dirp)
int XrdFfsPosix_closedir(DIR *dirp)
int XrdFfsPosix_readdirall(const char *rdrurl, const char *path, char ***direntarray, uid_t user_uid)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_closedir(), XrdFfsPosix_opendir(), XrdFfsPosix_readdir(), XrdFfsPosix_readdirall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_readlink()

static int xrootdfs_readlink ( const char *  path,
char *  buf,
size_t  size 
)
static

Definition at line 294 of file XrdFfsXrootdfs.cc.

295{
296/*
297 int res;
298
299 res = readlink(path, buf, size - 1);
300 if (res == -1)
301 return -errno;
302
303 buf[res] = '\0';
304*/
305 return 0;
306}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_release()

static int xrootdfs_release ( const char *  path,
struct fuse_file_info *  fi 
)
static

Definition at line 931 of file XrdFfsXrootdfs.cc.

932{
933 /* Just a stub. This method is optional and can safely be left
934 unimplemented */
935
936 int fd, oflag;
937 struct stat xrdfile, cnsfile;
938 char rootpath[MAXROOTURLLEN];
939
940 fd = (int) fi->fh;
944 fi->fh = 0;
945/*
946 Return at here because the current version of Cluster Name Space daemon
947 doesn't implement the 'truncate' functon we originally planned.
948
949 return 0;
950*/
951 if (xrootdfs.cns == NULL)
952 return 0;
953
954 int res;
955 char xattr[256], xrdtoken[256];
956 char *token, *key, *value;
957 char *lasts_xattr[256], *lasts_tokens[128];
958
959 rootpath[0]='\0';
960 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
961 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
962/*
963 * Get xrootd token info from data nodes. And set the token info on CNS
964 */
965 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
966 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
967 xrdtoken[0]='\0';
968 res = XrdFfsPosix_getxattr(rootpath, "xroot.xattr", xattr, 256);
969 if (res != -1)
970 {
971 token = strtok_r(xattr, "&", lasts_xattr);
972 while (token != NULL)
973 {
974 key = strtok_r(token, "=", lasts_tokens);
975 value = strtok_r(NULL, "=", lasts_tokens);
976 if (!strcmp(key,"oss.cgroup"))
977 strcpy(xrdtoken, value);
978
979 if (!strcmp(key,"oss.used"))
980 {long long llVal;
981 sscanf((const char*)value, "%lld", &llVal);
982 xrdfile.st_size = llVal;
983 }
984 token = strtok_r(NULL, "&", lasts_xattr);
985 }
986 }
987 else
988 {
989 XrdFfsPosix_stat(rootpath,&xrdfile);
990 }
991
992 rootpath[0]='\0';
993 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
994 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
995
996 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
997 if (xrdtoken[0] != '\0' && strstr(path,"?oss.cgroup=") == NULL)
998 {
999 strncat(rootpath,"?oss.cgroup=", MAXROOTURLLEN - strlen(rootpath) -1);
1000 strncat(rootpath,xrdtoken, MAXROOTURLLEN - strlen(rootpath) -1);
1001 }
1002
1003 if (XrdFfsPosix_stat(rootpath,&cnsfile) == -1)
1004 oflag = O_CREAT|O_WRONLY;
1005 else
1006 oflag = O_TRUNC|O_WRONLY;
1007
1008/*
1009 This creates a file on CNS with the right size. But it is actually an empty file.
1010 It doesn't use disk space, only inodes.
1011*/
1012 if (cnsfile.st_size != xrdfile.st_size)
1013 {
1014 fd = XrdFfsPosix_open(rootpath,oflag,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
1015 if (fd >= 0)
1016 {
1017 XrdFfsPosix_lseek(fd,(off_t)xrdfile.st_size-1,SEEK_SET);
1018 XrdFfsPosix_write(fd,"",1);
1020 }
1021 }
1022
1023 return 0;
1024}
off_t XrdFfsPosix_lseek(int fildes, off_t offset, int whence)
ssize_t XrdFfsPosix_write(int fildes, const void *buf, size_t nbyte)
void XrdFfsWcache_destroy(int fd)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::rdr, stat, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_close(), XrdFfsPosix_getxattr(), XrdFfsPosix_lseek(), XrdFfsPosix_open(), XrdFfsPosix_stat(), XrdFfsPosix_write(), XrdFfsWcache_destroy(), XrdFfsWcache_flush(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_removexattr()

static int xrootdfs_removexattr ( const char *  path,
const char *  name 
)
static

Definition at line 1213 of file XrdFfsXrootdfs.cc.

1214{
1215/*
1216 int res = lremovexattr(path, name);
1217 if (res == -1)
1218 return -errno;
1219*/
1220 return 0;
1221}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_rename()

static int xrootdfs_rename ( const char *  from,
const char *  to 
)
static

Definition at line 605 of file XrdFfsXrootdfs.cc.

606{
607 int res;
608 char from_path[MAXROOTURLLEN], to_path[MAXROOTURLLEN];
609 struct stat stbuf;
610
611 from_path[0]='\0';
612 strncat(from_path, xrootdfs.rdr, MAXROOTURLLEN - strlen(from_path) -1);
613 strncat(from_path, from, MAXROOTURLLEN - strlen(from_path) -1);
614
615 to_path[0]='\0';
616 strncat(to_path, xrootdfs.rdr, MAXROOTURLLEN - strlen(to_path) -1);
617 strncat(to_path, to, MAXROOTURLLEN - strlen(to_path) -1);
618/*
619 1. do actual renaming on data servers if if is a file in order to speed up
620 renaming
621 2. return -EXDEV for renaming of directory so that files in the directory
622 are renamed individually (in order for the .pfn pointing back correctly).
623 */
624
625 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
626 XrdFfsMisc_xrd_secsss_editurl(from_path, fuse_get_context()->uid, 0);
627
628 XrdFfsPosix_stat(from_path, &stbuf);
629 if (S_ISDIR(stbuf.st_mode)) /* && xrootdfs.cns == NULL && xrootdfs.ofsfwd == false) */
630 return -EXDEV;
631
632 if (xrootdfs.ofsfwd == true)
633 res = XrdFfsPosix_rename(from_path, to_path);
634 else
635 res = XrdFfsPosix_renameall(xrootdfs.rdr, from, to, fuse_get_context()->uid);
636
637 if (res == -1)
638 return -errno;
639
640/* data servers may not notify redirector about the renaming. So we notify redirector */
642
643 if (xrootdfs.cns != NULL && xrootdfs.ofsfwd == false)
644 {
645 from_path[0]='\0';
646 strncat(from_path, xrootdfs.cns, MAXROOTURLLEN - strlen(from_path) -1);
647 strncat(from_path, from, MAXROOTURLLEN - strlen(from_path) -1);
648
649 to_path[0]='\0';
650 strncat(to_path, xrootdfs.cns, MAXROOTURLLEN - strlen(to_path) -1);
651 strncat(to_path, to, MAXROOTURLLEN - strlen(to_path) -1);
652
653 res = XrdFfsPosix_rename(from_path, to_path);
654 if (res == -1)
655 return -errno;
656 }
657 return 0;
658
659/* return -EXDEV */
660}
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)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::ofsfwd, XROOTDFS::rdr, stat, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_clear_from_rdr_cache(), XrdFfsPosix_rename(), XrdFfsPosix_renameall(), XrdFfsPosix_stat(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_rmdir()

static int xrootdfs_rmdir ( const char *  path)
static

Definition at line 545 of file XrdFfsXrootdfs.cc.

546{
547 int res;
548// struct stat stbuf;
549 char rootpath[MAXROOTURLLEN];
550
551 rootpath[0]='\0';
552 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
553 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
554
555 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
556 if (xrootdfs.ofsfwd == true)
557 {
558 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
559 res = XrdFfsPosix_rmdir(rootpath);
560 }
561 else
562 res = XrdFfsPosix_rmdirall(xrootdfs.rdr, path, fuse_get_context()->uid);
563
564 if (res == -1)
565 return -errno;
566
567 if (xrootdfs.cns != NULL && xrootdfs.ofsfwd == false)
568 {
569 rootpath[0]='\0';
570 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
571 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
572
573 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
574 res = XrdFfsPosix_rmdir(rootpath);
575 if (res == -1)
576 return -errno;
577 }
578 /*
579 clear cache in redirector. otherwise, an immediate mkdir(path) will fail
580 if (xrootdfs.ofsfwd == false)
581 {
582 rootpath[0]='\0';
583 strcat(rootpath,xrootdfs.rdr);
584 strcat(rootpath,path);
585
586 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid);
587 XrdFfsPosix_clear_from_xrootdfs.rdr_cache(rootpath); // no needed. _mkdir() is doing this.
588 }
589 */
590 return 0;
591}
int XrdFfsPosix_rmdirall(const char *rdrurl, const char *path, uid_t user_uid)
int XrdFfsPosix_rmdir(const char *path)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::ofsfwd, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_rmdir(), XrdFfsPosix_rmdirall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_setxattr()

static int xrootdfs_setxattr ( const char *  path,
const char *  name,
const char *  value,
size_t  size,
int  flags 
)
static

Definition at line 1038 of file XrdFfsXrootdfs.cc.

1040{
1041 if (fuse_get_context()->uid != 0 && fuse_get_context()->uid != getuid())
1042 return -EPERM;
1043
1044 if (!strcmp(name,"xrootdfs.fs.dataserverlist"))
1045 {
1048 }
1049 else if (!strcmp(name,"xrootdfs.fs.nworkers"))
1050 {
1051 int i, j;
1052 char *tmp_value;
1053 tmp_value=strdup(value);
1054 if (size > 0) tmp_value[size] = '\0';
1055
1057 j = atoi(tmp_value);
1058 free(tmp_value);
1059 if (j > i)
1061 if (j < i)
1062 XrdFfsQueue_remove_workers( i-j ); // XrdFfsQueue_remove_workers() will wait until workers are removed.
1064#ifndef NOUSE_QUEUE
1065 syslog(LOG_INFO, "INFO: Adjust the number of workers from %d to %d", i, j);
1066#endif
1067 }
1068 return 0;
1069}
void XrdFfsMisc_refresh_url_cache(const char *url)
int XrdFfsQueue_remove_workers(int n)

References XROOTDFS::rdr, XrdFfsMisc_logging_url_cache(), XrdFfsMisc_refresh_url_cache(), XrdFfsQueue_count_workers(), XrdFfsQueue_create_workers(), XrdFfsQueue_remove_workers(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_sigusr1_handler()

void xrootdfs_sigusr1_handler ( int  sig)

Definition at line 1240 of file XrdFfsXrootdfs.cc.

1241{
1242/* Do this in a new thread because XrdFfsMisc_refresh_url_cache() contents mutex. */
1243 pthread_t *thread;
1244 pthread_attr_t attr;
1245 size_t stacksize = 2*1024*1024;
1246
1247 pthread_attr_init(&attr);
1248 pthread_attr_setstacksize(&attr, stacksize);
1249 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1250
1251 thread = (pthread_t*) malloc(sizeof(pthread_t));
1252 pthread_create(thread, &attr, XrdFfsMisc_logging_url_cache_pthread_create_cast,
1253 xrootdfs.rdr);
1254 pthread_detach(*thread);
1255 free(thread);
1256
1257 pthread_attr_destroy(&attr);
1258}
void * XrdFfsMisc_logging_url_cache_pthread_create_cast(void *arg)

References XROOTDFS::rdr, XrdFfsMisc_logging_url_cache_pthread_create_cast(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_statfs()

static int xrootdfs_statfs ( const char *  path,
struct statvfs stbuf 
)
static

Definition at line 864 of file XrdFfsXrootdfs.cc.

865{
866 int res;
867// char rootpath[1024], xattr[256];
868// char *token, *key, *value;
869// char *lasts_xattr[256], *lasts_tokens[128];
870// long long size;
871
872// XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid);
873#ifndef __APPLE__
874 stbuf->f_bsize = 1024;
875#else
876 stbuf->f_bsize = 1024 * 128; // work around 32 bit fsblkcnt_t in struct statvfs on Mac OSX
877 stbuf->f_frsize = stbuf->f_bsize; // seems there are other limitations, 1024*128 is a max we set
878#endif
879
880// res = XrdFfsPosix_statvfsall(xrootdfs.rdr, path, stbuf, fuse_get_context()->uid);
881 res = XrdFfsFsinfo_cache_search(&XrdFfsPosix_statvfsall, xrootdfs.rdr, path, stbuf, fuse_get_context()->uid);
882
883/*
884 stbuf->f_blocks /= stbuf->f_bsize;
885 stbuf->f_bavail /= stbuf->f_bsize;
886 stbuf->f_bfree /= stbuf->f_bsize;
887*/
888 return res;
889/*
890 stbuf->f_bsize = 16384;
891 stbuf->f_blocks = 1048576;
892 stbuf->f_bfree = stbuf->f_blocks;
893 stbuf->f_bavail = stbuf->f_blocks;
894
895 if (xrootdfs.cns == NULL) return 0;
896
897 rootpath[0]='\0';
898 strcat(rootpath,xrootdfs.cns);
899 strcat(rootpath,path);
900
901 res = XrdFfsPosix_getxattr(rootpath, "xroot.space", xattr, 256);
902 if (res == -1)
903 return 0;
904 else
905 {
906 token = strtok_r(xattr, "&", lasts_xattr);
907 while (token != NULL)
908 {
909 token = strtok_r(NULL, "&", lasts_xattr);
910 if (token == NULL) break;
911 key = strtok_r(token, "=", lasts_tokens);
912 value = strtok_r(NULL, "=", lasts_tokens);
913 if (!strcmp(key,"oss.used"))
914 {
915 sscanf((const char*)value, "%lld", &size);
916 stbuf->f_bavail = size / stbuf->f_bsize;
917 }
918 else if (!strcmp(key,"oss.quota"))
919 {
920 sscanf((const char*)value, "%lld", &size);
921 stbuf->f_blocks = size / stbuf->f_bsize;
922 }
923 }
924 stbuf->f_bavail = stbuf->f_blocks - stbuf->f_bavail;
925 stbuf->f_bfree = stbuf->f_bavail;
926 }
927 return 0;
928 */
929}
int XrdFfsFsinfo_cache_search(int(*func)(const char *, const char *, struct statvfs *, uid_t), const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)
int XrdFfsPosix_statvfsall(const char *rdrurl, const char *path, struct statvfs *stbuf, uid_t user_uid)

References XROOTDFS::rdr, XrdFfsFsinfo_cache_search(), XrdFfsPosix_statvfsall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_symlink()

static int xrootdfs_symlink ( const char *  from,
const char *  to 
)
static

Definition at line 593 of file XrdFfsXrootdfs.cc.

594{
595/*
596 int res;
597
598 res = symlink(from, to);
599 if (res == -1)
600 return -errno;
601*/
602 return -EIO;
603}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_truncate()

static int xrootdfs_truncate ( const char *  path,
off_t  size 
)
static

Definition at line 729 of file XrdFfsXrootdfs.cc.

730{
731 int res;
732 char rootpath[MAXROOTURLLEN];
733
734 rootpath[0]='\0';
735 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
736 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
737
738 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
739 if (xrootdfs.ofsfwd == true)
740 {
741 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
742 res = XrdFfsPosix_truncate(rootpath, size);
743 }
744 else
745 res = XrdFfsPosix_truncateall(xrootdfs.rdr, path, size, fuse_get_context()->uid);
746
747 if (res == -1)
748 return -errno;
749
750 if (xrootdfs.cns != NULL && xrootdfs.ofsfwd == false)
751 {
752 rootpath[0]='\0';
753 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
754 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
755
756 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
757 res = XrdFfsPosix_truncate(rootpath, size);
758 if (res == -1)
759 return -errno;
760 }
761 return 0;
762}
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)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::ofsfwd, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_truncate(), XrdFfsPosix_truncateall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_unlink()

static int xrootdfs_unlink ( const char *  path)
static

Definition at line 510 of file XrdFfsXrootdfs.cc.

511{
512 int res;
513 char rootpath[MAXROOTURLLEN];
514
515 rootpath[0]='\0';
516 strncat(rootpath,xrootdfs.rdr, MAXROOTURLLEN - strlen(rootpath) -1);
517 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
518
519 XrdFfsMisc_xrd_secsss_register(fuse_get_context()->uid, fuse_get_context()->gid, 0);
520 if (xrootdfs.ofsfwd == true)
521 {
522 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
523 res = XrdFfsPosix_unlink(rootpath);
524 }
525 else
526 res = XrdFfsPosix_unlinkall(xrootdfs.rdr, path, fuse_get_context()->uid);
527
528 if (res == -1)
529 return -errno;
530
531 if (xrootdfs.cns != NULL && xrootdfs.ofsfwd == false)
532 {
533 rootpath[0]='\0';
534 strncat(rootpath,xrootdfs.cns, MAXROOTURLLEN - strlen(rootpath) -1);
535 strncat(rootpath,path, MAXROOTURLLEN - strlen(rootpath) -1);
536
537 XrdFfsMisc_xrd_secsss_editurl(rootpath, fuse_get_context()->uid, 0);
538 res = XrdFfsPosix_unlink(rootpath);
539 if (res == -1)
540 return -errno;
541 }
542 return 0;
543}
int XrdFfsPosix_unlink(const char *path)
int XrdFfsPosix_unlinkall(const char *rdrurl, const char *path, uid_t user_uid)

References XROOTDFS::cns, MAXROOTURLLEN, XROOTDFS::ofsfwd, XROOTDFS::rdr, XrdFfsMisc_xrd_secsss_editurl(), XrdFfsMisc_xrd_secsss_register(), XrdFfsPosix_unlink(), XrdFfsPosix_unlinkall(), and xrootdfs.

Referenced by main().

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

◆ xrootdfs_usage()

static void xrootdfs_usage ( const char *  progname)
static

Definition at line 1262 of file XrdFfsXrootdfs.cc.

1263{
1264 fprintf(stderr,
1265"usage: %s mountpoint options\n"
1266"\n"
1267"XrootdFS options:\n"
1268" -h -help --help print help\n"
1269"\n"
1270"Default options:\n"
1271" fsname=xrootdfs,allow_other,max_write=131072,attr_timeout=10,entry_timeout=10,negative_timeout=5\n"
1272" In case of an Erasure Encoding storage, entry_timeout=0\n"
1273"\n"
1274"[Required]\n"
1275" -o rdr=redirector_url root URL of the Xrootd redirector\n"
1276"\n"
1277"[Optional]\n"
1278" -o cns=cns_server_url root URL of the CNS server\n"
1279" -o uid=username cause XrootdFS to switch effective uid to that of username if possible\n"
1280" -o sss[=keytab] use Xrootd seciruty module \"sss\", specifying a keytab file is optional\n"
1281" -o refreshdslist=NNNs/m/h/d refresh internal list of data servers in NNN sec/min/hour/day, default unit is second\n"
1282" Absents of this option will disable automatically refreshing\n"
1283" -o maxfd=N number of virtual file descriptors for posix requests, default 8192 (min 2048)\n"
1284" -o nworkers=N number of workers to handle parallel requests to data servers, default 4\n"
1285" -o fastls=RDR set to RDR when CNS is presented will cause stat() to go to redirector\n"
1286"\n", progname);
1287}

Referenced by xrootdfs_opt_proc().

+ Here is the caller graph for this function:

◆ xrootdfs_utimens()

static int xrootdfs_utimens ( const char *  path,
const struct timespec  ts[2] 
)
static

Definition at line 764 of file XrdFfsXrootdfs.cc.

765{
766/*
767 int res;
768 struct timeval tv[2];
769
770 tv[0].tv_sec = ts[0].tv_sec;
771 tv[0].tv_usec = ts[0].tv_nsec / 1000;
772 tv[1].tv_sec = ts[1].tv_sec;
773 tv[1].tv_usec = ts[1].tv_nsec / 1000;
774
775 res = utimes(path, tv);
776 if (res == -1)
777 return -errno;
778*/
779 return 0;
780}

Referenced by main().

+ Here is the caller graph for this function:

◆ xrootdfs_write()

static int xrootdfs_write ( const char *  path,
const char *  buf,
size_t  size,
off_t  offset,
struct fuse_file_info *  fi 
)
static

Definition at line 845 of file XrdFfsXrootdfs.cc.

847{
848 int fd;
849 int res;
850
851/*
852 File already existed. FUSE uses xrootdfs_open() and xrootdfs_truncate() to open and
853 truncate a file before calling xrootdfs_write()
854*/
855 fd = (int) fi->fh;
856// res = XrdFfsPosix_pwrite(fd, buf, size, offset);
857 res = XrdFfsWcache_pwrite(fd, (char *)buf, size, offset);
858 if (res == -1)
859 res = -errno;
860
861 return res;
862}
ssize_t XrdFfsWcache_pwrite(int fd, char *buf, size_t len, off_t offset)

References XrdFfsWcache_pwrite().

Referenced by main().

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

Variable Documentation

◆ cwdfd

int cwdfd

Definition at line 84 of file XrdFfsXrootdfs.cc.

Referenced by main(), and xrootdfs_init().

◆ usingEC

bool usingEC = false

Definition at line 91 of file XrdFfsXrootdfs.cc.

Referenced by main(), xrootdfs_create(), and xrootdfs_read().

◆ xrootdfs

◆ xrootdfs_oper

struct fuse_operations xrootdfs_oper
static

Definition at line 1260 of file XrdFfsXrootdfs.cc.

Referenced by main(), and xrootdfs_opt_proc().

◆ xrootdfs_opts

struct fuse_opt xrootdfs_opts[14]
static

Definition at line 87 of file XrdFfsXrootdfs.cc.

Referenced by main().