summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2013-04-15 15:27:31 +0200
committerAndreas Baumann <abaumann@yahoo.com>2013-04-15 15:27:31 +0200
commit30b23afb5fca43110f09201897742c378eccb285 (patch)
tree3a584c9e708e5ecd09357fa8415b916a694d33a3
parent8f92530fd96cadff64fabc711c6b523ffb27fe29 (diff)
downloadpgfuse-30b23afb5fca43110f09201897742c378eccb285.tar.gz
pgfuse-30b23afb5fca43110f09201897742c378eccb285.tar.bz2
added statsfs patch from Роман Бородин
-rw-r--r--INSTALL4
-rw-r--r--pgfuse.c39
-rw-r--r--pgsql.c51
-rw-r--r--pgsql.h4
4 files changed, 95 insertions, 3 deletions
diff --git a/INSTALL b/INSTALL
index 95af27d..8618f7a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -25,6 +25,10 @@ Installation
* Initialize the database schema (as user using fuse)
psql -U someuser somedb < schema.sql
+
+* Create special function (as PostgreSQL superuser)
+
+ psql somedb < function.sql
* Mount the FUSE filesystem
diff --git a/pgfuse.c b/pgfuse.c
index 88dbf1e..1f7a391 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -936,6 +936,10 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
{
PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
+ PGconn *conn;
+
+ int64_t fs_size, fs_used, fs_free, fs_avail;
+
if( data->verbose ) {
syslog( LOG_INFO, "Statfs called on '%s', thread #%u",
data->mountpoint, THREAD_ID );
@@ -947,12 +951,41 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
buf->f_bsize = data->block_size;
buf->f_frsize = data->block_size;
+
+ ACQUIRE( conn );
+ PSQL_BEGIN( conn );
+
+ fs_free = psql_get_fs_free( conn );
+
+ if( fs_free < 0 ) {
+ fs_free = INT_MAX;
+ } else {
+ fs_free = fs_free / data->block_size;
+
+ };
+
+ fs_used = psql_get_fs_used( conn );
+
+ if( fs_used < 0 ) {
+ PSQL_ROLLBACK( conn ); RELEASE( conn );
+ fs_used = INT_MAX;
+ fs_size = INT_MAX;
+ fs_free = INT_MAX;
+ fs_avail = INT_MAX;
+ } else {
+ fs_used = fs_used / data->block_size;
+ fs_size = fs_free + fs_used;
+ fs_avail = fs_free;
+ };
+
+ PSQL_COMMIT( conn ); RELEASE( conn );
+
/* Note: it's hard to tell how much space is left in the database
* and how big it is
*/
- buf->f_blocks = INT_MAX;
- buf->f_bfree = INT_MAX;
- buf->f_bavail = INT_MAX;
+ buf->f_blocks = fs_size;
+ buf->f_bfree = fs_free;
+ buf->f_bavail = fs_avail;
buf->f_files = INT_MAX;
buf->f_ffree = INT_MAX;
buf->f_favail = INT_MAX;
diff --git a/pgsql.c b/pgsql.c
index e42a6cf..6b7a263 100644
--- a/pgsql.c
+++ b/pgsql.c
@@ -928,3 +928,54 @@ size_t psql_get_block_size( PGconn *conn, const size_t block_size )
return db_block_size;
}
+size_t psql_get_fs_used( PGconn *conn )
+{
+ PGresult *res;
+ char *data;
+ size_t fs_used;
+ res = PQexec( conn, "SELECT SUM(size) FROM dir;" );
+ if( PQresultStatus( res ) != PGRES_TUPLES_OK ) {
+ syslog( LOG_ERR, "Error in psql_get_fs_used: %s", PQerrorMessage( conn ) );
+ PQclear( res );
+ return -EIO;
+ }
+
+ /* empty, this is ok, any blocksize acceptable after initialization */
+ if( PQntuples( res ) == 0 ) {
+ PQclear( res );
+ return 0;
+ }
+
+ data = PQgetvalue( res, 0, 0 );
+ fs_used = atol( data );
+
+ PQclear( res );
+
+ return fs_used;
+}
+
+size_t psql_get_fs_free( PGconn *conn )
+{
+ PGresult *res;
+ char *data;
+ size_t fs_free;
+ res = PQexec( conn, "SELECT db_disk_free();" );
+ if( PQresultStatus( res ) != PGRES_TUPLES_OK ) {
+ syslog( LOG_ERR, "Error in psql_get_fs_free: %s", PQerrorMessage( conn ) );
+ PQclear( res );
+ return -EIO;
+ }
+
+ /* empty, this is ok, any blocksize acceptable after initialization */
+ if( PQntuples( res ) == 0 ) {
+ PQclear( res );
+ return -EIO;
+ }
+
+ data = PQgetvalue( res, 0, 0 );
+ fs_free = atol( data );
+
+ PQclear( res );
+
+ return fs_free;
+}
diff --git a/pgsql.h b/pgsql.h
index 014cd96..29f9db9 100644
--- a/pgsql.h
+++ b/pgsql.h
@@ -98,4 +98,8 @@ int psql_rename( PGconn *conn, const int64_t from_id, const int64_t from_parent_
size_t psql_get_block_size( PGconn *conn, const size_t block_size );
+size_t psql_get_fs_used( PGconn *conn );
+
+size_t psql_get_fs_free( PGconn *conn );
+
#endif