From 68148447b090749057dc2815fb6f684c6ffbd66a Mon Sep 17 00:00:00 2001 From: ln-tech Date: Wed, 8 Jan 2020 22:23:28 +0100 Subject: fixed code: removed useless splicing, code optimization, commandline arguments fixed, auto_cache in lowlevel activated, multi and single threaded modes are supported now --- src/fuse/connection.c | 39 +++++---------------- src/fuse/connection.h | 3 -- src/fuse/main.c | 97 ++++++++++++--------------------------------------- src/fuse/main.h | 5 --- 4 files changed, 31 insertions(+), 113 deletions(-) delete mode 100644 src/fuse/main.h (limited to 'src/fuse') diff --git a/src/fuse/connection.c b/src/fuse/connection.c index cbfaf8c..f16eb1e 100644 --- a/src/fuse/connection.c +++ b/src/fuse/connection.c @@ -15,7 +15,6 @@ #include #include #include -#include "main.h" /* Constants */ static const size_t SHORTBUF = 100; @@ -32,7 +31,7 @@ static const int FAIL_BACKOFF_START_COUNT = 8; static bool connectionInitDone = false; static bool threadInitDone = false; static pthread_mutex_t mutexInit = PTHREAD_MUTEX_INITIALIZER; -extern bool keepRunning = true; +bool keepRunning = true; static bool learnNewServers; // List of pending requests @@ -222,10 +221,10 @@ bool connection_initThreads() logadd( LOG_ERROR, "Mutex or spinlock init failure" ); success = false; } else { - if ( pthread_create( &thread, NULL, &connection_receiveThreadMain, (void*)(size_t)connection.sockFd ) != 0 ) { + if (pthread_create( &thread, NULL, &connection_receiveThreadMain, (void*)(size_t)connection.sockFd ) != 0 ) { logadd( LOG_ERROR, "Could not create receive thread" ); success = false; - } else if ( pthread_create( &thread, NULL, &connection_backgroundThread, NULL ) != 0 ) { + } else if (pthread_create( &thread, NULL, &connection_backgroundThread, NULL ) != 0 ) { logadd( LOG_ERROR, "Could not create background thread" ); success = false; } @@ -347,11 +346,9 @@ static void* connection_receiveThreadMain(void *sockPtr) int sockFd = (int)(size_t)sockPtr; dnbd3_reply_t reply; pthread_detach( pthread_self() ); - while ( keepRunning ) { int ret; - struct fuse_bufvec splice_buf; do { ret = dnbd3_read_reply( sockFd, &reply, true ); if ( ret == REPLY_OK ) break; @@ -374,11 +371,6 @@ static void* connection_receiveThreadMain(void *sockPtr) } else { // Found a match request->buffer = malloc(request->length); // char* - if (request->mode == SPLICE) { - splice_buf = FUSE_BUFVEC_INIT(request->length); - splice_buf.buf[0].mem = request->buffer; - splice_buf.buf[0].pos = request->offset; - } const ssize_t ret = sock_recv( sockFd, request->buffer, request->length ); if ( ret != (ssize_t)request->length ) { logadd( LOG_DEBUG1, "receiving payload for a block reply failed" ); @@ -402,20 +394,10 @@ static void* connection_receiveThreadMain(void *sockPtr) } unlock_rw( &altLock ); } - int rep = -1; - if (request->mode == NO_SPLICE) { - rep = fuse_reply_buf(request->fuse_req, request->buffer, request->length); - } - else if (request->mode == SPLICE) { - rep = fuse_reply_data(request->fuse_req, &splice_buf, FUSE_BUF_FORCE_SPLICE); - // free(splice_buf); - } - if (rep == 0) { - // no error - } - else { - printf("ERROR ON FUSE REPLY %i \n", rep); - fuse_reply_err(request->fuse_req, rep); + int fuse_reply = fuse_reply_buf(request->fuse_req, request->buffer, request->length); + if (fuse_reply != 0) { + printf("ERROR ON FUSE REPLY %i \n", fuse_reply); + fuse_reply_err(request->fuse_req, fuse_reply); } free(request->buffer); request->buffer = NULL; @@ -443,7 +425,6 @@ static void* connection_receiveThreadMain(void *sockPtr) } } } - if (!keepRunning) connection_close(); logadd( LOG_DEBUG1, "Aus der Schleife rausgeflogen! ARRRRRRRRRR" ); fail:; // Make sure noone is trying to use the socket for sending by locking, @@ -462,6 +443,7 @@ fail:; static void* connection_backgroundThread(void *something UNUSED) { + pthread_detach( pthread_self() ); // fixes thread leak after fuse termination ticks nextKeepalive; ticks nextRttCheck; @@ -714,9 +696,6 @@ static void probeAltServers() } // Success, wake up caller logadd( LOG_DEBUG1, "[RTT] Successful direct probe" ); - //request->success = true; - //request->finished = true; - //signal_call( request->signal ); } else { // Wasn't a request that's in our request queue if ( !throwDataAway( sock, testLength ) ) { @@ -914,8 +893,6 @@ static bool throwDataAway(int sockFd, uint32_t amount) static void enqueueRequest(dnbd3_async_t *request) { request->next = NULL; - //request->finished = false; - //request->success = false; //logadd( LOG_DEBUG2, "Queue: %p @ %s : %d", request, file, line ); // Measure latency and add to switch formula timing_get( &request->time ); diff --git a/src/fuse/connection.h b/src/fuse/connection.h index d0a89dc..15075d5 100644 --- a/src/fuse/connection.h +++ b/src/fuse/connection.h @@ -9,8 +9,6 @@ #define FUSE_USE_VERSION 30 #include -#define NO_SPLICE 0 -#define SPLICE 1 extern bool keepRunning; struct _dnbd3_async; @@ -21,7 +19,6 @@ typedef struct _dnbd3_async { ticks time; // When request was put on wire, 0 if not measuring uint64_t offset; uint32_t length; - int mode; // 0 splice off, 1 splice on, ... fuse_req_t fuse_req; } dnbd3_async_t; diff --git a/src/fuse/main.c b/src/fuse/main.c index e3e818b..df85bc2 100644 --- a/src/fuse/main.c +++ b/src/fuse/main.c @@ -32,11 +32,9 @@ #include #define debugf(...) do { logadd( LOG_DEBUG1, __VA_ARGS__ ); } while (0) -#define MODE 0 static const char * const IMAGE_PATH = "/img"; -static const char * const STATS_PATH = "/status"; static const char *IMAGE_NAME = "img"; static const char *STATS_NAME = "status"; @@ -48,6 +46,7 @@ static struct timespec startupTime; static uid_t owner; static void (*fuse_sigIntHandler)(int) = NULL; static void (*fuse_sigTermHandler)(int) = NULL; +//static struct fuse_operations dnbd3_fuse_no_operations; static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize, off_t off, size_t maxsize); static int fillStatsFile(char *buf, size_t size, off_t offset); @@ -173,8 +172,11 @@ static void image_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info fuse_reply_err(req, EISDIR); else if ((fi->flags & 3) != O_RDONLY) fuse_reply_err(req, EACCES); - else + else { + // auto caching + fi->keep_cache = 1; fuse_reply_open(req, fi); + } } static int fillStatsFile(char *buf, size_t size, off_t offset) { @@ -229,7 +231,7 @@ static void image_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off { size = imageSize - offset; } - //debugf("\n OFFSET %d SIZE %d IMAGE %d \n", offset, size, imageSize); + if (useDebug) { uint64_t startBlock = offset / (4096); @@ -247,78 +249,27 @@ static void image_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off request->length = (uint32_t)size; request->offset = offset; request->fuse_req = req; - request->mode = MODE; if (!connection_read(request)) fuse_reply_err(req, EINVAL); } } static void image_sigHandler(int signum) { - keepRunning = false; + int temp_errno = errno; // Threadsanitizer: don't spoil errno if ( signum == SIGINT && fuse_sigIntHandler != NULL ) { + keepRunning = false; fuse_sigIntHandler(signum); } if ( signum == SIGTERM && fuse_sigTermHandler != NULL ) { + keepRunning = false; fuse_sigTermHandler(signum); } + errno = temp_errno; } static void image_ll_init(void *userdata, struct fuse_conn_info *conn) { -/* -Zero copy data transfer ("splicing") will be used under the following circumstances: - -FUSE_CAP_SPLICE_WRITE is set in fuse_conn_info.want, and -the kernel supports splicing from the fuse device (FUSE_CAP_SPLICE_WRITE is set in fuse_conn_info.capable), and -flags does not contain FUSE_BUF_NO_SPLICE -The amount of data that is provided in file-descriptor backed buffers (i.e., buffers for which bufv[n].flags == FUSE_BUF_FD) is at least twice the page size. -In order for SPLICE_F_MOVE to be used, the following additional conditions have to be fulfilled: - -FUSE_CAP_SPLICE_MOVE is set in fuse_conn_info.want, and -the kernel supports it (i.e, FUSE_CAP_SPLICE_MOVE is set in fuse_conn_info.capable), and -flags contains FUSE_BUF_SPLICE_MOVE -*/ (void) userdata; - - printf("Protocol version: %d.%d\n", conn->proto_major, - conn->proto_minor); - printf("Capabilities:\n"); - if(conn->capable & FUSE_CAP_FLOCK_LOCKS) - printf("\tFUSE_CAP_FLOCK_LOCKS\n"); - if(conn->capable & FUSE_CAP_ASYNC_READ) - printf("\tFUSE_CAP_ASYNC_READ\n"); - if(conn->capable & FUSE_CAP_POSIX_LOCKS) - printf("\tFUSE_CAP_POSIX_LOCKS\n"); - if(conn->capable & FUSE_CAP_ATOMIC_O_TRUNC) - printf("\tFUSE_CAP_ATOMIC_O_TRUNC\n"); - if(conn->capable & FUSE_CAP_EXPORT_SUPPORT) - printf("\tFUSE_CAP_EXPORT_SUPPORT\n"); - if(conn->capable & FUSE_CAP_DONT_MASK) - printf("\tFUSE_CAP_DONT_MASK\n"); - if(conn->capable & FUSE_CAP_SPLICE_MOVE) - printf("\tFUSE_CAP_SPLICE_MOVE\n"); - if(conn->capable & FUSE_CAP_SPLICE_READ) - printf("\tFUSE_CAP_SPLICE_READ\n"); - if(conn->capable & FUSE_CAP_SPLICE_WRITE) - printf("\tFUSE_CAP_SPLICE_WRITE\n"); - if(conn->capable & FUSE_CAP_IOCTL_DIR) - printf("\tFUSE_CAP_IOCTL_DIR\n"); - if(conn->capable & FUSE_CAP_BIG_WRITES) - printf("\tFUSE_CAP_BIG_WRITES\n"); - - if ( MODE == NO_SPLICE ) conn->want &= ~FUSE_CAP_SPLICE_WRITE & ~FUSE_CAP_SPLICE_MOVE & ~FUSE_CAP_SPLICE_READ; - else if ( MODE == SPLICE ) conn->want |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE | FUSE_CAP_SPLICE_READ; - if(conn->want & FUSE_CAP_SPLICE_WRITE) - printf("\tFUSE_CAP_SPLICE_WRITE on\n"); - else printf("\tFUSE_CAP_SPLICE_WRITE off\n"); - if(conn->want & FUSE_CAP_SPLICE_MOVE) - printf("\tFUSE_CAP_SPLICE_MOVE on\n"); - else printf("\tFUSE_CAP_SPLICE_MOVE off\n"); - if(conn->want & FUSE_CAP_SPLICE_READ) - printf("\tFUSE_CAP_SPLICE_READ on\n"); - else printf("\tFUSE_CAP_SPLICE_READ off\n"); - - if ( !connection_initThreads() ) { logadd( LOG_ERROR, "Could not initialize threads for dnbd3 connection, exiting..." ); exit( EXIT_FAILURE ); @@ -327,13 +278,9 @@ flags contains FUSE_BUF_SPLICE_MOVE struct sigaction newHandler; memset( &newHandler, 0, sizeof(newHandler) ); newHandler.sa_handler = &image_sigHandler; - //newHandler.sa_flags &= ~SA_RESTART; - newHandler.sa_flags |= SA_RESETHAND; // allows SIGINT with SPLICE sigemptyset( &newHandler.sa_mask ); - //rt_sigaction(sa_flags=SA_RESTORER|SA_ONSTACK|SA_INTERRUPT|SA_NODEFER|SA_RESETHAND|SA_SIGINFO|SA_NOCLDSTOP|SA_NOCLDWAIT|0x3fffff8 + struct sigaction oldHandler; - //oldHandler.sa_flags &= ~SA_RESTART; - //oldHandler.sa_flags |= SA_RESETHAND; // Retrieve old handlers when setting sigaction( SIGINT, &newHandler, &oldHandler ); fuse_sigIntHandler = oldHandler.sa_handler; @@ -368,14 +315,16 @@ static void printVersion() { char *arg[] = { "foo", "-V" }; printf( "DNBD3-Fuse Version 1.2.3.4, protocol version %d\n", (int)PROTOCOL_VERSION ); - //fuse_main( 2, arg, &dnbd3_fuse_no_operations, NULL ); + struct fuse_args args = FUSE_ARGS_INIT(2, arg); + fuse_parse_cmdline(&args, NULL, NULL, NULL); exit( 0 ); } static void printUsage(char *argv0, int exitCode) { char *arg[] = { argv0, "-h" }; - //fuse_main( 2, arg, &dnbd3_fuse_no_operations, NULL ); + struct fuse_args args = FUSE_ARGS_INIT(2, arg); + fuse_parse_cmdline(&args, NULL, NULL, NULL); printf( "\n" ); printf( "Usage: %s [--debug] [--option mountOpts] --host --image [--rid revision] \n", argv0 ); printf( "Or: %s [-d] [-o mountOpts] -h -i [-r revision] \n", argv0 ); @@ -415,10 +364,10 @@ int main(int argc, char *argv[]) int newArgc; int opt, lidx; bool learnNewServers = true; + bool single_thread = false; struct fuse_chan *ch; char *mountpoint; - int err = -1; - mountpoint = argv[5]; + int fuse_err; if ( argc <= 1 || strcmp( argv[1], "--help" ) == 0 || strcmp( argv[1], "--usage" ) == 0 ) { printUsage( argv[0], 0 ); @@ -472,7 +421,7 @@ int main(int argc, char *argv[]) newArgv[newArgc++] = "-d"; break; case 's': - newArgv[newArgc++] = "-s"; + single_thread = true; break; case 'S': learnNewServers = false; @@ -517,7 +466,6 @@ int main(int argc, char *argv[]) // Since dnbd3 is always read only and the remote image will not change newArgv[newArgc++] = "-o"; - //newArgv[newArgc++] = "ro,auto_cache,default_permissions"; newArgv[newArgc++] = "ro,default_permissions"; // Mount point goes last newArgv[newArgc++] = argv[optind]; @@ -530,7 +478,7 @@ int main(int argc, char *argv[]) clock_gettime( CLOCK_REALTIME, &startupTime ); owner = getuid(); - // LL partnewArgv[newArgc++] + // Fuse lowlevel loop struct fuse_args args = FUSE_ARGS_INIT(newArgc, newArgv); if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && (ch = fuse_mount(mountpoint, &args)) != NULL) { struct fuse_session *se; @@ -539,7 +487,8 @@ int main(int argc, char *argv[]) if (se != NULL) { if (fuse_set_signal_handlers(se) != -1) { fuse_session_add_chan(se, ch); - err = fuse_session_loop(se); + if (single_thread) fuse_err = fuse_session_loop(se); + else fuse_err = fuse_session_loop_mt(se); //MT produces errors (race conditions) in libfuse and didnt improve speed at all fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); } @@ -548,6 +497,6 @@ int main(int argc, char *argv[]) fuse_unmount(mountpoint, ch); } fuse_opt_free_args(&args); - - return err ? 1 : 0; + logadd( LOG_DEBUG1, "Terminating. FUSE REPLIED: %d\n", fuse_err); + return fuse_err; } diff --git a/src/fuse/main.h b/src/fuse/main.h deleted file mode 100644 index 3586803..0000000 --- a/src/fuse/main.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef _MAIN_H_ -#define _MAIN_H_ - - -#endif /* MAIN_H_ */ -- cgit v1.2.3-55-g7522