Implement StatFS for various VFS2 filesystems.

This mainly involved enabling kernfs' client filesystems to provide a
StatFS implementation.

Fixes #3411, #3515.

PiperOrigin-RevId: 329009864
This commit is contained in:
Rahat Mahmood
2020-08-28 14:31:11 -07:00
committed by gVisor bot
parent bdd5996a73
commit b4820e5986
29 changed files with 184 additions and 48 deletions
+1
View File
@@ -29,6 +29,7 @@ const (
SYSFS_MAGIC = 0x62656572
TMPFS_MAGIC = 0x01021994
V9FS_MAGIC = 0x01021997
FUSE_SUPER_MAGIC = 0x65735546
)
// Filesystem path limits, from uapi/linux/limits.h.
+9 -1
View File
@@ -111,12 +111,13 @@ func (fs *filesystem) Release(ctx context.Context) {
// rootInode is the root directory inode for the devpts mounts.
type rootInode struct {
rootInodeRefs
implStatFS
kernfs.AlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
kernfs.OrderedChildren
rootInodeRefs
locks vfs.FileLocks
@@ -240,3 +241,10 @@ func (i *rootInode) IterDirents(ctx context.Context, cb vfs.IterDirentsCallback,
func (i *rootInode) DecRef(context.Context) {
i.rootInodeRefs.DecRef(i.Destroy)
}
type implStatFS struct{}
// StatFS implements kernfs.Inode.StatFS.
func (*implStatFS) StatFS(context.Context, *vfs.Filesystem) (linux.Statfs, error) {
return vfs.GenericStatFS(linux.DEVPTS_SUPER_MAGIC), nil
}
+1
View File
@@ -30,6 +30,7 @@ import (
// masterInode is the inode for the master end of the Terminal.
type masterInode struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeNotDirectory
+1
View File
@@ -29,6 +29,7 @@ import (
// slaveInode is the inode for the slave end of the Terminal.
type slaveInode struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeNotDirectory
+7 -1
View File
@@ -200,9 +200,9 @@ func (fs *filesystem) Release(ctx context.Context) {
type inode struct {
inodeRefs
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNoDynamicLookup
kernfs.InodeNotSymlink
kernfs.InodeDirectoryNoNewChildren
kernfs.OrderedChildren
locks vfs.FileLocks
@@ -331,3 +331,9 @@ func (i *inode) Stat(ctx context.Context, fs *vfs.Filesystem, opts vfs.StatOptio
func (i *inode) DecRef(context.Context) {
i.inodeRefs.DecRef(i.Destroy)
}
// StatFS implements kernfs.Inode.StatFS.
func (i *inode) StatFS(ctx context.Context, fs *vfs.Filesystem) (linux.Statfs, error) {
// TODO(gvisor.dev/issues/3413): Complete the implementation of statfs.
return vfs.GenericStatFS(linux.FUSE_SUPER_MAGIC), nil
}
+1
View File
@@ -186,6 +186,7 @@ func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDe
// inode implements kernfs.Inode.
type inode struct {
kernfs.InodeNoStatFS
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
@@ -35,6 +35,7 @@ import (
// +stateify savable
type DynamicBytesFile struct {
InodeAttrs
InodeNoStatFS
InodeNoopRefCount
InodeNotDirectory
InodeNotSymlink
+2 -3
View File
@@ -721,14 +721,13 @@ func (fs *Filesystem) StatAt(ctx context.Context, rp *vfs.ResolvingPath, opts vf
// StatFSAt implements vfs.FilesystemImpl.StatFSAt.
func (fs *Filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linux.Statfs, error) {
fs.mu.RLock()
_, _, err := fs.walkExistingLocked(ctx, rp)
_, inode, err := fs.walkExistingLocked(ctx, rp)
fs.mu.RUnlock()
fs.processDeferredDecRefs(ctx)
if err != nil {
return linux.Statfs{}, err
}
// TODO(gvisor.dev/issue/1193): actually implement statfs.
return linux.Statfs{}, syserror.ENOSYS
return inode.StatFS(ctx, fs.VFSFilesystem())
}
// SymlinkAt implements vfs.FilesystemImpl.SymlinkAt.
+13 -3
View File
@@ -546,12 +546,13 @@ func (InodeSymlink) Open(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.D
//
// +stateify savable
type StaticDirectory struct {
StaticDirectoryRefs
InodeNotSymlink
InodeDirectoryNoNewChildren
InodeAttrs
InodeDirectoryNoNewChildren
InodeNoDynamicLookup
InodeNoStatFS
InodeNotSymlink
OrderedChildren
StaticDirectoryRefs
locks vfs.FileLocks
fdOpts GenericDirectoryFDOptions
@@ -609,3 +610,12 @@ type AlwaysValid struct{}
func (*AlwaysValid) Valid(context.Context) bool {
return true
}
// InodeNoStatFS partially implements the Inode interface, where the client
// filesystem doesn't support statfs(2).
type InodeNoStatFS struct{}
// StatFS implements Inode.StatFS.
func (*InodeNoStatFS) StatFS(context.Context, *vfs.Filesystem) (linux.Statfs, error) {
return linux.Statfs{}, syserror.ENOSYS
}
+5
View File
@@ -320,6 +320,11 @@ type Inode interface {
// Precondition: rp.Done(). vfsd.Impl() must be the kernfs Dentry containing
// the inode on which Open() is being called.
Open(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error)
// StatFS returns filesystem statistics for the client filesystem. This
// corresponds to vfs.FilesystemImpl.StatFSAt. If the client filesystem
// doesn't support statfs(2), this should return ENOSYS.
StatFS(ctx context.Context, fs *vfs.Filesystem) (linux.Statfs, error)
}
type inodeRefs interface {
+5 -3
View File
@@ -98,9 +98,10 @@ func (*attrs) SetStat(context.Context, *vfs.Filesystem, *auth.Credentials, vfs.S
type readonlyDir struct {
readonlyDirRefs
attrs
kernfs.InodeNotSymlink
kernfs.InodeNoDynamicLookup
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNoDynamicLookup
kernfs.InodeNoStatFS
kernfs.InodeNotSymlink
kernfs.OrderedChildren
locks vfs.FileLocks
@@ -137,9 +138,10 @@ func (d *readonlyDir) DecRef(context.Context) {
type dir struct {
dirRefs
attrs
kernfs.InodeNotSymlink
kernfs.InodeNoDynamicLookup
kernfs.InodeNotSymlink
kernfs.OrderedChildren
kernfs.InodeNoStatFS
locks vfs.FileLocks
+1
View File
@@ -28,6 +28,7 @@ type StaticSymlink struct {
InodeAttrs
InodeNoopRefCount
InodeSymlink
InodeNoStatFS
target string
}
+5 -3
View File
@@ -143,14 +143,16 @@ func (i *inode) SetStat(ctx context.Context, vfsfs *vfs.Filesystem, creds *auth.
return syserror.EPERM
}
// TODO(gvisor.dev/issue/1193): kernfs does not provide a way to implement
// statfs, from which we should indicate PIPEFS_MAGIC.
// Open implements kernfs.Inode.Open.
func (i *inode) Open(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
return i.pipe.Open(ctx, rp.Mount(), vfsd, opts.Flags, &i.locks)
}
// StatFS implements kernfs.Inode.StatFS.
func (i *inode) StatFS(ctx context.Context, fs *vfs.Filesystem) (linux.Statfs, error) {
return vfs.GenericStatFS(linux.PIPEFS_MAGIC), nil
}
// NewConnectedPipeFDs returns a pair of FileDescriptions representing the read
// and write ends of a newly-created pipe, as for pipe(2) and pipe2(2).
//
+7
View File
@@ -121,3 +121,10 @@ func newStaticDir(creds *auth.Credentials, devMajor, devMinor uint32, ino uint64
type InternalData struct {
Cgroups map[string]string
}
type implStatFS struct{}
// StatFS implements kernfs.Inode.StatFS.
func (*implStatFS) StatFS(context.Context, *vfs.Filesystem) (linux.Statfs, error) {
return vfs.GenericStatFS(linux.PROC_SUPER_MAGIC), nil
}
+6 -5
View File
@@ -31,12 +31,13 @@ import (
//
// +stateify savable
type subtasksInode struct {
subtasksInodeRefs
kernfs.InodeNotSymlink
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeAttrs
kernfs.OrderedChildren
implStatFS
kernfs.AlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
kernfs.OrderedChildren
subtasksInodeRefs
locks vfs.FileLocks
+4 -3
View File
@@ -32,12 +32,13 @@ import (
//
// +stateify savable
type taskInode struct {
taskInodeRefs
kernfs.InodeNotSymlink
implStatFS
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNoDynamicLookup
kernfs.InodeAttrs
kernfs.InodeNotSymlink
kernfs.OrderedChildren
taskInodeRefs
locks vfs.FileLocks
+15 -12
View File
@@ -100,13 +100,14 @@ func (i *fdDir) IterDirents(ctx context.Context, cb vfs.IterDirentsCallback, off
//
// +stateify savable
type fdDirInode struct {
fdDirInodeRefs
kernfs.InodeNotSymlink
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeAttrs
kernfs.OrderedChildren
kernfs.AlwaysValid
fdDir
fdDirInodeRefs
implStatFS
kernfs.AlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
kernfs.OrderedChildren
}
var _ kernfs.Inode = (*fdDirInode)(nil)
@@ -185,6 +186,7 @@ func (i *fdDirInode) DecRef(context.Context) {
//
// +stateify savable
type fdSymlink struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
@@ -233,13 +235,14 @@ func (s *fdSymlink) Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.VirtualDen
//
// +stateify savable
type fdInfoDirInode struct {
fdInfoDirInodeRefs
kernfs.InodeNotSymlink
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeAttrs
kernfs.OrderedChildren
kernfs.AlwaysValid
fdDir
fdInfoDirInodeRefs
implStatFS
kernfs.AlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
kernfs.OrderedChildren
}
var _ kernfs.Inode = (*fdInfoDirInode)(nil)
+2
View File
@@ -648,6 +648,7 @@ func (o *oomScoreAdj) Write(ctx context.Context, src usermem.IOSequence, offset
//
// +stateify savable
type exeSymlink struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
@@ -832,6 +833,7 @@ func (s *namespaceSymlink) Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.Vir
// namespaceInode is a synthetic inode created to represent a namespace in
// /proc/[pid]/ns/*.
type namespaceInode struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeNotDirectory
+6 -5
View File
@@ -37,12 +37,13 @@ const (
//
// +stateify savable
type tasksInode struct {
tasksInodeRefs
kernfs.InodeNotSymlink
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeAttrs
kernfs.OrderedChildren
implStatFS
kernfs.AlwaysValid
kernfs.InodeAttrs
kernfs.InodeDirectoryNoNewChildren
kernfs.InodeNotSymlink
kernfs.OrderedChildren
tasksInodeRefs
locks vfs.FileLocks
+2
View File
@@ -32,6 +32,7 @@ import (
)
type selfSymlink struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
@@ -74,6 +75,7 @@ func (*selfSymlink) SetStat(context.Context, *vfs.Filesystem, *auth.Credentials,
}
type threadSelfSymlink struct {
implStatFS
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
kernfs.InodeSymlink

Some files were not shown because too many files have changed in this diff Show More