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