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