xref: /haiku/src/add-ons/kernel/file_systems/bfs/CachedBlock.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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 	fBlock(NULL)
76 {
77 }
78 
79 
80 inline
81 CachedBlock::CachedBlock(Volume *volume, off_t block)
82 	:
83 	fVolume(volume),
84 	fBlock(NULL)
85 {
86 	SetTo(block);
87 }
88 
89 
90 inline
91 CachedBlock::CachedBlock(Volume *volume, block_run run)
92 	:
93 	fVolume(volume),
94 	fBlock(NULL)
95 {
96 	SetTo(volume->ToBlock(run));
97 }
98 
99 
100 inline
101 CachedBlock::CachedBlock(CachedBlock *cached)
102 	:
103 	fVolume(cached->fVolume),
104 	fBlockNumber(cached->BlockNumber()),
105 	fBlock(cached->fBlock)
106 {
107 	cached->Keep();
108 }
109 
110 
111 inline
112 CachedBlock::~CachedBlock()
113 {
114 	Unset();
115 }
116 
117 
118 inline void
119 CachedBlock::Keep()
120 {
121 	fBlock = NULL;
122 }
123 
124 
125 inline void
126 CachedBlock::Unset()
127 {
128 	if (fBlock != NULL)
129 		block_cache_put(fVolume->BlockCache(), fBlockNumber);
130 }
131 
132 
133 inline const uint8 *
134 CachedBlock::SetTo(off_t block, off_t base, size_t length)
135 {
136 	Unset();
137 	fBlockNumber = block;
138 	return fBlock = (uint8 *)block_cache_get_etc(fVolume->BlockCache(), 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, size_t length, bool empty)
158 {
159 	Unset();
160 	fBlockNumber = block;
161 
162 	if (empty)
163 		return fBlock = (uint8 *)block_cache_get_empty(fVolume->BlockCache(), block, transaction.ID());
164 
165 	return fBlock = (uint8 *)block_cache_get_writable_etc(fVolume->BlockCache(),
166 		block, base, length, transaction.ID());
167 }
168 
169 
170 inline uint8 *
171 CachedBlock::SetToWritable(Transaction &transaction, off_t block, bool empty)
172 {
173 	return SetToWritable(transaction, block, block, 1, empty);
174 }
175 
176 
177 inline uint8 *
178 CachedBlock::SetToWritable(Transaction &transaction, block_run run, bool empty)
179 {
180 	return SetToWritable(transaction, fVolume->ToBlock(run), empty);
181 }
182 
183 
184 inline status_t
185 CachedBlock::MakeWritable(Transaction &transaction)
186 {
187 	if (fBlock == NULL)
188 		return B_NO_INIT;
189 
190 	return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber, transaction.ID());
191 }
192 
193 
194 #endif	/* CACHED_BLOCK_H */
195