summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2012-04-17 17:29:28 +0200
committerAndreas Baumann <abaumann@yahoo.com>2012-04-17 17:29:28 +0200
commitb9a0010bb4fe327ae9361620f31cea955c597a4d (patch)
treeb68f56ddb0dc462183e2417acf993a0f71602a8c
parent2bff3ee6b41dc11e0bbaf9ef8a94a3bfce8b975c (diff)
downloadpgfuse-b9a0010bb4fe327ae9361620f31cea955c597a4d.tar.gz
pgfuse-b9a0010bb4fe327ae9361620f31cea955c597a4d.tar.bz2
started to prepare for multi-threaded version, logigng the pid/thread_id in verbose mode
-rw-r--r--README4
-rw-r--r--TODO3
-rw-r--r--config.h15
-rw-r--r--pgfuse.c147
4 files changed, 107 insertions, 62 deletions
diff --git a/README b/README
index d5dfe7b..4b9e367 100644
--- a/README
+++ b/README
@@ -30,6 +30,10 @@ mysqlfs:
The blueprint I used and got inspired from. Does exactly the same for
the MySQL database.
+libsqlfs:
+
+ The same for for storing files in a Sqlite database.
+
curlftpfs:
Blueprint for some debugging code.
diff --git a/TODO b/TODO
index 15cf40a..20af36b 100644
--- a/TODO
+++ b/TODO
@@ -7,6 +7,9 @@ TODO list (in order of priority)
here!
- extended attributes
- pooling of PQconn
+ - our own, thread-synchronized pooling?
+ - use pgpool? has secondary benefits like a replicated filesystem for
+ free
- replace dir.path with a range search tree algo in DB
- rename (after a redo of the dir table)
- thread-synchronization (we can ommit the -s flag)
diff --git a/config.h b/config.h
index 273c165..3e3bd65 100644
--- a/config.h
+++ b/config.h
@@ -19,21 +19,26 @@
#define CONFIG_H
/* version of PgFuse */
-#define PGFUSE_VERSION "0.0.1"
+
+#define PGFUSE_VERSION "0.0.1"
/* standard block size, rather a simulation currently */
-#define STANDARD_BLOCK_SIZE 512
+
+#define STANDARD_BLOCK_SIZE 512
/* maximal number of open files, may vary as there may be hashtable
* collitions. Must be a prime */
-#define MAX_NOF_OPEN_FILES 257
+
+#define MAX_NOF_OPEN_FILES 257
/* maximum size of a file, rather arbitrary, 2^31 is a current implementation
* limit, before fixing this, the storing and efficiency has to be rethought
* anyway.. */
-#define MAX_FILE_SIZE 10485760
+
+#define MAX_FILE_SIZE 10485760
/* maximum length of a filename , rather arbitrary choice */
-#define MAX_FILENAME_LENGTH 4096
+
+#define MAX_FILENAME_LENGTH 4096
#endif
diff --git a/pgfuse.c b/pgfuse.c
index 4453d66..3f7a288 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -57,6 +57,7 @@ typedef struct PgFuseData {
char *mountpoint; /* where we mount the virtual filesystem */
PGconn *conn; /* the database handle to operate on */
int read_only; /* whether the mount point is read-only */
+ int multi_threaded; /* whether we run multi-threaded */
} PgFuseData;
/* --- helper functions --- */
@@ -87,9 +88,10 @@ static void *pgfuse_init( struct fuse_conn_info *conn )
{
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
- syslog( LOG_INFO, "Mounting file system on '%s' ('%s', %s)",
+ syslog( LOG_INFO, "Mounting file system on '%s' ('%s', %s), thread #%d",
data->mountpoint, data->conninfo,
- data->read_only ? "read-only" : "read-write" );
+ data->read_only ? "read-only" : "read-write",
+ fuse_get_context( )->uid );
memset( pgfuse_files, 0, sizeof( PgFuseFile ) * MAX_NOF_OPEN_FILES );
@@ -107,8 +109,8 @@ static void pgfuse_destroy( void *userdata )
{
PgFuseData *data = (PgFuseData *)userdata;
- syslog( LOG_INFO, "Unmounting file system on '%s' (%s)",
- data->mountpoint, data->conninfo );
+ syslog( LOG_INFO, "Unmounting file system on '%s' (%s), thread #%d",
+ data->mountpoint, data->conninfo, fuse_get_context( )->uid );
PQfinish( data->conn );
}
@@ -120,7 +122,8 @@ static int pgfuse_fgetattr( const char *path, struct stat *stbuf, struct fuse_fi
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "FgetAttrs '%s' on '%s'", path, data->mountpoint );
+ syslog( LOG_INFO, "FgetAttrs '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
memset( stbuf, 0, sizeof( struct stat ) );
@@ -131,8 +134,9 @@ static int pgfuse_fgetattr( const char *path, struct stat *stbuf, struct fuse_fi
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for %s '%s' is %d",
- S_ISDIR( meta.mode ) ? "dir" : "file", path, id );
+ syslog( LOG_DEBUG, "Id for %s '%s' is %d, thread #%d",
+ S_ISDIR( meta.mode ) ? "dir" : "file", path, id,
+ fuse_get_context( )->uid );
}
stbuf->st_ino = id;
@@ -157,7 +161,8 @@ static int pgfuse_getattr( const char *path, struct stat *stbuf )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "GetAttrs '%s' on '%s'", path, data->mountpoint );
+ syslog( LOG_INFO, "GetAttrs '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
memset( stbuf, 0, sizeof( struct stat ) );
@@ -168,8 +173,9 @@ static int pgfuse_getattr( const char *path, struct stat *stbuf )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for %s '%s' is %d",
- S_ISDIR( meta.mode ) ? "dir" : "file", path, id );
+ syslog( LOG_DEBUG, "Id for %s '%s' is %d, thread #%d",
+ S_ISDIR( meta.mode ) ? "dir" : "file", path, id,
+ fuse_get_context( )->uid );
}
stbuf->st_ino = id;
@@ -195,7 +201,8 @@ static int pgfuse_access( const char *path, int mode )
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
if( data->verbose ) {
- syslog( LOG_INFO, "Access on '%s' and mode '%o", path, (unsigned int)mode );
+ syslog( LOG_INFO, "Access on '%s' and mode '%o, thread #%d",
+ path, (unsigned int)mode, fuse_get_context( )->uid );
}
/* TODO: check access, but not now. grant always access */
@@ -238,7 +245,8 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
if( data->verbose ) {
char *s = flags_to_string( fi->flags );
- syslog( LOG_INFO, "Create '%s' in mode '%o' on '%s' with flags '%s'", path, mode, data->mountpoint, s );
+ syslog( LOG_INFO, "Create '%s' in mode '%o' on '%s' with flags '%s', thread #%d",
+ path, mode, data->mountpoint, s, fuse_get_context( )->uid );
if( *s != '<' ) free( s );
}
@@ -253,7 +261,8 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
if( id >= 0 ) {
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for dir '%s' is %d", path, id );
+ syslog( LOG_DEBUG, "Id for dir '%s' is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( S_ISDIR(meta.mode ) ) {
@@ -280,7 +289,8 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for new file '%s' in dir '%s' is %d", path, parent_path, parent_id );
+ syslog( LOG_DEBUG, "Parent_id for new file '%s' in dir '%s' is %d, thread #%d",
+ path, parent_path, parent_id, fuse_get_context( )->uid );
}
free( copy_path );
@@ -320,7 +330,8 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for new file '%s' is %d", path, id );
+ syslog( LOG_DEBUG, "Id for new file '%s' is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( pgfuse_files[id % MAX_NOF_OPEN_FILES].id != 0 ) {
@@ -358,7 +369,8 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
if( data->verbose ) {
char *s = flags_to_string( fi->flags );
- syslog( LOG_INFO, "Open '%s' on '%s' with flags '%s'", path, data->mountpoint, s );
+ syslog( LOG_INFO, "Open '%s' on '%s' with flags '%s', thread #%d",
+ path, data->mountpoint, s, fuse_get_context( )->uid );
if( *s != '<' ) free( s );
}
@@ -368,7 +380,8 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id for file '%s' to open is %d", path, id );
+ syslog( LOG_DEBUG, "Id for file '%s' to open is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( S_ISDIR( meta.mode ) ) {
@@ -430,7 +443,8 @@ static int pgfuse_readdir( const char *path, void *buf, fuse_fill_dir_t filler,
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Readdir '%s' on '%s'", path, data->mountpoint );
+ syslog( LOG_INFO, "Readdir '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
filler( buf, ".", NULL, 0 );
@@ -469,8 +483,9 @@ static int pgfuse_mkdir( const char *path, mode_t mode )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Mkdir '%s' in mode '%o' on '%s'",
- path, (unsigned int)mode, data->mountpoint );
+ syslog( LOG_INFO, "Mkdir '%s' in mode '%o' on '%s', thread #%d",
+ path, (unsigned int)mode, data->mountpoint,
+ fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -494,7 +509,8 @@ static int pgfuse_mkdir( const char *path, mode_t mode )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for new dir '%s' is %d", path, parent_id );
+ syslog( LOG_DEBUG, "Parent_id for new dir '%s' is %d, thread #%d",
+ path, parent_id, fuse_get_context( )->uid );
}
free( copy_path );
@@ -531,7 +547,8 @@ static int pgfuse_rmdir( const char *path )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Rmdir '%s' on '%s'", path, data->mountpoint );
+ syslog( LOG_INFO, "Rmdir '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -543,7 +560,8 @@ static int pgfuse_rmdir( const char *path )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of dir '%s' to be removed is %d", path, id );
+ syslog( LOG_DEBUG, "Id of dir '%s' to be removed is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -563,7 +581,8 @@ static int pgfuse_unlink( const char *path )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Remove file '%s' on '%s'", path, data->mountpoint );
+ syslog( LOG_INFO, "Remove file '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -575,7 +594,8 @@ static int pgfuse_unlink( const char *path )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of file '%s' to be removed is %d", path, id );
+ syslog( LOG_DEBUG, "Id of file '%s' to be removed is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -602,8 +622,9 @@ static int pgfuse_fsync( const char *path, int isdatasync, struct fuse_file_info
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "%s on file '%s' on '%s'",
- isdatasync ? "FDataSync" : "FSync", path, data->mountpoint );
+ syslog( LOG_INFO, "%s on file '%s' on '%s', thread #%d",
+ isdatasync ? "FDataSync" : "FSync", path, data->mountpoint,
+ fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -645,8 +666,8 @@ static int pgfuse_release( const char *path, struct fuse_file_info *fi )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Releasing '%s' on '%s'",
- path, data->mountpoint );
+ syslog( LOG_INFO, "Releasing '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
if( fi->fh == 0 ) {
@@ -697,8 +718,9 @@ static int pgfuse_write( const char *path, const char *buf, size_t size,
PgFuseFile *f;
if( data->verbose ) {
- syslog( LOG_INFO, "Write to '%s' from offset %d, size %d on '%s'",
- path, (unsigned int)offset, (unsigned int)size, data->mountpoint );
+ syslog( LOG_INFO, "Write to '%s' from offset %d, size %d on '%s', thread #%d",
+ path, (unsigned int)offset, (unsigned int)size, data->mountpoint,
+ fuse_get_context( )->uid );
}
if( fi->fh == 0 ) {
@@ -742,8 +764,9 @@ static int pgfuse_read( const char *path, char *buf, size_t size,
PgFuseFile *f;
if( data->verbose ) {
- syslog( LOG_INFO, "Read to '%s' from offset %d, size %d on '%s'",
- path, (unsigned int)offset, (unsigned int)size, data->mountpoint );
+ syslog( LOG_INFO, "Read to '%s' from offset %d, size %d on '%s', thread #%d",
+ path, (unsigned int)offset, (unsigned int)size, data->mountpoint,
+ fuse_get_context( )->uid );
}
if( fi->fh == 0 ) {
@@ -769,8 +792,8 @@ static int pgfuse_truncate( const char* path, off_t offset )
PgFuseFile *f;
if( data->verbose ) {
- syslog( LOG_INFO, "Truncate of '%s' to size '%d' on '%s'",
- path, (unsigned int)offset, data->mountpoint );
+ syslog( LOG_INFO, "Truncate of '%s' to size '%d' on '%s', thread #%d",
+ path, (unsigned int)offset, data->mountpoint, fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -783,7 +806,8 @@ static int pgfuse_truncate( const char* path, off_t offset )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Id of file '%s' to be truncated is %d", path, id );
+ syslog( LOG_DEBUG, "Id of file '%s' to be truncated is %d, thread #%d",
+ path, id, fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -807,8 +831,9 @@ static int pgfuse_ftruncate( const char *path, off_t offset, struct fuse_file_in
PgFuseFile *f;
if( data->verbose ) {
- syslog( LOG_INFO, "Truncate of '%s' to size '%d' on '%s'",
- path, (unsigned int)offset, data->mountpoint );
+ syslog( LOG_INFO, "Truncate of '%s' to size '%d' on '%s', thread #%d",
+ path, (unsigned int)offset, data->mountpoint,
+ fuse_get_context( )->uid );
}
if( fi->fh == 0 ) {
@@ -831,8 +856,8 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
if( data->verbose ) {
- syslog( LOG_INFO, "Statfs called on '%s'",
- data->mountpoint );
+ syslog( LOG_INFO, "Statfs called on '%s', thread #%d",
+ data->mountpoint, fuse_get_context( )->uid );
}
/* Note: f_frsize, f_favail, f_fsid and f_flag are currently ignored by FUSE */
@@ -866,8 +891,9 @@ static int pgfuse_chmod( const char *path, mode_t mode )
int res;
if( data->verbose ) {
- syslog( LOG_INFO, "Chmod on '%s' to mode '%o' on '%s'",
- path, (unsigned int)mode, data->mountpoint );
+ syslog( LOG_INFO, "Chmod on '%s' to mode '%o' on '%s', thread #%d",
+ path, (unsigned int)mode, data->mountpoint,
+ fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -890,8 +916,9 @@ static int pgfuse_chown( const char *path, uid_t uid, gid_t gid )
int res;
if( data->verbose ) {
- syslog( LOG_INFO, "Chown on '%s' to uid '%d' and gid '%d' on '%s'",
- path, (unsigned int)uid, (unsigned int)gid, data->mountpoint );
+ syslog( LOG_INFO, "Chown on '%s' to uid '%d' and gid '%d' on '%s', thread #%d",
+ path, (unsigned int)uid, (unsigned int)gid, data->mountpoint,
+ fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -919,8 +946,8 @@ static int pgfuse_symlink( const char *from, const char *to )
PgMeta meta;
if( data->verbose ) {
- syslog( LOG_INFO, "Symlink from '%s' to '%s' on '%s'",
- from, to, data->mountpoint );
+ syslog( LOG_INFO, "Symlink from '%s' to '%s' on '%s', thread #%d",
+ from, to, data->mountpoint, fuse_get_context( )->uid );
}
if( data->read_only ) {
@@ -944,7 +971,8 @@ static int pgfuse_symlink( const char *from, const char *to )
}
if( data->verbose ) {
- syslog( LOG_DEBUG, "Parent_id for symlink '%s' is %d", to, parent_id );
+ syslog( LOG_DEBUG, "Parent_id for symlink '%s' is %d, thread #%d",
+ to, parent_id, fuse_get_context( )->uid );
}
free( copy_to );
@@ -1001,8 +1029,8 @@ static int pgfuse_readlink( const char *path, char *buf, size_t size )
int res;
if( data->verbose ) {
- syslog( LOG_INFO, "Dereferencing symlink '%s' on '%s'",
- path, data->mountpoint );
+ syslog( LOG_INFO, "Dereferencing symlink '%s' on '%s', thread #%d",
+ path, data->mountpoint, fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -1035,8 +1063,9 @@ static int pgfuse_utimens( const char *path, const struct timespec tv[2] )
int res;
if( data->verbose ) {
- syslog( LOG_INFO, "Utimens on '%s' to access time '%d' and modification time '%d' on '%s'",
- path, (unsigned int)tv[0].tv_sec, (unsigned int)tv[1].tv_sec, data->mountpoint );
+ syslog( LOG_INFO, "Utimens on '%s' to access time '%d' and modification time '%d' on '%s', thread #%d",
+ path, (unsigned int)tv[0].tv_sec, (unsigned int)tv[1].tv_sec, data->mountpoint,
+ fuse_get_context( )->uid );
}
id = psql_get_meta( data->conn, path, &meta );
@@ -1096,7 +1125,7 @@ static struct fuse_operations pgfuse_oper = {
/* --- parse arguments --- */
-typedef struct PgFuse {
+typedef struct PgFuseOptions {
int print_help; /* whether we should print a help page */
int print_version; /* whether we should print the version */
int verbose; /* whether we should be verbose */
@@ -1104,9 +1133,9 @@ typedef struct PgFuse {
char *mountpoint; /* where we mount the virtual filesystem */
int read_only; /* whether to mount read-only */
int multi_threaded; /* whether we run multi-threaded */
-} PgFuse;
+} PgFuseOptions;
-#define PGFUSE_OPT( t, p, v ) { t, offsetof( PgFuse, p ), v }
+#define PGFUSE_OPT( t, p, v ) { t, offsetof( PgFuseOptions, p ), v }
enum {
KEY_HELP,
@@ -1128,7 +1157,7 @@ static struct fuse_opt pgfuse_opts[] = {
static int pgfuse_opt_proc( void* data, const char* arg, int key,
struct fuse_args* outargs )
{
- PgFuse *pgfuse = (PgFuse *)data;
+ PgFuseOptions *pgfuse = (PgFuseOptions *)data;
switch( key ) {
case FUSE_OPT_KEY_OPT:
@@ -1203,7 +1232,7 @@ int main( int argc, char *argv[] )
int res;
PGconn *conn;
struct fuse_args args = FUSE_ARGS_INIT( argc, argv );
- PgFuse pgfuse;
+ PgFuseOptions pgfuse;
PgFuseData userdata;
const char *value;
@@ -1218,7 +1247,7 @@ int main( int argc, char *argv[] )
/* print options of FUSE itself */
argv[1] = "-ho";
argv[2] = "mountpoint";
- dup2( STDOUT_FILENO, STDERR_FILENO ); /* force fuse help to stdout */
+ (void)dup2( STDOUT_FILENO, STDERR_FILENO ); /* force fuse help to stdout */
fuse_main( 2, argv, &pgfuse_oper, NULL);
exit( EXIT_SUCCESS );
}
@@ -1264,6 +1293,9 @@ int main( int argc, char *argv[] )
return 1;
}
+ /* Make sure we have the more modern uint64 representation for timestamps,
+ * bail out otherwise
+ */
if( strcmp( value, "on" ) != 0 ) {
fprintf( stderr, "Expecting UINT64 for timestamps, not doubles. You may use an old version of PostgreSQL (<8.4)\n"
"or PostgreSQL has been compiled with the deprecated compile option '--disable-integer-datetimes'\n" );
@@ -1280,6 +1312,7 @@ int main( int argc, char *argv[] )
userdata.mountpoint = pgfuse.mountpoint;
userdata.verbose = pgfuse.verbose;
userdata.read_only = pgfuse.read_only;
+ userdata.multi_threaded = pgfuse.multi_threaded;
res = fuse_main( args.argc, args.argv, &pgfuse_oper, &userdata );