mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
committed by
gVisor bot
parent
bdd5996a73
commit
b4820e5986
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ type StaticSymlink struct {
|
||||
InodeAttrs
|
||||
InodeNoopRefCount
|
||||
InodeSymlink
|
||||
InodeNoStatFS
|
||||
|
||||
target string
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
//
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user