2014-11-15 16:33:24 +01:00
# include "Fuse.h"
2014-11-04 22:33:43 +01:00
# include <memory>
# include <cassert>
2018-05-21 08:18:34 +02:00
# include "../fs_interface/FuseErrnoException.h"
2014-11-28 14:46:45 +01:00
# include "Filesystem.h"
2015-07-21 19:45:44 +02:00
# include <iostream>
2016-02-11 12:53:42 +01:00
# include <cpp-utils/assert/assert.h>
# include <cpp-utils/logging/logging.h>
2019-01-19 22:02:41 +01:00
# include <cpp-utils/process/subprocess.h>
2015-11-13 00:03:22 +01:00
# include <csignal>
2018-12-03 07:57:21 +01:00
# include "InvalidFilesystem.h"
2014-11-15 16:33:24 +01:00
2019-01-19 22:02:41 +01:00
# if defined(_MSC_VER)
# include <codecvt>
# include <dokan/dokan.h>
# endif
2015-10-15 03:41:02 +02:00
using std : : vector ;
2014-11-04 22:33:43 +01:00
using std : : string ;
namespace bf = boost : : filesystem ;
2015-10-17 17:23:35 +02:00
using namespace cpputils : : logging ;
2018-12-03 07:57:21 +01:00
using std : : make_shared ;
using std : : shared_ptr ;
2014-11-16 00:05:28 +01:00
using namespace fspp : : fuse ;
2014-11-04 22:33:43 +01:00
2018-07-30 09:33:34 +02:00
namespace {
bool is_valid_fspp_path ( const bf : : path & path ) {
// TODO In boost 1.63, we can use path.generic() or path.generic_path() instead of path.generic_string()
2018-07-30 09:42:51 +02:00
return path . has_root_directory ( ) // must be absolute path
& & ! path . has_root_name ( ) // on Windows, it shouldn't have a device specifier (i.e. no "C:")
& & ( path . string ( ) = = path . generic_string ( ) ) ; // must use portable '/' as directory separator
2018-07-30 09:33:34 +02:00
}
}
2017-12-03 20:01:41 +01:00
# define FUSE_OBJ (static_cast<Fuse *>(fuse_get_context()->private_data))
2014-11-04 22:33:43 +01:00
2015-09-30 14:13:26 +02:00
// Remove the following line, if you don't want to output each fuse operation on the console
//#define FSPP_LOG 1
2014-11-04 22:33:43 +01:00
namespace {
2018-09-16 03:02:03 +02:00
int fusepp_getattr ( const char * path , fspp : : fuse : : STAT * stbuf ) {
2014-11-20 13:11:07 +01:00
int rs = FUSE_OBJ - > getattr ( bf : : path ( path ) , stbuf ) ;
return rs ;
2014-11-04 22:33:43 +01:00
}
2018-09-16 03:02:03 +02:00
int fusepp_fgetattr ( const char * path , fspp : : fuse : : STAT * stbuf , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > fgetattr ( bf : : path ( path ) , stbuf , fileinfo ) ;
}
int fusepp_readlink ( const char * path , char * buf , size_t size ) {
return FUSE_OBJ - > readlink ( bf : : path ( path ) , buf , size ) ;
}
2018-09-14 11:34:11 +02:00
int fusepp_mknod ( const char * path , : : mode_t mode , dev_t rdev ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > mknod ( bf : : path ( path ) , mode , rdev ) ;
}
2018-09-14 11:34:11 +02:00
int fusepp_mkdir ( const char * path , : : mode_t mode ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > mkdir ( bf : : path ( path ) , mode ) ;
}
int fusepp_unlink ( const char * path ) {
return FUSE_OBJ - > unlink ( bf : : path ( path ) ) ;
}
int fusepp_rmdir ( const char * path ) {
return FUSE_OBJ - > rmdir ( bf : : path ( path ) ) ;
}
2015-04-22 16:00:14 +02:00
int fusepp_symlink ( const char * to , const char * from ) {
return FUSE_OBJ - > symlink ( bf : : path ( to ) , bf : : path ( from ) ) ;
2014-11-04 22:33:43 +01:00
}
int fusepp_rename ( const char * from , const char * to ) {
return FUSE_OBJ - > rename ( bf : : path ( from ) , bf : : path ( to ) ) ;
}
int fusepp_link ( const char * from , const char * to ) {
return FUSE_OBJ - > link ( bf : : path ( from ) , bf : : path ( to ) ) ;
}
2018-09-14 11:34:11 +02:00
int fusepp_chmod ( const char * path , : : mode_t mode ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > chmod ( bf : : path ( path ) , mode ) ;
}
2018-09-14 11:34:11 +02:00
int fusepp_chown ( const char * path , : : uid_t uid , : : gid_t gid ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > chown ( bf : : path ( path ) , uid , gid ) ;
}
2018-09-15 23:32:58 +02:00
int fusepp_truncate ( const char * path , int64_t size ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > truncate ( bf : : path ( path ) , size ) ;
}
2018-09-15 23:32:58 +02:00
int fusepp_ftruncate ( const char * path , int64_t size , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > ftruncate ( bf : : path ( path ) , size , fileinfo ) ;
}
int fusepp_utimens ( const char * path , const timespec times [ 2 ] ) {
return FUSE_OBJ - > utimens ( bf : : path ( path ) , times ) ;
}
int fusepp_open ( const char * path , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > open ( bf : : path ( path ) , fileinfo ) ;
}
int fusepp_release ( const char * path , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > release ( bf : : path ( path ) , fileinfo ) ;
}
2018-09-15 23:32:58 +02:00
int fusepp_read ( const char * path , char * buf , size_t size , int64_t offset , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > read ( bf : : path ( path ) , buf , size , offset , fileinfo ) ;
}
2018-09-15 23:32:58 +02:00
int fusepp_write ( const char * path , const char * buf , size_t size , int64_t offset , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > write ( bf : : path ( path ) , buf , size , offset , fileinfo ) ;
}
int fusepp_statfs ( const char * path , struct statvfs * fsstat ) {
return FUSE_OBJ - > statfs ( bf : : path ( path ) , fsstat ) ;
}
int fusepp_flush ( const char * path , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > flush ( bf : : path ( path ) , fileinfo ) ;
}
int fusepp_fsync ( const char * path , int datasync , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > fsync ( bf : : path ( path ) , datasync , fileinfo ) ;
}
//int fusepp_setxattr(const char*, const char*, const char*, size_t, int)
//int fusepp_getxattr(const char*, const char*, char*, size_t)
//int fusepp_listxattr(const char*, char*, size_t)
//int fusepp_removexattr(const char*, const char*)
int fusepp_opendir ( const char * path , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > opendir ( bf : : path ( path ) , fileinfo ) ;
}
2018-09-15 23:32:58 +02:00
int fusepp_readdir ( const char * path , void * buf , fuse_fill_dir_t filler , int64_t offset , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > readdir ( bf : : path ( path ) , buf , filler , offset , fileinfo ) ;
}
int fusepp_releasedir ( const char * path , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > releasedir ( bf : : path ( path ) , fileinfo ) ;
}
int fusepp_fsyncdir ( const char * path , int datasync , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > fsyncdir ( bf : : path ( path ) , datasync , fileinfo ) ;
}
void * fusepp_init ( fuse_conn_info * conn ) {
auto f = FUSE_OBJ ;
f - > init ( conn ) ;
return f ;
}
void fusepp_destroy ( void * userdata ) {
auto f = FUSE_OBJ ;
2015-07-22 13:48:34 +02:00
ASSERT ( userdata = = f , " Wrong userdata set " ) ;
UNUSED ( userdata ) ; //In case the assert is disabled
2014-11-04 22:33:43 +01:00
f - > destroy ( ) ;
}
int fusepp_access ( const char * path , int mask ) {
return FUSE_OBJ - > access ( bf : : path ( path ) , mask ) ;
}
2018-09-14 11:34:11 +02:00
int fusepp_create ( const char * path , : : mode_t mode , fuse_file_info * fileinfo ) {
2014-11-04 22:33:43 +01:00
return FUSE_OBJ - > create ( bf : : path ( path ) , mode , fileinfo ) ;
}
/*int fusepp_lock(const char*, fuse_file_info*, int cmd, flock*)
int fusepp_bmap ( const char * , size_t blocksize , uint64_t * idx )
int fusepp_ioctl ( const char * , int cmd , void * arg , fuse_file_info * , unsigned int flags , void * data )
int fusepp_poll ( const char * , fuse_file_info * , fuse_pollhandle * ph , unsigned * reventsp )
2018-09-15 23:32:58 +02:00
int fusepp_write_buf ( const char * , fuse_bufvec * buf , int64_t off , fuse_file_info * )
int fusepp_read_buf ( const chas * , struct fuse_bufvec * * bufp , size_t size , int64_t off , fuse_file_info * )
2014-11-04 22:33:43 +01:00
int fusepp_flock ( const char * , fuse_file_info * , int op )
2018-09-15 23:32:58 +02:00
int fusepp_fallocate ( const char * , int , int64_t , int64_t , fuse_file_info * ) */
2014-11-04 22:33:43 +01:00
fuse_operations * operations ( ) {
2015-07-21 18:22:55 +02:00
static std : : unique_ptr < fuse_operations > singleton ( nullptr ) ;
2014-11-04 22:33:43 +01:00
if ( ! singleton ) {
2015-07-21 18:22:55 +02:00
singleton = std : : make_unique < fuse_operations > ( ) ;
2014-11-04 22:33:43 +01:00
singleton - > getattr = & fusepp_getattr ;
singleton - > fgetattr = & fusepp_fgetattr ;
singleton - > readlink = & fusepp_readlink ;
singleton - > mknod = & fusepp_mknod ;
singleton - > mkdir = & fusepp_mkdir ;
singleton - > unlink = & fusepp_unlink ;
singleton - > rmdir = & fusepp_rmdir ;
singleton - > symlink = & fusepp_symlink ;
singleton - > rename = & fusepp_rename ;
singleton - > link = & fusepp_link ;
singleton - > chmod = & fusepp_chmod ;
singleton - > chown = & fusepp_chown ;
singleton - > truncate = & fusepp_truncate ;
singleton - > utimens = & fusepp_utimens ;
singleton - > open = & fusepp_open ;
singleton - > read = & fusepp_read ;
singleton - > write = & fusepp_write ;
singleton - > statfs = & fusepp_statfs ;
singleton - > flush = & fusepp_flush ;
singleton - > release = & fusepp_release ;
singleton - > fsync = & fusepp_fsync ;
/*#ifdef HAVE_SYS_XATTR_H
singleton - > setxattr = & fusepp_setxattr ;
singleton - > getxattr = & fusepp_getxattr ;
singleton - > listxattr = & fusepp_listxattr ;
singleton - > removexattr = & fusepp_removexattr ;
# endif* /
singleton - > opendir = & fusepp_opendir ;
singleton - > readdir = & fusepp_readdir ;
singleton - > releasedir = & fusepp_releasedir ;
singleton - > fsyncdir = & fusepp_fsyncdir ;
singleton - > init = & fusepp_init ;
singleton - > destroy = & fusepp_destroy ;
singleton - > access = & fusepp_access ;
singleton - > create = & fusepp_create ;
singleton - > ftruncate = & fusepp_ftruncate ;
}
return singleton . get ( ) ;
}
}
Fuse : : ~ Fuse ( ) {
2016-05-10 01:07:02 +02:00
for ( char * arg : _argv ) {
2017-10-02 08:56:31 +02:00
delete [ ] arg ;
2016-05-10 01:07:02 +02:00
arg = nullptr ;
}
_argv . clear ( ) ;
2014-11-04 22:33:43 +01:00
}
2018-12-09 18:27:53 +01:00
Fuse : : Fuse ( std : : function < shared_ptr < Filesystem > ( Fuse * fuse ) > init , std : : function < void ( ) > onMounted , std : : string fstype , boost : : optional < std : : string > fsname )
: _init ( std : : move ( init ) ) , _onMounted ( std : : move ( onMounted ) ) , _fs ( make_shared < InvalidFilesystem > ( ) ) , _mountdir ( ) , _running ( false ) , _fstype ( std : : move ( fstype ) ) , _fsname ( std : : move ( fsname ) ) {
ASSERT ( static_cast < bool > ( _init ) , " Invalid init given " ) ;
ASSERT ( static_cast < bool > ( _onMounted ) , " Invalid onMounted given " ) ;
2014-11-15 16:33:24 +01:00
}
2015-11-17 07:05:04 +01:00
void Fuse : : _logException ( const std : : exception & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " Exception thrown: {} " , e . what ( ) ) ;
2015-11-17 07:05:04 +01:00
}
void Fuse : : _logUnknownException ( ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " Unknown exception thrown " ) ;
2015-11-17 07:05:04 +01:00
}
2016-05-10 01:07:02 +02:00
void Fuse : : run ( const bf : : path & mountdir , const vector < string > & fuseOptions ) {
_mountdir = mountdir ;
ASSERT ( _argv . size ( ) = = 0 , " Filesystem already started " ) ;
2016-06-04 09:45:49 +02:00
_argv = _build_argv ( mountdir , fuseOptions ) ;
2017-12-03 20:01:41 +01:00
fuse_main ( _argv . size ( ) , _argv . data ( ) , operations ( ) , this ) ;
2016-06-04 09:45:49 +02:00
}
vector < char * > Fuse : : _build_argv ( const bf : : path & mountdir , const vector < string > & fuseOptions ) {
vector < char * > argv ;
2016-06-07 21:44:35 +02:00
argv . reserve ( 6 + fuseOptions . size ( ) ) ; // fuseOptions + executable name + mountdir + 2x fuse options (subtype, fsname), each taking 2 entries ("-o", "key=value").
argv . push_back ( _create_c_string ( _fstype ) ) ; // The first argument (executable name) is the file system type
2018-05-21 01:20:38 +02:00
argv . push_back ( _create_c_string ( mountdir . string ( ) ) ) ; // The second argument is the mountdir
2016-05-10 01:07:02 +02:00
for ( const string & option : fuseOptions ) {
2016-06-07 21:44:35 +02:00
argv . push_back ( _create_c_string ( option ) ) ;
2016-05-10 01:07:02 +02:00
}
2016-06-07 21:44:35 +02:00
_add_fuse_option_if_not_exists ( & argv , " subtype " , _fstype ) ;
_add_fuse_option_if_not_exists ( & argv , " fsname " , _fsname . get_value_or ( _fstype ) ) ;
2018-10-19 20:37:21 +02:00
# ifdef __APPLE__
// Make volume name default to mountdir on macOS
_add_fuse_option_if_not_exists ( & argv , " volname " , mountdir . filename ( ) . string ( ) ) ;
# endif
2016-07-16 17:08:53 +02:00
// TODO Also set read/write size for osxfuse. The options there are called differently.
2016-07-22 20:44:06 +02:00
// large_read not necessary because reads are large anyhow. This option is only important for 2.4.
//argv.push_back(_create_c_string("-o"));
//argv.push_back(_create_c_string("large_read"));
2016-07-16 16:09:47 +02:00
argv . push_back ( _create_c_string ( " -o " ) ) ;
argv . push_back ( _create_c_string ( " big_writes " ) ) ;
2016-06-04 09:45:49 +02:00
return argv ;
}
void Fuse : : _add_fuse_option_if_not_exists ( vector < char * > * argv , const string & key , const string & value ) {
if ( ! _has_option ( * argv , key ) ) {
argv - > push_back ( _create_c_string ( " -o " ) ) ;
argv - > push_back ( _create_c_string ( key + " = " + value ) ) ;
2016-06-02 11:51:44 +02:00
}
2016-06-04 09:45:49 +02:00
}
bool Fuse : : _has_option ( const vector < char * > & vec , const string & key ) {
2016-06-23 02:57:00 +02:00
// The fuse option can either be present as "-okey=value" or as "-o key=value", we have to check both.
return _has_entry_with_prefix ( key + " = " , vec ) | | _has_entry_with_prefix ( " -o " + key + " = " , vec ) ;
}
bool Fuse : : _has_entry_with_prefix ( const string & prefix , const vector < char * > & vec ) {
auto found = std : : find_if ( vec . begin ( ) , vec . end ( ) , [ & prefix ] ( const char * entry ) {
return 0 = = std : : strncmp ( prefix . c_str ( ) , entry , prefix . size ( ) ) ;
2016-06-04 09:45:49 +02:00
} ) ;
return found ! = vec . end ( ) ;
2015-10-15 03:41:02 +02:00
}
2016-05-10 01:07:02 +02:00
char * Fuse : : _create_c_string ( const string & str ) {
// The memory allocated here is destroyed in the destructor of the Fuse class.
char * c_str = new char [ str . size ( ) + 1 ] ;
std : : memcpy ( c_str , str . c_str ( ) , str . size ( ) + 1 ) ;
return c_str ;
}
2014-11-18 00:14:33 +01:00
bool Fuse : : running ( ) const {
return _running ;
}
2015-11-13 00:03:22 +01:00
void Fuse : : stop ( ) {
2019-01-19 22:02:41 +01:00
unmount ( _mountdir , false ) ;
}
void Fuse : : unmount ( const bf : : path & mountdir , bool force ) {
2015-11-13 00:03:22 +01:00
//TODO Find better way to unmount (i.e. don't use external fusermount). Unmounting by kill(getpid(), SIGINT) worked, but left the mount directory transport endpoint as not connected.
2019-01-19 22:02:41 +01:00
# if defined(__APPLE__)
int returncode = cpputils : : Subprocess : : call ( std : : string ( " umount " ) + mountdir . string ( ) ) . exitcode ;
# elif defined(_MSC_VER)
std : : wstring mountdir_ = std : : wstring_convert < std : : codecvt_utf8_utf16 < wchar_t > > ( ) . from_bytes ( mountdir . string ( ) ) ;
BOOL success = DokanRemoveMountPoint ( mountdir_ . c_str ( ) ) ;
int returncode = success ? 0 : - 1 ;
2016-02-14 01:00:00 +01:00
# else
2019-01-19 22:02:41 +01:00
std : : string command = force ? " fusermount -u " : " fusermount -z -u " ; // "-z" takes care that if the filesystem can't be unmounted right now because something is opened, it will be unmounted as soon as it can be.
int returncode = cpputils : : Subprocess : : call (
command + " " + mountdir . string ( ) ) . exitcode ;
2016-02-14 01:00:00 +01:00
# endif
2019-01-19 22:02:41 +01:00
if ( returncode ! = 0 ) {
throw std : : runtime_error ( " Could not unmount filesystem " ) ;
2015-11-13 00:03:22 +01:00
}
}
2018-09-16 03:02:03 +02:00
int Fuse : : getattr ( const bf : : path & path , fspp : : fuse : : STAT * stbuf ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " getattr({}, _, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
_fs - > lstat ( path , stbuf ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::getattr: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-16 03:02:03 +02:00
int Fuse : : fgetattr ( const bf : : path & path , fspp : : fuse : : STAT * stbuf , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " fgetattr({}, _, _) \n " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
// On FreeBSD, trying to do anything with the mountpoint ends up
// opening it, and then using the FD for an fgetattr. So in the
// special case of a path of "/", I need to do a getattr on the
2016-02-19 02:10:10 +01:00
// underlying base directory instead of doing the fgetattr().
2014-11-15 16:33:24 +01:00
// TODO Check if necessary
2018-05-21 01:20:38 +02:00
if ( path . string ( ) = = " / " ) {
2014-11-15 16:33:24 +01:00
return getattr ( path , stbuf ) ;
}
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2015-04-21 21:08:23 +02:00
_fs - > fstat ( fileinfo - > fh , stbuf ) ;
2015-07-21 19:45:44 +02:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::fgetattr: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : readlink ( const bf : : path & path , char * buf , size_t size ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " readlink({}, _, {}) " , path , size ) ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-22 16:00:14 +02:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2018-09-15 23:32:58 +02:00
_fs - > readSymlink ( path , buf , fspp : : num_bytes_t ( size ) ) ;
2015-04-22 16:00:14 +02:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::readlink: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2015-04-22 16:00:14 +02:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2015-04-22 16:00:14 +02:00
}
2014-11-15 16:33:24 +01:00
}
2018-09-14 11:34:11 +02:00
int Fuse : : mknod ( const bf : : path & path , : : mode_t mode , dev_t rdev ) {
2014-11-15 16:33:24 +01:00
UNUSED ( rdev ) ;
UNUSED ( mode ) ;
UNUSED ( path ) ;
2017-02-04 20:03:20 +01:00
LOG ( WARN , " Called non-implemented mknod({}, {}, _) " , path , mode ) ;
2014-11-15 16:33:24 +01:00
return ENOSYS ;
}
2018-09-14 11:34:11 +02:00
int Fuse : : mkdir ( const bf : : path & path , : : mode_t mode ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " mkdir({}, {}) " , path , mode ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2015-04-22 14:31:15 +02:00
auto context = fuse_get_context ( ) ;
_fs - > mkdir ( path , mode , context - > uid , context - > gid ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::mkdir: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : unlink ( const bf : : path & path ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " unlink({}) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
_fs - > unlink ( path ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::unlink: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : rmdir ( const bf : : path & path ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " rmdir({}) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
_fs - > rmdir ( path ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::rmdir: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2019-01-13 18:27:50 +01:00
int Fuse : : symlink ( const bf : : path & to , const bf : : path & from ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2019-01-13 18:27:50 +01:00
LOG ( DEBUG , " symlink({}, {}) " , to , from ) ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-22 16:00:14 +02:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( from ) , " has to be an absolute path " ) ;
2015-04-23 09:17:23 +02:00
auto context = fuse_get_context ( ) ;
2019-01-13 18:27:50 +01:00
_fs - > createSymlink ( to , from , context - > uid , context - > gid ) ;
2015-04-22 16:00:14 +02:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::symlink: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2015-04-22 16:00:14 +02:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2015-04-22 16:00:14 +02:00
}
2014-11-15 16:33:24 +01:00
}
int Fuse : : rename ( const bf : : path & from , const bf : : path & to ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " rename({}, {}) " , from , to ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( from ) , " from has to be an absolute path " ) ;
ASSERT ( is_valid_fspp_path ( to ) , " rename target has to be an absolute path. If this assert throws, we have to add code here that makes the path absolute. " ) ;
2014-11-19 00:14:35 +01:00
_fs - > rename ( from , to ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::rename: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2018-07-31 16:29:35 +02:00
} catch ( const fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
//TODO
int Fuse : : link ( const bf : : path & from , const bf : : path & to ) {
2017-02-04 20:03:20 +01:00
LOG ( WARN , " NOT IMPLEMENTED: link({}, {}) " , from , to ) ;
2014-11-15 17:24:07 +01:00
//auto real_from = _impl->RootDir() / from;
//auto real_to = _impl->RootDir() / to;
2018-05-21 01:20:38 +02:00
//int retstat = ::link(real_from.string().c_str(), real_to.string().c_str());
2014-11-15 16:33:24 +01:00
//return errcode_map(retstat);
return ENOSYS ;
}
2018-09-14 11:34:11 +02:00
int Fuse : : chmod ( const bf : : path & path , : : mode_t mode ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " chmod({}, {}) " , path , mode ) ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-21 21:08:23 +02:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2015-04-21 21:08:23 +02:00
_fs - > chmod ( path , mode ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::chmod: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2015-04-21 21:08:23 +02:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2015-04-21 21:08:23 +02:00
}
2014-11-15 16:33:24 +01:00
}
2018-09-14 11:34:11 +02:00
int Fuse : : chown ( const bf : : path & path , : : uid_t uid , : : gid_t gid ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " chown({}, {}, {}) " , path , uid , gid ) ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-21 21:08:23 +02:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2015-04-21 21:08:23 +02:00
_fs - > chown ( path , uid , gid ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::chown: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2015-04-21 21:08:23 +02:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2015-04-21 21:08:23 +02:00
}
2014-11-15 16:33:24 +01:00
}
2018-09-15 23:32:58 +02:00
int Fuse : : truncate ( const bf : : path & path , int64_t size ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " truncate({}, {}) " , path , size ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2018-09-15 23:32:58 +02:00
_fs - > truncate ( path , fspp : : num_bytes_t ( size ) ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::truncate: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-15 23:32:58 +02:00
int Fuse : : ftruncate ( const bf : : path & path , int64_t size , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " ftruncate({}, {}) " , path , size ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
try {
2018-09-15 23:32:58 +02:00
_fs - > ftruncate ( fileinfo - > fh , fspp : : num_bytes_t ( size ) ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::ftruncate: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : utimens ( const bf : : path & path , const timespec times [ 2 ] ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " utimens({}, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2016-02-09 09:19:45 +01:00
_fs - > utimens ( path , times [ 0 ] , times [ 1 ] ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::utimens: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : open ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " open({}, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
fileinfo - > fh = _fs - > openFile ( path , fileinfo - > flags ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::open: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : release ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " release({}, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
try {
2014-11-19 00:14:35 +01:00
_fs - > closeFile ( fileinfo - > fh ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::release: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-15 23:32:58 +02:00
int Fuse : : read ( const bf : : path & path , char * buf , size_t size , int64_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " read({}, _, {}, {}, _) " , path , size , offset ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
try {
2018-09-15 23:32:58 +02:00
return _fs - > read ( fileinfo - > fh , buf , fspp : : num_bytes_t ( size ) , fspp : : num_bytes_t ( offset ) ) . value ( ) ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::read: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-15 23:32:58 +02:00
int Fuse : : write ( const bf : : path & path , const char * buf , size_t size , int64_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " write({}, _, {}, {}, _) " , path , size , offsset ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
try {
2018-09-15 23:32:58 +02:00
_fs - > write ( fileinfo - > fh , buf , fspp : : num_bytes_t ( size ) , fspp : : num_bytes_t ( offset ) ) ;
2014-11-15 16:33:24 +01:00
return size ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::write: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-14 11:34:11 +02:00
int Fuse : : statfs ( const bf : : path & path , struct : : statvfs * fsstat ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " statfs({}, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2018-09-22 23:24:31 +02:00
UNUSED ( path ) ;
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2018-09-22 23:24:31 +02:00
_fs - > statfs ( fsstat ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::statfs: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : flush ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( WARN , " flush({}, _) " , path ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
2014-11-21 01:11:24 +01:00
try {
_fs - > flush ( fileinfo - > fh ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::flush: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-21 01:11:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-21 01:11:24 +01:00
}
2014-11-15 16:33:24 +01:00
}
int Fuse : : fsync ( const bf : : path & path , int datasync , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " fsync({}, {}, _) " , path , datasync ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( path ) ;
try {
if ( datasync ) {
2014-11-19 00:14:35 +01:00
_fs - > fdatasync ( fileinfo - > fh ) ;
2014-11-15 16:33:24 +01:00
} else {
2014-11-19 00:14:35 +01:00
_fs - > fsync ( fileinfo - > fh ) ;
2014-11-15 16:33:24 +01:00
}
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::fsync: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : opendir ( const bf : : path & path , fuse_file_info * fileinfo ) {
UNUSED ( path ) ;
UNUSED ( fileinfo ) ;
2017-02-04 20:03:20 +01:00
//LOG(DEBUG, "opendir({}, _)", path);
2014-11-15 16:33:24 +01:00
//We don't need opendir, because readdir works directly on the path
return 0 ;
}
2018-09-15 23:32:58 +02:00
int Fuse : : readdir ( const bf : : path & path , void * buf , fuse_fill_dir_t filler , int64_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " readdir({}, _, _, {}, _) " , path , offest ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( fileinfo ) ;
UNUSED ( offset ) ;
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
auto entries = _fs - > readDir ( path ) ;
2018-09-16 03:02:03 +02:00
fspp : : fuse : : STAT stbuf { } ;
2014-11-15 16:33:24 +01:00
for ( const auto & entry : * entries ) {
2015-04-21 23:19:50 +02:00
//We could pass more file metadata to filler() in its third parameter,
//but it doesn't help performance since fuse ignores everything in stbuf
//except for file-type bits in st_mode and (if used) st_ino.
2014-11-15 16:33:24 +01:00
//It does getattr() calls on all entries nevertheless.
2015-03-11 00:22:36 +01:00
if ( entry . type = = Dir : : EntryType : : DIR ) {
2015-04-21 23:19:50 +02:00
stbuf . st_mode = S_IFDIR ;
2015-04-22 16:00:14 +02:00
} else if ( entry . type = = Dir : : EntryType : : FILE ) {
2015-04-21 23:19:50 +02:00
stbuf . st_mode = S_IFREG ;
2015-04-22 16:00:14 +02:00
} else if ( entry . type = = Dir : : EntryType : : SYMLINK ) {
stbuf . st_mode = S_IFLNK ;
} else {
2015-07-22 13:48:34 +02:00
ASSERT ( false , " Unknown entry type " ) ;
2015-03-11 00:22:36 +01:00
}
if ( filler ( buf , entry . name . c_str ( ) , & stbuf , 0 ) ! = 0 ) {
2014-11-15 16:33:24 +01:00
return - ENOMEM ;
}
}
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::readdir: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
int Fuse : : releasedir ( const bf : : path & path , fuse_file_info * fileinfo ) {
UNUSED ( path ) ;
UNUSED ( fileinfo ) ;
2017-02-04 20:03:20 +01:00
//LOG(DEBUG, "releasedir({}, _)", path);
2014-11-15 16:33:24 +01:00
//We don't need releasedir, because readdir works directly on the path
return 0 ;
}
//TODO
int Fuse : : fsyncdir ( const bf : : path & path , int datasync , fuse_file_info * fileinfo ) {
UNUSED ( fileinfo ) ;
UNUSED ( datasync ) ;
UNUSED ( path ) ;
2017-02-04 20:03:20 +01:00
//LOG(WARN, "Called non-implemented fsyncdir({}, {}, _)", path, datasync);
2014-11-15 16:33:24 +01:00
return 0 ;
}
void Fuse : : init ( fuse_conn_info * conn ) {
UNUSED ( conn ) ;
2018-12-03 07:57:21 +01:00
_fs = _init ( this ) ;
2017-02-04 20:03:20 +01:00
LOG ( INFO , " Filesystem started. " ) ;
2016-02-14 01:18:19 +01:00
2014-11-18 00:14:33 +01:00
_running = true ;
2018-12-09 18:27:53 +01:00
_onMounted ( ) ;
2015-10-17 17:23:35 +02:00
# ifdef FSPP_LOG
cpputils : : logging : : setLevel ( DEBUG ) ;
# endif
2014-11-15 16:33:24 +01:00
}
void Fuse : : destroy ( ) {
2018-12-03 07:57:21 +01:00
_fs = make_shared < InvalidFilesystem > ( ) ;
2017-02-04 20:03:20 +01:00
LOG ( INFO , " Filesystem stopped. " ) ;
2016-02-14 01:18:19 +01:00
_running = false ;
2018-12-03 07:57:21 +01:00
cpputils : : logging : : logger ( ) - > flush ( ) ;
2014-11-15 16:33:24 +01:00
}
int Fuse : : access ( const bf : : path & path , int mask ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " access({}, {}) " , path , mask ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2014-11-19 00:14:35 +01:00
_fs - > access ( path , mask ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::access: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}
2018-09-14 11:34:11 +02:00
int Fuse : : create ( const bf : : path & path , : : mode_t mode , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2017-02-04 20:03:20 +01:00
LOG ( DEBUG , " create({}, {}, _) " , path , mode ) ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2018-07-30 09:33:34 +02:00
ASSERT ( is_valid_fspp_path ( path ) , " has to be an absolute path " ) ;
2015-04-22 14:31:15 +02:00
auto context = fuse_get_context ( ) ;
fileinfo - > fh = _fs - > createAndOpenFile ( path , mode , context - > uid , context - > gid ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2018-05-17 08:03:03 +02:00
LOG ( ERR , " AssertFailed in Fuse::create: {} " , e . what ( ) ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-15 16:33:24 +01:00
} catch ( FuseErrnoException & e ) {
return - e . getErrno ( ) ;
2015-11-17 07:05:04 +01:00
} catch ( const std : : exception & e ) {
_logException ( e ) ;
return - EIO ;
} catch ( . . . ) {
_logUnknownException ( ) ;
return - EIO ;
2014-11-15 16:33:24 +01:00
}
}