mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
ext4: disklayout: SuperBlock interface implementations.
PiperOrigin-RevId: 255687771
This commit is contained in:
@@ -9,14 +9,21 @@ go_library(
|
||||
"block_group_32.go",
|
||||
"block_group_64.go",
|
||||
"superblock.go",
|
||||
"superblock_32.go",
|
||||
"superblock_64.go",
|
||||
"superblock_old.go",
|
||||
"test_utils.go",
|
||||
],
|
||||
importpath = "gvisor.dev/gvisor/pkg/sentry/fs/ext4/disklayout",
|
||||
deps = ["//pkg/binary"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "disklayout_test",
|
||||
size = "small",
|
||||
srcs = ["block_group_test.go"],
|
||||
srcs = [
|
||||
"block_group_test.go",
|
||||
"superblock_test.go",
|
||||
],
|
||||
embed = [":disklayout"],
|
||||
deps = ["//pkg/binary"],
|
||||
)
|
||||
|
||||
@@ -16,19 +16,11 @@ package disklayout
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
)
|
||||
|
||||
// TestBlockGroupSize tests the fact that the block group struct for
|
||||
// 32-bit ext filesystems should be exactly 32 bytes big and for 64-bit fs it
|
||||
// should be 64 bytes.
|
||||
// TestBlockGroupSize tests that the block group descriptor structs are of the
|
||||
// correct size.
|
||||
func TestBlockGroupSize(t *testing.T) {
|
||||
if got, want := int(binary.Size(BlockGroup32Bit{})), 32; got != want {
|
||||
t.Errorf("BlockGroup32Bit should be exactly 32 bytes but is %d bytes", got)
|
||||
}
|
||||
|
||||
if got, want := int(binary.Size(BlockGroup64Bit{})), 64; got != want {
|
||||
t.Errorf("BlockGroup64Bit should be exactly 64 bytes but is %d bytes", got)
|
||||
}
|
||||
assertSize(t, BlockGroup32Bit{}, 32)
|
||||
assertSize(t, BlockGroup64Bit{}, 64)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package disklayout
|
||||
|
||||
// SuperBlock32Bit implements SuperBlock and represents the 32-bit version of
|
||||
// the ext4_super_block struct in fs/ext4/ext4.h.
|
||||
//
|
||||
// The suffix `Raw` has been added to indicate that the field does not have a
|
||||
// counterpart in the 64-bit version and to resolve name collision with the
|
||||
// interface.
|
||||
type SuperBlock32Bit struct {
|
||||
// We embed the old superblock struct here because the 32-bit version is just
|
||||
// an extension of the old version.
|
||||
SuperBlockOld
|
||||
|
||||
FirstInode uint32
|
||||
InodeSizeRaw uint16
|
||||
BlockGroupNumber uint16
|
||||
FeatureCompat uint32
|
||||
FeatureIncompat uint32
|
||||
FeatureRoCompat uint32
|
||||
UUID [16]byte
|
||||
VolumeName [16]byte
|
||||
LastMounted [64]byte
|
||||
AlgoUsageBitmap uint32
|
||||
PreallocBlocks uint8
|
||||
PreallocDirBlocks uint8
|
||||
ReservedGdtBlocks uint16
|
||||
JournalUUID [16]byte
|
||||
JournalInum uint32
|
||||
JournalDev uint32
|
||||
LastOrphan uint32
|
||||
HashSeed [4]uint32
|
||||
DefaultHashVersion uint8
|
||||
JnlBackupType uint8
|
||||
BgDescSizeRaw uint16
|
||||
DefaultMountOpts uint32
|
||||
FirstMetaBg uint32
|
||||
MkfsTime uint32
|
||||
JnlBlocks [17]uint32
|
||||
}
|
||||
|
||||
// Only override methods which change based on the additional fields above.
|
||||
// Not overriding SuperBlock.BgDescSize because it would still return 32 here.
|
||||
|
||||
// InodeSize implements SuperBlock.InodeSize.
|
||||
func (sb *SuperBlock32Bit) InodeSize() uint16 {
|
||||
return sb.InodeSizeRaw
|
||||
}
|
||||
|
||||
// CompatibleFeatures implements SuperBlock.CompatibleFeatures.
|
||||
func (sb *SuperBlock32Bit) CompatibleFeatures() CompatFeatures {
|
||||
return CompatFeaturesFromInt(sb.FeatureCompat)
|
||||
}
|
||||
|
||||
// IncompatibleFeatures implements SuperBlock.IncompatibleFeatures.
|
||||
func (sb *SuperBlock32Bit) IncompatibleFeatures() IncompatFeatures {
|
||||
return IncompatFeaturesFromInt(sb.FeatureIncompat)
|
||||
}
|
||||
|
||||
// ReadOnlyCompatibleFeatures implements SuperBlock.ReadOnlyCompatibleFeatures.
|
||||
func (sb *SuperBlock32Bit) ReadOnlyCompatibleFeatures() RoCompatFeatures {
|
||||
return RoCompatFeaturesFromInt(sb.FeatureRoCompat)
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package disklayout
|
||||
|
||||
// SuperBlock64Bit implements SuperBlock and represents the 64-bit version of
|
||||
// the ext4_super_block struct in fs/ext4/ext4.h. This sums up to be exactly
|
||||
// 1024 bytes (smallest possible block size) and hence the superblock always
|
||||
// fits in no more than one data block.
|
||||
//
|
||||
// The suffix `Hi` here stands for upper bits because they represent the upper
|
||||
// half of the fields.
|
||||
type SuperBlock64Bit struct {
|
||||
// We embed the 32-bit struct here because 64-bit version is just an extension
|
||||
// of the 32-bit version.
|
||||
SuperBlock32Bit
|
||||
|
||||
BlocksCountHi uint32
|
||||
ReservedBlocksCountHi uint32
|
||||
FreeBlocksCountHi uint32
|
||||
MinInodeSize uint16
|
||||
WantInodeSize uint16
|
||||
Flags uint32
|
||||
RaidStride uint16
|
||||
MmpInterval uint16
|
||||
MmpBlock uint64
|
||||
RaidStripeWidth uint32
|
||||
LogGroupsPerFlex uint8
|
||||
ChecksumType uint8
|
||||
_ uint16
|
||||
KbytesWritten uint64
|
||||
SnapshotInum uint32
|
||||
SnapshotID uint32
|
||||
SnapshotRsrvBlocksCount uint64
|
||||
SnapshotList uint32
|
||||
ErrorCount uint32
|
||||
FirstErrorTime uint32
|
||||
FirstErrorInode uint32
|
||||
FirstErrorBlock uint64
|
||||
FirstErrorFunction [32]byte
|
||||
FirstErrorLine uint32
|
||||
LastErrorTime uint32
|
||||
LastErrorInode uint32
|
||||
LastErrorLine uint32
|
||||
LastErrorBlock uint64
|
||||
LastErrorFunction [32]byte
|
||||
MountOpts [64]byte
|
||||
UserQuotaInum uint32
|
||||
GroupQuotaInum uint32
|
||||
OverheadBlocks uint32
|
||||
BackupBgs [2]uint32
|
||||
EncryptAlgos [4]uint8
|
||||
EncryptPwSalt [16]uint8
|
||||
LostFoundInode uint32
|
||||
ProjectQuotaInode uint32
|
||||
ChecksumSeed uint32
|
||||
WtimeHi uint8
|
||||
MtimeHi uint8
|
||||
MkfsTimeHi uint8
|
||||
LastCheckHi uint8
|
||||
FirstErrorTimeHi uint8
|
||||
LastErrorTimeHi uint8
|
||||
_ [2]uint8
|
||||
Encoding uint16
|
||||
EncodingFlags uint16
|
||||
_ [95]uint32
|
||||
Checksum uint32
|
||||
}
|
||||
|
||||
// Only override methods which change based on the 64-bit feature.
|
||||
|
||||
// BlocksCount implements SuperBlock.BlocksCount.
|
||||
func (sb *SuperBlock64Bit) BlocksCount() uint64 {
|
||||
return (uint64(sb.BlocksCountHi) << 32) | uint64(sb.BlocksCountLo)
|
||||
}
|
||||
|
||||
// FreeBlocksCount implements SuperBlock.FreeBlocksCount.
|
||||
func (sb *SuperBlock64Bit) FreeBlocksCount() uint64 {
|
||||
return (uint64(sb.FreeBlocksCountHi) << 32) | uint64(sb.FreeBlocksCountLo)
|
||||
}
|
||||
|
||||
// BgDescSize implements SuperBlock.BgDescSize.
|
||||
func (sb *SuperBlock64Bit) BgDescSize() uint16 { return sb.BgDescSizeRaw }
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package disklayout
|
||||
|
||||
// SuperBlockOld implements SuperBlock and represents the old version of the
|
||||
// superblock struct in ext2 and ext3 systems.
|
||||
//
|
||||
// The suffix `Lo` here stands for lower bits because this is also used in the
|
||||
// 64-bit version where these fields represent the lower half of the fields.
|
||||
// The suffix `Raw` has been added to indicate that the field does not have a
|
||||
// counterpart in the 64-bit version and to resolve name collision with the
|
||||
// interface.
|
||||
type SuperBlockOld struct {
|
||||
InodesCountRaw uint32
|
||||
BlocksCountLo uint32
|
||||
ReservedBlocksCount uint32
|
||||
FreeBlocksCountLo uint32
|
||||
FreeInodesCountRaw uint32
|
||||
FirstDataBlockRaw uint32
|
||||
LogBlockSize uint32
|
||||
LogClusterSize uint32
|
||||
BlocksPerGroupRaw uint32
|
||||
ClustersPerGroupRaw uint32
|
||||
InodesPerGroupRaw uint32
|
||||
Mtime uint32
|
||||
Wtime uint32
|
||||
MountCountRaw uint16
|
||||
MaxMountCountRaw uint16
|
||||
MagicRaw uint16
|
||||
State uint16
|
||||
Errors uint16
|
||||
MinorRevLevel uint16
|
||||
LastCheck uint32
|
||||
CheckInterval uint32
|
||||
CreatorOS uint32
|
||||
RevLevel uint32
|
||||
DefResUID uint16
|
||||
DefResGID uint16
|
||||
}
|
||||
|
||||
// InodesCount implements SuperBlock.InodesCount.
|
||||
func (sb *SuperBlockOld) InodesCount() uint32 { return sb.InodesCountRaw }
|
||||
|
||||
// BlocksCount implements SuperBlock.BlocksCount.
|
||||
func (sb *SuperBlockOld) BlocksCount() uint64 { return uint64(sb.BlocksCountLo) }
|
||||
|
||||
// FreeBlocksCount implements SuperBlock.FreeBlocksCount.
|
||||
func (sb *SuperBlockOld) FreeBlocksCount() uint64 { return uint64(sb.FreeBlocksCountLo) }
|
||||
|
||||
// FreeInodesCount implements SuperBlock.FreeInodesCount.
|
||||
func (sb *SuperBlockOld) FreeInodesCount() uint32 { return sb.FreeInodesCountRaw }
|
||||
|
||||
// MountCount implements SuperBlock.MountCount.
|
||||
func (sb *SuperBlockOld) MountCount() uint16 { return sb.MountCountRaw }
|
||||
|
||||
// MaxMountCount implements SuperBlock.MaxMountCount.
|
||||
func (sb *SuperBlockOld) MaxMountCount() uint16 { return sb.MaxMountCountRaw }
|
||||
|
||||
// FirstDataBlock implements SuperBlock.FirstDataBlock.
|
||||
func (sb *SuperBlockOld) FirstDataBlock() uint32 { return sb.FirstDataBlockRaw }
|
||||
|
||||
// BlockSize implements SuperBlock.BlockSize.
|
||||
func (sb *SuperBlockOld) BlockSize() uint64 { return 1 << (10 + sb.LogBlockSize) }
|
||||
|
||||
// BlocksPerGroup implements SuperBlock.BlocksPerGroup.
|
||||
func (sb *SuperBlockOld) BlocksPerGroup() uint32 { return sb.BlocksPerGroupRaw }
|
||||
|
||||
// ClusterSize implements SuperBlock.ClusterSize.
|
||||
func (sb *SuperBlockOld) ClusterSize() uint64 { return 1 << (10 + sb.LogClusterSize) }
|
||||
|
||||
// ClustersPerGroup implements SuperBlock.ClustersPerGroup.
|
||||
func (sb *SuperBlockOld) ClustersPerGroup() uint32 { return sb.ClustersPerGroupRaw }
|
||||
|
||||
// InodeSize implements SuperBlock.InodeSize.
|
||||
func (sb *SuperBlockOld) InodeSize() uint16 { return 128 }
|
||||
|
||||
// InodesPerGroup implements SuperBlock.InodesPerGroup.
|
||||
func (sb *SuperBlockOld) InodesPerGroup() uint32 { return sb.InodesPerGroupRaw }
|
||||
|
||||
// BgDescSize implements SuperBlock.BgDescSize.
|
||||
func (sb *SuperBlockOld) BgDescSize() uint16 { return 32 }
|
||||
|
||||
// CompatibleFeatures implements SuperBlock.CompatibleFeatures.
|
||||
func (sb *SuperBlockOld) CompatibleFeatures() CompatFeatures { return CompatFeatures{} }
|
||||
|
||||
// IncompatibleFeatures implements SuperBlock.IncompatibleFeatures.
|
||||
func (sb *SuperBlockOld) IncompatibleFeatures() IncompatFeatures { return IncompatFeatures{} }
|
||||
|
||||
// ReadOnlyCompatibleFeatures implements SuperBlock.ReadOnlyCompatibleFeatures.
|
||||
func (sb *SuperBlockOld) ReadOnlyCompatibleFeatures() RoCompatFeatures { return RoCompatFeatures{} }
|
||||
|
||||
// Magic implements SuperBlock.Magic.
|
||||
func (sb *SuperBlockOld) Magic() uint16 { return sb.MagicRaw }
|
||||
|
||||
// Revision implements SuperBlock.Revision.
|
||||
func (sb *SuperBlockOld) Revision() SbRevision { return SbRevision(sb.RevLevel) }
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package disklayout
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestSuperBlockSize tests that the superblock structs are of the correct
|
||||
// size.
|
||||
func TestSuperBlockSize(t *testing.T) {
|
||||
assertSize(t, SuperBlockOld{}, 84)
|
||||
assertSize(t, SuperBlock32Bit{}, 336)
|
||||
assertSize(t, SuperBlock64Bit{}, 1024)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2019 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package disklayout
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/binary"
|
||||
)
|
||||
|
||||
func assertSize(t *testing.T, v interface{}, want uintptr) {
|
||||
t.Helper()
|
||||
|
||||
if got := binary.Size(v); got != want {
|
||||
t.Errorf("struct %s should be exactly %d bytes but is %d bytes", reflect.TypeOf(v).Name(), want, got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user