Skip to content

Commit 0d7a624

Browse files
committed
Adding statvfs
1 parent 76bcb3d commit 0d7a624

File tree

3 files changed

+98
-21
lines changed

3 files changed

+98
-21
lines changed

src/fs.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,83 @@ crypt4gh_sqlite_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
11471147
return crypt4gh_sqlite_xattr_exec(req, ino, name, NULL, 0, 0, removexattr_query);
11481148
}
11491149

1150+
/* =====================================
1151+
StatFS
1152+
===================================== */
1153+
1154+
static char *statfs_query = "SELECT count(inode) AS f_files, "
1155+
" CAST(sum(size) / 4096 AS int64) as f_blocks, "
1156+
" max(length(name)) as f_namemax "
1157+
"FROM entries e ";
1158+
1159+
static void
1160+
crypt4gh_sqlite_statfs(fuse_req_t req, fuse_ino_t ino)
1161+
{
1162+
D1("STATFS %lu", ino);
1163+
1164+
sqlite3_stmt *stmt = NULL;
1165+
if(sqlite3_prepare_v2(config.db, statfs_query, -1, &stmt, NULL) /* != SQLITE_OK */ ||
1166+
!stmt){
1167+
E("Preparing statement: %s | %s", statfs_query, sqlite3_errmsg(config.db));
1168+
return (void) fuse_reply_err(req, EIO);
1169+
}
1170+
1171+
/* Bind arguments */
1172+
// sqlite3_bind_int64(stmt, 1, ino);
1173+
1174+
print_expand_statement(stmt);
1175+
1176+
int rc = 0;
1177+
int found = 0;
1178+
while(1){ /* Execute the query. */
1179+
1180+
rc = sqlite3_step(stmt);
1181+
if(rc == SQLITE_DONE || rc == SQLITE_ERROR)
1182+
break;
1183+
1184+
if(!found && rc == SQLITE_ROW){
1185+
1186+
struct statvfs s;
1187+
memset(&s, 0, sizeof(struct statvfs));
1188+
1189+
/* Filesystem block size */
1190+
s.f_bsize = 4096;
1191+
/* Fragment size */
1192+
s.f_frsize = 4096;
1193+
/* Size of fs in f_frsize units */
1194+
s.f_blocks = (fsblkcnt_t)sqlite3_column_int64(stmt, 1);
1195+
/* Number of free blocks */
1196+
s.f_bfree = 0;
1197+
/* Number of free blocks for unprivileged users */
1198+
s.f_bavail = 0;
1199+
/* Number of inodes */
1200+
s.f_files = (fsfilcnt_t)sqlite3_column_int64(stmt, 0);
1201+
/* Number of free inodes */
1202+
s.f_ffree = 0;
1203+
/* Number of free inodes for unprivileged users */
1204+
s.f_favail = 0;
1205+
/* Filesystem ID */
1206+
s.f_fsid = ino;
1207+
// See: https://man7.org/linux/man-pages/man2/statfs.2.html#VERSIONS
1208+
/* Mount flags */
1209+
s.f_flag = ST_NOATIME | ST_NODEV | ST_NODIRATIME | ST_NOEXEC | ST_NOSUID;
1210+
if(!config.is_readwrite)
1211+
s.f_flag |= ST_RDONLY;
1212+
/* Maximum filename length */
1213+
s.f_namemax = (unsigned long)sqlite3_column_int64(stmt, 2);
1214+
1215+
1216+
fuse_reply_statfs(req, &s);
1217+
found = 1;
1218+
}
1219+
}
1220+
1221+
sqlite3_finalize(stmt);
1222+
1223+
if(found) return;
1224+
fuse_reply_err(req, ENOSYS); // and stop asking
1225+
}
1226+
11501227
/* =====================================
11511228
Operations
11521229
===================================== */
@@ -1175,6 +1252,6 @@ fs_operations(void)
11751252
fs_oper.setxattr = crypt4gh_sqlite_setxattr;
11761253
fs_oper.removexattr = crypt4gh_sqlite_removexattr;
11771254

1178-
//fs_oper.statfs = crypt4gh_sqlite_statfs;
1255+
fs_oper.statfs = crypt4gh_sqlite_statfs;
11791256
return &fs_oper;
11801257
}

src/includes.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,11 @@
2121
#endif
2222

2323
#ifndef FUSE_USE_VERSION
24-
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 12)
24+
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 14)
2525
#endif
2626

2727
#include <fuse_lowlevel.h>
2828

29-
#ifndef FUSE_MAKE_VERSION
30-
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 100 + (min))
31-
#endif
32-
33-
#ifndef FUSE_VERSION
34-
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
35-
#endif
36-
3729
#include <assert.h>
3830
#include <stdio.h>
3931
#include <stdlib.h>
@@ -53,6 +45,7 @@
5345
#include <limits.h>
5446
#include <strings.h>
5547
#include <sys/stat.h>
48+
#include <sys/statvfs.h>
5649
#include <ctype.h>
5750

5851
#define OFF_FMT "%lu"
@@ -116,6 +109,7 @@ struct fs_config {
116109
time_t mounted_at;
117110
int direct_io;
118111

112+
int is_readwrite;
119113
unsigned int dperm;
120114
unsigned int fperm;
121115

@@ -151,6 +145,7 @@ struct fs_config {
151145
int singlethread;
152146
int clone_fd;
153147
int max_idle_threads;
148+
int max_threads;
154149
};
155150

156151

src/main.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ static struct fuse_opt fs_opts[] = {
8484
CRYPT4GH_SQLITE_OPT("-s" , singlethread , 1),
8585
CRYPT4GH_SQLITE_OPT("clone_fd" , clone_fd , 1),
8686
CRYPT4GH_SQLITE_OPT("max_idle_threads=%u", max_idle_threads, 0),
87+
CRYPT4GH_SQLITE_OPT("max_threads=%u", max_threads, 0),
8788

8889
CRYPT4GH_SQLITE_OPT("entry_timeout=%lf", entry_timeout, 0),
8990
CRYPT4GH_SQLITE_OPT("attr_timeout=%lf", attr_timeout, 0),
@@ -286,10 +287,13 @@ int main(int argc, char *argv[])
286287
config.singlethread = 0;
287288
config.foreground = 0;
288289
config.mounted_at = time(NULL);
289-
config.max_idle_threads = DEFAULT_MAX_THREADS;
290+
290291
config.entry_timeout = DEFAULT_ENTRY_TIMEOUT;
291292
config.attr_timeout = DEFAULT_ATTR_TIMEOUT;
292293

294+
config.max_threads = DEFAULT_MAX_THREADS;
295+
config.max_idle_threads = UINT_MAX;
296+
293297
config.uid = getuid(); /* current user */
294298
config.gid = getgid(); /* current group */
295299

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

355359
/* checking if the DB is writable */
356-
int is_readwrite = !access(config.db_path, R_OK | W_OK);
357-
D1("Opening SQLite path: %s (%s)", config.db_path, (is_readwrite) ? "read-write" : "read-only");
360+
config.is_readwrite = !access(config.db_path, R_OK | W_OK);
361+
D1("Opening SQLite path: %s (%s)", config.db_path, (config.is_readwrite) ? "read-write" : "read-only");
358362
sqlite3_open_v2(config.db_path, &config.db,
359-
((is_readwrite) ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY)
363+
(config.is_readwrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY)
360364
| SQLITE_OPEN_FULLMUTEX,
361365
NULL);
362366
if (config.db == NULL){
@@ -379,7 +383,7 @@ int main(int argc, char *argv[])
379383
operations = fs_operations();
380384

381385
/* disable if you can't write in the DB file */
382-
if(!is_readwrite){
386+
if(!config.is_readwrite){
383387
operations->setxattr = NULL;
384388
operations->removexattr = NULL;
385389
}
@@ -422,12 +426,13 @@ int main(int argc, char *argv[])
422426
D2("Mode: single-threaded");
423427
res = fuse_session_loop(se);
424428
} else {
425-
struct fuse_loop_config cf = {
426-
.clone_fd = config.clone_fd,
427-
.max_idle_threads = config.max_idle_threads,
428-
};
429-
D2("Mode: multi-threaded (max idle threads: %d)", cf.max_idle_threads);
430-
res = fuse_session_loop_mt(se, &cf);
429+
struct fuse_loop_config *cf = fuse_loop_cfg_create();
430+
fuse_loop_cfg_set_idle_threads(cf, config.max_idle_threads);
431+
fuse_loop_cfg_set_max_threads(cf, config.max_threads);
432+
fuse_loop_cfg_set_clone_fd(cf, config.clone_fd);
433+
D2("Mode: multi-threaded (max idle threads: %d)", config.max_threads);
434+
res = fuse_session_loop_mt(se, cf);
435+
fuse_loop_cfg_destroy(cf);
431436
}
432437

433438
bailout_unmount:

0 commit comments

Comments
 (0)