Skip to content

Commit

Permalink
Adding statvfs
Browse files Browse the repository at this point in the history
  • Loading branch information
silverdaz committed Dec 9, 2024
1 parent 76bcb3d commit 0d7a624
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 21 deletions.
79 changes: 78 additions & 1 deletion src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,83 @@ crypt4gh_sqlite_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
return crypt4gh_sqlite_xattr_exec(req, ino, name, NULL, 0, 0, removexattr_query);
}

/* =====================================
StatFS
===================================== */

static char *statfs_query = "SELECT count(inode) AS f_files, "
" CAST(sum(size) / 4096 AS int64) as f_blocks, "
" max(length(name)) as f_namemax "
"FROM entries e ";

static void
crypt4gh_sqlite_statfs(fuse_req_t req, fuse_ino_t ino)
{
D1("STATFS %lu", ino);

sqlite3_stmt *stmt = NULL;
if(sqlite3_prepare_v2(config.db, statfs_query, -1, &stmt, NULL) /* != SQLITE_OK */ ||
!stmt){
E("Preparing statement: %s | %s", statfs_query, sqlite3_errmsg(config.db));
return (void) fuse_reply_err(req, EIO);
}

/* Bind arguments */
// sqlite3_bind_int64(stmt, 1, ino);

print_expand_statement(stmt);

int rc = 0;
int found = 0;
while(1){ /* Execute the query. */

rc = sqlite3_step(stmt);
if(rc == SQLITE_DONE || rc == SQLITE_ERROR)
break;

if(!found && rc == SQLITE_ROW){

struct statvfs s;
memset(&s, 0, sizeof(struct statvfs));

/* Filesystem block size */
s.f_bsize = 4096;
/* Fragment size */
s.f_frsize = 4096;
/* Size of fs in f_frsize units */
s.f_blocks = (fsblkcnt_t)sqlite3_column_int64(stmt, 1);
/* Number of free blocks */
s.f_bfree = 0;
/* Number of free blocks for unprivileged users */
s.f_bavail = 0;
/* Number of inodes */
s.f_files = (fsfilcnt_t)sqlite3_column_int64(stmt, 0);
/* Number of free inodes */
s.f_ffree = 0;
/* Number of free inodes for unprivileged users */
s.f_favail = 0;
/* Filesystem ID */
s.f_fsid = ino;
// See: https://man7.org/linux/man-pages/man2/statfs.2.html#VERSIONS
/* Mount flags */
s.f_flag = ST_NOATIME | ST_NODEV | ST_NODIRATIME | ST_NOEXEC | ST_NOSUID;
if(!config.is_readwrite)
s.f_flag |= ST_RDONLY;
/* Maximum filename length */
s.f_namemax = (unsigned long)sqlite3_column_int64(stmt, 2);


fuse_reply_statfs(req, &s);
found = 1;
}
}

sqlite3_finalize(stmt);

if(found) return;
fuse_reply_err(req, ENOSYS); // and stop asking
}

/* =====================================
Operations
===================================== */
Expand Down Expand Up @@ -1175,6 +1252,6 @@ fs_operations(void)
fs_oper.setxattr = crypt4gh_sqlite_setxattr;
fs_oper.removexattr = crypt4gh_sqlite_removexattr;

//fs_oper.statfs = crypt4gh_sqlite_statfs;
fs_oper.statfs = crypt4gh_sqlite_statfs;
return &fs_oper;
}
13 changes: 4 additions & 9 deletions src/includes.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,11 @@
#endif

#ifndef FUSE_USE_VERSION
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 12)
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 14)
#endif

#include <fuse_lowlevel.h>

#ifndef FUSE_MAKE_VERSION
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 100 + (min))
#endif

#ifndef FUSE_VERSION
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
#endif

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
Expand All @@ -53,6 +45,7 @@
#include <limits.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <ctype.h>

#define OFF_FMT "%lu"
Expand Down Expand Up @@ -116,6 +109,7 @@ struct fs_config {
time_t mounted_at;
int direct_io;

int is_readwrite;
unsigned int dperm;
unsigned int fperm;

Expand Down Expand Up @@ -151,6 +145,7 @@ struct fs_config {
int singlethread;
int clone_fd;
int max_idle_threads;
int max_threads;
};


Expand Down
27 changes: 16 additions & 11 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ static struct fuse_opt fs_opts[] = {
CRYPT4GH_SQLITE_OPT("-s" , singlethread , 1),
CRYPT4GH_SQLITE_OPT("clone_fd" , clone_fd , 1),
CRYPT4GH_SQLITE_OPT("max_idle_threads=%u", max_idle_threads, 0),
CRYPT4GH_SQLITE_OPT("max_threads=%u", max_threads, 0),

CRYPT4GH_SQLITE_OPT("entry_timeout=%lf", entry_timeout, 0),
CRYPT4GH_SQLITE_OPT("attr_timeout=%lf", attr_timeout, 0),
Expand Down Expand Up @@ -286,10 +287,13 @@ int main(int argc, char *argv[])
config.singlethread = 0;
config.foreground = 0;
config.mounted_at = time(NULL);
config.max_idle_threads = DEFAULT_MAX_THREADS;

config.entry_timeout = DEFAULT_ENTRY_TIMEOUT;
config.attr_timeout = DEFAULT_ATTR_TIMEOUT;

config.max_threads = DEFAULT_MAX_THREADS;
config.max_idle_threads = UINT_MAX;

config.uid = getuid(); /* current user */
config.gid = getgid(); /* current group */

Expand Down Expand Up @@ -353,10 +357,10 @@ int main(int argc, char *argv[])
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);

/* checking if the DB is writable */
int is_readwrite = !access(config.db_path, R_OK | W_OK);
D1("Opening SQLite path: %s (%s)", config.db_path, (is_readwrite) ? "read-write" : "read-only");
config.is_readwrite = !access(config.db_path, R_OK | W_OK);
D1("Opening SQLite path: %s (%s)", config.db_path, (config.is_readwrite) ? "read-write" : "read-only");
sqlite3_open_v2(config.db_path, &config.db,
((is_readwrite) ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY)
(config.is_readwrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY)
| SQLITE_OPEN_FULLMUTEX,
NULL);
if (config.db == NULL){
Expand All @@ -379,7 +383,7 @@ int main(int argc, char *argv[])
operations = fs_operations();

/* disable if you can't write in the DB file */
if(!is_readwrite){
if(!config.is_readwrite){
operations->setxattr = NULL;
operations->removexattr = NULL;
}
Expand Down Expand Up @@ -422,12 +426,13 @@ int main(int argc, char *argv[])
D2("Mode: single-threaded");
res = fuse_session_loop(se);
} else {
struct fuse_loop_config cf = {
.clone_fd = config.clone_fd,
.max_idle_threads = config.max_idle_threads,
};
D2("Mode: multi-threaded (max idle threads: %d)", cf.max_idle_threads);
res = fuse_session_loop_mt(se, &cf);
struct fuse_loop_config *cf = fuse_loop_cfg_create();
fuse_loop_cfg_set_idle_threads(cf, config.max_idle_threads);
fuse_loop_cfg_set_max_threads(cf, config.max_threads);
fuse_loop_cfg_set_clone_fd(cf, config.clone_fd);
D2("Mode: multi-threaded (max idle threads: %d)", config.max_threads);
res = fuse_session_loop_mt(se, cf);
fuse_loop_cfg_destroy(cf);
}

bailout_unmount:
Expand Down

0 comments on commit 0d7a624

Please sign in to comment.