2014-11-15 16:33:24 +01:00
# include "Fuse.h"
2014-11-04 22:33:43 +01:00
# include <memory>
# include <cassert>
2015-02-17 00:48:49 +01:00
# include "FuseErrnoException.h"
2014-11-28 14:46:45 +01:00
# include "Filesystem.h"
2015-07-21 19:45:44 +02:00
# include <iostream>
2015-07-22 13:48:34 +02:00
# include <messmer/cpp-utils/assert/assert.h>
2015-10-30 20:18:31 +01:00
# include <messmer/cpp-utils/logging/logging.h>
2015-11-13 00:03:22 +01:00
# include <csignal>
2014-11-15 16:33:24 +01:00
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 ;
2014-11-16 00:05:28 +01:00
using namespace fspp : : fuse ;
2014-11-04 22:33:43 +01:00
# define FUSE_OBJ ((Fuse *) fuse_get_context()->private_data)
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 {
int fusepp_getattr ( const char * path , struct 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
}
int fusepp_fgetattr ( const char * path , struct stat * stbuf , fuse_file_info * fileinfo ) {
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 ) ;
}
int fusepp_mknod ( const char * path , mode_t mode , dev_t rdev ) {
return FUSE_OBJ - > mknod ( bf : : path ( path ) , mode , rdev ) ;
}
int fusepp_mkdir ( const char * path , mode_t mode ) {
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 ) ) ;
}
int fusepp_chmod ( const char * path , mode_t mode ) {
return FUSE_OBJ - > chmod ( bf : : path ( path ) , mode ) ;
}
int fusepp_chown ( const char * path , uid_t uid , gid_t gid ) {
return FUSE_OBJ - > chown ( bf : : path ( path ) , uid , gid ) ;
}
int fusepp_truncate ( const char * path , off_t size ) {
return FUSE_OBJ - > truncate ( bf : : path ( path ) , size ) ;
}
int fusepp_ftruncate ( const char * path , off_t size , fuse_file_info * fileinfo ) {
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 ) ;
}
int fusepp_read ( const char * path , char * buf , size_t size , off_t offset , fuse_file_info * fileinfo ) {
return FUSE_OBJ - > read ( bf : : path ( path ) , buf , size , offset , fileinfo ) ;
}
int fusepp_write ( const char * path , const char * buf , size_t size , off_t offset , fuse_file_info * fileinfo ) {
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 ) ;
}
int fusepp_readdir ( const char * path , void * buf , fuse_fill_dir_t filler , off_t offset , fuse_file_info * fileinfo ) {
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 ) ;
}
int fusepp_create ( const char * path , mode_t mode , fuse_file_info * fileinfo ) {
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 )
int fusepp_write_buf ( const char * , fuse_bufvec * buf , off_t off , fuse_file_info * )
int fusepp_read_buf ( const chas * , struct fuse_bufvec * * bufp , size_t size , off_T off , fuse_file_info * )
int fusepp_flock ( const char * , fuse_file_info * , int op )
int fusepp_fallocate ( const char * , int , off_t , off_t , fuse_file_info * ) */
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 ( ) {
}
2014-11-19 00:14:35 +01:00
Fuse : : Fuse ( Filesystem * fs )
2015-11-13 00:03:22 +01:00
: _fs ( fs ) , _mountdir ( ) , _running ( false ) {
2014-11-15 16:33:24 +01:00
}
2014-11-04 22:33:43 +01:00
void Fuse : : run ( int argc , char * * argv ) {
2015-10-15 03:41:02 +02:00
vector < char * > _argv ( argv , argv + argc ) ;
2015-11-13 00:03:22 +01:00
_mountdir = argv [ 1 ] ;
2015-10-15 03:41:02 +02:00
fuse_main ( _argv . size ( ) , _argv . data ( ) , operations ( ) , ( void * ) this ) ;
}
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 ( ) {
//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.
int ret = system ( ( " fusermount -z -u " + _mountdir . native ( ) ) . c_str ( ) ) ; // "-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.
if ( ret ! = 0 ) {
LOG ( ERROR ) < < " Could not unmount filesystem " ;
}
}
2014-11-15 16:33:24 +01:00
int Fuse : : getattr ( const bf : : path & path , struct stat * stbuf ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " getattr( " < < path < < " , _, _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::getattr: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
int Fuse : : fgetattr ( const bf : : path & path , struct stat * stbuf , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " fgetattr( " < < path < < " , _, _) \n " ;
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
// underlying root directory instead of doing the fgetattr().
// TODO Check if necessary
if ( path . native ( ) = = " / " ) {
return getattr ( path , stbuf ) ;
}
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::fgetattr: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
int Fuse : : readlink ( const bf : : path & path , char * buf , size_t size ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " readlink( " < < path < < " , _, " < < size < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-22 16:00:14 +02:00
try {
_fs - > readSymlink ( path , buf , size ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
2014-11-15 16:33:24 +01:00
}
int Fuse : : mknod ( const bf : : path & path , mode_t mode , dev_t rdev ) {
UNUSED ( rdev ) ;
UNUSED ( mode ) ;
UNUSED ( path ) ;
2015-10-17 17:23:35 +02:00
LOG ( WARN ) < < " Called non-implemented mknod( " < < path < < " , " < < mode < < " , _) " ;
2014-11-15 16:33:24 +01:00
return ENOSYS ;
}
int Fuse : : mkdir ( const bf : : path & path , mode_t mode ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " mkdir( " < < path < < " , " < < mode < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::mkdir: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
int Fuse : : unlink ( const bf : : path & path ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " unlink( " < < path < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::unlink: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
int Fuse : : rmdir ( const bf : : path & path ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " rmdir( " < < path < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::rmdir: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
int Fuse : : symlink ( const bf : : path & from , const bf : : path & to ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " symlink( " < < from < < " , " < < to < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-22 16:00:14 +02:00
try {
2015-04-23 09:17:23 +02:00
auto context = fuse_get_context ( ) ;
_fs - > createSymlink ( from , to , 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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::symlink: " < < 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 ( ) ;
}
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
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " rename( " < < from < < " , " < < to < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " AssertFailed in Fuse::rename: " < < e . what ( ) ;
2015-07-21 19:45:44 +02:00
return - EIO ;
2014-11-28 14:46:45 +01:00
} catch ( fspp : : fuse : : FuseErrnoException & e ) {
2014-11-15 16:33:24 +01:00
return - e . getErrno ( ) ;
}
}
//TODO
int Fuse : : link ( const bf : : path & from , const bf : : path & to ) {
2015-10-17 17:23:35 +02: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;
2014-11-15 16:33:24 +01:00
//int retstat = ::link(real_from.c_str(), real_to.c_str());
//return errcode_map(retstat);
return ENOSYS ;
}
int Fuse : : chmod ( const bf : : path & path , mode_t mode ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " chmod( " < < path < < " , " < < mode < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2015-04-21 21:08:23 +02:00
try {
_fs - > chmod ( path , mode ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
2014-11-15 16:33:24 +01: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
2015-10-17 17:23:35 +02: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 {
_fs - > chown ( path , uid , gid ) ;
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
2014-11-15 16:33:24 +01:00
}
int Fuse : : truncate ( const bf : : path & path , off_t size ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " truncate( " < < path < < " , " < < size < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2014-11-19 00:14:35 +01:00
_fs - > truncate ( path , size ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : ftruncate ( const bf : : path & path , off_t size , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02: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 {
2014-11-19 00:14:35 +01:00
_fs - > ftruncate ( fileinfo - > fh , size ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
//TODO
int Fuse : : utimens ( const bf : : path & path , const timespec times [ 2 ] ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " utimens( " < < path < < " , _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2014-11-19 00:14:35 +01:00
_fs - > utimens ( path , times ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : open ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " open( " < < path < < " , _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : release ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02: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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : read ( const bf : : path & path , char * buf , size_t size , off_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02: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 {
2014-11-19 00:14:35 +01:00
return _fs - > read ( fileinfo - > fh , buf , size , offset ) ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : write ( const bf : : path & path , const char * buf , size_t size , off_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " write( " < < path < < " , _, " < < size < < " , " < < offset < < " , _) " ;
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 - > write ( fileinfo - > fh , buf , size , offset ) ;
2014-11-15 16:33:24 +01:00
return size ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
//TODO
int Fuse : : statfs ( const bf : : path & path , struct statvfs * fsstat ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " statfs( " < < path < < " , _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
2014-11-19 00:14:35 +01:00
_fs - > statfs ( path , fsstat ) ;
2014-11-15 16:33:24 +01:00
return 0 ;
2015-07-22 13:48:34 +02:00
} catch ( const cpputils : : AssertFailed & e ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
//TODO
int Fuse : : flush ( const bf : : path & path , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
//TODO Implement it
LOG ( WARN ) < < " Called non-implemented 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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
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
2015-10-17 17:23:35 +02: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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : opendir ( const bf : : path & path , fuse_file_info * fileinfo ) {
UNUSED ( path ) ;
UNUSED ( fileinfo ) ;
2015-10-17 17:23:35 +02: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 ;
}
int Fuse : : readdir ( const bf : : path & path , void * buf , fuse_fill_dir_t filler , off_t offset , fuse_file_info * fileinfo ) {
2015-09-30 14:13:26 +02:00
# ifdef FSPP_LOG
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " readdir( " < < path < < " , _, _, " < < offset < < " , _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
UNUSED ( fileinfo ) ;
UNUSED ( offset ) ;
try {
2014-11-19 00:14:35 +01:00
auto entries = _fs - > readDir ( path ) ;
2015-03-11 00:22:36 +01:00
struct 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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
int Fuse : : releasedir ( const bf : : path & path , fuse_file_info * fileinfo ) {
UNUSED ( path ) ;
UNUSED ( fileinfo ) ;
2015-10-17 17:23:35 +02: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 ) ;
2015-10-17 17:23:35 +02: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 ) ;
2014-11-18 00:14:33 +01:00
_running = true ;
2015-10-17 17:23:35 +02:00
# ifdef FSPP_LOG
cpputils : : logging : : setLevel ( DEBUG ) ;
# endif
2015-10-30 20:18:31 +01:00
LOG ( INFO ) < < " Filesystem started. " ;
2014-11-15 16:33:24 +01:00
}
void Fuse : : destroy ( ) {
2014-11-18 00:14:33 +01:00
_running = false ;
2015-10-30 20:18:31 +01:00
LOG ( INFO ) < < " Filesystem stopped. " ;
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
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " access( " < < path < < " , " < < mask < < " ) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}
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
2015-10-17 17:23:35 +02:00
LOG ( DEBUG ) < < " create( " < < path < < " , " < < mode < < " , _) " ;
2015-09-30 14:13:26 +02:00
# endif
2014-11-15 16:33:24 +01:00
try {
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 ) {
2015-10-17 17:23:35 +02:00
LOG ( ERROR ) < < " 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 ( ) ;
}
}