github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/block/dynamicDiskBlockFactory.go (about) 1 package block 2 3 import ( 4 "github.com/Microsoft/azure-vhd-utils/vhdcore" 5 "github.com/Microsoft/azure-vhd-utils/vhdcore/block/bitmap" 6 "github.com/Microsoft/azure-vhd-utils/vhdcore/common" 7 ) 8 9 // DynamicDiskBlockFactory is a type which is used for following purposes 10 // To create a Block instance representing a dynamic disk block 11 // To get the number of blocks in the dynamic disk 12 // To get the block size of the block in dynamic disk 13 // To get a Sector instance representing sector of dynamic disk's block 14 // To get the logical footer range of fixed disk generated from the dynamic disk 15 // 16 type DynamicDiskBlockFactory struct { 17 params *FactoryParams 18 bitmapFactory *bitmap.Factory 19 sectorFactory *SectorFactory 20 blockDataReader DataReader 21 cachedDynamicBlock *Block 22 } 23 24 // NewDynamicDiskFactory creates a DynamicDiskBlockFactory instance which can be used to create a 25 // Block objects representing dynamic disk block of a size specified in header BlockSize field 26 // parameter params contains header, footer, BAT of dynamic disk and reader to read the disk. 27 // 28 func NewDynamicDiskFactory(params *FactoryParams) *DynamicDiskBlockFactory { 29 blockFactory := &DynamicDiskBlockFactory{params: params} 30 31 blockFactory.bitmapFactory = bitmap.NewFactory(blockFactory.params.VhdReader, 32 blockFactory.params.BlockAllocationTable) 33 34 blockFactory.sectorFactory = NewSectorFactory(blockFactory.params.VhdReader, 35 blockFactory.params.BlockAllocationTable.HasData, 36 blockFactory.params.BlockAllocationTable.GetBlockDataAddress) 37 38 blockFactory.blockDataReader = NewDynamicDiskBlockReader(blockFactory.params.VhdReader, 39 blockFactory.params.BlockAllocationTable, 40 blockFactory.params.VhdHeader.BlockSize) 41 return blockFactory 42 } 43 44 // GetBlockCount returns the number of blocks in the dynamic disk. 45 // 46 func (f *DynamicDiskBlockFactory) GetBlockCount() int64 { 47 return int64(f.params.BlockAllocationTable.BATEntriesCount) 48 } 49 50 // GetBlockSize returns the size of the 'data section' of block in bytes in the dynamic disk. 51 // 52 func (f *DynamicDiskBlockFactory) GetBlockSize() int64 { 53 return int64(f.params.VhdHeader.BlockSize) 54 } 55 56 // GetFooterRange returns the logical range of the footer when converting this dynamic vhd to fixed 57 // logical range of footer is the absolute start and end byte offset of the footer. 58 // 59 func (f *DynamicDiskBlockFactory) GetFooterRange() *common.IndexRange { 60 return common.NewIndexRangeFromLength(f.GetBlockCount()*f.GetBlockSize(), vhdcore.VhdFooterSize) 61 } 62 63 // Create returns an instance of Block which represents a dynamic disk block, the parameter blockIndex 64 // identifies the block. This function return error if the block cannot be created due to any read error. 65 // 66 func (f *DynamicDiskBlockFactory) Create(blockIndex uint32) (*Block, error) { 67 if f.cachedDynamicBlock == nil || f.cachedDynamicBlock.BlockIndex != blockIndex { 68 logicalRange := common.NewIndexRangeFromLength(int64(blockIndex)*f.GetBlockSize(), f.GetBlockSize()) 69 f.cachedDynamicBlock = &Block{ 70 BlockIndex: blockIndex, 71 LogicalRange: logicalRange, 72 VhdUniqueID: f.params.VhdFooter.UniqueID, 73 BlockDataReader: f.blockDataReader, 74 } 75 76 if f.params.BlockAllocationTable.HasData(blockIndex) { 77 var err error 78 f.cachedDynamicBlock.BitMap, err = f.bitmapFactory.Create(blockIndex) 79 if err != nil { 80 return nil, err 81 } 82 83 f.cachedDynamicBlock.IsEmpty = false 84 } else { 85 f.cachedDynamicBlock.BitMap = nil 86 f.cachedDynamicBlock.IsEmpty = true 87 } 88 } 89 90 return f.cachedDynamicBlock, nil 91 } 92 93 // GetSector returns an instance of Sector in a dynamic disk, parameter block object identifying the block 94 // containing the sector, the parameter sectorIndex identifies the sector in the block. This function return 95 // error if the sector cannot be created due to any read error or if the requested sector index is invalid. 96 // 97 func (f *DynamicDiskBlockFactory) GetSector(block *Block, sectorIndex uint32) (*Sector, error) { 98 blockIndex := block.BlockIndex 99 if block.IsEmpty { 100 return f.sectorFactory.CreateEmptySector(blockIndex, sectorIndex), nil 101 } 102 103 return f.sectorFactory.Create(block, sectorIndex) 104 } 105 106 // GetBitmapFactory returns an instance of BitmapFactory that can be used to create the bitmap of a block 107 // by reading block from dynamic disk. 108 // 109 func (f *DynamicDiskBlockFactory) GetBitmapFactory() *bitmap.Factory { 110 return f.bitmapFactory 111 }