xref: /haiku/src/add-ons/kernel/file_systems/ext2/Volume.h (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
1 /*
2  * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
3  * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
4  * This file may be used under the terms of the MIT License.
5  */
6 #ifndef VOLUME_H
7 #define VOLUME_H
8 
9 
10 #include <lock.h>
11 
12 #include "ext2.h"
13 #include "BlockAllocator.h"
14 #include "InodeAllocator.h"
15 #include "Transaction.h"
16 
17 class Inode;
18 class Journal;
19 
20 
21 enum volume_flags {
22 	VOLUME_READ_ONLY	= 0x0001
23 };
24 
25 
26 class Volume : public TransactionListener {
27 public:
28 								Volume(fs_volume* volume);
29 								~Volume();
30 
31 			status_t			Mount(const char* device, uint32 flags);
32 			status_t			Unmount();
33 
34 			bool				IsValidSuperBlock();
35 			bool				IsReadOnly() const
36 									{ return (fFlags & VOLUME_READ_ONLY) != 0; }
37 			mutex&				Lock();
38 			bool				HasExtendedAttributes() const;
39 
40 			Inode*				RootNode() const { return fRootNode; }
41 			int					Device() const { return fDevice; }
42 
43 			dev_t				ID() const
44 									{ return fFSVolume ? fFSVolume->id : -1; }
45 			fs_volume*			FSVolume() const { return fFSVolume; }
46 			const char*			Name() const;
47 			void				SetName(const char* name);
48 
49 			uint32				NumInodes() const
50 									{ return fNumInodes; }
51 			uint32				NumGroups() const
52 									{ return fNumGroups; }
53 			fsblock_t			NumBlocks() const
54 									{ return fSuperBlock.NumBlocks(
55 										Has64bitFeature()); }
56 			off_t				NumFreeBlocks() const
57 									{ return fFreeBlocks; }
58 			uint32				FirstDataBlock() const
59 									{ return fFirstDataBlock; }
60 
61 			uint32				BlockSize() const { return fBlockSize; }
62 			uint32				BlockShift() const { return fBlockShift; }
63 			uint32				BlocksPerGroup() const
64 									{ return fSuperBlock.BlocksPerGroup(); }
65 			uint32				InodeSize() const
66 									{ return fSuperBlock.InodeSize(); }
67 			uint32				InodesPerGroup() const
68 									{ return fSuperBlock.InodesPerGroup(); }
69 			ext2_super_block&	SuperBlock() { return fSuperBlock; }
70 
71 			status_t			GetInodeBlock(ino_t id, off_t& block);
72 			uint32				InodeBlockIndex(ino_t id) const;
73 			status_t			GetBlockGroup(int32 index,
74 									ext2_block_group** _group);
75 			status_t			WriteBlockGroup(Transaction& transaction,
76 									int32 index);
77 
78 			Journal*			GetJournal() { return fJournal; }
79 
80 			bool				IndexedDirectories() const
81 								{ return (fSuperBlock.CompatibleFeatures()
82 									& EXT2_FEATURE_DIRECTORY_INDEX) != 0; }
83 			bool				HasJournalFeature() const
84 								{ return (fSuperBlock.CompatibleFeatures()
85 									& EXT2_FEATURE_HAS_JOURNAL) != 0; }
86 			bool				Has64bitFeature() const
87 								{ return (fSuperBlock.IncompatibleFeatures()
88 									& EXT2_INCOMPATIBLE_FEATURE_64BIT) != 0; }
89 			bool				HasExtentsFeature() const
90 								{ return (fSuperBlock.IncompatibleFeatures()
91 									& EXT2_INCOMPATIBLE_FEATURE_EXTENTS)
92 									!= 0; }
93 			bool				HasChecksumFeature() const
94 								{ return (fSuperBlock.ReadOnlyFeatures()
95 									& EXT2_READ_ONLY_FEATURE_GDT_CSUM) != 0; }
96 			bool				HasMetaGroupFeature() const
97 								{ return (fSuperBlock.IncompatibleFeatures()
98 									& EXT2_INCOMPATIBLE_FEATURE_META_GROUP)
99 									!= 0; }
100 			bool				HasMetaGroupChecksumFeature() const
101 								{ return (fSuperBlock.ReadOnlyFeatures()
102 									& EXT4_READ_ONLY_FEATURE_METADATA_CSUM)
103 									!= 0; }
104 			bool				HasChecksumSeedFeature() const
105 								{ return (fSuperBlock.IncompatibleFeatures()
106 									& EXT2_INCOMPATIBLE_FEATURE_CSUM_SEED)
107 									!= 0; }
108 			uint8				DefaultHashVersion() const
109 								{ return fSuperBlock.default_hash_version; }
110 			bool				HugeFiles() const
111 								{ return (fSuperBlock.ReadOnlyFeatures()
112 									& EXT2_READ_ONLY_FEATURE_HUGE_FILE) != 0; }
113 			status_t			ActivateLargeFiles(Transaction& transaction);
114 			status_t			ActivateDirNLink(Transaction& transaction);
115 
116 			status_t			SaveOrphan(Transaction& transaction,
117 									ino_t newID, ino_t &oldID);
118 			status_t			RemoveOrphan(Transaction& transaction,
119 									ino_t id);
120 
121 			status_t			AllocateInode(Transaction& transaction,
122 									Inode* parent, int32 mode, ino_t& id);
123 			status_t			FreeInode(Transaction& transaction, ino_t id,
124 									bool isDirectory);
125 
126 			status_t			AllocateBlocks(Transaction& transaction,
127 									uint32 minimum, uint32 maximum,
128 									uint32& blockGroup, fsblock_t& start,
129 									uint32& length);
130 			status_t			FreeBlocks(Transaction& transaction,
131 									fsblock_t start, uint32 length);
132 
133 			status_t			LoadSuperBlock();
134 			status_t			WriteSuperBlock(Transaction& transaction);
135 
136 			// cache access
137 			void*				BlockCache() { return fBlockCache; }
138 
139 			uint32				ChecksumSeed() const
140 									{ return fChecksumSeed; }
141 			uint16				GroupDescriptorSize() const
142 									{ return fGroupDescriptorSize; }
143 
144 			status_t			FlushDevice();
145 			status_t			Sync();
146 
147 	static	status_t			Identify(int fd, ext2_super_block* superBlock);
148 
149 			// TransactionListener functions
150 			void				TransactionDone(bool success);
151 			void				RemovedFromTransaction();
152 
153 private:
154 	static	uint32				_UnsupportedIncompatibleFeatures(
155 									ext2_super_block& superBlock);
156 	static	uint32				_UnsupportedReadOnlyFeatures(
157 									ext2_super_block& superBlock);
158 			uint32				_GroupDescriptorBlock(uint32 blockIndex);
159 			uint16				_GroupCheckSum(ext2_block_group *group,
160 									int32 index);
161 			void				_SuperBlockChecksumSeed();
162 			bool				_VerifySuperBlock();
163 
164 private:
165 			mutex				fLock;
166 			fs_volume*			fFSVolume;
167 			int					fDevice;
168 			ext2_super_block	fSuperBlock;
169 
170 			BlockAllocator*		fBlockAllocator;
171 			InodeAllocator		fInodeAllocator;
172 			Journal*			fJournal;
173 			Inode*				fJournalInode;
174 
175 			uint32				fFlags;
176 			uint32				fBlockSize;
177 			uint32				fBlockShift;
178 			uint32				fFirstDataBlock;
179 
180 			uint32				fNumInodes;
181 			uint32				fNumGroups;
182 			off_t				fFreeBlocks;
183 			uint32				fFreeInodes;
184 			uint32				fGroupsPerBlock;
185 			uint8**				fGroupBlocks;
186 			uint32				fInodesPerBlock;
187 			uint16				fGroupDescriptorSize;
188 
189 			void*				fBlockCache;
190 			Inode*				fRootNode;
191 
192 			uint32				fChecksumSeed;
193 };
194 
195 
196 inline mutex&
197 Volume::Lock()
198 {
199 	 return fLock;
200 }
201 
202 #endif	// VOLUME_H
203