From e976b212db5247a8fcd29528149b2722803ff3d5 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <vital.had@gmail.com>
Date: Fri, 8 May 2026 01:50:39 +0800
Subject: [PATCH] Revert "fuse: Adapt gvfsd-fuse to use fuse 3.x"

This reverts commit 7a0a06186b6fef07b8fce2360c04fd075fc84ed1.

diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index 85eb1966..3c480c7a 100644
--- client/gvfsfusedaemon.c
+++ client/gvfsfusedaemon.c
@@ -44,7 +44,7 @@
 #include <gvfsdbus.h>
 #include <gvfsutils.h>
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 26
 
 #include <fuse.h>
 #include <fuse_lowlevel.h>
@@ -861,7 +861,7 @@
 }
 
 static gint
-vfs_getattr (const gchar *path, struct stat *sbuf, struct fuse_file_info *fi)
+vfs_getattr (const gchar *path, struct stat *sbuf)
 {
   GFile      *file;
   gint        result = 0;
@@ -1585,16 +1585,12 @@
       return result;
     }
 
-  filler (buf, ".", NULL, 0, 0);
-  filler (buf, "..", NULL, 0, 0);
+  filler (buf, ".", NULL, 0);
+  filler (buf, "..", NULL, 0);
 
   while ((file_info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)
     {
-      struct stat sbuf = {0};
-
-      set_attributes_from_info (file_info, &sbuf);
-
-      filler (buf, g_file_info_get_name (file_info), &sbuf, 0, FUSE_FILL_DIR_PLUS);
+      filler (buf, g_file_info_get_name (file_info), NULL, 0);
       g_object_unref (file_info);
     }
 
@@ -1605,13 +1601,12 @@
 
 static gint
 vfs_readdir (const gchar *path, gpointer buf, fuse_fill_dir_t filler, off_t offset,
-             struct fuse_file_info *fi, enum fuse_readdir_flags fl)
+             struct fuse_file_info *fi)
 {
   GFile       *base_file;
   gint         result = 0;
 
   g_debug ("vfs_readdir: %s\n", path);
-  g_debug ("vfs_readdir: flags=%o\n", fl);
 
   if (path_is_mount_list (path))
     {
@@ -1619,8 +1614,8 @@
 
       /* Mount list */
 
-      filler (buf, ".", NULL, 0, 0);
-      filler (buf, "..", NULL, 0, 0);
+      filler (buf, ".", NULL, 0);
+      filler (buf, "..", NULL, 0);
 
       mount_list_lock ();
 
@@ -1628,7 +1623,7 @@
         {
           MountRecord *mount_record = l->data;
 
-          filler (buf, mount_record->name, NULL, 0, 0);
+          filler (buf, mount_record->name, NULL, 0);
         }
 
       mount_list_unlock ();
@@ -1652,21 +1647,13 @@
 }
 
 static gint
-vfs_rename (const gchar *old_path, const gchar *new_path, unsigned int vfs_flags)
+vfs_rename (const gchar *old_path, const gchar *new_path)
 {
   GFile  *old_file;
   GFile  *new_file;
-  GFileCopyFlags flags = G_FILE_COPY_OVERWRITE;
   GError *error  = NULL;
   gint    result = 0;
 
-  /* Can not implement this flag because limitation of GFile. */
-  if (vfs_flags & RENAME_EXCHANGE)
-    return -EINVAL;
-
-  if (vfs_flags & RENAME_NOREPLACE)
-    flags = G_FILE_COPY_NONE;
-
   g_debug ("vfs_rename: %s -> %s\n", old_path, new_path);
 
   old_file = file_from_full_path (old_path);
@@ -1682,7 +1669,7 @@
           file_handle_close_stream (fh);
         }
 
-      g_file_move (old_file, new_file, flags, NULL, NULL, NULL, &error);
+      g_file_move (old_file, new_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
 
       if (error)
         {
@@ -2090,15 +2077,6 @@
 }
 
 static gint
-vfs_truncate_dispatch (const gchar *path, off_t size, struct fuse_file_info *fi)
-{
-  if (fi)
-    return vfs_ftruncate (path, size, fi);
-
-  return vfs_truncate (path, size);
-}
-
-static gint
 vfs_symlink (const gchar *path_old, const gchar *path_new)
 {
   GFile  *file;
@@ -2204,7 +2182,7 @@
 }
 
 static gint
-vfs_utimens (const gchar *path, const struct timespec tv [2], struct fuse_file_info *fi)
+vfs_utimens (const gchar *path, const struct timespec tv [2])
 {
   GFile  *file;
   GError *error  = NULL;
@@ -2279,7 +2257,7 @@
 }
 
 static gint
-vfs_chmod (const gchar *path, mode_t mode, struct fuse_file_info *fi)
+vfs_chmod (const gchar *path, mode_t mode)
 {
   GFile  *file;
   GError *error  = NULL;
@@ -2402,7 +2380,7 @@
 }
 
 static gpointer
-vfs_init (struct fuse_conn_info *conn, struct fuse_config *cfg)
+vfs_init (struct fuse_conn_info *conn)
 {
   GVfsDBusMountTracker *proxy;
   GError *error;
@@ -2474,17 +2452,15 @@
   subthread_main_loop = g_main_loop_new (NULL, FALSE);
   subthread = g_thread_new ("gvfs-fuse-sub", (GThreadFunc) subthread_main, NULL);
 
-#ifdef HAVE_FUSE_FEATURE_FLAG_FUNCS
   /* Indicate O_TRUNC support for open() */
-  fuse_set_feature_flag(conn, FUSE_CAP_ATOMIC_O_TRUNC);
+  conn->want |= FUSE_CAP_ATOMIC_O_TRUNC;
 
   /* Prevent out-of-order readahead */
-  fuse_unset_feature_flag(conn, FUSE_CAP_ASYNC_READ);
-#else
-  /* Same as above for libfuse <3.17 */
-  conn->want |= FUSE_CAP_ATOMIC_O_TRUNC;
-  conn->want &= ~FUSE_CAP_ASYNC_READ;
-#endif
+  conn->async_read = 0;
+
+  /* Use up to a 64KiB write block size.  Only has an effect if -o big_writes
+   * is given on the command-line. */
+  conn->max_write = 65536;
 
   return NULL;
 }
@@ -2531,7 +2507,8 @@
   .unlink      = vfs_unlink,
   .mkdir       = vfs_mkdir,
   .rmdir       = vfs_rmdir,
-  .truncate    = vfs_truncate_dispatch,
+  .ftruncate   = vfs_ftruncate,
+  .truncate    = vfs_truncate,
   .symlink     = vfs_symlink,
   .access      = vfs_access,
   .utimens     = vfs_utimens,
@@ -2543,7 +2520,6 @@
   .getxattr    = vfs_getxattr,
   .listxattr   = vfs_listxattr,
   .removexattr = vfs_removexattr,
-  .ftruncate   = vfs_ftruncate,
 #endif
 };
 
@@ -2565,67 +2541,35 @@
 main (gint argc, gchar *argv [])
 {
   struct fuse *fuse;
+  struct fuse_chan *ch;
   struct fuse_session *se;
+  char *mountpoint;
+  int multithreaded;
   int res;
-  struct fuse_cmdline_opts opts;
-  struct fuse_args args = FUSE_ARGS_INIT (argc, argv);
-
-  setlocale (LC_ALL, "");
-
-  if (fuse_opt_parse (&args, NULL, NULL, NULL) == -1)
-    return 1;
-
-  if (fuse_parse_cmdline (&args, &opts) != 0)
-    return 1;
-
-  if (opts.show_version)
-    {
-      printf ("%s\n", PACKAGE_STRING);
-      fuse_lowlevel_version ();
-      return 0;
-    }
-
-  if (opts.show_help)
-    {
-      printf ("usage: %s [options] <mountpoint>\n\n", argv[0]);
-      printf ("FUSE options:\n");
-      fuse_cmdline_help ();
-      return 0;
-    }
 
-  if (!opts.mountpoint)
-    {
-      fprintf (stderr, "error: no mountpoint specified\n");
-      return 1;
-    }
-
-  fuse = fuse_new (&args, &vfs_oper, sizeof (vfs_oper), NULL /* user data */);
+  fuse = fuse_setup (argc, argv, &vfs_oper, sizeof (vfs_oper), &mountpoint,
+                     &multithreaded, NULL /* user data */);
   if (fuse == NULL)
     return 1;
 
-  if (fuse_mount (fuse, opts.mountpoint) != 0)
-    return 1;
-
-  if (fuse_daemonize (opts.foreground) != 0)
-    return 1;
+  if (multithreaded)
+    res = fuse_loop_mt (fuse);
+  else
+    res = fuse_loop (fuse);
 
   se = fuse_get_session (fuse);
-  if (fuse_set_signal_handlers (se) != 0)
-    return 1;
-
-  if (opts.singlethread)
-    res = fuse_loop (fuse);
-  else
-    res = fuse_loop_mt (fuse, opts.clone_fd);
+  ch = fuse_session_next_chan (se, NULL);
 
   /* Ignore new signals during exit procedure in order to terminate properly */
   set_custom_signal_handlers (SIG_IGN);
   fuse_remove_signal_handlers (se);
 
-  fuse_unmount (fuse);
+  fuse_unmount (mountpoint, ch);
   fuse_destroy (fuse);
-  free (opts.mountpoint);
-  fuse_opt_free_args (&args);
+  free (mountpoint);
 
-  return res;
+  if (res == -1)
+    return 1;
+
+  return 0;
 }

diff --git a/daemon/main.c b/daemon/main.c
index a36c96b4..3354df5a 100644
--- daemon/main.c
+++ daemon/main.c
@@ -96,7 +96,9 @@ on_name_acquired (GDBusConnection *connection,
       argv2[0] = LIBEXEC_DIR "/gvfsd-fuse";
       argv2[1] = fuse_path;
       argv2[2] = "-f";
-      argv2[3] = NULL;
+      argv2[3] = "-o";
+      argv2[4] = "big_writes";
+      argv2[5] = NULL;
       
       g_spawn_async (NULL,
                      argv2,
diff --git a/meson.build b/meson.build
index 369e55f1..6c3d80b5 100644
--- meson.build
+++ meson.build
@@ -332,7 +332,7 @@ config_h.set('HAVE_GUDEV', enable_gudev)
 # *** Check for FUSE ***
 enable_fuse = get_option('fuse')
 if enable_fuse
-  fuse_dep = dependency('fuse3', version: '>= 3.0.0')
+  fuse_dep = dependency('fuse', version: '>= 2.8.0')
 endif
 config_h.set('HAVE_FUSE', enable_fuse)
 
