Skip to content

Commit 1ab97fb

Browse files
kahingjacobsa
authored andcommitted
handle forget inline instead of in goroutine
when we are under memory pressure, or echo 3 > /proc/sys/vm/drop_caches, kernel can send us many forget ops at the same time if we have lots of inodes in memory. Running them all in goroutines can lead to even more memory usage and eventually OOM.
1 parent fe7f3a5 commit 1ab97fb

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

fuseutil/file_system.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ type FileSystem interface {
7272
// method.Respond with the resulting error. Unsupported ops are responded to
7373
// directly with ENOSYS.
7474
//
75-
// Each call to a FileSystem method is made on its own goroutine, and is free
76-
// to block.
75+
// Each call to a FileSystem method (except ForgetInode) is made on
76+
// its own goroutine, and is free to block. ForgetInode may be called
77+
// synchronously, and should not depend on calls to other methods
78+
// being received concurrently.
7779
//
7880
// (It is safe to naively process ops concurrently because the kernel
7981
// guarantees to serialize operations that the user expects to happen in order,
@@ -109,7 +111,15 @@ func (s *fileSystemServer) ServeOps(c *fuse.Connection) {
109111
}
110112

111113
s.opsInFlight.Add(1)
112-
go s.handleOp(c, ctx, op)
114+
if _, ok := op.(*fuseops.ForgetInodeOp); ok {
115+
// Special case: call in this goroutine for
116+
// forget inode ops, which may come in a
117+
// flurry from the kernel and are generally
118+
// cheap for the file system to handle
119+
s.handleOp(c, ctx, op)
120+
} else {
121+
go s.handleOp(c, ctx, op)
122+
}
113123
}
114124
}
115125

0 commit comments

Comments
 (0)