xref: /haiku/src/add-ons/kernel/file_systems/bfs/Volume.h (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
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 VOLUME_H
6 #define VOLUME_H
7 
8 
9 #include "system_dependencies.h"
10 
11 #include "bfs.h"
12 #include "BlockAllocator.h"
13 
14 class Journal;
15 class Inode;
16 class Query;
17 
18 enum volume_flags {
19 	VOLUME_READ_ONLY	= 0x0001
20 };
21 
22 enum volume_initialize_flags {
23 	VOLUME_NO_INDICES	= 0x0001,
24 };
25 
26 class Volume {
27 public:
28 							Volume(fs_volume* volume);
29 							~Volume();
30 
31 			status_t		Mount(const char* device, uint32 flags);
32 			status_t		Unmount();
33 			status_t		Initialize(int fd, const char* name,
34 								uint32 blockSize, uint32 flags);
35 
36 			bool			IsInitializing() const { return fVolume == NULL; }
37 
38 			bool			IsValidSuperBlock();
39 			bool			IsReadOnly() const;
40 			void			Panic();
41 			mutex&			Lock();
42 
43 			block_run		Root() const { return fSuperBlock.root_dir; }
44 			Inode*			RootNode() const { return fRootNode; }
45 			block_run		Indices() const { return fSuperBlock.indices; }
46 			Inode*			IndicesNode() const { return fIndicesNode; }
47 			block_run		Log() const { return fSuperBlock.log_blocks; }
48 			vint32&			LogStart() { return fLogStart; }
49 			vint32&			LogEnd() { return fLogEnd; }
50 			int				Device() const { return fDevice; }
51 
52 			dev_t			ID() const { return fVolume ? fVolume->id : -1; }
53 			fs_volume*		FSVolume() const { return fVolume; }
54 			const char*		Name() const { return fSuperBlock.name; }
55 
56 			off_t			NumBlocks() const
57 								{ return fSuperBlock.NumBlocks(); }
58 			off_t			UsedBlocks() const
59 								{ return fSuperBlock.UsedBlocks(); }
60 			off_t			FreeBlocks() const
61 								{ return NumBlocks() - UsedBlocks(); }
62 
63 			uint32			BlockSize() const { return fBlockSize; }
64 			uint32			BlockShift() const { return fBlockShift; }
65 			uint32			InodeSize() const
66 								{ return fSuperBlock.InodeSize(); }
67 			uint32			AllocationGroups() const
68 								{ return fSuperBlock.AllocationGroups(); }
69 			uint32			AllocationGroupShift() const
70 								{ return fAllocationGroupShift; }
71 			disk_super_block& SuperBlock() { return fSuperBlock; }
72 
73 			off_t			ToOffset(block_run run) const
74 								{ return ToBlock(run) << BlockShift(); }
75 			off_t			ToBlock(block_run run) const
76 								{ return ((((off_t)run.AllocationGroup())
77 										<< AllocationGroupShift())
78 									| (off_t)run.Start()); }
79 			block_run		ToBlockRun(off_t block) const;
80 			status_t		ValidateBlockRun(block_run run);
81 
82 			off_t			ToVnode(block_run run) const
83 								{ return ToBlock(run); }
84 			off_t			ToVnode(off_t block) const { return block; }
85 			off_t			VnodeToBlock(ino_t id) const { return (off_t)id; }
86 
87 			status_t		CreateIndicesRoot(Transaction& transaction);
88 
89 			// block bitmap
90 			BlockAllocator&	Allocator();
91 			status_t		AllocateForInode(Transaction& transaction,
92 								const Inode* parent, mode_t type,
93 								block_run& run);
94 			status_t		AllocateForInode(Transaction& transaction,
95 								const block_run* parent, mode_t type,
96 								block_run& run);
97 			status_t		Allocate(Transaction& transaction, Inode* inode,
98 								off_t numBlocks, block_run& run,
99 								uint16 minimum = 1);
100 			status_t		Free(Transaction& transaction, block_run run);
101 
102 			// cache access
103 			status_t		WriteSuperBlock();
104 			status_t		FlushDevice();
105 
106 			// queries
107 			void			UpdateLiveQueries(Inode* inode,
108 								const char* attribute, int32 type,
109 								const uint8* oldKey, size_t oldLength,
110 								const uint8* newKey, size_t newLength);
111 			bool			CheckForLiveQuery(const char* attribute);
112 			void			AddQuery(Query* query);
113 			void			RemoveQuery(Query* query);
114 
115 			status_t		Sync();
116 			Journal*		GetJournal(off_t refBlock) const;
117 
118 			void*			BlockCache() { return fBlockCache; }
119 
120 			uint32			GetUniqueID();
121 
122 	static	status_t		CheckSuperBlock(const uint8* data,
123 								uint32* _offset = NULL);
124 	static	status_t		Identify(int fd, disk_super_block* superBlock);
125 
126 	protected:
127 			fs_volume*		fVolume;
128 			int				fDevice;
129 			disk_super_block fSuperBlock;
130 
131 			uint32			fBlockSize;
132 			uint32			fBlockShift;
133 			uint32			fAllocationGroupShift;
134 
135 			BlockAllocator	fBlockAllocator;
136 			mutex			fLock;
137 			Journal*		fJournal;
138 			vint32			fLogStart;
139 			vint32			fLogEnd;
140 
141 			Inode*			fRootNode;
142 			Inode*			fIndicesNode;
143 
144 			vint32			fDirtyCachedBlocks;
145 
146 			mutex			fQueryLock;
147 			SinglyLinkedList<Query> fQueries;
148 
149 			int32			fUniqueID;
150 			uint32			fFlags;
151 
152 			void*			fBlockCache;
153 };
154 
155 
156 // inline functions
157 
158 inline bool
159 Volume::IsReadOnly() const
160 {
161 	 return fFlags & VOLUME_READ_ONLY;
162 }
163 
164 
165 inline mutex&
166 Volume::Lock()
167 {
168 	 return fLock;
169 }
170 
171 
172 inline BlockAllocator&
173 Volume::Allocator()
174 {
175 	 return fBlockAllocator;
176 }
177 
178 
179 inline status_t
180 Volume::AllocateForInode(Transaction& transaction, const block_run* parent,
181 	mode_t type, block_run& run)
182 {
183 	return fBlockAllocator.AllocateForInode(transaction, parent, type, run);
184 }
185 
186 
187 inline status_t
188 Volume::Allocate(Transaction& transaction, Inode* inode, off_t numBlocks,
189 	block_run& run, uint16 minimum)
190 {
191 	return fBlockAllocator.Allocate(transaction, inode, numBlocks, run,
192 		minimum);
193 }
194 
195 
196 inline status_t
197 Volume::Free(Transaction& transaction, block_run run)
198 {
199 	return fBlockAllocator.Free(transaction, run);
200 }
201 
202 
203 inline status_t
204 Volume::FlushDevice()
205 {
206 	return block_cache_sync(fBlockCache);
207 }
208 
209 
210 inline Journal*
211 Volume::GetJournal(off_t /*refBlock*/) const
212 {
213 	 return fJournal;
214 }
215 
216 
217 inline uint32
218 Volume::GetUniqueID()
219 {
220 	 return atomic_add(&fUniqueID, 1);
221 }
222 
223 #endif	// VOLUME_H
224