1/* 2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef BLOCK_ALLOCATOR_H 6#define BLOCK_ALLOCATOR_H 7 8 9#include <lock.h> 10 11 12struct Transaction; 13struct Volume; 14 15 16class BlockAllocator { 17public: 18 BlockAllocator(Volume* volume); 19 ~BlockAllocator(); 20 21 uint64 BaseBlock() const 22 { return fAllocationGroupBlock; } 23 uint64 FreeBlocks() const { return fFreeBlocks; } 24 25 status_t Init(uint64 blockBitmap, uint64 freeBlocks); 26 status_t Initialize(Transaction& transaction); 27 28 status_t Allocate(uint64 baseHint, uint64 count, 29 Transaction& transaction, 30 uint64& _allocatedBase, 31 uint64& _allocatedCount); 32 status_t AllocateExactly(uint64 base, 33 uint64 count, Transaction& transaction); 34 status_t Free(uint64 base, uint64 count, 35 Transaction& transaction); 36 37 void ResetFreeBlocks(uint64 count); 38 // interface for Transaction only 39 40private: 41 status_t _Allocate(uint64 base, uint64 searchEnd, 42 uint64 count, Transaction& transaction, 43 uint64* _allocatedBase, 44 uint64& _allocatedCount); 45 status_t _AllocateInGroup(uint64 base, uint64 searchEnd, 46 uint32 count, Transaction& transaction, 47 uint64* _allocatedBase, 48 uint32& _allocatedCount); 49 status_t _AllocateInBitmapBlock(uint64 base, 50 uint32 count, Transaction& transaction, 51 uint64* _allocatedBase, 52 uint32& _allocatedCount); 53 54 status_t _Free(uint64 base, uint64 count, 55 Transaction& transaction); 56 status_t _FreeInGroup(uint64 base, uint32 count, 57 Transaction& transaction); 58 status_t _FreeInBitmapBlock(uint64 base, uint32 count, 59 Transaction& transaction); 60 61 status_t _UpdateSuperBlock(Transaction& transaction); 62 63private: 64 mutex fLock; 65 Volume* fVolume; 66 uint64 fTotalBlocks; 67 uint64 fFreeBlocks; 68 uint64 fAllocationGroupBlock; 69 uint64 fAllocationGroupCount; 70 uint64 fBitmapBlock; 71 uint64 fBitmapBlockCount; 72}; 73 74 75class AllocatedBlock { 76public: 77 AllocatedBlock(BlockAllocator* allocator, Transaction& transaction) 78 : 79 fAllocator(allocator), 80 fTransaction(transaction), 81 fIndex(0) 82 { 83 } 84 85 ~AllocatedBlock() 86 { 87 if (fIndex > 0) 88 fAllocator->Free(fIndex, 1, fTransaction); 89 } 90 91 uint64 Index() const 92 { 93 return fIndex; 94 } 95 96 status_t Allocate(uint64 baseHint = 0) 97 { 98 uint64 allocatedBlocks; 99 status_t error = fAllocator->Allocate(0, 1, fTransaction, fIndex, 100 allocatedBlocks); 101 if (error != B_OK) 102 fIndex = 0; 103 return error; 104 } 105 106 uint64 Detach() 107 { 108 uint64 index = fIndex; 109 fIndex = 0; 110 return index; 111 } 112 113private: 114 BlockAllocator* fAllocator; 115 Transaction& fTransaction; 116 uint64 fIndex; 117}; 118 119 120#endif // BLOCK_ALLOCATOR_H 121