gvisor/pkg/sentry/fsimpl/ext/disklayout/block_group.go

138 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
// BlockGroup represents a Linux ext block group descriptor. An ext file system
// is split into a series of block groups. This provides an access layer to
// information needed to access and use a block group.
//
// Location:
// - The block group descriptor table is always placed in the blocks
// immediately after the block containing the superblock.
// - The 1st block group descriptor in the original table is in the
// (sb.FirstDataBlock() + 1)th block.
// - See SuperBlock docs to see where the block group descriptor table is
// replicated.
// - sb.BgDescSize() must be used as the block group descriptor entry size
// while reading the table from disk.
//
// See https://www.kernel.org/doc/html/latest/filesystems/ext4/globals.html#block-group-descriptors.
type BlockGroup interface {
// InodeTable returns the absolute block number of the block containing the
// inode table. This points to an array of Inode structs. Inode tables are
// statically allocated at mkfs time. The superblock records the number of
// inodes per group (length of this table) and the size of each inode struct.
InodeTable() uint64
// BlockBitmap returns the absolute block number of the block containing the
// block bitmap. This bitmap tracks the usage of data blocks within this block
// group and has its own checksum.
BlockBitmap() uint64
// InodeBitmap returns the absolute block number of the block containing the
// inode bitmap. This bitmap tracks the usage of this group's inode table
// entries and has its own checksum.
InodeBitmap() uint64
// ExclusionBitmap returns the absolute block number of the snapshot exclusion
// bitmap.
ExclusionBitmap() uint64
// FreeBlocksCount returns the number of free blocks in the group.
FreeBlocksCount() uint32
// FreeInodesCount returns the number of free inodes in the group.
FreeInodesCount() uint32
// DirectoryCount returns the number of inodes that represent directories
// under this block group.
DirectoryCount() uint32
// UnusedInodeCount returns the number of unused inodes beyond the last used
// inode in this group's inode table. As a result, we neednt scan past the
// (InodesPerGroup - UnusedInodeCount())th entry in the inode table.
UnusedInodeCount() uint32
// BlockBitmapChecksum returns the block bitmap checksum. This is calculated
// using crc32c(FS UUID + group number + entire bitmap).
BlockBitmapChecksum() uint32
// InodeBitmapChecksum returns the inode bitmap checksum. This is calculated
// using crc32c(FS UUID + group number + entire bitmap).
InodeBitmapChecksum() uint32
// Checksum returns this block group's checksum.
//
// If SbMetadataCsum feature is set:
// - checksum is crc32c(FS UUID + group number + group descriptor
// structure) & 0xFFFF.
//
// If SbGdtCsum feature is set:
// - checksum is crc16(FS UUID + group number + group descriptor
// structure).
//
// SbMetadataCsum and SbGdtCsum should not be both set.
// If they are, Linux warns and asks to run fsck.
Checksum() uint16
// Flags returns BGFlags which represents the block group flags.
Flags() BGFlags
}
// These are the different block group flags.
const (
// BgInodeUninit indicates that inode table and bitmap are not initialized.
BgInodeUninit uint16 = 0x1
// BgBlockUninit indicates that block bitmap is not initialized.
BgBlockUninit uint16 = 0x2
// BgInodeZeroed indicates that inode table is zeroed.
BgInodeZeroed uint16 = 0x4
)
// BGFlags represents all the different combinations of block group flags.
type BGFlags struct {
InodeUninit bool
BlockUninit bool
InodeZeroed bool
}
// ToInt converts a BGFlags struct back to its 16-bit representation.
func (f BGFlags) ToInt() uint16 {
var res uint16
if f.InodeUninit {
res |= BgInodeUninit
}
if f.BlockUninit {
res |= BgBlockUninit
}
if f.InodeZeroed {
res |= BgInodeZeroed
}
return res
}
// BGFlagsFromInt converts the 16-bit flag representation to a BGFlags struct.
func BGFlagsFromInt(flags uint16) BGFlags {
return BGFlags{
InodeUninit: flags&BgInodeUninit > 0,
BlockUninit: flags&BgBlockUninit > 0,
InodeZeroed: flags&BgInodeZeroed > 0,
}
}