summaryrefslogtreecommitdiff
path: root/pgfuse.c
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2012-04-19 20:16:50 +0200
committerAndreas Baumann <abaumann@yahoo.com>2012-04-19 20:16:50 +0200
commitd5cbfd4ddf3fec5edb76a93d41a16a7c8397a485 (patch)
tree83c233b56dceb5e164d428d72d1104e4de668f58 /pgfuse.c
parent0b06672e144335ae5a3d7c4a19f35c2cfc142722 (diff)
downloadpgfuse-d5cbfd4ddf3fec5edb76a93d41a16a7c8397a485.tar.gz
pgfuse-d5cbfd4ddf3fec5edb76a93d41a16a7c8397a485.tar.bz2
-
Diffstat (limited to 'pgfuse.c')
-rw-r--r--pgfuse.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/pgfuse.c b/pgfuse.c
index ec267a5..8c4a6dd 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -30,6 +30,8 @@
#include <fuse.h> /* for user-land filesystem */
#include <fuse_opt.h> /* fuse command line parser */
+#include <pthread.h> /* for mutexes */
+
#if FUSE_VERSION < 28
#error Currently only written for newest FUSE APIversion (FUSE_VERSION 28)
#endif
@@ -38,14 +40,20 @@
#include "pgsql.h" /* implements Postgresql accessers */
#include "pool.h" /* implements the connection pool */
-/* --- fuse callbacks --- */
+/* --- FUSE private context data --- */
+
+typedef struct PgFuseFile {
+ int id; /* id as in the database and in the FUSE context (fh) */
+ pthread_mutex_t lock; /* lock parallel thread operations on the same file */
+} PgFuseFile;
typedef struct PgFuseData {
int verbose; /* whether we should be verbose */
char *conninfo; /* connection info as used in PQconnectdb */
char *mountpoint; /* where we mount the virtual filesystem */
- PGconn *conn; /* the database handle to operate on (single-thread) */
- PgConnPool pool; /* the database pool to operate on (multi-thread) */
+ PGconn *conn; /* the database handle to operate on (single-thread only) */
+ PgConnPool pool; /* the database pool to operate on (multi-thread only) */
+ PgFuseFile files[MAX_NOF_OPEN_FILES]; /* synchronization array (multi-thread only) */
int read_only; /* whether the mount point is read-only */
int multi_threaded; /* whether we run multi-threaded */
} PgFuseData;
@@ -121,11 +129,40 @@ static void *pgfuse_init( struct fuse_conn_info *conn )
}
} else {
int res;
+ int i;
+ pthread_mutexattr_t attr;
+
res = psql_pool_init( &data->pool, data->conninfo, MAX_DB_CONNECTIONS );
if( res < 0 ) {
syslog( LOG_ERR, "Allocating database connection pool failed!" );
exit( EXIT_FAILURE );
}
+
+ res = pthread_mutexattr_init( &attr );
+ if( res < 0 ) {
+ syslog( LOG_ERR, "Error while initalizing thread attributes: %d!", res );
+ exit( EXIT_FAILURE );
+ }
+ res = pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
+ if( res < 0 ) {
+ syslog( LOG_ERR, "Error while setting thread attributes: %d!", res );
+ exit( EXIT_FAILURE );
+ }
+
+ memset( &data->files, 0, sizeof( PgFuseFile ) * MAX_NOF_OPEN_FILES );
+ for( i = 0; i < MAX_NOF_OPEN_FILES; i++ ) {
+ res = pthread_mutex_init( &data->files[i].lock, &attr );
+ if( res < 0 ) {
+ syslog( LOG_ERR, "Error while initializing mutex: %d!", res );
+ exit( EXIT_FAILURE );
+ }
+ }
+
+ res = pthread_mutexattr_destroy( &attr );
+ if( res < 0 ) {
+ syslog( LOG_ERR, "Error while destroying thread attributes: %d!", res );
+ exit( EXIT_FAILURE );
+ }
}
return data;
@@ -134,7 +171,8 @@ static void *pgfuse_init( struct fuse_conn_info *conn )
static void pgfuse_destroy( void *userdata )
{
PgFuseData *data = (PgFuseData *)userdata;
-
+ int i;
+
syslog( LOG_INFO, "Unmounting file system on '%s' (%s), thread #%u",
data->mountpoint, data->conninfo, THREAD_ID );
@@ -143,6 +181,10 @@ static void pgfuse_destroy( void *userdata )
} else {
(void)psql_pool_destroy( &data->pool );
}
+
+ for( i = 0; i < MAX_NOF_OPEN_FILES; i++ ) {
+ (void)pthread_mutex_destroy( &data->files[i].lock );
+ }
}
static int pgfuse_fgetattr( const char *path, struct stat *stbuf, struct fuse_file_info *fi )
@@ -422,11 +464,12 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
}
/* currently don't allow parallel access */
- if( meta.ref_count > 0 ) {
+/*
+ if( meta.ref_count > 0 ) {
PSQL_ROLLBACK( conn ); RELEASE( conn );
return -ETXTBSY;
}
-
+*/
if( data->verbose ) {
syslog( LOG_DEBUG, "Id for file '%s' to open is %d, thread #%u",
path, id, THREAD_ID );