Skip to content

Commit a8ab442

Browse files
committed
FUSE: Use the writeback cache mode
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.
1 parent 5f90704 commit a8ab442

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

go_dependencies.bzl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,8 +504,9 @@ def go_dependencies():
504504
name = "com_github_hanwen_go_fuse_v2",
505505
importpath = "github.com/hanwen/go-fuse/v2",
506506
patches = [
507-
"@com_github_buildbarn_bb_remote_execution//:patches/com_github_hanwen_go_fuse_v2/direntrylist-offsets-and-testability.diff",
508-
"@com_github_buildbarn_bb_remote_execution//:patches/com_github_hanwen_go_fuse_v2/notify-testability.diff",
507+
"//:patches/com_github_hanwen_go_fuse_v2/direntrylist-offsets-and-testability.diff",
508+
"//:patches/com_github_hanwen_go_fuse_v2/notify-testability.diff",
509+
"//:patches/com_github_hanwen_go_fuse_v2/writeback-cache.diff",
509510
],
510511
sum = "h1:t5ivNIH2PK+zw4OBul/iJjsoG9K6kXo4nMDoBpciC8A=",
511512
version = "v2.3.0",
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
diff --git fuse/api.go fuse/api.go
2+
index a0ec84f..5b7a8ab 100644
3+
--- fuse/api.go
4+
+++ fuse/api.go
5+
@@ -249,6 +249,13 @@ type MountOptions struct {
6+
// for more details.
7+
SyncRead bool
8+
9+
+ // Let the kernel use the writeback cache mode, as opposed to
10+
+ // write-through mode.
11+
+ //
12+
+ // See the following page for more details:
13+
+ // https://www.kernel.org/doc/Documentation/filesystems/fuse-io.txt
14+
+ EnableWritebackCache bool
15+
+
16+
// If set, fuse will first attempt to use syscall.Mount instead of
17+
// fusermount to mount the filesystem. This will not update /etc/mtab
18+
// but might be needed if fusermount is not available.
19+
diff --git fuse/opcode.go fuse/opcode.go
20+
index 7b72cb6..e1ff6f2 100644
21+
--- fuse/opcode.go
22+
+++ fuse/opcode.go
23+
@@ -115,6 +115,9 @@ func doInit(server *Server, req *request) {
24+
// Clear CAP_READDIRPLUS
25+
server.kernelSettings.Flags &= ^uint32(CAP_READDIRPLUS)
26+
}
27+
+ if server.opts.EnableWritebackCache {
28+
+ server.kernelSettings.Flags |= CAP_WRITEBACK_CACHE
29+
+ }
30+
31+
dataCacheMode := input.Flags & CAP_AUTO_INVAL_DATA
32+
if server.opts.ExplicitDataCacheControl {

pkg/filesystem/virtual/configuration/fuse_mount_enabled.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ func (m *fuseMount) Expose(terminationGroup program.Group, rootDirectory virtual
7272
FsName: m.fsName,
7373
AllowOther: m.configuration.AllowOther,
7474
DirectMount: m.configuration.DirectMount,
75+
// Speed up workloads that perform many tiny
76+
// writes. This means data is only guaranteed to
77+
// make it into the virtual file system after
78+
// calling close()/fsync()/munmap()/msync().
79+
EnableWritebackCache: true,
7580
})
7681
if err != nil {
7782
return util.StatusWrap(err, "Failed to create FUSE server")

0 commit comments

Comments
 (0)