From 30b23afb5fca43110f09201897742c378eccb285 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 15 Apr 2013 15:27:31 +0200 Subject: added statsfs patch from Роман Бородин MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- INSTALL | 4 ++++ pgfuse.c | 39 ++++++++++++++++++++++++++++++++++++--- pgsql.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ pgsql.h | 4 ++++ 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 -- cgit v1.2.3-54-g00ecf