xref: /haiku/src/add-ons/kernel/file_systems/udf/CachedBlock.h (revision ae0a10cad3999b13cbfa47a3d947a5219d2d90f4)
1 /*
2  * 	Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com
3  * 	Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net
4  * 	Copyright 2002-2020, Axel Dörfler, axeld@pinc-software.de
5  * 	Distributed under the terms of the MIT License.
6  */
7 #ifndef _UDF_CACHED_BLOCK_H
8 #define _UDF_CACHED_BLOCK_H
9 
10 /*! \file CachedBlock.h
11 
12 	Based on the CachedBlock class from BFS, written by
13 	Axel Dörfler, axeld@pinc-software.de
14 */
15 
16 #include <fs_cache.h>
17 #include <util/kernel_cpp.h>
18 
19 #include "UdfDebug.h"
20 #include "UdfStructures.h"
21 #include "Volume.h"
22 
23 
24 class CachedBlock {
25 public:
26 								CachedBlock(Volume *volume);
27 								CachedBlock(CachedBlock *cached);
28 								~CachedBlock();
29 
30 	uint8						*Block() const { return fBlock; }
31 	off_t						BlockNumber() const { return fBlockNumber; }
32 	uint32						BlockSize() const { return fVolume->BlockSize(); }
33 	uint32						BlockShift() const { return fVolume->BlockShift(); }
34 
35 	inline void					Keep();
36 	inline void					Unset();
37 
38 	inline status_t				SetTo(off_t block);
39 	inline status_t				SetTo(off_t block, off_t base, size_t length);
40 	inline status_t				SetTo(long_address address);
41 	template <class Accessor, class Descriptor>
42 	inline status_t				SetTo(Accessor &accessor,
43 									Descriptor &descriptor);
44 
45 protected:
46 	uint8						*fBlock;
47 	off_t						fBlockNumber;
48 	Volume						*fVolume;
49 };
50 
51 
52 inline
53 CachedBlock::CachedBlock(Volume *volume)
54 	:
55 	fBlock(NULL),
56 	fBlockNumber(0),
57 	fVolume(volume)
58 {
59 }
60 
61 
62 inline
63 CachedBlock::CachedBlock(CachedBlock *cached)
64 	:
65 	fBlock(cached->fBlock),
66 	fBlockNumber(cached->BlockNumber()),
67 	fVolume(cached->fVolume)
68 {
69 	cached->Keep();
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 status_t
98 CachedBlock::SetTo(off_t block)
99 {
100 	return SetTo(block, block, 1);
101 }
102 
103 
104 inline status_t
105 CachedBlock::SetTo(off_t block, off_t base, size_t length)
106 {
107 	Unset();
108 	fBlockNumber = block;
109 	return block_cache_get_etc(fVolume->BlockCache(), block, base, length,
110 		(const void**)&fBlock);
111 }
112 
113 
114 inline status_t
115 CachedBlock::SetTo(long_address address)
116 {
117 	off_t block;
118 	if (fVolume->MapBlock(address, &block) == B_OK)
119 		return SetTo(block, block, 1);
120 
121 	return B_BAD_VALUE;
122 }
123 
124 
125 template <class Accessor, class Descriptor>
126 inline status_t
127 CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor)
128 {
129 	// Make a long_address out of the descriptor and call it a day
130 	long_address address;
131 	address.set_to(accessor.GetBlock(descriptor),
132 		accessor.GetPartition(descriptor));
133     return SetTo(address);
134 }
135 
136 
137 #endif	// _UDF_CACHED_BLOCK_H
138