Skip to content

Commit

Permalink
[Server] Add directory-relative operations for Xcache use.
Browse files Browse the repository at this point in the history
  • Loading branch information
abh3 committed Jun 2, 2020
1 parent 721ac53 commit 5aea9d1
Show file tree
Hide file tree
Showing 3 changed files with 354 additions and 0 deletions.
204 changes: 204 additions & 0 deletions src/XrdOss/XrdOssAt.cc
@@ -0,0 +1,204 @@
/******************************************************************************/
/* */
/* X r d O s s A t . c c */
/* */
/* (c) 2020 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/

#include <errno.h>
#include <fcntl.h>
#include <string>
#include <sys/stat.h>

#include "XrdOss/XrdOss.hh"
#include "XrdOss/XrdOssApi.hh"
#include "XrdOss/XrdOssAt.hh"
#include "XrdOss/XrdOssCache.hh"
#include "XrdOss/XrdOssError.hh"
#include "XrdSys/XrdSysFD.hh"

/******************************************************************************/
/* L o c a l D e f i n e s */
/******************************************************************************/

// Common prologue fo each public method
//
#ifdef HAVE_FSTATAT
#define BOILER_PLATE(fd, dfObj) \
{if (!(dfObj.DFType() & XrdOssDF::DF_isDir)) return -ENOTDIR;\
if (!path || *path == '/') return -XRDOSS_E8027;\
if ((fd = dfObj.getFD()) < 0) return -XRDOSS_E8002;\
}
#else
#define BOILER_PLATE(dfObj,fd) return -ENOTSUP;
#endif

// Open the target
//
#ifdef O_CLOEXEC
#define OPEN_AT(dst, dfd, p, f)\
dst = openat(dfd, p, f|O_CLOEXEC);\
if (dst < 0) return -errno;
#else
#define OPEN_AT(dst, dfd, p, f)\
dst = openat(dfd, p, f); \
if (dst >= 0) fcntl(dst, F_SETFD, FD_CLOEXEC);\
else return -errno
#endif

namespace
{
class openHelper
{public:
int FD;
openHelper() : FD(-1) {}
~openHelper() {if (FD >= 0) close(FD);}
};
}

/******************************************************************************/
/* O p e n d i r */
/******************************************************************************/

int XrdOssAt::Opendir(XrdOssDF &atDir, const char *path, XrdOucEnv &env,
XrdOssDF *&ossDF)
{
openHelper hOpen;
DIR *dirP;
int dirFD;

// Standard boilerplate
//
BOILER_PLATE(dirFD, atDir);

// Open the target
//
OPEN_AT(hOpen.FD, dirFD, path, O_RDONLY);

// Create a new dir entry from this FD
//
dirP = fdopendir(hOpen.FD);
if (!dirP) return (errno ? -errno : -ENOMSG);

// Finally return a new directory object
//
ossDF = new XrdOssDir(atDir.getTID(), dirP);
hOpen.FD = -1;
return 0;
}

/******************************************************************************/
/* O p e n R O */
/******************************************************************************/

int XrdOssAt::OpenRO(XrdOssDF &atDir, const char *path, XrdOucEnv &env,
XrdOssDF *&ossDF)
{
openHelper hOpen;
int dirFD;

// Standard boilerplate
//
BOILER_PLATE(dirFD, atDir);

// Open the target
//
OPEN_AT(hOpen.FD, dirFD, path, O_RDONLY);

// Return a new file object
//
ossDF = new XrdOssFile(atDir.getTID(), hOpen.FD);
hOpen.FD = -1;
return 0;
}

/******************************************************************************/
/* R e m d i r */
/******************************************************************************/

int XrdOssAt::Remdir(XrdOssDF &atDir, const char *path)
{
int dirFD;

// Standard boilerplate
//
BOILER_PLATE(dirFD, atDir);

// Effect the removal
//
if (unlinkat(dirFD, path, AT_REMOVEDIR)) return -errno;

// All done
//
return 0;
}

/******************************************************************************/
/* S t a t */
/******************************************************************************/

int XrdOssAt::Stat(XrdOssDF &atDir, const char *path, struct stat &buf,
int opts)
{
int dirFD;

// Standard boilerplate
//
BOILER_PLATE(dirFD, atDir);

// Do the stat call
//
if (fstatat(dirFD, path, &buf, 0)) return -errno;

// Check if we need to provide dev info
//
if (opts & At_dInfo) XrdOssCache::DevInfo(buf);

// All done
//
return 0;
}

/******************************************************************************/
/* U n l i n k */
/******************************************************************************/

int XrdOssAt::Unlink(XrdOssDF &atDir, const char *path)
{
int dirFD;

// Standard boilerplate
//
BOILER_PLATE(dirFD, atDir);

// Effect the removal
//
if (unlinkat(dirFD, path, 0)) return -errno;

// All done
//
return 0;
}
149 changes: 149 additions & 0 deletions src/XrdOss/XrdOssAt.hh
@@ -0,0 +1,149 @@
#ifndef _XRDOSSAT_H
#define _XRDOSSAT_H
/******************************************************************************/
/* */
/* X r d O s s A t . h h */
/* */
/* (c) 2020 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/

#include <stdint.h>
#include <sys/types.h>

struct stat;
class XrdOss;
class XrdOssDF;

/******************************************************************************/
//!
//! This class defines the object that handles extended operations that are
//! relative to an open directory. Create a single instance of this class by
//! passing it the pointer to the asociated file system (XrdOss) and use the
//! methods herein to effect various operations relative to an XrdOss directory.
//!
//! @note
//! 1) The following relative methods are not currently implemented:
//! access() (aka faccessat), chmod() (aka fchmodat), chown() (aka fchownat),
//! mkdir() (aka mkdirat), readlink() (aka readlinkat),
//! rename (a.k.a renameat), symlink() (aka symlinkat), and
//! utimes() (a.k.a utimesat).
//! 2) The path argument must be relative and is not subject to name2name()
//! processing. This is in contrast to standard Unix "at" calls.
//! 3) Only the online copy of the target is subject to these calls. Use the
//! the standard calls for remote storage backed file systems.
/******************************************************************************/

class XrdOssAt
{
public:

//-----------------------------------------------------------------------------
//! Open a directory relative to an open directory.
//!
//! @param atDir - Reference to the directory object to use.
//! @param path - Pointer to the relative path of the directory to be opened.
//! @param env - Reference to environmental information.
//! @param ossDF - Reference to where the directory object pointer is to be
//! returned upon success.
//!
//! @return 0 upon success or -errno or -osserr (see XrdOssError.hh).
//-----------------------------------------------------------------------------

int Opendir(XrdOssDF &atDir, const char *path, XrdOucEnv &env, XrdOssDF *&ossDF);

//-----------------------------------------------------------------------------
//! Open a file in r/o mode relative to an open directory.
//!
//! @param atDir - Reference to the directory object to use.
//! @param path - Pointer to the relative path of the file to be opened.
//! @param env - Reference to environmental information.
//! @param ossDF - Reference to where the file object pointer is to be
//! returned upon success.
//!
//! @return 0 upon success or -errno or -osserr (see XrdOssError.hh).
//-----------------------------------------------------------------------------

int OpenRO(XrdOssDF &atDir, const char *path, XrdOucEnv &env, XrdOssDF *&ossDF);

//-----------------------------------------------------------------------------
//! Remove a directory relative to an open directory. Only the online entry
//! is removed (use standard remdir() for tape backed systems).
//!
//! @param atDir - Reference to the directory object to use.
//! @param path - Pointer to the path of the directory to be removed.
//!
//! @return 0 upon success or -errno or -osserr (see XrdOssError.hh).
//-----------------------------------------------------------------------------

int Remdir(XrdOssDF &atDir, const char *path);

//-----------------------------------------------------------------------------
//! Return state information on the target relative to an open directory.
//!
//! @param atDir - Reference to the directory object to use.
//! @param path - Pointer to the path of the target to be interrogated.
//! @param buf - Reference to the structure where info it to be returned.
//! @param opts - Options:
//! At_dInfo - provide bdevID in st_rdev and partID in st_dev
//!
//! @return 0 upon success or -errno or -osserr (see XrdOssError.hh).
//-----------------------------------------------------------------------------

static const int At_dInfo = 0x00000001;

int Stat(XrdOssDF &atDir, const char *path, struct stat &buf, int opts=0);

//-----------------------------------------------------------------------------
//! Remove a file relative to an open directory. Only the online copy is
//! is removed (use standard unlink() for tape backed systems).
//!
//! @param atDir - Reference to the directory object to use.
//! @param path - Pointer to the path of the file to be removed.
//!
//! @return 0 upon success or -errno or -osserr (see XrdOssError.hh).
//-----------------------------------------------------------------------------

int Unlink(XrdOssDF &atDir, const char *path);

//-----------------------------------------------------------------------------
//! Constructor
//!
//! @param ossfd - Reference to the OSS system interface.
//-----------------------------------------------------------------------------

XrdOssAt(XrdOss &ossfs) : ossFS(ossfs) {}

//-----------------------------------------------------------------------------
//! Destructor
//-----------------------------------------------------------------------------

~XrdOssAt() {}

private:

XrdOss &ossFS;
};
#endif
1 change: 1 addition & 0 deletions src/XrdServer.cmake
Expand Up @@ -103,6 +103,7 @@ add_library(
# XrdOss - Default storage system
#-----------------------------------------------------------------------------
XrdOss/XrdOss.cc XrdOss/XrdOss.hh
XrdOss/XrdOssAt.cc XrdOss/XrdOssAt.hh
XrdOss/XrdOssAio.cc
XrdOss/XrdOssTrace.hh
XrdOss/XrdOssError.hh
Expand Down

0 comments on commit 5aea9d1

Please sign in to comment.