ext: Add tests for root directory inode.

PiperOrigin-RevId: 259856442
This commit is contained in:
Ayush Ranjan
2019-07-24 17:59:57 -07:00
committed by gVisor bot
parent 2ed832ff86
commit 417096f781
5 changed files with 107 additions and 1 deletions
+1
View File
@@ -44,6 +44,7 @@ go_test(
"//pkg/sentry/context",
"//pkg/sentry/context/contexttest",
"//pkg/sentry/fs/ext/disklayout",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/vfs",
"//runsc/test/testutil",
"@com_github_google_go-cmp//cmp:go_default_library",
+9
View File
@@ -31,6 +31,15 @@ type dentry struct {
// Compiles only if dentry implements vfs.DentryImpl.
var _ vfs.DentryImpl = (*dentry)(nil)
// newDentry is the dentry constructor.
func newDentry(in *inode) *dentry {
d := &dentry{
inode: in,
}
d.vfsd.Init(d)
return d
}
// IncRef implements vfs.DentryImpl.IncRef.
func (d *dentry) IncRef(vfsfs *vfs.Filesystem) {
d.inode.incRef()
+6
View File
@@ -20,6 +20,12 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
)
// Special inodes. See https://www.kernel.org/doc/html/latest/filesystems/ext4/overview.html#special-inodes.
const (
// RootDirInode is the inode number of the root directory inode.
RootDirInode = 2
)
// The Inode interface must be implemented by structs representing ext inodes.
// The inode stores all the metadata pertaining to the file (except for the
// file name which is held by the directory entry). It does NOT expose all
+6 -1
View File
@@ -131,7 +131,12 @@ func (fstype filesystemType) NewFilesystem(ctx context.Context, creds *auth.Cred
return nil, nil, err
}
return &fs.vfsfs, nil, nil
rootInode, err := fs.getOrCreateInode(disklayout.RootDirInode)
if err != nil {
return nil, nil, err
}
return &fs.vfsfs, &newDentry(rootInode).vfsd, nil
}
// getOrCreateInode gets the inode corresponding to the inode number passed in.
+85
View File
@@ -25,6 +25,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/context"
"gvisor.dev/gvisor/pkg/sentry/context/contexttest"
"gvisor.dev/gvisor/pkg/sentry/fs/ext/disklayout"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/runsc/test/testutil"
@@ -82,6 +83,90 @@ func setUp(t *testing.T, imagePath string) (context.Context, *vfs.Filesystem, *v
return mockCtx, fs, d, tearDown, nil
}
// TestRootDir tests that the root directory inode is correctly initialized and
// returned from setUp.
func TestRootDir(t *testing.T) {
type inodeProps struct {
Mode linux.FileMode
UID auth.KUID
GID auth.KGID
Size uint64
InodeSize uint16
Links uint16
Flags disklayout.InodeFlags
}
type rootDirTest struct {
name string
image string
wantInode inodeProps
}
tests := []rootDirTest{
{
name: "ext4 root dir",
image: ext4ImagePath,
wantInode: inodeProps{
Mode: linux.ModeDirectory | 0755,
Size: 0x400,
InodeSize: 0x80,
Links: 3,
Flags: disklayout.InodeFlags{Extents: true},
},
},
{
name: "ext3 root dir",
image: ext3ImagePath,
wantInode: inodeProps{
Mode: linux.ModeDirectory | 0755,
Size: 0x400,
InodeSize: 0x80,
Links: 3,
},
},
{
name: "ext2 root dir",
image: ext2ImagePath,
wantInode: inodeProps{
Mode: linux.ModeDirectory | 0755,
Size: 0x400,
InodeSize: 0x80,
Links: 3,
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, _, vfsd, tearDown, err := setUp(t, test.image)
if err != nil {
t.Fatalf("setUp failed: %v", err)
}
defer tearDown()
d, ok := vfsd.Impl().(*dentry)
if !ok {
t.Fatalf("ext dentry of incorrect type: %T", vfsd.Impl())
}
// Offload inode contents into local structs for comparison.
gotInode := inodeProps{
Mode: d.inode.diskInode.Mode(),
UID: d.inode.diskInode.UID(),
GID: d.inode.diskInode.GID(),
Size: d.inode.diskInode.Size(),
InodeSize: d.inode.diskInode.InodeSize(),
Links: d.inode.diskInode.LinksCount(),
Flags: d.inode.diskInode.Flags(),
}
if diff := cmp.Diff(gotInode, test.wantInode); diff != "" {
t.Errorf("inode mismatch (-want +got):\n%s", diff)
}
})
}
}
// TestFilesystemInit tests that the filesystem superblock and block group
// descriptors are correctly read in and initialized.
func TestFilesystemInit(t *testing.T) {