diff options
author | Andreas Baumann <abaumann@yahoo.com> | 2012-04-19 20:16:50 +0200 |
---|---|---|
committer | Andreas Baumann <abaumann@yahoo.com> | 2012-04-19 20:16:50 +0200 |
commit | d5cbfd4ddf3fec5edb76a93d41a16a7c8397a485 (patch) | |
tree | 83c233b56dceb5e164d428d72d1104e4de668f58 /pgfuse.c | |
parent | 0b06672e144335ae5a3d7c4a19f35c2cfc142722 (diff) | |
download | pgfuse-d5cbfd4ddf3fec5edb76a93d41a16a7c8397a485.tar.gz pgfuse-d5cbfd4ddf3fec5edb76a93d41a16a7c8397a485.tar.bz2 |
-
Diffstat (limited to 'pgfuse.c')
-rw-r--r-- | pgfuse.c | 55 |
1 files changed, 49 insertions, 6 deletions
@@ -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 ); |