xref: /haiku/src/add-ons/kernel/file_systems/ext2/CachedBlock.h (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
1 /*
2  * Copyright 2001-2008, 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 #include <fs_cache.h>
11 
12 #include "Transaction.h"
13 #include "Volume.h"
14 
15 
16 class CachedBlock {
17 public:
18 							CachedBlock(Volume* volume);
19 							CachedBlock(Volume* volume, off_t block);
20 							~CachedBlock();
21 
22 			void			Keep();
23 			void			Unset();
24 
25 			const uint8*	SetTo(off_t block);
26 			uint8*			SetToWritable(Transaction& transaction,
27 								off_t block, bool empty = false);
28 			uint8*			SetToWritableWithoutTransaction(off_t block,
29 								bool empty = false);
30 
31 			const uint8*	Block() const { return fBlock; }
32 			off_t			BlockNumber() const { return fBlockNumber; }
33 
34 private:
35 							CachedBlock(const CachedBlock &);
36 							CachedBlock &operator=(const CachedBlock &);
37 								// no implementation
38 
39 			uint8*			_SetToWritableEtc(int32 transaction, off_t block,
40 								bool empty);
41 
42 protected:
43 			Volume*			fVolume;
44 			off_t			fBlockNumber;
45 			uint8*			fBlock;
46 };
47 
48 
49 // inlines
50 
51 
52 inline
53 CachedBlock::CachedBlock(Volume* volume)
54 	:
55 	fVolume(volume),
56 	fBlockNumber(0),
57 	fBlock(NULL)
58 {
59 }
60 
61 
62 inline
63 CachedBlock::CachedBlock(Volume* volume, off_t block)
64 	:
65 	fVolume(volume),
66 	fBlockNumber(0),
67 	fBlock(NULL)
68 {
69 	SetTo(block);
70 }
71 
72 
73 inline
74 CachedBlock::~CachedBlock()
75 {
76 	Unset();
77 }
78 
79 
80 inline void
81 CachedBlock::Keep()
82 {
83 	fBlock = NULL;
84 }
85 
86 
87 inline void
88 CachedBlock::Unset()
89 {
90 	if (fBlock != NULL) {
91 		block_cache_put(fVolume->BlockCache(), fBlockNumber);
92 		fBlock = NULL;
93 	}
94 }
95 
96 
97 inline const uint8 *
98 CachedBlock::SetTo(off_t block)
99 {
100 	Unset();
101 	fBlockNumber = block;
102 	return fBlock = (uint8 *)block_cache_get(fVolume->BlockCache(), block);
103 }
104 
105 
106 inline uint8*
107 CachedBlock::SetToWritable(Transaction& transaction, off_t block, bool empty)
108 {
109 	return _SetToWritableEtc(transaction.ID(), block, empty);
110 }
111 
112 
113 inline uint8*
114 CachedBlock::SetToWritableWithoutTransaction(off_t block, bool empty)
115 {
116 	return _SetToWritableEtc((int32)-1, block, empty);
117 }
118 
119 inline uint8*
120 CachedBlock::_SetToWritableEtc(int32 transaction, off_t block, bool empty)
121 {
122 	Unset();
123 	fBlockNumber = block;
124 
125 	if (empty) {
126 		fBlock = (uint8*)block_cache_get_empty(fVolume->BlockCache(),
127 			block, transaction);
128 	} else {
129 		fBlock = (uint8*)block_cache_get_writable(fVolume->BlockCache(),
130 			block, transaction);
131 	}
132 
133 	return fBlock;
134 }
135 
136 #endif	// CACHED_BLOCK_H
137