summaryrefslogtreecommitdiff
path: root/AEpy/FusePatches.py
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2018-12-16 23:05:33 +0100
committernorly <ny-git@enpas.org>2018-12-16 23:21:11 +0100
commitf06df88629c6ae1205f522148102a0c3d04d1cf2 (patch)
tree1aa836591c2a9b34032150752218fb31e87562de /AEpy/FusePatches.py
parent8fc49cd8badf6ceb6b6dfe03deb961cadf61839f (diff)
Import first working version
Diffstat (limited to 'AEpy/FusePatches.py')
-rw-r--r--AEpy/FusePatches.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/AEpy/FusePatches.py b/AEpy/FusePatches.py
new file mode 100644
index 0000000..f02ddd2
--- /dev/null
+++ b/AEpy/FusePatches.py
@@ -0,0 +1,53 @@
+# Ugly patches for fusepy to accommodate inflexible userspace applications.
+#
+
+from ctypes import c_uint, cast, POINTER, Structure
+from fusepy import FUSE
+
+
+class fuse_conn_info(Structure):
+ _fields_ = [
+ ('proto_major', c_uint),
+ ('proto_minor', c_uint),
+ ('async_read', c_uint),
+ ('max_write', c_uint),
+ ('max_readahead', c_uint),
+ ('capable', c_uint),
+ ('want', c_uint),
+ ('max_background', c_uint),
+ ('congestion_threshold', c_uint)
+ ]
+
+
+# Ugly patch for fusepy to allow changing max_readahead.
+#
+# This is necessary for FUSE filesystems which need to avoid unnecessary
+# data transfers.
+#
+# Example:
+# If a GIO (as in GLib/GNOME's GIO) based file manager (e.g. XFCE's Thunar)
+# tries to determine each file's type by inspecting its header (GLib 2.50
+# reads up to 4 KB of each file), this results in a lot of traffic. If the
+# kernel increases this to 16 KB as part of its buffered I/O's readahead,
+# things become very slow on exotically slow links or host media.
+# In fact, this patch has been written with a 2 KByte/s link in mind.
+#
+# Why not turn off this header-sniffing feature in userspace?
+# Because... Neither Thunar nor GLib/GIO have this option, and exotic FUSE
+# filesystems still need to work on them until they have a mechanism to turn
+# this off. Preferably with a hint in stat() or statfs().
+#
+# NOTE:
+# The kernel will impose a lower bound on max_readahead.
+# As of 4.9 on x86-64, this is 4096 bytes.
+# (still a lot on a 2 KB/s link, but Thunar won't be *completely* useless)
+#
+def patch_max_readahead(max_readahead):
+ old_init = FUSE.init
+
+ def _new_fuse_init(self, conn):
+ conn2 = cast(conn, POINTER(fuse_conn_info))
+ conn2.contents.max_readahead = max_readahead
+ return old_init(self, conn)
+
+ FUSE.init = _new_fuse_init