summaryrefslogtreecommitdiffstats
path: root/src/fuse
diff options
context:
space:
mode:
authorln-tech2020-01-08 22:23:28 +0100
committerln-tech2020-01-08 22:23:28 +0100
commit68148447b090749057dc2815fb6f684c6ffbd66a (patch)
treef1fd139d51d15a04c9f9c9b244008d1764d342f3 /src/fuse
parentcode fixes, keepRunning is back, threads seem to be safe (diff)
downloaddnbd3-68148447b090749057dc2815fb6f684c6ffbd66a.tar.gz
dnbd3-68148447b090749057dc2815fb6f684c6ffbd66a.tar.xz
dnbd3-68148447b090749057dc2815fb6f684c6ffbd66a.zip
fixed code: removed useless splicing, code optimization, commandline arguments fixed, auto_cache in lowlevel activated, multi and single threaded modes are supported now
Diffstat (limited to 'src/fuse')
-rw-r--r--src/fuse/connection.c39
-rw-r--r--src/fuse/connection.h3
-rw-r--r--src/fuse/main.c97
-rw-r--r--src/fuse/main.h5
4 files changed, 31 insertions, 113 deletions
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 <errno.h>
#include <time.h>
#include <inttypes.h>
-#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 <fuse_lowlevel.h>
-#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 <pthread.h>
#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 <serverAddress(es)> --image <imageName> [--rid revision] <mountPoint>\n", argv0 );
printf( "Or: %s [-d] [-o mountOpts] -h <serverAddress(es)> -i <imageName> [-r revision] <mountPoint>\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_ */