Migrate to FUSE 3.x API

- Update FUSE_USE_VERSION from 26 to 30
- Replace fuse_mount/fuse_unmount with fuse_session_mount/fuse_session_unmount
- Update fuse_new() to take args first, remove channel parameter
- Add flags parameter to readdir handler (enum fuse_readdir_flags)
- Add flags parameter to rename handler (for renameat2 support)
- Update filler function calls to include FUSE_FILL_DIR_PLUS flag
- Merge ftruncate into truncate handler (FUSE 3 combines them)
- Update fuse_loop_mt to fuse_loop_mt_31 with loop config
- Link against libfuse3 instead of libfuse
- Remove fuse_chan usage (deprecated in FUSE 3)

Addresses #342
This commit is contained in:
Levi Neely 2026-03-04 19:24:26 +01:00
parent 90945b8817
commit 72d8102db1
3 changed files with 45 additions and 39 deletions

View File

@ -6,7 +6,7 @@ DIST_CFLAGS := $(CFLAGS)
DIST_CXXFLAGS := $(CXXFLAGS)
COMMONFLAGS = -fsanitize=address
CFLAGS = -fPIC $(COMMONFLAGS) -I./pclsync -I/usr/include $(shell pkg-config --cflags $$(pkg-config --list-all | grep -o 'mbedtls[0-9.]*\s' | head -1) 2>/dev/null || pkg-config --cflags mbedtls 2>/dev/null || echo "-I/usr/local/include")
CFLAGS = -fPIC $(COMMONFLAGS) -I./pclsync -I/usr/include $(shell pkg-config --cflags fuse3 2>/dev/null) $(shell pkg-config --cflags $$(pkg-config --list-all | grep -o 'mbedtls[0-9.]*\s' | head -1) 2>/dev/null || pkg-config --cflags mbedtls 2>/dev/null || echo "-I/usr/local/include")
ifneq (,$(filter clang%,$(CC)))
CFLAGS += -Wthread-safety
endif
@ -20,7 +20,7 @@ LIBLDFLAGS = $(COMMONFLAGS) -lreadline -lpthread -ludev -lsqlite3 -lz $(shell \
else \
pkg-config --libs mbedtls mbedx509 mbedcrypto 2>/dev/null || echo "-L/usr/local/lib -lmbedtls -lmbedx509 -lmbedcrypto"; \
fi)
EXECLDFLAGS = $(COMMONFLAGS) -lboost_program_options -lfuse
EXECLDFLAGS = $(COMMONFLAGS) -lboost_program_options -lfuse3
SCAN := 0
SRCDIR := .
@ -42,14 +42,14 @@ LIBOUT := libpcloudcc_lib.so
# Build type specific flags
ifeq ($(BUILD), debug)
CFLAGS += -g -O0 -DDEBUG -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
CFLAGS += -g -O0 -DDEBUG -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=30 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
CXXFLAGS += -g -O0 -DDEBUG -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
DEBUGSRC := $(wildcard $(LIBDIR)/debug/*.c)
DEBUGOBJ := $(notdir $(DEBUGSRC:%.c=%.o))
COBJ += $(DEBUGOBJ)
else ifeq ($(BUILD), release)
CFLAGS += -g -O0 -DNDEBUG -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
CXXFLAGS += -g -O0 -DNDEBUG -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
CFLAGS += -O2 -DNDEBUG -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=30 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
CXXFLAGS += -O2 -DNDEBUG -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=30 -D_GNU_SOURCE -DPSYNC_SSL_DEBUG_LEVEL=$(SSLDBGLVL)
COMMONFLAGS := $(filter-out -fsanitize=address,$(COMMONFLAGS))
LIBLDFLAGS := $(filter-out -fsanitize=address,$(LIBLDFLAGS))
EXECLDFLAGS := $(filter-out -fsanitize=address,$(EXECLDFLAGS))

View File

@ -91,8 +91,6 @@ typedef off_t fuse_off_t;
#define PSYNC_FS_ERR_MOVE_ACROSS_CRYPTO EXDEV
static int shutdown_in_progress = 0;
volatile sig_atomic_t shutdown_requested = 0;
static struct fuse_chan *psync_fuse_channel = NULL;
static struct fuse *psync_fuse = NULL;
static char *psync_current_mountpoint = NULL;
static psync_generic_callback_t psync_start_callback = NULL;
@ -877,15 +875,16 @@ static int filler_decoded(pcrypto_textdec_t dec,
namedec = pcryptofolder_flddecode_filename(dec, name);
if (!namedec)
return 0;
ret = filler(buf, namedec, st, off);
ret = filler(buf, namedec, st, off, FUSE_FILL_DIR_PLUS);
pmem_free(PMEM_SUBSYS_OTHER, namedec);
return ret;
} else
return filler(buf, name, st, off);
return filler(buf, name, st, off, FUSE_FILL_DIR_PLUS);
}
static int pfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
fuse_off_t offset, struct fuse_file_info *fi) {
fuse_off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags readdir_flags) {
psync_sql_res *res;
psync_variant_row row;
psync_fsfolderid_t folderid;
@ -918,9 +917,9 @@ static int pfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
}
} else
dec = NULL;
filler(buf, ".", NULL, 0);
filler(buf, ".", NULL, 0, FUSE_FILL_DIR_PLUS);
if (folderid != 0)
filler(buf, "..", NULL, 0);
filler(buf, "..", NULL, 0, FUSE_FILL_DIR_PLUS);
folder = pfs_task_get_folder_tasks_rdlocked(folderid);
if (folderid >= 0) {
res = psql_query_nolock(
@ -2885,7 +2884,7 @@ static int pfs_is_nonempty_folder(psync_fsfolderid_t parent_folderid,
return ret;
}
static int pfs_rename(const char *old_path, const char *new_path) {
static int pfs_rename(const char *old_path, const char *new_path, unsigned int rename_flags) {
psync_fspath_t *fold_path, *fnew_path;
psync_sql_res *res;
psync_fstask_folder_t *folder;
@ -3286,18 +3285,23 @@ static int pfs_ftruncate(const char *path, fuse_off_t size,
(unsigned long)size);
}
static int pfs_truncate(const char *path, fuse_off_t size) {
struct fuse_file_info fi;
static int pfs_truncate(const char *path, fuse_off_t size, struct fuse_file_info *fi) {
struct fuse_file_info fi_local;
int ret;
pfs_set_thread_name();
pdbg_logf(D_NOTICE, "truncate %s %lu", path, (unsigned long)size);
memset(&fi, 0, sizeof(fi));
ret = pfs_open(path, &fi);
if (fi) {
return pfs_ftruncate(path, size, fi);
}
memset(&fi_local, 0, sizeof(fi_local));
ret = pfs_open(path, &fi_local);
if (ret)
return ret;
ret = pfs_ftruncate(path, size, &fi);
pfs_flush(path, &fi);
pfs_release(path, &fi);
ret = pfs_ftruncate(path, size, &fi_local);
pfs_flush(path, &fi_local);
pfs_release(path, &fi_local);
return ret;
}
@ -3546,8 +3550,8 @@ static void pfs_do_stop(void) {
mp = psync_fuse_get_mountpoint();
if (mp) {
if (stat(mp, &st_before) == 0) {
fuse_unmount(mp, psync_fuse_channel);
psync_fuse_channel = NULL;
struct fuse_session *se = fuse_get_session(psync_fuse);
fuse_session_unmount(se);
clock_gettime(CLOCK_REALTIME, &ts);
// Check if the mountpoint is still accessible
@ -3633,13 +3637,10 @@ static void psync_fuse_thread() {
}
pthread_mutex_unlock(&start_mutex);
pdbg_logf(D_NOTICE, "running fuse_loop_mt");
fr = fuse_loop_mt(psync_fuse);
if (shutdown_requested) {
pdbg_logf(D_NOTICE, "shutdown requested, exiting fuse loop");
pfs_do_stop();
}
struct fuse_loop_config loop_config;
loop_config.clone_fd = 1;
loop_config.max_idle_threads = 10;
fr = fuse_loop_mt_31(psync_fuse, &loop_config);
pdbg_logf(D_NOTICE, "fuse_loop_mt exited with code %d, running fuse_destroy", fr);
pthread_mutex_lock(&start_mutex);
fuse_destroy(psync_fuse);
@ -3739,7 +3740,6 @@ static int pfs_do_start() {
psync_oper.chmod = pfs_chmod;
psync_oper.chown = pfs_chown;
psync_oper.utimens = pfs_utimens;
psync_oper.ftruncate = pfs_ftruncate;
psync_oper.truncate = pfs_truncate;
psync_oper.setxattr = pfs_xatr_set;
@ -3770,18 +3770,24 @@ static int pfs_do_start() {
goto err00;
}
psync_fuse_channel = fuse_mount(mp, &args);
if (pdbg_unlikely(!psync_fuse_channel)) {
psync_fuse = fuse_new(&args, &psync_oper, sizeof(psync_oper), NULL);
if (pdbg_unlikely(!psync_fuse)) {
pdbg_logf(D_CRITICAL,
"CRITICAL ERROR: fuse_mount() failed for mount point %s. "
"CRITICAL ERROR: fuse_new() failed. "
"The FUSE filesystem cannot be started. errno=%d (%s)",
mp, errno, strerror(errno));
errno, strerror(errno));
goto err0;
}
psync_fuse = fuse_new(psync_fuse_channel, &args, &psync_oper,
sizeof(psync_oper), NULL);
if (pdbg_unlikely(!psync_fuse))
struct fuse_session *se = fuse_get_session(psync_fuse);
if (fuse_session_mount(se, mp) != 0) {
pdbg_logf(D_CRITICAL,
"CRITICAL ERROR: fuse_session_mount() failed for mount point %s. "
"The FUSE filesystem cannot be started. errno=%d (%s)",
mp, errno, strerror(errno));
goto err1;
}
psync_current_mountpoint = mp;
started = 1;
pthread_mutex_unlock(&start_mutex);
@ -3789,7 +3795,7 @@ static int pfs_do_start() {
prun_thread("fuse", psync_fuse_thread);
return 0;
err1:
fuse_unmount(mp, psync_fuse_channel);
fuse_destroy(psync_fuse);
err0:
pmem_free(PMEM_SUBSYS_OTHER, mp);
err00:

View File

@ -29,7 +29,7 @@
DAMAGE.
*/
#define FUSE_USE_VERSION 26
#define FUSE_USE_VERSION 30
#include <errno.h>
#include <fuse.h>