btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / src / add-ons / kernel / file_systems / ext2 / Journal.h
blob4ebbb51a7138f49d9f4feb2e6f589856031cb0bd
1 /*
2 * Copyright 2010, Haiku Inc. All rights reserved.
3 * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
4 * This file may be used under the terms of the MIT License.
6 * Authors:
7 * Janito V. Ferreira Filho
8 */
9 #ifndef JOURNAL_H
10 #define JOURNAL_H
13 #define JOURNAL_MAGIC 0xc03b3998U
15 #define JOURNAL_DESCRIPTOR_BLOCK 1
16 #define JOURNAL_COMMIT_BLOCK 2
17 #define JOURNAL_SUPERBLOCK_V1 3
18 #define JOURNAL_SUPERBLOCK_V2 4
19 #define JOURNAL_REVOKE_BLOCK 5
21 #define JOURNAL_FLAG_ESCAPED 1
22 #define JOURNAL_FLAG_SAME_UUID 2
23 #define JOURNAL_FLAG_DELETED 4
24 #define JOURNAL_FLAG_LAST_TAG 8
26 #define JOURNAL_FEATURE_INCOMPATIBLE_REVOKE 1
28 #define JOURNAL_KNOWN_READ_ONLY_COMPATIBLE_FEATURES 0
29 #define JOURNAL_KNOWN_INCOMPATIBLE_FEATURES \
30 JOURNAL_FEATURE_INCOMPATIBLE_REVOKE
33 #include "Volume.h"
35 #include <AutoDeleter.h>
36 #include <util/DoublyLinkedList.h>
38 #include "Transaction.h"
41 class RevokeManager;
44 struct JournalHeader {
45 uint32 magic;
46 uint32 block_type;
47 uint32 sequence;
48 char data[0];
50 uint32 Magic() const
51 { return B_BENDIAN_TO_HOST_INT32(magic); }
52 uint32 BlockType() const
53 { return B_BENDIAN_TO_HOST_INT32(block_type); }
54 uint32 Sequence() const
55 { return B_BENDIAN_TO_HOST_INT32(sequence); }
57 bool CheckMagic() const
58 { return Magic() == JOURNAL_MAGIC; }
60 void IncrementSequence()
61 { sequence = B_HOST_TO_BENDIAN_INT32(Sequence() + 1); }
62 void DecrementSequence()
63 { sequence = B_HOST_TO_BENDIAN_INT32(Sequence() - 1); }
64 void MakeDescriptor(uint32 sequence);
65 void MakeCommit(uint32 sequence);
66 } _PACKED;
69 struct JournalBlockTag {
70 uint32 block_number;
71 uint32 flags;
73 uint32 BlockNumber() const
74 { return B_BENDIAN_TO_HOST_INT32(block_number); }
75 uint32 Flags() const
76 { return B_BENDIAN_TO_HOST_INT32(flags); }
78 void SetBlockNumber(uint32 block)
79 { block_number = B_HOST_TO_BENDIAN_INT32(block); }
80 void SetFlags(uint32 new_flags)
81 { flags = B_HOST_TO_BENDIAN_INT32(new_flags); }
82 void SetLastTagFlag()
83 { flags |= B_HOST_TO_BENDIAN_INT32(JOURNAL_FLAG_LAST_TAG); }
84 void SetEscapedFlag()
85 { flags |= B_HOST_TO_BENDIAN_INT32(JOURNAL_FLAG_ESCAPED); }
86 } _PACKED;
89 struct JournalRevokeHeader {
90 JournalHeader header;
91 uint32 num_bytes;
93 uint32 revoke_blocks[0];
95 uint32 NumBytes() const
96 { return B_BENDIAN_TO_HOST_INT32(num_bytes); }
97 uint32 RevokeBlock(int offset) const
98 { return B_BENDIAN_TO_HOST_INT32(revoke_blocks[offset]); }
99 } _PACKED;
102 struct JournalSuperBlock {
103 JournalHeader header;
105 uint32 block_size;
106 uint32 num_blocks;
107 uint32 first_log_block;
109 uint32 first_commit_id;
110 uint32 log_start;
112 uint32 error;
114 uint32 compatible_features;
115 uint32 incompatible_features;
116 uint32 read_only_compatible_features;
118 uint8 uuid[16];
120 uint32 num_users;
121 uint32 dynamic_superblock;
123 uint32 max_transaction_blocks;
124 uint32 max_transaction_data;
126 uint32 padding[44];
128 uint8 user_ids[16*48];
130 uint32 BlockSize() const
131 { return B_BENDIAN_TO_HOST_INT32(block_size); }
132 uint32 NumBlocks() const
133 { return B_BENDIAN_TO_HOST_INT32(num_blocks); }
134 uint32 FirstLogBlock() const
135 { return B_BENDIAN_TO_HOST_INT32(first_log_block); }
136 uint32 FirstCommitID() const
137 { return B_BENDIAN_TO_HOST_INT32(first_commit_id); }
138 uint32 LogStart() const
139 { return B_BENDIAN_TO_HOST_INT32(log_start); }
140 uint32 IncompatibleFeatures() const
141 { return B_BENDIAN_TO_HOST_INT32(incompatible_features); }
142 uint32 ReadOnlyCompatibleFeatures() const
143 { return B_BENDIAN_TO_HOST_INT32(read_only_compatible_features); }
144 uint32 MaxTransactionBlocks() const
145 { return B_BENDIAN_TO_HOST_INT32(max_transaction_blocks); }
146 uint32 MaxTransactionData() const
147 { return B_BENDIAN_TO_HOST_INT32(max_transaction_data); }
149 void SetLogStart(uint32 logStart)
150 { log_start = B_HOST_TO_BENDIAN_INT32(logStart); }
151 void SetFirstCommitID(uint32 firstCommitID)
152 { first_commit_id = B_HOST_TO_BENDIAN_INT32(firstCommitID); }
153 } _PACKED;
155 class LogEntry;
156 class Transaction;
157 typedef DoublyLinkedList<LogEntry> LogEntryList;
160 class Journal {
161 public:
162 Journal(Volume *fsVolume, Volume *jVolume);
163 virtual ~Journal();
165 virtual status_t InitCheck();
166 virtual status_t Uninit();
168 virtual status_t Recover();
169 virtual status_t StartLog();
170 status_t RestartLog();
172 virtual status_t Lock(Transaction* owner,
173 bool separateSubTransactions);
174 virtual status_t Unlock(Transaction* owner, bool success);
176 virtual status_t MapBlock(off_t logical, fsblock_t& physical);
177 inline uint32 FreeLogBlocks() const;
179 status_t FlushLogAndBlocks();
181 int32 TransactionID() const;
183 Volume* GetFilesystemVolume()
184 { return fFilesystemVolume; }
185 protected:
186 Journal();
188 status_t _WritePartialTransactionToLog(
189 JournalHeader* descriptorBlock,
190 bool detached, uint8** escapedBlock,
191 uint32& logBlock, off_t& blockNumber,
192 long& cookie,
193 ArrayDeleter<uint8>& escapedDataDeleter,
194 uint32& blockCount, bool& finished);
195 virtual status_t _WriteTransactionToLog();
197 status_t _SaveSuperBlock();
198 status_t _LoadSuperBlock();
201 Volume* fJournalVolume;
202 void* fJournalBlockCache;
203 Volume* fFilesystemVolume;
204 void* fFilesystemBlockCache;
206 recursive_lock fLock;
207 Transaction* fOwner;
209 RevokeManager* fRevokeManager;
211 status_t fInitStatus;
212 uint32 fBlockSize;
213 uint32 fFirstCommitID;
214 uint32 fFirstCacheCommitID;
215 uint32 fFirstLogBlock;
216 uint32 fLogSize;
217 uint32 fVersion;
219 bool fIsStarted;
220 uint32 fLogStart;
221 uint32 fLogEnd;
222 uint32 fFreeBlocks;
223 uint32 fMaxTransactionSize;
225 uint32 fCurrentCommitID;
227 LogEntryList fLogEntries;
228 mutex fLogEntriesLock;
229 bool fHasSubTransaction;
230 bool fSeparateSubTransactions;
231 int32 fUnwrittenTransactions;
232 int32 fTransactionID;
234 private:
235 status_t _CheckFeatures(JournalSuperBlock* superblock);
237 uint32 _CountTags(JournalHeader *descriptorBlock);
238 status_t _RecoverPassScan(uint32& lastCommitID);
239 status_t _RecoverPassRevoke(uint32 lastCommitID);
240 status_t _RecoverPassReplay(uint32 lastCommitID);
242 status_t _FlushLog(bool canWait, bool flushBlocks);
244 inline uint32 _WrapAroundLog(uint32 block);
246 size_t _CurrentTransactionSize() const;
247 size_t _FullTransactionSize() const;
248 size_t _MainTransactionSize() const;
250 virtual status_t _TransactionDone(bool success);
252 static void _TransactionWritten(int32 transactionID,
253 int32 event, void* _logEntry);
254 static void _TransactionIdle(int32 transactionID,
255 int32 event, void* _journal);
258 #endif // JOURNAL_H