xref: /haiku/src/add-ons/kernel/file_systems/bfs/CachedBlock.h (revision a127b88ecbfab58f64944c98aa47722a18e363b2)
1 /*
2  * Copyright 2001-2020, 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 
9 //!	Interface for the block cache
10 
11 
12 #include "system_dependencies.h"
13 
14 #include "Volume.h"
15 #include "Journal.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(CachedBlock* cached);
28 								~CachedBlock();
29 
30 	inline	void				Keep();
31 	inline	void				Unset();
32 
33 	inline status_t				SetTo(off_t block, off_t base, size_t length);
34 	inline status_t				SetTo(off_t block);
35 	inline status_t				SetTo(block_run run);
36 	inline status_t				SetToWritable(Transaction& transaction,
37 									off_t block, off_t base, size_t length,
38 									bool empty = false);
39 	inline status_t				SetToWritable(Transaction& transaction,
40 									off_t block, bool empty = false);
41 	inline status_t				SetToWritable(Transaction& transaction,
42 									block_run run, bool empty = false);
43 	inline status_t				MakeWritable(Transaction& transaction);
44 
45 			const uint8*		Block() const { return fBlock; }
46 			uint8*				WritableBlock() const { return fBlock; }
47 			off_t				BlockNumber() const { return fBlockNumber; }
48 			uint32				BlockSize() const
49 									{ return fVolume->BlockSize(); }
50 			uint32				BlockShift() const
51 									{ return fVolume->BlockShift(); }
52 
53 private:
54 	CachedBlock(const CachedBlock& other);
55 	CachedBlock& operator=(const CachedBlock& other);
56 		// no implementation
57 
58 protected:
59 			Volume*				fVolume;
60 			off_t				fBlockNumber;
61 			uint8*				fBlock;
62 };
63 
64 
65 // inlines
66 
67 
68 inline
69 CachedBlock::CachedBlock(Volume* volume)
70 	:
71 	fVolume(volume),
72 	fBlockNumber(0),
73 	fBlock(NULL)
74 {
75 }
76 
77 
78 inline
79 CachedBlock::CachedBlock(CachedBlock* cached)
80 	:
81 	fVolume(cached->fVolume),
82 	fBlockNumber(cached->BlockNumber()),
83 	fBlock(cached->fBlock)
84 {
85 	cached->Keep();
86 }
87 
88 
89 inline
90 CachedBlock::~CachedBlock()
91 {
92 	Unset();
93 }
94 
95 
96 inline void
97 CachedBlock::Keep()
98 {
99 	fBlock = NULL;
100 }
101 
102 
103 inline void
104 CachedBlock::Unset()
105 {
106 	if (fBlock != NULL) {
107 		block_cache_put(fVolume->BlockCache(), fBlockNumber);
108 		fBlock = NULL;
109 	}
110 }
111 
112 
113 inline status_t
114 CachedBlock::SetTo(off_t block, off_t base, size_t length)
115 {
116 	Unset();
117 	fBlockNumber = block;
118 	return block_cache_get_etc(fVolume->BlockCache(), block, base, length,
119 		(const void**)&fBlock);
120 }
121 
122 
123 inline status_t
124 CachedBlock::SetTo(off_t block)
125 {
126 	return SetTo(block, block, 1);
127 }
128 
129 
130 inline status_t
131 CachedBlock::SetTo(block_run run)
132 {
133 	return SetTo(fVolume->ToBlock(run));
134 }
135 
136 
137 inline status_t
138 CachedBlock::SetToWritable(Transaction& transaction, off_t block, off_t base,
139 	size_t length, bool empty)
140 {
141 	Unset();
142 	fBlockNumber = block;
143 
144 	if (empty) {
145 		fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
146 			block, transaction.ID());
147 		return fBlock != NULL ? B_OK : B_NO_MEMORY;
148 	}
149 
150 	return block_cache_get_writable_etc(fVolume->BlockCache(),
151 		block, base, length, transaction.ID(), (void**)&fBlock);
152 }
153 
154 
155 inline status_t
156 CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
157 {
158 	return SetToWritable(transaction, block, block, 1, empty);
159 }
160 
161 
162 inline status_t
163 CachedBlock::SetToWritable(Transaction& transaction, block_run run, bool empty)
164 {
165 	return SetToWritable(transaction, fVolume->ToBlock(run), empty);
166 }
167 
168 
169 inline status_t
170 CachedBlock::MakeWritable(Transaction& transaction)
171 {
172 	if (fBlock == NULL)
173 		return B_NO_INIT;
174 
175 	return block_cache_make_writable(fVolume->BlockCache(), fBlockNumber,
176 		transaction.ID());
177 }
178 
179 
180 #endif	// CACHED_BLOCK_H
181