diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | pgfuse.c | 35 | ||||
-rw-r--r-- | pgsql.c | 74 | ||||
-rw-r--r-- | pgsql.h | 6 |
4 files changed, 70 insertions, 46 deletions
@@ -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 @@ -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 ) { @@ -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 *)¶m1, (char *)¶m2, (char *)¶m3 }; - 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 *)¶m1, (char *)¶m2, (char *)¶m3, (char *)¶m4, (char *)¶m5 }; + 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 *)¶m1, new_file, path, (const char *)¶m2 }; - 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 *)¶m1, new_file, path, (const char *)¶m2, (const char *)¶m3, (const char *)¶m4 }; + 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 *)¶m1, new_dir, path, (char *)¶m2 }; - 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 *)¶m1, new_dir, path, (char *)¶m2, (char *)¶m3, (char *)¶m4 }; + 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 ) ); @@ -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 ); |