Add support for per mount dcache option.

This allows for more fine-grained dcache setting on a per gofer mount basis.
Note that the global `--dcache` flag still takes precedence if set.

Fixes #10218

PiperOrigin-RevId: 623646235
This commit is contained in:
Ayush Ranjan
2024-04-10 17:02:14 -07:00
committed by gVisor bot
parent d514dc4424
commit 4583d9fc47
3 changed files with 31 additions and 6 deletions
+5
View File
@@ -1757,6 +1757,11 @@ func (fs *filesystem) MountOptions() string {
{moptDfltGID, fs.opts.dfltgid},
}
if globalDentryCache != nil {
optsKV = append(optsKV, mopt{moptDcache, fmt.Sprintf("%d-global", globalDentryCache.maxCachedDentries)})
} else {
optsKV = append(optsKV, mopt{moptDcache, fs.opts.dcache})
}
switch fs.opts.interop {
case InteropModeExclusive:
optsKV = append(optsKV, mopt{moptCache, cacheFSCache})
+25 -5
View File
@@ -81,6 +81,7 @@ const (
moptDfltUID = "dfltuid"
moptDfltGID = "dfltgid"
moptCache = "cache"
moptDcache = "dcache"
moptForcePageCache = "force_page_cache"
moptLimitHostFDTranslation = "limit_host_fd_translation"
moptOverlayfsStaleRead = "overlayfs_stale_read"
@@ -99,7 +100,7 @@ const (
)
// SupportedMountOptions is the set of mount options that can be set externally.
var SupportedMountOptions = []string{moptOverlayfsStaleRead, moptDisableFileHandleSharing}
var SupportedMountOptions = []string{moptOverlayfsStaleRead, moptDisableFileHandleSharing, moptDcache}
const (
defaultMaxCachedDentries = 1000
@@ -143,6 +144,9 @@ func (cache *stringFixedCache) add(name string) string {
// +stateify savable
type dentryCache struct {
// maxCachedDentries is the maximum number of cacheable dentries.
// maxCachedDentries is immutable.
maxCachedDentries uint64
// mu protects the below fields.
mu sync.Mutex `state:"nosave"`
// dentries contains all dentries with 0 references. Due to race conditions,
@@ -150,8 +154,6 @@ type dentryCache struct {
dentries dentryList
// dentriesLen is the number of dentries in dentries.
dentriesLen uint64
// maxCachedDentries is the maximum number of cacheable dentries.
maxCachedDentries uint64
}
// SetDentryCacheSize sets the size of the global gofer dentry cache.
@@ -166,7 +168,7 @@ func SetDentryCacheSize(size int) {
globalDentryCache = &dentryCache{maxCachedDentries: uint64(size)}
}
// globalDentryCache is a global cache of dentries across all gofers.
// globalDentryCache is a global cache of dentries across all gofer clients.
var globalDentryCache *dentryCache
// Valid values for "trans" mount option.
@@ -251,6 +253,10 @@ type filesystemOptions struct {
dfltuid auth.KUID
dfltgid auth.KGID
// dcache is the maximum number of dentries that can be cached. This is
// effective only if globalDentryCache is not being used.
dcache uint64
// If forcePageCache is true, host FDs may not be used for application
// memory mappings even if available; instead, the client must perform its
// own caching of regular file pages. This is primarily useful for testing.
@@ -439,6 +445,20 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
}
}
// Parse the dentry cache size.
fsopts.dcache = defaultMaxCachedDentries
if dcacheStr, ok := mopts[moptDcache]; ok {
delete(mopts, moptDcache)
dcache, err := strconv.ParseInt(dcacheStr, 10, 64)
if err != nil {
ctx.Warningf("gofer.FilesystemType.GetFilesystem: invalid dcache: %s=%s", moptDcache, dcacheStr)
return nil, nil, linuxerr.EINVAL
}
if dcache >= 0 {
fsopts.dcache = uint64(dcache)
}
}
// Parse the default UID and GID.
fsopts.dfltuid = _V9FS_DEFUID
if dfltuidstr, ok := mopts[moptDfltUID]; ok {
@@ -534,7 +554,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
if globalDentryCache != nil {
fs.dentryCache = globalDentryCache
} else {
fs.dentryCache = &dentryCache{maxCachedDentries: defaultMaxCachedDentries}
fs.dentryCache = &dentryCache{maxCachedDentries: fsopts.dcache}
}
fs.vfsfs.Init(vfsObj, &fstype, fs)
+1 -1
View File
@@ -292,7 +292,7 @@ type Config struct {
// each.
FDLimit int `flag:"fdlimit"`
// DCache sets the global dirent cache size. If zero, per-mount caches are
// DCache sets the global dirent cache size. If negative, per-mount caches are
// used.
DCache int `flag:"dcache"`