summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--pgfuse.c35
-rw-r--r--pgsql.c74
-rw-r--r--pgsql.h6
4 files changed, 70 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index 487e12e..594abbf 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,6 @@ test: pgfuse testfsync
-rmdir mnt/dir/dir2/bfile
# test fdatasync and fsync
./testfsync
- sleep 2
# show filesystem stats (statvfs)
df -k mnt
df -i mnt
diff --git a/pgfuse.c b/pgfuse.c
index 6ab424f..daf5655 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -45,7 +45,7 @@ typedef struct PgFuseFile {
size_t size; /* current size of the buffer (malloc/realloc) */
size_t used; /* used size in the buffer */
int ref_count; /* reference counter (for double opens, dup, etc.) */
- mode_t mode; /* type and permissions of file */
+ PgMeta meta; /* the current filenode metadata */
} PgFuseFile;
static PgFuseFile pgfuse_files[MAX_NOF_OPEN_FILES];
@@ -122,8 +122,8 @@ static int pgfuse_getattr( const char *path, struct stat *stbuf )
/* TODO: set correctly from table */
stbuf->st_nlink = 2;
/* set rights to the user running 'pgfuse' */
- stbuf->st_uid = geteuid( );
- stbuf->st_gid = getegid( );
+ stbuf->st_uid = meta.uid;
+ stbuf->st_gid = meta.gid;
return 0;
}
@@ -231,7 +231,13 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
new_file = basename( copy_path );
- res = psql_create_file( data->conn, parent_id, path, new_file, mode );
+ meta.size = 0;
+ meta.mode = mode;
+ /* TODO: use FUSE context */
+ meta.uid = geteuid( );
+ meta.gid = getegid( );
+
+ res = psql_create_file( data->conn, parent_id, path, new_file, meta );
if( res < 0 ) {
free( copy_path );
return res;
@@ -268,7 +274,7 @@ static int pgfuse_create( const char *path, mode_t mode, struct fuse_file_info *
return -ENOMEM;
}
f->ref_count = 1;
- f->mode = mode;
+ f->meta = meta;
fi->fh = id;
@@ -330,7 +336,7 @@ static int pgfuse_open( const char *path, struct fuse_file_info *fi )
return -ENOMEM;
}
f->ref_count = 1;
- f->mode = meta.mode;
+ f->meta = meta;
res = psql_read_buf( data->conn, id, path, &f->buf, f->used );
if( res != f->used ) {
@@ -437,10 +443,13 @@ static int pgfuse_mkdir( const char *path, mode_t mode )
new_dir = basename( copy_path );
- /* not set by fuse */
- mode |= S_IFDIR;
+ meta.size = 0;
+ meta.mode = mode | S_IFDIR; /* S_IFDIR is not set by fuse */
+ /* TODO: use FUSE context */
+ meta.uid = geteuid( );
+ meta.gid = getegid( );
- res = psql_create_dir( data->conn, parent_id, path, new_dir, mode );
+ res = psql_create_dir( data->conn, parent_id, path, new_dir, meta );
free( copy_path );
@@ -542,8 +551,8 @@ static int pgfuse_fsync( const char *path, int isdatasync, struct fuse_file_info
res = 0;
if( !isdatasync ) {
- meta.size = f->used;
- meta.mode = f->mode;
+ f->meta.size = f->used;
+ meta = f->meta;
res = psql_write_meta( data->conn, f->id, path, meta );
}
@@ -590,8 +599,8 @@ static int pgfuse_release( const char *path, struct fuse_file_info *fi )
return 0;
}
- meta.size = f->used;
- meta.mode = f->mode;
+ f->meta.size = f->used;
+ meta = f->meta;
res = psql_write_meta( data->conn, f->id, path, meta );
if( res >= 0 ) {
diff --git a/pgsql.c b/pgsql.c
index c43739c..aa306e2 100644
--- a/pgsql.c
+++ b/pgsql.c
@@ -27,9 +27,7 @@
int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta )
{
PGresult *res;
- int i_id;
- int i_size;
- int i_mode;
+ int idx;
char *iptr;
int id;
@@ -37,7 +35,7 @@ int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta )
int lengths[1] = { strlen( path ) };
int binary[1] = { 1 };
- res = PQexecParams( conn, "SELECT id, size, mode FROM dir WHERE path = $1::varchar",
+ res = PQexecParams( conn, "SELECT id, size, mode, uid, gid FROM dir WHERE path = $1::varchar",
1, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_TUPLES_OK ) {
@@ -57,16 +55,26 @@ int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta )
return -EIO;
}
- i_id = PQfnumber( res, "id" );
- i_size = PQfnumber( res, "size" );
- i_mode = PQfnumber( res, "mode" );
- iptr = PQgetvalue( res, 0, i_id );
+ idx = PQfnumber( res, "id" );
+ iptr = PQgetvalue( res, 0, idx );
id = ntohl( *( (uint32_t *)iptr ) );
- iptr = PQgetvalue( res, 0, i_size );
+
+ idx = PQfnumber( res, "size" );
+ iptr = PQgetvalue( res, 0, idx );
meta->size = ntohl( *( (uint32_t *)iptr ) );
- iptr = PQgetvalue( res, 0, i_mode );
+
+ idx = PQfnumber( res, "mode" );
+ iptr = PQgetvalue( res, 0, idx );
meta->mode = ntohl( *( (uint32_t *)iptr ) );
+ idx = PQfnumber( res, "uid" );
+ iptr = PQgetvalue( res, 0, idx );
+ meta->uid = ntohl( *( (uint32_t *)iptr ) );
+
+ idx = PQfnumber( res, "gid" );
+ iptr = PQgetvalue( res, 0, idx );
+ meta->gid = ntohl( *( (uint32_t *)iptr ) );
+
PQclear( res );
return id;
@@ -77,13 +85,15 @@ int psql_write_meta( PGconn *conn, const int id, const char *path, PgMeta meta )
int param1 = htonl( id );
int param2 = htonl( meta.size );
int param3 = htonl( meta.mode );
- const char *values[3] = { (char *)&param1, (char *)&param2, (char *)&param3 };
- int lengths[3] = { sizeof( param1 ), sizeof( param2 ), sizeof( param3 ) };
- int binary[3] = { 1, 1, 1 };
+ int param4 = htonl( meta.uid );
+ int param5 = htonl( meta.gid );
+ const char *values[5] = { (char *)&param1, (char *)&param2, (char *)&param3, (char *)&param4, (char *)&param5 };
+ int lengths[5] = { sizeof( param1 ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ), sizeof( param5 ) };
+ int binary[5] = { 1, 1, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "UPDATE dir SET size=$2::int4, mode=$3::int4 WHERE id=$1::int4",
- 3, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "UPDATE dir SET size=$2::int4, mode=$3::int4, uid=$4::int4, gid=$5::int4 WHERE id=$1::int4",
+ 5, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_write_meta for file '%s': %s", path, PQerrorMessage( conn ) );
@@ -96,17 +106,19 @@ int psql_write_meta( PGconn *conn, const int id, const char *path, PgMeta meta )
return 0;
}
-int psql_create_file( PGconn *conn, const int parent_id, const char *path, const char *new_file, const mode_t mode )
+int psql_create_file( PGconn *conn, const int parent_id, const char *path, const char *new_file, PgMeta meta )
{
int param1 = htonl( parent_id );
- int param2 = htonl( mode );
- const char *values[4] = { (const char *)&param1, new_file, path, (const char *)&param2 };
- int lengths[4] = { sizeof( param1 ), strlen( new_file ), strlen( path ), sizeof( param2 ) };
- int binary[4] = { 1, 0, 0, 1 };
+ int param2 = htonl( meta.mode );
+ int param3 = htonl( meta.uid );
+ int param4 = htonl( meta.gid );
+ const char *values[6] = { (const char *)&param1, new_file, path, (const char *)&param2, (const char *)&param3, (const char *)&param4 };
+ int lengths[6] = { sizeof( param1 ), strlen( new_file ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ) };
+ int binary[6] = { 1, 0, 0, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4 )",
- 4, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode, uid, gid ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4 )",
+ 6, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_create_file for path '%s': %s",
@@ -116,7 +128,7 @@ int psql_create_file( PGconn *conn, const int parent_id, const char *path, const
}
PQclear( res );
-
+
return 0;
}
@@ -187,17 +199,19 @@ int psql_readdir( PGconn *conn, const int parent_id, void *buf, fuse_fill_dir_t
return 0;
}
-int psql_create_dir( PGconn *conn, const int parent_id, const char *path, const char *new_dir, const mode_t mode )
+int psql_create_dir( PGconn *conn, const int parent_id, const char *path, const char *new_dir, PgMeta meta )
{
int param1 = htonl( parent_id );
- int param2 = htonl( mode );
- const char *values[4] = { (char *)&param1, new_dir, path, (char *)&param2 };
- int lengths[4] = { sizeof( param1 ), strlen( new_dir ), strlen( path ), sizeof( param2 ) };
- int binary[4] = { 1, 0, 0, 1 };
+ int param2 = htonl( meta.mode );
+ int param3 = htonl( meta.uid );
+ int param4 = htonl( meta.gid );
+ const char *values[6] = { (char *)&param1, new_dir, path, (char *)&param2, (char *)&param3, (char *)&param4 };
+ int lengths[6] = { sizeof( param1 ), strlen( new_dir ), strlen( path ), sizeof( param2 ), sizeof( param3 ), sizeof( param4 ) };
+ int binary[6] = { 1, 0, 0, 1, 1, 1 };
PGresult *res;
- res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4 )",
- 4, NULL, values, lengths, binary, 1 );
+ res = PQexecParams( conn, "INSERT INTO dir( parent_id, name, path, mode, uid, gid ) VALUES ($1::int4, $2::varchar, $3::varchar, $4::int4, $5::int4, $6::int4 )",
+ 6, NULL, values, lengths, binary, 1 );
if( PQresultStatus( res ) != PGRES_COMMAND_OK ) {
syslog( LOG_ERR, "Error in psql_create_dir for path '%s': %s", path, PQerrorMessage( conn ) );
diff --git a/pgsql.h b/pgsql.h
index 5cd2d7e..53474a8 100644
--- a/pgsql.h
+++ b/pgsql.h
@@ -28,19 +28,21 @@
typedef struct PgMeta {
size_t size; /* the size of the file */
mode_t mode; /* type and permissions of file/directory */
+ uid_t uid; /* owner of the file/directory */
+ gid_t gid; /* group owner of the file/directory */
} PgMeta;
int psql_get_meta( PGconn *conn, const char *path, PgMeta *meta );
int psql_write_meta( PGconn *conn, const int id, const char *path, PgMeta meta );
-int psql_create_file( PGconn *conn, const int parent_id, const char *path, const char *new_file, const mode_t mode );
+int psql_create_file( PGconn *conn, const int parent_id, const char *path, const char *new_file, PgMeta meta );
int psql_read_buf( PGconn *conn, const int id, const char *path, char **buf, const size_t len );
int psql_readdir( PGconn *conn, const int parent_id, void *buf, fuse_fill_dir_t filler );
-int psql_create_dir( PGconn *conn, const int parent_id, const char *path, const char *new_dir, const mode_t mode );
+int psql_create_dir( PGconn *conn, const int parent_id, const char *path, const char *new_dir, PgMeta meta );
int psql_delete_dir( PGconn *conn, const int id, const char *path );