Skip to content

Commit

Permalink
FUSE: Use the writeback cache mode
Browse files Browse the repository at this point in the history
As go-fuse doesn't set this flag right now, we end up using the
write-through cache mode. This means that every call to write() also
translates to an operation against the FUSE server. This pessimizes
workloads that perform many tiny writes.

We know that this change is safe, because only between Linux 5.4-5.10
they made some changes to fully respect write-through mode. Furthermore,
OSXFUSE on macOS doesn't even support write-through mode. It was
using writeback mode to begin with.
  • Loading branch information
EdSchouten committed May 30, 2023
1 parent 5f90704 commit a8ab442
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
5 changes: 3 additions & 2 deletions go_dependencies.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,9 @@ def go_dependencies():
name = "com_github_hanwen_go_fuse_v2",
importpath = "github.com/hanwen/go-fuse/v2",
patches = [
"@com_github_buildbarn_bb_remote_execution//:patches/com_github_hanwen_go_fuse_v2/direntrylist-offsets-and-testability.diff",
"@com_github_buildbarn_bb_remote_execution//:patches/com_github_hanwen_go_fuse_v2/notify-testability.diff",
"//:patches/com_github_hanwen_go_fuse_v2/direntrylist-offsets-and-testability.diff",
"//:patches/com_github_hanwen_go_fuse_v2/notify-testability.diff",
"//:patches/com_github_hanwen_go_fuse_v2/writeback-cache.diff",
],
sum = "h1:t5ivNIH2PK+zw4OBul/iJjsoG9K6kXo4nMDoBpciC8A=",
version = "v2.3.0",
Expand Down
32 changes: 32 additions & 0 deletions patches/com_github_hanwen_go_fuse_v2/writeback-cache.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git fuse/api.go fuse/api.go
index a0ec84f..5b7a8ab 100644
--- fuse/api.go
+++ fuse/api.go
@@ -249,6 +249,13 @@ type MountOptions struct {
// for more details.
SyncRead bool

+ // Let the kernel use the writeback cache mode, as opposed to
+ // write-through mode.
+ //
+ // See the following page for more details:
+ // https://www.kernel.org/doc/Documentation/filesystems/fuse-io.txt
+ EnableWritebackCache bool
+
// If set, fuse will first attempt to use syscall.Mount instead of
// fusermount to mount the filesystem. This will not update /etc/mtab
// but might be needed if fusermount is not available.
diff --git fuse/opcode.go fuse/opcode.go
index 7b72cb6..e1ff6f2 100644
--- fuse/opcode.go
+++ fuse/opcode.go
@@ -115,6 +115,9 @@ func doInit(server *Server, req *request) {
// Clear CAP_READDIRPLUS
server.kernelSettings.Flags &= ^uint32(CAP_READDIRPLUS)
}
+ if server.opts.EnableWritebackCache {
+ server.kernelSettings.Flags |= CAP_WRITEBACK_CACHE
+ }

dataCacheMode := input.Flags & CAP_AUTO_INVAL_DATA
if server.opts.ExplicitDataCacheControl {
5 changes: 5 additions & 0 deletions pkg/filesystem/virtual/configuration/fuse_mount_enabled.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func (m *fuseMount) Expose(terminationGroup program.Group, rootDirectory virtual
FsName: m.fsName,
AllowOther: m.configuration.AllowOther,
DirectMount: m.configuration.DirectMount,
// Speed up workloads that perform many tiny
// writes. This means data is only guaranteed to
// make it into the virtual file system after
// calling close()/fsync()/munmap()/msync().
EnableWritebackCache: true,
})
if err != nil {
return util.StatusWrap(err, "Failed to create FUSE server")
Expand Down

0 comments on commit a8ab442

Please sign in to comment.