diff options
author | Zyad A. Ali <zyad.ali.me@gmail.com> | 2021-07-19 18:24:58 +0200 |
---|---|---|
committer | Zyad A. Ali <zyad.ali.me@gmail.com> | 2021-09-15 21:56:35 +0200 |
commit | fc5469af61148365c8c2baeb54f6664095ef6fd0 (patch) | |
tree | 2131451cb6de70b4a80793788f8a88d6e7e5526f /pkg/sentry/fsimpl/mqfs | |
parent | 61cbf77873ad5095f1a5f4726f486c883cf7e7dc (diff) |
Implement vfs.FilesystemType and kernfs.Filesystem for mqfs.
Updates #136
Diffstat (limited to 'pkg/sentry/fsimpl/mqfs')
-rw-r--r-- | pkg/sentry/fsimpl/mqfs/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/mqfs/mqfs.go | 107 |
2 files changed, 108 insertions, 0 deletions
diff --git a/pkg/sentry/fsimpl/mqfs/BUILD b/pkg/sentry/fsimpl/mqfs/BUILD index 8a5925396..afe1f3cd5 100644 --- a/pkg/sentry/fsimpl/mqfs/BUILD +++ b/pkg/sentry/fsimpl/mqfs/BUILD @@ -17,6 +17,7 @@ go_template_instance( go_library( name = "mqfs", srcs = [ + "mqfs.go", "inodes.go", "root_inode_refs.go", ], diff --git a/pkg/sentry/fsimpl/mqfs/mqfs.go b/pkg/sentry/fsimpl/mqfs/mqfs.go new file mode 100644 index 000000000..18bc66134 --- /dev/null +++ b/pkg/sentry/fsimpl/mqfs/mqfs.go @@ -0,0 +1,107 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package mqfs provides a filesystem implementation to back POSIX message +// queues. +package mqfs + +import ( + "fmt" + "strconv" + + "gvisor.dev/gvisor/pkg/context" + "gvisor.dev/gvisor/pkg/errors/linuxerr" + "gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs" + "gvisor.dev/gvisor/pkg/sentry/kernel/auth" + "gvisor.dev/gvisor/pkg/sentry/vfs" +) + +const ( + fsName = "mqueue" + defaultMaxCachedDentries = uint64(1000) +) + +// FilesystemType implements vfs.FilesystemType. +// +// +stateify savable +type FilesystemType struct{} + +// Name implements vfs.FilesystemType.Name. +func (FilesystemType) Name() string { + return fsName +} + +// Release implements vfs.FilesystemType.Release. +func (FilesystemType) Release(ctx context.Context) {} + +// GetFilesystem implements vfs.FilesystemType.GetFilesystem. +func (ft FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) { + devMinor, err := vfsObj.GetAnonBlockDevMinor() + if err != nil { + return nil, nil, err + } + + maxCachedDentries, err := maxCachedDentries(ctx, vfs.GenericParseMountOptions(opts.Data)) + if err != nil { + return nil, nil, err + } + + fs := &filesystem{ + devMinor: devMinor, + Filesystem: kernfs.Filesystem{ + MaxCachedDentries: maxCachedDentries, + }, + } + fs.VFSFilesystem().Init(vfsObj, &ft, fs) + + var dentry kernfs.Dentry + dentry.InitRoot(&fs.Filesystem, fs.newRootInode(ctx, creds)) + + return fs.VFSFilesystem(), dentry.VFSDentry(), nil +} + +// maxCachedDentries checks mopts for dentry_cache_limit. If a value is +// specified, parse it into uint64 and return it. Otherwise, return the default +// value. An error is returned if a value is found but can't be parsed. +func maxCachedDentries(ctx context.Context, mopts map[string]string) (_ uint64, err error) { + max := defaultMaxCachedDentries + if str, ok := mopts["dentry_cache_limit"]; ok { + delete(mopts, "dentry_cache_limit") + max, err = strconv.ParseUint(str, 10, 64) + if err != nil { + ctx.Warningf("mqfs.FilesystemType.GetFilesystem: invalid dentry cache limit: dentry_cache_limit=%s", str) + return 0, linuxerr.EINVAL + } + } + return max, nil +} + +// filesystem implements kernfs.Filesystem. +// +// +stateify savable +type filesystem struct { + kernfs.Filesystem + devMinor uint32 +} + +// Release implements vfs.FilesystemImpl.Release. +func (fs *filesystem) Release(ctx context.Context) { + fs.Filesystem.VFSFilesystem().VirtualFilesystem().PutAnonBlockDevMinor(fs.devMinor) + fs.Filesystem.Release(ctx) +} + +// MountOptions implements vfs.FilesystemImpl.MountOptions. +func (fs *filesystem) MountOptions() string { + return fmt.Sprintf("dentry_cache_limit=%d", fs.MaxCachedDentries) +} |