The structure of the Reiser file system
It can often be read that reiserfs only records the file system meta data in its journal. This is not entirely correct. It is true, that purpose of the journaling is to ensure the integrity of the meta data. However, reiserfs journals entire disk blocks as they have to appear in the file system after the journal transaction is committed. Since directories, stat data and small files are stored directly in the leaf nodes of the tree, some amount of data is also contained in the journal and could be used to reconstruct earlier versions of a file or directory.
Journal Header The journal header is a single block which describes where the first unflushed transaction can be found in the journal. The journal header is the last block of the journal. In our example the journal's first transaction starts at block 18 and there are 8192 journal blocks. Therefore. the journal header is at block 8210. There are only 12 bytes of information in the journal header. The rest of the block is undefined.
Name |
Size |
Description |
Last flush ID |
4 |
The transaction ID of the last fully flushed transaction |
Unflushed offset |
4 |
The offset (in blocks) of the next transaction in the journal |
Mount ID |
4 |
The mount ID of the flushed transaction |
The transaction pointed to by the offset must have a higher transaction ID or a higher mount ID than the flushed transaction in order to be considered an unflushed transaction. If this is not the case, all transactions are considered flushed and the block pointed to by the offset is used to start recording new journal transactions.
Example:
00000000 e2 74 02 00 24 1c 00 00 1d 01 00 00 12 00 00 00 ât..$...........
Last flush ID: 160994 Unflushed offset: 7204 blocks Mount ID: 285
In this example, the first unflushed transaction can be found at block 7222 (since the journal starts at block 18). However, the block found there does not contain a transaction description (see below) and therefore there aren't any unflushed transactions for the partition.
Transactions Transactions describe changes in the file system. Instead of directly modifying blocks in the file system tree, instead the new or changed blocks are first written into the journal and mapped to their real location in the file system.
A transaction consists of a transaction description block, a list of blocks, and a commit block at the end. All those blocks are contiguous within the journal.
Description block The description block contains the transaction and mount IDs, the number of blocks in the transaction, a magic number, and the first possible half of mappings.
Name |
Size |
Description |
Transaction ID |
4 |
The transaction ID |
Len |
4 |
Length (in blocks) of the transaction |
Mount ID |
4 |
Mount ID of the transaction |
Real blocks |
Block size - 24 |
Mapping for blocks in transaction |
Magic |
12 |
Magic number. Should be "ReIsErLB" |
The "Real blocks" field is theoretically dependant on the block size. The first 12 bytes of the block have the IDs and the length, and the last 12 bytes contain the magic string. Everything in between is used for the block mapping. However, in the Linux 2.4.x implementation, the struct for a description block defines |