Set file mode and type to attribute
Makes less error prone to find file type. Updates #1197 PiperOrigin-RevId: 302974244
This commit is contained in:
parent
2e09f2bdce
commit
c7f5673529
|
@ -15,6 +15,8 @@
|
|||
package tmpfs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
|
@ -33,6 +35,14 @@ func (fs *filesystem) newDeviceFile(creds *auth.Credentials, mode linux.FileMode
|
|||
major: major,
|
||||
minor: minor,
|
||||
}
|
||||
switch kind {
|
||||
case vfs.BlockDevice:
|
||||
mode |= linux.S_IFBLK
|
||||
case vfs.CharDevice:
|
||||
mode |= linux.S_IFCHR
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid DeviceKind: %v", kind))
|
||||
}
|
||||
file.inode.init(file, fs, creds, mode)
|
||||
file.inode.nlink = 1 // from parent directory
|
||||
return &file.inode
|
||||
|
|
|
@ -34,16 +34,11 @@ type directory struct {
|
|||
|
||||
func (fs *filesystem) newDirectory(creds *auth.Credentials, mode linux.FileMode) *inode {
|
||||
dir := &directory{}
|
||||
dir.inode.init(dir, fs, creds, mode)
|
||||
dir.inode.init(dir, fs, creds, linux.S_IFDIR|mode)
|
||||
dir.inode.nlink = 2 // from "." and parent directory or ".." for root
|
||||
return &dir.inode
|
||||
}
|
||||
|
||||
func (i *inode) isDir() bool {
|
||||
_, ok := i.impl.(*directory)
|
||||
return ok
|
||||
}
|
||||
|
||||
type directoryFD struct {
|
||||
fileDescription
|
||||
vfs.DirectoryFileDescriptionDefaultImpl
|
||||
|
|
|
@ -34,7 +34,7 @@ type namedPipe struct {
|
|||
// * rp.Mount().CheckBeginWrite() has been called successfully.
|
||||
func (fs *filesystem) newNamedPipe(creds *auth.Credentials, mode linux.FileMode) *inode {
|
||||
file := &namedPipe{pipe: pipe.NewVFSPipe(pipe.DefaultPipeSize, usermem.PageSize)}
|
||||
file.inode.init(file, fs, creds, mode)
|
||||
file.inode.init(file, fs, creds, linux.S_IFIFO|mode)
|
||||
file.inode.nlink = 1 // Only the parent has a link.
|
||||
return &file.inode
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ func (fs *filesystem) newRegularFile(creds *auth.Credentials, mode linux.FileMod
|
|||
file := ®ularFile{
|
||||
memFile: fs.memFile,
|
||||
}
|
||||
file.inode.init(file, fs, creds, mode)
|
||||
file.inode.init(file, fs, creds, linux.S_IFREG|mode)
|
||||
file.inode.nlink = 1 // from parent directory
|
||||
return &file.inode
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package tmpfs
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
)
|
||||
|
||||
|
@ -27,7 +28,7 @@ func (fs *filesystem) newSymlink(creds *auth.Credentials, target string) *inode
|
|||
link := &symlink{
|
||||
target: target,
|
||||
}
|
||||
link.inode.init(link, fs, creds, 0777)
|
||||
link.inode.init(link, fs, creds, linux.S_IFLNK|0777)
|
||||
link.inode.nlink = 1 // from parent directory
|
||||
return &link.inode
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ type inode struct {
|
|||
// Inode metadata. Writing multiple fields atomically requires holding
|
||||
// mu, othewise atomic operations can be used.
|
||||
mu sync.Mutex
|
||||
mode uint32 // excluding file type bits, which are based on impl
|
||||
mode uint32 // file type and mode
|
||||
nlink uint32 // protected by filesystem.mu instead of inode.mu
|
||||
uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
|
||||
gid uint32 // auth.KGID, but ...
|
||||
|
@ -168,6 +168,9 @@ type inode struct {
|
|||
const maxLinks = math.MaxUint32
|
||||
|
||||
func (i *inode) init(impl interface{}, fs *filesystem, creds *auth.Credentials, mode linux.FileMode) {
|
||||
if mode.FileType() == 0 {
|
||||
panic("file type is required in FileMode")
|
||||
}
|
||||
i.clock = fs.clock
|
||||
i.refs = 1
|
||||
i.mode = uint32(mode)
|
||||
|
@ -269,31 +272,21 @@ func (i *inode) statTo(stat *linux.Statx) {
|
|||
// TODO(gvisor.dev/issues/1197): Device number.
|
||||
switch impl := i.impl.(type) {
|
||||
case *regularFile:
|
||||
stat.Mode |= linux.S_IFREG
|
||||
stat.Mask |= linux.STATX_SIZE | linux.STATX_BLOCKS
|
||||
stat.Size = uint64(atomic.LoadUint64(&impl.size))
|
||||
// In tmpfs, this will be FileRangeSet.Span() / 512 (but also cached in
|
||||
// a uint64 accessed using atomic memory operations to avoid taking
|
||||
// locks).
|
||||
stat.Blocks = allocatedBlocksForSize(stat.Size)
|
||||
case *directory:
|
||||
stat.Mode |= linux.S_IFDIR
|
||||
case *symlink:
|
||||
stat.Mode |= linux.S_IFLNK
|
||||
stat.Mask |= linux.STATX_SIZE | linux.STATX_BLOCKS
|
||||
stat.Size = uint64(len(impl.target))
|
||||
stat.Blocks = allocatedBlocksForSize(stat.Size)
|
||||
case *namedPipe:
|
||||
stat.Mode |= linux.S_IFIFO
|
||||
case *deviceFile:
|
||||
switch impl.kind {
|
||||
case vfs.BlockDevice:
|
||||
stat.Mode |= linux.S_IFBLK
|
||||
case vfs.CharDevice:
|
||||
stat.Mode |= linux.S_IFCHR
|
||||
}
|
||||
stat.RdevMajor = impl.major
|
||||
stat.RdevMinor = impl.minor
|
||||
case *directory, *namedPipe:
|
||||
// Nothing to do.
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown inode type: %T", i.impl))
|
||||
}
|
||||
|
@ -316,7 +309,8 @@ func (i *inode) setStat(ctx context.Context, creds *auth.Credentials, stat *linu
|
|||
)
|
||||
mask := stat.Mask
|
||||
if mask&linux.STATX_MODE != 0 {
|
||||
atomic.StoreUint32(&i.mode, uint32(stat.Mode))
|
||||
ft := atomic.LoadUint32(&i.mode) & linux.S_IFMT
|
||||
atomic.StoreUint32(&i.mode, ft|uint32(stat.Mode&^linux.S_IFMT))
|
||||
needsCtimeBump = true
|
||||
}
|
||||
if mask&linux.STATX_UID != 0 {
|
||||
|
@ -439,6 +433,10 @@ func (i *inode) direntType() uint8 {
|
|||
}
|
||||
}
|
||||
|
||||
func (i *inode) isDir() bool {
|
||||
return linux.FileMode(i.mode).FileType() == linux.S_IFDIR
|
||||
}
|
||||
|
||||
// fileDescription is embedded by tmpfs implementations of
|
||||
// vfs.FileDescriptionImpl.
|
||||
type fileDescription struct {
|
||||
|
|
Loading…
Reference in New Issue