Skip to content

Commit

Permalink
Allow kernel to cache readdir entries to reduce overhead of meta engi…
Browse files Browse the repository at this point in the history
…nes (#5462)

Signed-off-by: Changxin Miao <[email protected]>
  • Loading branch information
polyrabbit authored Dec 31, 2024
1 parent 591e095 commit beaa0d0
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ func metaCacheFlags(defaultEntryCache float64) []cli.Flag {
Value: "1.0s",
Usage: "dir entry cache timeout",
},
&cli.BoolFlag{
Name: "readdir-cache",
Usage: "enable kernel caching of readdir entries, with timeout controlled by attr-cache flag (require linux kernel 4.20+)",
},
&cli.StringFlag{
Name: "open-cache",
Value: "0s",
Expand Down
10 changes: 10 additions & 0 deletions cmd/mount_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,16 @@ func mountMain(v *vfs.VFS, c *cli.Context) {
conf.AttrTimeout = utils.Duration(c.String("attr-cache"))
conf.EntryTimeout = utils.Duration(c.String("entry-cache"))
conf.DirEntryTimeout = utils.Duration(c.String("dir-entry-cache"))
conf.ReaddirCache = c.Bool("readdir-cache")
if conf.ReaddirCache {
if conf.AttrTimeout == 0 {
logger.Warnf("readdir-cache is enabled without attr-cache, it's performance may be affected")
}
major, minor := utils.GetKernelVersion()
if major < 4 || (major == 4 && minor < 20) {
logger.Warnf("readdir-cache requires kernel version 4.20 or higher, current version: %d.%d", major, minor)
}
}
conf.NonDefaultPermission = c.Bool("non-default-permission")
rootSquash := c.String("root-squash")
if rootSquash != "" {
Expand Down
3 changes: 3 additions & 0 deletions pkg/fuse/fuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ func (fs *fileSystem) OpenDir(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse
defer releaseContext(ctx)
fh, err := fs.v.Opendir(ctx, Ino(in.NodeId), in.Flags)
out.Fh = fh
if fs.conf.ReaddirCache {
out.OpenFlags |= fuse.FOPEN_CACHE_DIR | fuse.FOPEN_KEEP_CACHE // both flags are required
}
return fuse.Status(err)
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/vfs/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ type Config struct {
AttrTimeout time.Duration
DirEntryTimeout time.Duration
EntryTimeout time.Duration
ReaddirCache bool
BackupMeta time.Duration
BackupSkipTrash bool
FastResolve bool `json:",omitempty"`
Expand Down Expand Up @@ -422,7 +423,7 @@ func (v *VFS) UpdateLength(inode Ino, attr *meta.Attr) {
}

func (v *VFS) Readdir(ctx Context, ino Ino, size uint32, off int, fh uint64, plus bool) (entries []*meta.Entry, readAt time.Time, err syscall.Errno) {
defer func() { logit(ctx, "readdir", err, "(%d,%d,%d): (%d)", ino, size, off, len(entries)) }()
defer func() { logit(ctx, "readdir", err, "(%d,%d,%d,%t): (%d)", ino, size, off, plus, len(entries)) }()
h := v.findHandle(ino, fh)
if h == nil {
err = syscall.EBADF
Expand Down

0 comments on commit beaa0d0

Please sign in to comment.