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 }