mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Return non-zero size for tmpfs statfs(2).
This does not implement accepting or enforcing any size limit, which will be more complex and has performance implications; it just returns a fixed non-zero size. Updates #1936 PiperOrigin-RevId: 328428588
This commit is contained in:
+6
-5
@@ -44,17 +44,18 @@ type Statfs struct {
|
||||
// Type is one of the filesystem magic values, defined above.
|
||||
Type uint64
|
||||
|
||||
// BlockSize is the data block size.
|
||||
// BlockSize is the optimal transfer block size in bytes.
|
||||
BlockSize int64
|
||||
|
||||
// Blocks is the number of data blocks in use.
|
||||
// Blocks is the maximum number of data blocks the filesystem may store, in
|
||||
// units of BlockSize.
|
||||
Blocks uint64
|
||||
|
||||
// BlocksFree is the number of free blocks.
|
||||
// BlocksFree is the number of free data blocks, in units of BlockSize.
|
||||
BlocksFree uint64
|
||||
|
||||
// BlocksAvailable is the number of blocks free for use by
|
||||
// unprivileged users.
|
||||
// BlocksAvailable is the number of data blocks free for use by
|
||||
// unprivileged users, in units of BlockSize.
|
||||
BlocksAvailable uint64
|
||||
|
||||
// Files is the number of used file nodes on the filesystem.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package tmpfs
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
@@ -32,9 +34,15 @@ import (
|
||||
var fsInfo = fs.Info{
|
||||
Type: linux.TMPFS_MAGIC,
|
||||
|
||||
// tmpfs currently does not support configurable size limits. In Linux,
|
||||
// such a tmpfs mount will return f_blocks == f_bfree == f_bavail == 0 from
|
||||
// statfs(2). However, many applications treat this as having a size limit
|
||||
// of 0. To work around this, claim to have a very large but non-zero size,
|
||||
// chosen to ensure that BlockSize * Blocks does not overflow int64 (which
|
||||
// applications may also handle incorrectly).
|
||||
// TODO(b/29637826): allow configuring a tmpfs size and enforce it.
|
||||
TotalBlocks: 0,
|
||||
FreeBlocks: 0,
|
||||
TotalBlocks: math.MaxInt64 / usermem.PageSize,
|
||||
FreeBlocks: math.MaxInt64 / usermem.PageSize,
|
||||
}
|
||||
|
||||
// rename implements fs.InodeOperations.Rename for tmpfs nodes.
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
)
|
||||
|
||||
// Sync implements vfs.FilesystemImpl.Sync.
|
||||
@@ -706,16 +705,7 @@ func (fs *filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linu
|
||||
if _, err := resolveLocked(ctx, rp); err != nil {
|
||||
return linux.Statfs{}, err
|
||||
}
|
||||
statfs := linux.Statfs{
|
||||
Type: linux.TMPFS_MAGIC,
|
||||
BlockSize: usermem.PageSize,
|
||||
FragmentSize: usermem.PageSize,
|
||||
NameLength: linux.NAME_MAX,
|
||||
// TODO(b/29637826): Allow configuring a tmpfs size and enforce it.
|
||||
Blocks: 0,
|
||||
BlocksFree: 0,
|
||||
}
|
||||
return statfs, nil
|
||||
return globalStatfs, nil
|
||||
}
|
||||
|
||||
// SymlinkAt implements vfs.FilesystemImpl.SymlinkAt.
|
||||
|
||||
@@ -201,6 +201,25 @@ func (fs *filesystem) Release(ctx context.Context) {
|
||||
fs.vfsfs.VirtualFilesystem().PutAnonBlockDevMinor(fs.devMinor)
|
||||
}
|
||||
|
||||
// immutable
|
||||
var globalStatfs = linux.Statfs{
|
||||
Type: linux.TMPFS_MAGIC,
|
||||
BlockSize: usermem.PageSize,
|
||||
FragmentSize: usermem.PageSize,
|
||||
NameLength: linux.NAME_MAX,
|
||||
|
||||
// tmpfs currently does not support configurable size limits. In Linux,
|
||||
// such a tmpfs mount will return f_blocks == f_bfree == f_bavail == 0 from
|
||||
// statfs(2). However, many applications treat this as having a size limit
|
||||
// of 0. To work around this, claim to have a very large but non-zero size,
|
||||
// chosen to ensure that BlockSize * Blocks does not overflow int64 (which
|
||||
// applications may also handle incorrectly).
|
||||
// TODO(b/29637826): allow configuring a tmpfs size and enforce it.
|
||||
Blocks: math.MaxInt64 / usermem.PageSize,
|
||||
BlocksFree: math.MaxInt64 / usermem.PageSize,
|
||||
BlocksAvailable: math.MaxInt64 / usermem.PageSize,
|
||||
}
|
||||
|
||||
// dentry implements vfs.DentryImpl.
|
||||
type dentry struct {
|
||||
vfsd vfs.Dentry
|
||||
@@ -698,6 +717,11 @@ func (fd *fileDescription) SetStat(ctx context.Context, opts vfs.SetStatOptions)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StatFS implements vfs.FileDescriptionImpl.StatFS.
|
||||
func (fd *fileDescription) StatFS(ctx context.Context) (linux.Statfs, error) {
|
||||
return globalStatfs, nil
|
||||
}
|
||||
|
||||
// Listxattr implements vfs.FileDescriptionImpl.Listxattr.
|
||||
func (fd *fileDescription) Listxattr(ctx context.Context, size uint64) ([]string, error) {
|
||||
return fd.inode().listxattr(size)
|
||||
|
||||
Reference in New Issue
Block a user