xref: /haiku/src/tests/system/kernel/file_corruption/fs/BlockAllocator.h (revision 1e0016e1a9f1458b25c64b9032ffe60286770a09)
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 
12 struct Transaction;
13 struct Volume;
14 
15 
16 class BlockAllocator {
17 public:
18 								BlockAllocator(Volume* volume);
19 								~BlockAllocator();
20 
BaseBlock()21 			uint64				BaseBlock() const
22 									{ return fAllocationGroupBlock; }
FreeBlocks()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 
40 private:
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 
63 private:
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 
75 class AllocatedBlock {
76 public:
AllocatedBlock(BlockAllocator * allocator,Transaction & transaction)77 	AllocatedBlock(BlockAllocator* allocator, Transaction& transaction)
78 		:
79 		fAllocator(allocator),
80 		fTransaction(transaction),
81 		fIndex(0)
82 	{
83 	}
84 
~AllocatedBlock()85 	~AllocatedBlock()
86 	{
87 		if (fIndex > 0)
88 			fAllocator->Free(fIndex, 1, fTransaction);
89 	}
90 
Index()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 
Detach()106 	uint64 Detach()
107 	{
108 		uint64 index = fIndex;
109 		fIndex = 0;
110 		return index;
111 	}
112 
113 private:
114 	BlockAllocator*	fAllocator;
115 	Transaction&	fTransaction;
116 	uint64			fIndex;
117 };
118 
119 
120 #endif	// BLOCK_ALLOCATOR_H
121