Add FilesystemType.Name method, and FilesystemType field to Filesystem struct.

Both have analogues in Linux:
* struct file_system_type has a char *name field.
* struct super_block keeps a pointer to the file_system_type.

These fields are necessary to support the `filesystem type` field in
/proc/[pid]/mountinfo.

PiperOrigin-RevId: 303434063
This commit is contained in:
Nicolas Lacasse 2020-03-27 16:53:28 -07:00 committed by gVisor bot
parent 2a4aff7f7e
commit 10f2c8db91
13 changed files with 91 additions and 19 deletions

View File

@ -42,6 +42,11 @@ type FilesystemType struct {
root *vfs.Dentry
}
// Name implements vfs.FilesystemType.Name.
func (*FilesystemType) Name() string {
return Name
}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (fst *FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
fst.initOnce.Do(func() {

View File

@ -30,6 +30,9 @@ import (
"gvisor.dev/gvisor/pkg/syserror"
)
// Name is the name of this filesystem.
const Name = "ext"
// FilesystemType implements vfs.FilesystemType.
type FilesystemType struct{}
@ -91,8 +94,13 @@ func isCompatible(sb disklayout.SuperBlock) bool {
return true
}
// Name implements vfs.FilesystemType.Name.
func (FilesystemType) Name() string {
return Name
}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
func (fsType FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
// TODO(b/134676337): Ensure that the user is mounting readonly. If not,
// EACCESS should be returned according to mount(2). Filesystem independent
// flags (like readonly) are currently not available in pkg/sentry/vfs.
@ -103,7 +111,7 @@ func (FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFile
}
fs := filesystem{dev: dev, inodeCache: make(map[uint32]*inode)}
fs.vfsfs.Init(vfsObj, &fs)
fs.vfsfs.Init(vfsObj, &fsType, &fs)
fs.sb, err = readSuperBlock(dev)
if err != nil {
return nil, nil, err

View File

@ -199,6 +199,11 @@ const (
InteropModeShared
)
// Name implements vfs.FilesystemType.Name.
func (FilesystemType) Name() string {
return Name
}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
@ -374,7 +379,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
dentries: make(map[*dentry]struct{}),
specialFileFDs: make(map[*specialFileFD]struct{}),
}
fs.vfsfs.Init(vfsObj, fs)
fs.vfsfs.Init(vfsObj, &fstype, fs)
// Construct the root dentry.
root, err := fs.newDentry(ctx, attachFile, qid, attrMask, &attr)

View File

@ -38,6 +38,19 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
// filesystemType implements vfs.FilesystemType.
type filesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (filesystemType) GetFilesystem(context.Context, *vfs.VirtualFilesystem, *auth.Credentials, string, vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
panic("cannot instaniate a host filesystem")
}
// Name implements FilesystemType.Name.
func (filesystemType) Name() string {
return "none"
}
// filesystem implements vfs.FilesystemImpl.
type filesystem struct {
kernfs.Filesystem
@ -46,7 +59,7 @@ type filesystem struct {
// NewMount returns a new disconnected mount in vfsObj that may be passed to ImportFD.
func NewMount(vfsObj *vfs.VirtualFilesystem) (*vfs.Mount, error) {
fs := &filesystem{}
fs.Init(vfsObj)
fs.Init(vfsObj, &filesystemType{})
vfsfs := fs.VFSFilesystem()
// NewDisconnectedMount will take an additional reference on vfsfs.
defer vfsfs.DecRef()

View File

@ -63,9 +63,6 @@ import (
"gvisor.dev/gvisor/pkg/sync"
)
// FilesystemType implements vfs.FilesystemType.
type FilesystemType struct{}
// Filesystem mostly implements vfs.FilesystemImpl for a generic in-memory
// filesystem. Concrete implementations are expected to embed this in their own
// Filesystem type.
@ -138,8 +135,8 @@ func (fs *Filesystem) processDeferredDecRefsLocked() {
// Init initializes a kernfs filesystem. This should be called from during
// vfs.FilesystemType.NewFilesystem for the concrete filesystem embedding
// kernfs.
func (fs *Filesystem) Init(vfsObj *vfs.VirtualFilesystem) {
fs.vfsfs.Init(vfsObj, fs)
func (fs *Filesystem) Init(vfsObj *vfs.VirtualFilesystem, fsType vfs.FilesystemType) {
fs.vfsfs.Init(vfsObj, fsType, fs)
}
// VFSFilesystem returns the generic vfs filesystem object.

View File

@ -187,9 +187,13 @@ func (*dir) NewNode(context.Context, string, vfs.MknodOptions) (*vfs.Dentry, err
return nil, syserror.EPERM
}
func (fst *fsType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opt vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
func (fsType) Name() string {
return "kernfs"
}
func (fst fsType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opt vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
fs := &filesystem{}
fs.Init(vfsObj)
fs.Init(vfsObj, &fst)
root := fst.rootFn(creds, fs)
return fs.VFSFilesystem(), root.VFSDentry(), nil
}

View File

@ -36,8 +36,13 @@ type FilesystemType struct{}
var _ vfs.FilesystemType = (*FilesystemType)(nil)
// GetFilesystem implements vfs.FilesystemType.
func (ft *FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
// Name implements vfs.FilesystemType.Name.
func (FilesystemType) Name() string {
return Name
}
// 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) {
k := kernel.KernelFromContext(ctx)
if k == nil {
return nil, nil, fmt.Errorf("procfs requires a kernel")
@ -48,7 +53,7 @@ func (ft *FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virtual
}
procfs := &kernfs.Filesystem{}
procfs.VFSFilesystem().Init(vfsObj, procfs)
procfs.VFSFilesystem().Init(vfsObj, &ft, procfs)
var cgroups map[string]string
if opts.InternalData != nil {

View File

@ -39,10 +39,15 @@ type filesystem struct {
kernfs.Filesystem
}
// Name implements vfs.FilesystemType.Name.
func (FilesystemType) Name() string {
return Name
}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
func (fsType FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
fs := &filesystem{}
fs.Filesystem.Init(vfsObj)
fs.Filesystem.Init(vfsObj, &fsType)
k := kernel.KernelFromContext(ctx)
maxCPUCores := k.ApplicationCores()
defaultSysDirMode := linux.FileMode(0755)

View File

@ -63,6 +63,11 @@ type filesystem struct {
nextInoMinusOne uint64 // accessed using atomic memory operations
}
// Name implements vfs.FilesystemType.Name.
func (FilesystemType) Name() string {
return Name
}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
memFileProvider := pgalloc.MemoryFileProviderFromContext(ctx)
@ -74,7 +79,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
memFile: memFileProvider.MemoryFile(),
clock: clock,
}
fs.vfsfs.Init(vfsObj, &fs)
fs.vfsfs.Init(vfsObj, &fstype, &fs)
root := fs.newDentry(fs.newDirectory(creds, 01777))
return &fs.vfsfs, &root.vfsd, nil
}

View File

@ -51,6 +51,19 @@ const (
anonFileGID = auth.RootKGID
)
// anonFilesystemType implements FilesystemType.
type anonFilesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (anonFilesystemType) GetFilesystem(context.Context, *VirtualFilesystem, *auth.Credentials, string, GetFilesystemOptions) (*Filesystem, *Dentry, error) {
panic("cannot instaniate an anon filesystem")
}
// Name implemenents FilesystemType.Name.
func (anonFilesystemType) Name() string {
return "none"
}
// anonFilesystem is the implementation of FilesystemImpl that backs
// VirtualDentries returned by VirtualFilesystem.NewAnonVirtualDentry().
//

View File

@ -42,21 +42,30 @@ type Filesystem struct {
// immutable.
vfs *VirtualFilesystem
// fsType is the FilesystemType of this Filesystem.
fsType FilesystemType
// impl is the FilesystemImpl associated with this Filesystem. impl is
// immutable. This should be the last field in Dentry.
impl FilesystemImpl
}
// Init must be called before first use of fs.
func (fs *Filesystem) Init(vfsObj *VirtualFilesystem, impl FilesystemImpl) {
func (fs *Filesystem) Init(vfsObj *VirtualFilesystem, fsType FilesystemType, impl FilesystemImpl) {
fs.refs = 1
fs.vfs = vfsObj
fs.fsType = fsType
fs.impl = impl
vfsObj.filesystemsMu.Lock()
vfsObj.filesystems[fs] = struct{}{}
vfsObj.filesystemsMu.Unlock()
}
// FilesystemType returns the FilesystemType for this Filesystem.
func (fs *Filesystem) FilesystemType() FilesystemType {
return fs.fsType
}
// VirtualFilesystem returns the containing VirtualFilesystem.
func (fs *Filesystem) VirtualFilesystem() *VirtualFilesystem {
return fs.vfs

View File

@ -30,6 +30,9 @@ type FilesystemType interface {
// along with its mount root. A reference is taken on the returned
// Filesystem and Dentry.
GetFilesystem(ctx context.Context, vfsObj *VirtualFilesystem, creds *auth.Credentials, source string, opts GetFilesystemOptions) (*Filesystem, *Dentry, error)
// Name returns the name of this FilesystemType.
Name() string
}
// GetFilesystemOptions contains options to FilesystemType.GetFilesystem.

View File

@ -134,7 +134,7 @@ func (vfs *VirtualFilesystem) Init() error {
anonfs := anonFilesystem{
devMinor: anonfsDevMinor,
}
anonfs.vfsfs.Init(vfs, &anonfs)
anonfs.vfsfs.Init(vfs, &anonFilesystemType{}, &anonfs)
defer anonfs.vfsfs.DecRef()
anonMount, err := vfs.NewDisconnectedMount(&anonfs.vfsfs, nil, &MountOptions{})
if err != nil {