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