github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/block/block.go (about)

     1  package block
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/Microsoft/azure-vhd-utils/vhdcore"
     7  	"github.com/Microsoft/azure-vhd-utils/vhdcore/block/bitmap"
     8  	"github.com/Microsoft/azure-vhd-utils/vhdcore/common"
     9  )
    10  
    11  // Block type represents Block of a vhd. A block of a dynamic or differential vhd starts with a
    12  // 'bitmap' section followed by the 'data' section, in case of fixed vhd the entire block is used
    13  // to store the 'data'.
    14  //
    15  type Block struct {
    16  	// BlockIndex is the index of the block, block indices are consecutive values starting from 0
    17  	// for the first block.
    18  	BlockIndex uint32
    19  	// IsEmpty is true if the block is empty, for dynamic and differencing disk the BAT entry of an
    20  	// empty block contains 0xFFFFFFFF.
    21  	IsEmpty bool
    22  	// BitMap represents 'bitmap section' of the block. Each bit in the bitmap represents the state
    23  	// of a sector in the block.
    24  	//
    25  	// This field is always nil for fixed disk. For Dynamic and differencing disk this field is set
    26  	// if the block is not marked as empty in the BAT.
    27  	//
    28  	// The dynamic and differencing subsystem reads the sector marked as dirty from the current disk,
    29  	// if a sector is marked as clean and if the current disk disk is dynamic then the sector will be
    30  	// read from the parent disk.
    31  	BitMap *bitmap.BitMap
    32  	// LogicalRange holds the absolute start and end byte offset of the block's 'data' in the converted
    33  	// fixed disk. When converting dynamic and differential vhd to fixed vhd, we place all block's 'data'
    34  	// consecutively starting at byte offset 0 of the fixed disk.
    35  	LogicalRange *common.IndexRange
    36  	// VhdUniqueId holds the unique identifier of the vhd that the block belongs to. The vhd unique
    37  	// identifier is stored in the vhd footer unique id field.
    38  	VhdUniqueID *common.UUID
    39  	// BlockData is a byte slice containing the block's 'data'
    40  	blockData []byte
    41  	// blockDataReader is the reader for reading the block's 'data' from the disk.
    42  	BlockDataReader DataReader
    43  	// sectorProvider enables retrieving the sector
    44  	blockFactory Factory
    45  }
    46  
    47  // Data returns the block data, the content of entire block in case of fixed vhd and the content
    48  // of block's data section in case of dynamic and differential vhd.
    49  //
    50  func (b *Block) Data() ([]byte, error) {
    51  	if b.blockData == nil {
    52  		var err error
    53  		b.blockData, err = b.BlockDataReader.Read(b)
    54  		if err != nil {
    55  			return nil, err
    56  		}
    57  	}
    58  	return b.blockData, nil
    59  }
    60  
    61  // GetSector returns an instance of Sector representing a sector with the given Id in this block.
    62  // The parameter sectorIndex is the index of the sector in this block to read.
    63  //
    64  func (b *Block) GetSector(sectorIndex uint32) (*Sector, error) {
    65  	return b.blockFactory.GetSector(b, sectorIndex)
    66  }
    67  
    68  // GetSectorCount returns the number of sectors in the block.
    69  //
    70  func (b *Block) GetSectorCount() int64 {
    71  	return b.LogicalRange.Length() / vhdcore.VhdSectorLength
    72  }
    73  
    74  // String returns formatted representation of the block
    75  // This satisfies Stringer interface.
    76  //
    77  func (b *Block) String() string {
    78  	return fmt.Sprintf("Block:%d", b.BlockIndex)
    79  }