xref: /haiku/src/add-ons/kernel/file_systems/bfs/CachedBlock.h (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1 /*
2  * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
3  * This file may be used under the terms of the MIT License.
4  */
5 #ifndef CACHED_BLOCK_H
6 #define CACHED_BLOCK_H
7 
8 //!	interface for the block cache
9 
10 
11 #include "system_dependencies.h"
12 
13 #include "Volume.h"
14 #include "Journal.h"
15 #include "Debug.h"
16 
17 
18 // The CachedBlock class is completely implemented as inlines.
19 // It should be used when cache single blocks to make sure they
20 // will be properly released after use (and it's also very
21 // convenient to use them).
22 
23 class CachedBlock {
24 	public:
25 		CachedBlock(Volume* volume);
26 		CachedBlock(Volume* volume, off_t block);
27 		CachedBlock(Volume* volume, block_run run);
28 		CachedBlock(CachedBlock* cached);
29 		~CachedBlock();
30 
31 		inline void Keep();
32 		inline void Unset();
33 
34 		inline const uint8* SetTo(off_t block, off_t base, size_t length);
35 		inline const uint8* SetTo(off_t block);
36 		inline const uint8* SetTo(block_run run);
37 		inline uint8* SetToWritable(Transaction& transaction, off_t block,
38 			off_t base, size_t length, bool empty = false);
39 		inline uint8* SetToWritable(Transaction& transaction, off_t block,
40 			bool empty = false);
41 		inline uint8* SetToWritable(Transaction& transaction, block_run run,
42 			bool empty = false);
43 		inline status_t MakeWritable(Transaction& transaction);
44 
45 		const uint8* Block() const { return fBlock; }
46 		off_t BlockNumber() const { return fBlockNumber; }
47 		uint32 BlockSize() const { return fVolume->BlockSize(); }
48 		uint32 BlockShift() const { return fVolume->BlockShift(); }
49 
50 	private:
51 		CachedBlock(const CachedBlock& other);
52 		CachedBlock& operator=(const CachedBlock& other);
53 			// no implementation
54 
55 	protected:
56 		Volume	*fVolume;
57 		off_t	fBlockNumber;
58 		uint8	*fBlock;
59 };
60 
61 
62 // inlines
63 
64 
65 inline
66 CachedBlock::CachedBlock(Volume* volume)
67 	:
68 	fVolume(volume),
69 	fBlockNumber(0),
70 	fBlock(NULL)
71 {
72 }
73 
74 
75 inline
76 CachedBlock::CachedBlock(Volume* volume, off_t block)
77 	:
78 	fVolume(volume),
79 	fBlockNumber(0),
80 	fBlock(NULL)
81 {
82 	SetTo(block);
83 }
84 
85 
86 inline
87 CachedBlock::CachedBlock(Volume* volume, block_run run)
88 	:
89 	fVolume(volume),
90 	fBlockNumber(0),
91 	fBlock(NULL)
92 {
93 	SetTo(volume->ToBlock(run));
94 }
95 
96 
97 inline
98 CachedBlock::CachedBlock(CachedBlock* cached)
99 	:
100 	fVolume(cached->fVolume),
101 	fBlockNumber(cached->BlockNumber()),
102 	fBlock(cached->fBlock)
103 {
104 	cached->Keep();
105 }
106 
107 
108 inline
109 CachedBlock::~CachedBlock()
110 {
111 	Unset();
112 }
113 
114 
115 inline void
116 CachedBlock::Keep()
117 {
118 	fBlock = NULL;
119 }
120 
121 
122 inline void
123 CachedBlock::Unset()
124 {
125 	if (fBlock != NULL) {
126 		block_cache_put(fVolume->BlockCache(), fBlockNumber);
127 		fBlock = NULL;
128 	}
129 }
130 
131 
132 inline const uint8*
133 CachedBlock::SetTo(off_t block, off_t base, size_t length)
134 {
135 	Unset();
136 	fBlockNumber = block;
137 	return fBlock = (uint8*)block_cache_get_etc(fVolume->BlockCache(),
138 		block, base, length);
139 }
140 
141 
142 inline const uint8*
143 CachedBlock::SetTo(off_t block)
144 {
145 	return SetTo(block, block, 1);
146 }
147 
148 
149 inline const uint8*
150 CachedBlock::SetTo(block_run run)
151 {
152 	return SetTo(fVolume->ToBlock(run));
153 }
154 
155 
156 inline uint8*
157 CachedBlock::SetToWritable(Transaction& transaction, off_t block, off_t base,
158 	size_t length, bool empty)
159 {
160 	Unset();
161 	fBlockNumber = block;
162 
163 	if (empty) {
164 		fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
165 			block, transaction.ID());
166 	} else {
167 		fBlock = (uint8*)block_cache_get_writable_etc(fVolume->BlockCache(),
168 			block, base, length, transaction.ID());
169 	}
170 
171 	return fBlock;
172 }
173 
174 
175 inline uint8*
176 CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
177 {
178 	return SetToWritable(transaction, block, block, 1, empty);
179 }
180 
181 
182 inline uint8*
183 CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty)
184 {
185 	return SetToWritable(transaction, fVolume->ToBlock(run), empty);
186 }
187 
188 
189 inline status_t
190 CachedBlock::MakeWritable(Transaction& transaction)
191 {
192 	if (fBlock == NULL)
193 		return B_NO_INIT;
194 
195 	return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber,
196 		transaction.ID());
197 }
198 
199 #endif	// CACHED_BLOCK_H
200