162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ciJournal (jbd2)
462306a36Sopenharmony_ci--------------
562306a36Sopenharmony_ci
662306a36Sopenharmony_ciIntroduced in ext3, the ext4 filesystem employs a journal to protect the
762306a36Sopenharmony_cifilesystem against metadata inconsistencies in the case of a system crash. Up
862306a36Sopenharmony_cito 10,240,000 file system blocks (see man mke2fs(8) for more details on journal
962306a36Sopenharmony_cisize limits) can be reserved inside the filesystem as a place to land
1062306a36Sopenharmony_ci“important” data writes on-disk as quickly as possible. Once the important
1162306a36Sopenharmony_cidata transaction is fully written to the disk and flushed from the disk write
1262306a36Sopenharmony_cicache, a record of the data being committed is also written to the journal. At
1362306a36Sopenharmony_cisome later point in time, the journal code writes the transactions to their
1462306a36Sopenharmony_cifinal locations on disk (this could involve a lot of seeking or a lot of small
1562306a36Sopenharmony_ciread-write-erases) before erasing the commit record. Should the system
1662306a36Sopenharmony_cicrash during the second slow write, the journal can be replayed all the
1762306a36Sopenharmony_ciway to the latest commit record, guaranteeing the atomicity of whatever
1862306a36Sopenharmony_cigets written through the journal to the disk. The effect of this is to
1962306a36Sopenharmony_ciguarantee that the filesystem does not become stuck midway through a
2062306a36Sopenharmony_cimetadata update.
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciFor performance reasons, ext4 by default only writes filesystem metadata
2362306a36Sopenharmony_cithrough the journal. This means that file data blocks are /not/
2462306a36Sopenharmony_ciguaranteed to be in any consistent state after a crash. If this default
2562306a36Sopenharmony_ciguarantee level (``data=ordered``) is not satisfactory, there is a mount
2662306a36Sopenharmony_cioption to control journal behavior. If ``data=journal``, all data and
2762306a36Sopenharmony_cimetadata are written to disk through the journal. This is slower but
2862306a36Sopenharmony_cisafest. If ``data=writeback``, dirty data blocks are not flushed to the
2962306a36Sopenharmony_cidisk before the metadata are written to disk through the journal.
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciIn case of ``data=ordered`` mode, Ext4 also supports fast commits which
3262306a36Sopenharmony_cihelp reduce commit latency significantly. The default ``data=ordered``
3362306a36Sopenharmony_cimode works by logging metadata blocks to the journal. In fast commit
3462306a36Sopenharmony_cimode, Ext4 only stores the minimal delta needed to recreate the
3562306a36Sopenharmony_ciaffected metadata in fast commit space that is shared with JBD2.
3662306a36Sopenharmony_ciOnce the fast commit area fills in or if fast commit is not possible
3762306a36Sopenharmony_cior if JBD2 commit timer goes off, Ext4 performs a traditional full commit.
3862306a36Sopenharmony_ciA full commit invalidates all the fast commits that happened before
3962306a36Sopenharmony_ciit and thus it makes the fast commit area empty for further fast
4062306a36Sopenharmony_cicommits. This feature needs to be enabled at mkfs time.
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciThe journal inode is typically inode 8. The first 68 bytes of the
4362306a36Sopenharmony_cijournal inode are replicated in the ext4 superblock. The journal itself
4462306a36Sopenharmony_ciis normal (but hidden) file within the filesystem. The file usually
4562306a36Sopenharmony_ciconsumes an entire block group, though mke2fs tries to put it in the
4662306a36Sopenharmony_cimiddle of the disk.
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciAll fields in jbd2 are written to disk in big-endian order. This is the
4962306a36Sopenharmony_ciopposite of ext4.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciNOTE: Both ext4 and ocfs2 use jbd2.
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ciThe maximum size of a journal embedded in an ext4 filesystem is 2^32
5462306a36Sopenharmony_ciblocks. jbd2 itself does not seem to care.
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciLayout
5762306a36Sopenharmony_ci~~~~~~
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciGenerally speaking, the journal has this format:
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci.. list-table::
6262306a36Sopenharmony_ci   :widths: 16 48 16
6362306a36Sopenharmony_ci   :header-rows: 1
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci   * - Superblock
6662306a36Sopenharmony_ci     - descriptor_block (data_blocks or revocation_block) [more data or
6762306a36Sopenharmony_ci       revocations] commmit_block
6862306a36Sopenharmony_ci     - [more transactions...]
6962306a36Sopenharmony_ci   * - 
7062306a36Sopenharmony_ci     - One transaction
7162306a36Sopenharmony_ci     -
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciNotice that a transaction begins with either a descriptor and some data,
7462306a36Sopenharmony_cior a block revocation list. A finished transaction always ends with a
7562306a36Sopenharmony_cicommit. If there is no commit record (or the checksums don't match), the
7662306a36Sopenharmony_citransaction will be discarded during replay.
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ciExternal Journal
7962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ciOptionally, an ext4 filesystem can be created with an external journal
8262306a36Sopenharmony_cidevice (as opposed to an internal journal, which uses a reserved inode).
8362306a36Sopenharmony_ciIn this case, on the filesystem device, ``s_journal_inum`` should be
8462306a36Sopenharmony_cizero and ``s_journal_uuid`` should be set. On the journal device there
8562306a36Sopenharmony_ciwill be an ext4 super block in the usual place, with a matching UUID.
8662306a36Sopenharmony_ciThe journal superblock will be in the next full block after the
8762306a36Sopenharmony_cisuperblock.
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci.. list-table::
9062306a36Sopenharmony_ci   :widths: 12 12 12 32 12
9162306a36Sopenharmony_ci   :header-rows: 1
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci   * - 1024 bytes of padding
9462306a36Sopenharmony_ci     - ext4 Superblock
9562306a36Sopenharmony_ci     - Journal Superblock
9662306a36Sopenharmony_ci     - descriptor_block (data_blocks or revocation_block) [more data or
9762306a36Sopenharmony_ci       revocations] commmit_block
9862306a36Sopenharmony_ci     - [more transactions...]
9962306a36Sopenharmony_ci   * - 
10062306a36Sopenharmony_ci     -
10162306a36Sopenharmony_ci     -
10262306a36Sopenharmony_ci     - One transaction
10362306a36Sopenharmony_ci     -
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciBlock Header
10662306a36Sopenharmony_ci~~~~~~~~~~~~
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ciEvery block in the journal starts with a common 12-byte header
10962306a36Sopenharmony_ci``struct journal_header_s``:
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci.. list-table::
11262306a36Sopenharmony_ci   :widths: 8 8 24 40
11362306a36Sopenharmony_ci   :header-rows: 1
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci   * - Offset
11662306a36Sopenharmony_ci     - Type
11762306a36Sopenharmony_ci     - Name
11862306a36Sopenharmony_ci     - Description
11962306a36Sopenharmony_ci   * - 0x0
12062306a36Sopenharmony_ci     - __be32
12162306a36Sopenharmony_ci     - h_magic
12262306a36Sopenharmony_ci     - jbd2 magic number, 0xC03B3998.
12362306a36Sopenharmony_ci   * - 0x4
12462306a36Sopenharmony_ci     - __be32
12562306a36Sopenharmony_ci     - h_blocktype
12662306a36Sopenharmony_ci     - Description of what this block contains. See the jbd2_blocktype_ table
12762306a36Sopenharmony_ci       below.
12862306a36Sopenharmony_ci   * - 0x8
12962306a36Sopenharmony_ci     - __be32
13062306a36Sopenharmony_ci     - h_sequence
13162306a36Sopenharmony_ci     - The transaction ID that goes with this block.
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci.. _jbd2_blocktype:
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciThe journal block type can be any one of:
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci.. list-table::
13862306a36Sopenharmony_ci   :widths: 16 64
13962306a36Sopenharmony_ci   :header-rows: 1
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci   * - Value
14262306a36Sopenharmony_ci     - Description
14362306a36Sopenharmony_ci   * - 1
14462306a36Sopenharmony_ci     - Descriptor. This block precedes a series of data blocks that were
14562306a36Sopenharmony_ci       written through the journal during a transaction.
14662306a36Sopenharmony_ci   * - 2
14762306a36Sopenharmony_ci     - Block commit record. This block signifies the completion of a
14862306a36Sopenharmony_ci       transaction.
14962306a36Sopenharmony_ci   * - 3
15062306a36Sopenharmony_ci     - Journal superblock, v1.
15162306a36Sopenharmony_ci   * - 4
15262306a36Sopenharmony_ci     - Journal superblock, v2.
15362306a36Sopenharmony_ci   * - 5
15462306a36Sopenharmony_ci     - Block revocation records. This speeds up recovery by enabling the
15562306a36Sopenharmony_ci       journal to skip writing blocks that were subsequently rewritten.
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ciSuper Block
15862306a36Sopenharmony_ci~~~~~~~~~~~
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ciThe super block for the journal is much simpler as compared to ext4's.
16162306a36Sopenharmony_ciThe key data kept within are size of the journal, and where to find the
16262306a36Sopenharmony_cistart of the log of transactions.
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciThe journal superblock is recorded as ``struct journal_superblock_s``,
16562306a36Sopenharmony_ciwhich is 1024 bytes long:
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci.. list-table::
16862306a36Sopenharmony_ci   :widths: 8 8 24 40
16962306a36Sopenharmony_ci   :header-rows: 1
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci   * - Offset
17262306a36Sopenharmony_ci     - Type
17362306a36Sopenharmony_ci     - Name
17462306a36Sopenharmony_ci     - Description
17562306a36Sopenharmony_ci   * -
17662306a36Sopenharmony_ci     -
17762306a36Sopenharmony_ci     -
17862306a36Sopenharmony_ci     - Static information describing the journal.
17962306a36Sopenharmony_ci   * - 0x0
18062306a36Sopenharmony_ci     - journal_header_t (12 bytes)
18162306a36Sopenharmony_ci     - s_header
18262306a36Sopenharmony_ci     - Common header identifying this as a superblock.
18362306a36Sopenharmony_ci   * - 0xC
18462306a36Sopenharmony_ci     - __be32
18562306a36Sopenharmony_ci     - s_blocksize
18662306a36Sopenharmony_ci     - Journal device block size.
18762306a36Sopenharmony_ci   * - 0x10
18862306a36Sopenharmony_ci     - __be32
18962306a36Sopenharmony_ci     - s_maxlen
19062306a36Sopenharmony_ci     - Total number of blocks in this journal.
19162306a36Sopenharmony_ci   * - 0x14
19262306a36Sopenharmony_ci     - __be32
19362306a36Sopenharmony_ci     - s_first
19462306a36Sopenharmony_ci     - First block of log information.
19562306a36Sopenharmony_ci   * -
19662306a36Sopenharmony_ci     -
19762306a36Sopenharmony_ci     -
19862306a36Sopenharmony_ci     - Dynamic information describing the current state of the log.
19962306a36Sopenharmony_ci   * - 0x18
20062306a36Sopenharmony_ci     - __be32
20162306a36Sopenharmony_ci     - s_sequence
20262306a36Sopenharmony_ci     - First commit ID expected in log.
20362306a36Sopenharmony_ci   * - 0x1C
20462306a36Sopenharmony_ci     - __be32
20562306a36Sopenharmony_ci     - s_start
20662306a36Sopenharmony_ci     - Block number of the start of log. Contrary to the comments, this field
20762306a36Sopenharmony_ci       being zero does not imply that the journal is clean!
20862306a36Sopenharmony_ci   * - 0x20
20962306a36Sopenharmony_ci     - __be32
21062306a36Sopenharmony_ci     - s_errno
21162306a36Sopenharmony_ci     - Error value, as set by jbd2_journal_abort().
21262306a36Sopenharmony_ci   * -
21362306a36Sopenharmony_ci     -
21462306a36Sopenharmony_ci     -
21562306a36Sopenharmony_ci     - The remaining fields are only valid in a v2 superblock.
21662306a36Sopenharmony_ci   * - 0x24
21762306a36Sopenharmony_ci     - __be32
21862306a36Sopenharmony_ci     - s_feature_compat;
21962306a36Sopenharmony_ci     - Compatible feature set. See the table jbd2_compat_ below.
22062306a36Sopenharmony_ci   * - 0x28
22162306a36Sopenharmony_ci     - __be32
22262306a36Sopenharmony_ci     - s_feature_incompat
22362306a36Sopenharmony_ci     - Incompatible feature set. See the table jbd2_incompat_ below.
22462306a36Sopenharmony_ci   * - 0x2C
22562306a36Sopenharmony_ci     - __be32
22662306a36Sopenharmony_ci     - s_feature_ro_compat
22762306a36Sopenharmony_ci     - Read-only compatible feature set. There aren't any of these currently.
22862306a36Sopenharmony_ci   * - 0x30
22962306a36Sopenharmony_ci     - __u8
23062306a36Sopenharmony_ci     - s_uuid[16]
23162306a36Sopenharmony_ci     - 128-bit uuid for journal. This is compared against the copy in the ext4
23262306a36Sopenharmony_ci       super block at mount time.
23362306a36Sopenharmony_ci   * - 0x40
23462306a36Sopenharmony_ci     - __be32
23562306a36Sopenharmony_ci     - s_nr_users
23662306a36Sopenharmony_ci     - Number of file systems sharing this journal.
23762306a36Sopenharmony_ci   * - 0x44
23862306a36Sopenharmony_ci     - __be32
23962306a36Sopenharmony_ci     - s_dynsuper
24062306a36Sopenharmony_ci     - Location of dynamic super block copy. (Not used?)
24162306a36Sopenharmony_ci   * - 0x48
24262306a36Sopenharmony_ci     - __be32
24362306a36Sopenharmony_ci     - s_max_transaction
24462306a36Sopenharmony_ci     - Limit of journal blocks per transaction. (Not used?)
24562306a36Sopenharmony_ci   * - 0x4C
24662306a36Sopenharmony_ci     - __be32
24762306a36Sopenharmony_ci     - s_max_trans_data
24862306a36Sopenharmony_ci     - Limit of data blocks per transaction. (Not used?)
24962306a36Sopenharmony_ci   * - 0x50
25062306a36Sopenharmony_ci     - __u8
25162306a36Sopenharmony_ci     - s_checksum_type
25262306a36Sopenharmony_ci     - Checksum algorithm used for the journal.  See jbd2_checksum_type_ for
25362306a36Sopenharmony_ci       more info.
25462306a36Sopenharmony_ci   * - 0x51
25562306a36Sopenharmony_ci     - __u8[3]
25662306a36Sopenharmony_ci     - s_padding2
25762306a36Sopenharmony_ci     -
25862306a36Sopenharmony_ci   * - 0x54
25962306a36Sopenharmony_ci     - __be32
26062306a36Sopenharmony_ci     - s_num_fc_blocks
26162306a36Sopenharmony_ci     - Number of fast commit blocks in the journal.
26262306a36Sopenharmony_ci   * - 0x58
26362306a36Sopenharmony_ci     - __be32
26462306a36Sopenharmony_ci     - s_head
26562306a36Sopenharmony_ci     - Block number of the head (first unused block) of the journal, only
26662306a36Sopenharmony_ci       up-to-date when the journal is empty.
26762306a36Sopenharmony_ci   * - 0x5C
26862306a36Sopenharmony_ci     - __u32
26962306a36Sopenharmony_ci     - s_padding[40]
27062306a36Sopenharmony_ci     -
27162306a36Sopenharmony_ci   * - 0xFC
27262306a36Sopenharmony_ci     - __be32
27362306a36Sopenharmony_ci     - s_checksum
27462306a36Sopenharmony_ci     - Checksum of the entire superblock, with this field set to zero.
27562306a36Sopenharmony_ci   * - 0x100
27662306a36Sopenharmony_ci     - __u8
27762306a36Sopenharmony_ci     - s_users[16*48]
27862306a36Sopenharmony_ci     - ids of all file systems sharing the log. e2fsprogs/Linux don't allow
27962306a36Sopenharmony_ci       shared external journals, but I imagine Lustre (or ocfs2?), which use
28062306a36Sopenharmony_ci       the jbd2 code, might.
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci.. _jbd2_compat:
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ciThe journal compat features are any combination of the following:
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci.. list-table::
28762306a36Sopenharmony_ci   :widths: 16 64
28862306a36Sopenharmony_ci   :header-rows: 1
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci   * - Value
29162306a36Sopenharmony_ci     - Description
29262306a36Sopenharmony_ci   * - 0x1
29362306a36Sopenharmony_ci     - Journal maintains checksums on the data blocks.
29462306a36Sopenharmony_ci       (JBD2_FEATURE_COMPAT_CHECKSUM)
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci.. _jbd2_incompat:
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ciThe journal incompat features are any combination of the following:
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci.. list-table::
30162306a36Sopenharmony_ci   :widths: 16 64
30262306a36Sopenharmony_ci   :header-rows: 1
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci   * - Value
30562306a36Sopenharmony_ci     - Description
30662306a36Sopenharmony_ci   * - 0x1
30762306a36Sopenharmony_ci     - Journal has block revocation records. (JBD2_FEATURE_INCOMPAT_REVOKE)
30862306a36Sopenharmony_ci   * - 0x2
30962306a36Sopenharmony_ci     - Journal can deal with 64-bit block numbers.
31062306a36Sopenharmony_ci       (JBD2_FEATURE_INCOMPAT_64BIT)
31162306a36Sopenharmony_ci   * - 0x4
31262306a36Sopenharmony_ci     - Journal commits asynchronously. (JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)
31362306a36Sopenharmony_ci   * - 0x8
31462306a36Sopenharmony_ci     - This journal uses v2 of the checksum on-disk format. Each journal
31562306a36Sopenharmony_ci       metadata block gets its own checksum, and the block tags in the
31662306a36Sopenharmony_ci       descriptor table contain checksums for each of the data blocks in the
31762306a36Sopenharmony_ci       journal. (JBD2_FEATURE_INCOMPAT_CSUM_V2)
31862306a36Sopenharmony_ci   * - 0x10
31962306a36Sopenharmony_ci     - This journal uses v3 of the checksum on-disk format. This is the same as
32062306a36Sopenharmony_ci       v2, but the journal block tag size is fixed regardless of the size of
32162306a36Sopenharmony_ci       block numbers. (JBD2_FEATURE_INCOMPAT_CSUM_V3)
32262306a36Sopenharmony_ci   * - 0x20
32362306a36Sopenharmony_ci     - Journal has fast commit blocks. (JBD2_FEATURE_INCOMPAT_FAST_COMMIT)
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci.. _jbd2_checksum_type:
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ciJournal checksum type codes are one of the following.  crc32 or crc32c are the
32862306a36Sopenharmony_cimost likely choices.
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci.. list-table::
33162306a36Sopenharmony_ci   :widths: 16 64
33262306a36Sopenharmony_ci   :header-rows: 1
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci   * - Value
33562306a36Sopenharmony_ci     - Description
33662306a36Sopenharmony_ci   * - 1
33762306a36Sopenharmony_ci     - CRC32
33862306a36Sopenharmony_ci   * - 2
33962306a36Sopenharmony_ci     - MD5
34062306a36Sopenharmony_ci   * - 3
34162306a36Sopenharmony_ci     - SHA1
34262306a36Sopenharmony_ci   * - 4
34362306a36Sopenharmony_ci     - CRC32C
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ciDescriptor Block
34662306a36Sopenharmony_ci~~~~~~~~~~~~~~~~
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ciThe descriptor block contains an array of journal block tags that
34962306a36Sopenharmony_cidescribe the final locations of the data blocks that follow in the
35062306a36Sopenharmony_cijournal. Descriptor blocks are open-coded instead of being completely
35162306a36Sopenharmony_cidescribed by a data structure, but here is the block structure anyway.
35262306a36Sopenharmony_ciDescriptor blocks consume at least 36 bytes, but use a full block:
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci.. list-table::
35562306a36Sopenharmony_ci   :widths: 8 8 24 40
35662306a36Sopenharmony_ci   :header-rows: 1
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci   * - Offset
35962306a36Sopenharmony_ci     - Type
36062306a36Sopenharmony_ci     - Name
36162306a36Sopenharmony_ci     - Descriptor
36262306a36Sopenharmony_ci   * - 0x0
36362306a36Sopenharmony_ci     - journal_header_t
36462306a36Sopenharmony_ci     - (open coded)
36562306a36Sopenharmony_ci     - Common block header.
36662306a36Sopenharmony_ci   * - 0xC
36762306a36Sopenharmony_ci     - struct journal_block_tag_s
36862306a36Sopenharmony_ci     - open coded array[]
36962306a36Sopenharmony_ci     - Enough tags either to fill up the block or to describe all the data
37062306a36Sopenharmony_ci       blocks that follow this descriptor block.
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ciJournal block tags have any of the following formats, depending on which
37362306a36Sopenharmony_cijournal feature and block tag flags are set.
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ciIf JBD2_FEATURE_INCOMPAT_CSUM_V3 is set, the journal block tag is
37662306a36Sopenharmony_cidefined as ``struct journal_block_tag3_s``, which looks like the
37762306a36Sopenharmony_cifollowing. The size is 16 or 32 bytes.
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci.. list-table::
38062306a36Sopenharmony_ci   :widths: 8 8 24 40
38162306a36Sopenharmony_ci   :header-rows: 1
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci   * - Offset
38462306a36Sopenharmony_ci     - Type
38562306a36Sopenharmony_ci     - Name
38662306a36Sopenharmony_ci     - Descriptor
38762306a36Sopenharmony_ci   * - 0x0
38862306a36Sopenharmony_ci     - __be32
38962306a36Sopenharmony_ci     - t_blocknr
39062306a36Sopenharmony_ci     - Lower 32-bits of the location of where the corresponding data block
39162306a36Sopenharmony_ci       should end up on disk.
39262306a36Sopenharmony_ci   * - 0x4
39362306a36Sopenharmony_ci     - __be32
39462306a36Sopenharmony_ci     - t_flags
39562306a36Sopenharmony_ci     - Flags that go with the descriptor. See the table jbd2_tag_flags_ for
39662306a36Sopenharmony_ci       more info.
39762306a36Sopenharmony_ci   * - 0x8
39862306a36Sopenharmony_ci     - __be32
39962306a36Sopenharmony_ci     - t_blocknr_high
40062306a36Sopenharmony_ci     - Upper 32-bits of the location of where the corresponding data block
40162306a36Sopenharmony_ci       should end up on disk. This is zero if JBD2_FEATURE_INCOMPAT_64BIT is
40262306a36Sopenharmony_ci       not enabled.
40362306a36Sopenharmony_ci   * - 0xC
40462306a36Sopenharmony_ci     - __be32
40562306a36Sopenharmony_ci     - t_checksum
40662306a36Sopenharmony_ci     - Checksum of the journal UUID, the sequence number, and the data block.
40762306a36Sopenharmony_ci   * -
40862306a36Sopenharmony_ci     -
40962306a36Sopenharmony_ci     -
41062306a36Sopenharmony_ci     - This field appears to be open coded. It always comes at the end of the
41162306a36Sopenharmony_ci       tag, after t_checksum. This field is not present if the "same UUID" flag
41262306a36Sopenharmony_ci       is set.
41362306a36Sopenharmony_ci   * - 0x8 or 0xC
41462306a36Sopenharmony_ci     - char
41562306a36Sopenharmony_ci     - uuid[16]
41662306a36Sopenharmony_ci     - A UUID to go with this tag. This field appears to be copied from the
41762306a36Sopenharmony_ci       ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that
41862306a36Sopenharmony_ci       field.
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci.. _jbd2_tag_flags:
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ciThe journal tag flags are any combination of the following:
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci.. list-table::
42562306a36Sopenharmony_ci   :widths: 16 64
42662306a36Sopenharmony_ci   :header-rows: 1
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci   * - Value
42962306a36Sopenharmony_ci     - Description
43062306a36Sopenharmony_ci   * - 0x1
43162306a36Sopenharmony_ci     - On-disk block is escaped. The first four bytes of the data block just
43262306a36Sopenharmony_ci       happened to match the jbd2 magic number.
43362306a36Sopenharmony_ci   * - 0x2
43462306a36Sopenharmony_ci     - This block has the same UUID as previous, therefore the UUID field is
43562306a36Sopenharmony_ci       omitted.
43662306a36Sopenharmony_ci   * - 0x4
43762306a36Sopenharmony_ci     - The data block was deleted by the transaction. (Not used?)
43862306a36Sopenharmony_ci   * - 0x8
43962306a36Sopenharmony_ci     - This is the last tag in this descriptor block.
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ciIf JBD2_FEATURE_INCOMPAT_CSUM_V3 is NOT set, the journal block tag
44262306a36Sopenharmony_ciis defined as ``struct journal_block_tag_s``, which looks like the
44362306a36Sopenharmony_cifollowing. The size is 8, 12, 24, or 28 bytes:
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci.. list-table::
44662306a36Sopenharmony_ci   :widths: 8 8 24 40
44762306a36Sopenharmony_ci   :header-rows: 1
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci   * - Offset
45062306a36Sopenharmony_ci     - Type
45162306a36Sopenharmony_ci     - Name
45262306a36Sopenharmony_ci     - Descriptor
45362306a36Sopenharmony_ci   * - 0x0
45462306a36Sopenharmony_ci     - __be32
45562306a36Sopenharmony_ci     - t_blocknr
45662306a36Sopenharmony_ci     - Lower 32-bits of the location of where the corresponding data block
45762306a36Sopenharmony_ci       should end up on disk.
45862306a36Sopenharmony_ci   * - 0x4
45962306a36Sopenharmony_ci     - __be16
46062306a36Sopenharmony_ci     - t_checksum
46162306a36Sopenharmony_ci     - Checksum of the journal UUID, the sequence number, and the data block.
46262306a36Sopenharmony_ci       Note that only the lower 16 bits are stored.
46362306a36Sopenharmony_ci   * - 0x6
46462306a36Sopenharmony_ci     - __be16
46562306a36Sopenharmony_ci     - t_flags
46662306a36Sopenharmony_ci     - Flags that go with the descriptor. See the table jbd2_tag_flags_ for
46762306a36Sopenharmony_ci       more info.
46862306a36Sopenharmony_ci   * -
46962306a36Sopenharmony_ci     -
47062306a36Sopenharmony_ci     -
47162306a36Sopenharmony_ci     - This next field is only present if the super block indicates support for
47262306a36Sopenharmony_ci       64-bit block numbers.
47362306a36Sopenharmony_ci   * - 0x8
47462306a36Sopenharmony_ci     - __be32
47562306a36Sopenharmony_ci     - t_blocknr_high
47662306a36Sopenharmony_ci     - Upper 32-bits of the location of where the corresponding data block
47762306a36Sopenharmony_ci       should end up on disk.
47862306a36Sopenharmony_ci   * -
47962306a36Sopenharmony_ci     -
48062306a36Sopenharmony_ci     -
48162306a36Sopenharmony_ci     - This field appears to be open coded. It always comes at the end of the
48262306a36Sopenharmony_ci       tag, after t_flags or t_blocknr_high. This field is not present if the
48362306a36Sopenharmony_ci       "same UUID" flag is set.
48462306a36Sopenharmony_ci   * - 0x8 or 0xC
48562306a36Sopenharmony_ci     - char
48662306a36Sopenharmony_ci     - uuid[16]
48762306a36Sopenharmony_ci     - A UUID to go with this tag. This field appears to be copied from the
48862306a36Sopenharmony_ci       ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that
48962306a36Sopenharmony_ci       field.
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ciIf JBD2_FEATURE_INCOMPAT_CSUM_V2 or
49262306a36Sopenharmony_ciJBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the block is a
49362306a36Sopenharmony_ci``struct jbd2_journal_block_tail``, which looks like this:
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci.. list-table::
49662306a36Sopenharmony_ci   :widths: 8 8 24 40
49762306a36Sopenharmony_ci   :header-rows: 1
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci   * - Offset
50062306a36Sopenharmony_ci     - Type
50162306a36Sopenharmony_ci     - Name
50262306a36Sopenharmony_ci     - Descriptor
50362306a36Sopenharmony_ci   * - 0x0
50462306a36Sopenharmony_ci     - __be32
50562306a36Sopenharmony_ci     - t_checksum
50662306a36Sopenharmony_ci     - Checksum of the journal UUID + the descriptor block, with this field set
50762306a36Sopenharmony_ci       to zero.
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ciData Block
51062306a36Sopenharmony_ci~~~~~~~~~~
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ciIn general, the data blocks being written to disk through the journal
51362306a36Sopenharmony_ciare written verbatim into the journal file after the descriptor block.
51462306a36Sopenharmony_ciHowever, if the first four bytes of the block match the jbd2 magic
51562306a36Sopenharmony_cinumber then those four bytes are replaced with zeroes and the “escaped”
51662306a36Sopenharmony_ciflag is set in the descriptor block tag.
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ciRevocation Block
51962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ciA revocation block is used to prevent replay of a block in an earlier
52262306a36Sopenharmony_citransaction. This is used to mark blocks that were journalled at one
52362306a36Sopenharmony_citime but are no longer journalled. Typically this happens if a metadata
52462306a36Sopenharmony_ciblock is freed and re-allocated as a file data block; in this case, a
52562306a36Sopenharmony_cijournal replay after the file block was written to disk will cause
52662306a36Sopenharmony_cicorruption.
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci**NOTE**: This mechanism is NOT used to express “this journal block is
52962306a36Sopenharmony_cisuperseded by this other journal block”, as the author (djwong)
53062306a36Sopenharmony_cimistakenly thought. Any block being added to a transaction will cause
53162306a36Sopenharmony_cithe removal of all existing revocation records for that block.
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ciRevocation blocks are described in
53462306a36Sopenharmony_ci``struct jbd2_journal_revoke_header_s``, are at least 16 bytes in
53562306a36Sopenharmony_cilength, but use a full block:
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci.. list-table::
53862306a36Sopenharmony_ci   :widths: 8 8 24 40
53962306a36Sopenharmony_ci   :header-rows: 1
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci   * - Offset
54262306a36Sopenharmony_ci     - Type
54362306a36Sopenharmony_ci     - Name
54462306a36Sopenharmony_ci     - Description
54562306a36Sopenharmony_ci   * - 0x0
54662306a36Sopenharmony_ci     - journal_header_t
54762306a36Sopenharmony_ci     - r_header
54862306a36Sopenharmony_ci     - Common block header.
54962306a36Sopenharmony_ci   * - 0xC
55062306a36Sopenharmony_ci     - __be32
55162306a36Sopenharmony_ci     - r_count
55262306a36Sopenharmony_ci     - Number of bytes used in this block.
55362306a36Sopenharmony_ci   * - 0x10
55462306a36Sopenharmony_ci     - __be32 or __be64
55562306a36Sopenharmony_ci     - blocks[0]
55662306a36Sopenharmony_ci     - Blocks to revoke.
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ciAfter r_count is a linear array of block numbers that are effectively
55962306a36Sopenharmony_cirevoked by this transaction. The size of each block number is 8 bytes if
56062306a36Sopenharmony_cithe superblock advertises 64-bit block number support, or 4 bytes
56162306a36Sopenharmony_ciotherwise.
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ciIf JBD2_FEATURE_INCOMPAT_CSUM_V2 or
56462306a36Sopenharmony_ciJBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the revocation
56562306a36Sopenharmony_ciblock is a ``struct jbd2_journal_revoke_tail``, which has this format:
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci.. list-table::
56862306a36Sopenharmony_ci   :widths: 8 8 24 40
56962306a36Sopenharmony_ci   :header-rows: 1
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci   * - Offset
57262306a36Sopenharmony_ci     - Type
57362306a36Sopenharmony_ci     - Name
57462306a36Sopenharmony_ci     - Description
57562306a36Sopenharmony_ci   * - 0x0
57662306a36Sopenharmony_ci     - __be32
57762306a36Sopenharmony_ci     - r_checksum
57862306a36Sopenharmony_ci     - Checksum of the journal UUID + revocation block
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_ciCommit Block
58162306a36Sopenharmony_ci~~~~~~~~~~~~
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ciThe commit block is a sentry that indicates that a transaction has been
58462306a36Sopenharmony_cicompletely written to the journal. Once this commit block reaches the
58562306a36Sopenharmony_cijournal, the data stored with this transaction can be written to their
58662306a36Sopenharmony_cifinal locations on disk.
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ciThe commit block is described by ``struct commit_header``, which is 32
58962306a36Sopenharmony_cibytes long (but uses a full block):
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci.. list-table::
59262306a36Sopenharmony_ci   :widths: 8 8 24 40
59362306a36Sopenharmony_ci   :header-rows: 1
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci   * - Offset
59662306a36Sopenharmony_ci     - Type
59762306a36Sopenharmony_ci     - Name
59862306a36Sopenharmony_ci     - Descriptor
59962306a36Sopenharmony_ci   * - 0x0
60062306a36Sopenharmony_ci     - journal_header_s
60162306a36Sopenharmony_ci     - (open coded)
60262306a36Sopenharmony_ci     - Common block header.
60362306a36Sopenharmony_ci   * - 0xC
60462306a36Sopenharmony_ci     - unsigned char
60562306a36Sopenharmony_ci     - h_chksum_type
60662306a36Sopenharmony_ci     - The type of checksum to use to verify the integrity of the data blocks
60762306a36Sopenharmony_ci       in the transaction. See jbd2_checksum_type_ for more info.
60862306a36Sopenharmony_ci   * - 0xD
60962306a36Sopenharmony_ci     - unsigned char
61062306a36Sopenharmony_ci     - h_chksum_size
61162306a36Sopenharmony_ci     - The number of bytes used by the checksum. Most likely 4.
61262306a36Sopenharmony_ci   * - 0xE
61362306a36Sopenharmony_ci     - unsigned char
61462306a36Sopenharmony_ci     - h_padding[2]
61562306a36Sopenharmony_ci     -
61662306a36Sopenharmony_ci   * - 0x10
61762306a36Sopenharmony_ci     - __be32
61862306a36Sopenharmony_ci     - h_chksum[JBD2_CHECKSUM_BYTES]
61962306a36Sopenharmony_ci     - 32 bytes of space to store checksums. If
62062306a36Sopenharmony_ci       JBD2_FEATURE_INCOMPAT_CSUM_V2 or JBD2_FEATURE_INCOMPAT_CSUM_V3
62162306a36Sopenharmony_ci       are set, the first ``__be32`` is the checksum of the journal UUID and
62262306a36Sopenharmony_ci       the entire commit block, with this field zeroed. If
62362306a36Sopenharmony_ci       JBD2_FEATURE_COMPAT_CHECKSUM is set, the first ``__be32`` is the
62462306a36Sopenharmony_ci       crc32 of all the blocks already written to the transaction.
62562306a36Sopenharmony_ci   * - 0x30
62662306a36Sopenharmony_ci     - __be64
62762306a36Sopenharmony_ci     - h_commit_sec
62862306a36Sopenharmony_ci     - The time that the transaction was committed, in seconds since the epoch.
62962306a36Sopenharmony_ci   * - 0x38
63062306a36Sopenharmony_ci     - __be32
63162306a36Sopenharmony_ci     - h_commit_nsec
63262306a36Sopenharmony_ci     - Nanoseconds component of the above timestamp.
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ciFast commits
63562306a36Sopenharmony_ci~~~~~~~~~~~~
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ciFast commit area is organized as a log of tag length values. Each TLV has
63862306a36Sopenharmony_cia ``struct ext4_fc_tl`` in the beginning which stores the tag and the length
63962306a36Sopenharmony_ciof the entire field. It is followed by variable length tag specific value.
64062306a36Sopenharmony_ciHere is the list of supported tags and their meanings:
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci.. list-table::
64362306a36Sopenharmony_ci   :widths: 8 20 20 32
64462306a36Sopenharmony_ci   :header-rows: 1
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci   * - Tag
64762306a36Sopenharmony_ci     - Meaning
64862306a36Sopenharmony_ci     - Value struct
64962306a36Sopenharmony_ci     - Description
65062306a36Sopenharmony_ci   * - EXT4_FC_TAG_HEAD
65162306a36Sopenharmony_ci     - Fast commit area header
65262306a36Sopenharmony_ci     - ``struct ext4_fc_head``
65362306a36Sopenharmony_ci     - Stores the TID of the transaction after which these fast commits should
65462306a36Sopenharmony_ci       be applied.
65562306a36Sopenharmony_ci   * - EXT4_FC_TAG_ADD_RANGE
65662306a36Sopenharmony_ci     - Add extent to inode
65762306a36Sopenharmony_ci     - ``struct ext4_fc_add_range``
65862306a36Sopenharmony_ci     - Stores the inode number and extent to be added in this inode
65962306a36Sopenharmony_ci   * - EXT4_FC_TAG_DEL_RANGE
66062306a36Sopenharmony_ci     - Remove logical offsets to inode
66162306a36Sopenharmony_ci     - ``struct ext4_fc_del_range``
66262306a36Sopenharmony_ci     - Stores the inode number and the logical offset range that needs to be
66362306a36Sopenharmony_ci       removed
66462306a36Sopenharmony_ci   * - EXT4_FC_TAG_CREAT
66562306a36Sopenharmony_ci     - Create directory entry for a newly created file
66662306a36Sopenharmony_ci     - ``struct ext4_fc_dentry_info``
66762306a36Sopenharmony_ci     - Stores the parent inode number, inode number and directory entry of the
66862306a36Sopenharmony_ci       newly created file
66962306a36Sopenharmony_ci   * - EXT4_FC_TAG_LINK
67062306a36Sopenharmony_ci     - Link a directory entry to an inode
67162306a36Sopenharmony_ci     - ``struct ext4_fc_dentry_info``
67262306a36Sopenharmony_ci     - Stores the parent inode number, inode number and directory entry
67362306a36Sopenharmony_ci   * - EXT4_FC_TAG_UNLINK
67462306a36Sopenharmony_ci     - Unlink a directory entry of an inode
67562306a36Sopenharmony_ci     - ``struct ext4_fc_dentry_info``
67662306a36Sopenharmony_ci     - Stores the parent inode number, inode number and directory entry
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci   * - EXT4_FC_TAG_PAD
67962306a36Sopenharmony_ci     - Padding (unused area)
68062306a36Sopenharmony_ci     - None
68162306a36Sopenharmony_ci     - Unused bytes in the fast commit area.
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci   * - EXT4_FC_TAG_TAIL
68462306a36Sopenharmony_ci     - Mark the end of a fast commit
68562306a36Sopenharmony_ci     - ``struct ext4_fc_tail``
68662306a36Sopenharmony_ci     - Stores the TID of the commit, CRC of the fast commit of which this tag
68762306a36Sopenharmony_ci       represents the end of
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ciFast Commit Replay Idempotence
69062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ciFast commits tags are idempotent in nature provided the recovery code follows
69362306a36Sopenharmony_cicertain rules. The guiding principle that the commit path follows while
69462306a36Sopenharmony_cicommitting is that it stores the result of a particular operation instead of
69562306a36Sopenharmony_cistoring the procedure.
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ciLet's consider this rename operation: 'mv /a /b'. Let's assume dirent '/a'
69862306a36Sopenharmony_ciwas associated with inode 10. During fast commit, instead of storing this
69962306a36Sopenharmony_cioperation as a procedure "rename a to b", we store the resulting file system
70062306a36Sopenharmony_cistate as a "series" of outcomes:
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci- Link dirent b to inode 10
70362306a36Sopenharmony_ci- Unlink dirent a
70462306a36Sopenharmony_ci- Inode 10 with valid refcount
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ciNow when recovery code runs, it needs "enforce" this state on the file
70762306a36Sopenharmony_cisystem. This is what guarantees idempotence of fast commit replay.
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ciLet's take an example of a procedure that is not idempotent and see how fast
71062306a36Sopenharmony_cicommits make it idempotent. Consider following sequence of operations:
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci1) rm A
71362306a36Sopenharmony_ci2) mv B A
71462306a36Sopenharmony_ci3) read A
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ciIf we store this sequence of operations as is then the replay is not idempotent.
71762306a36Sopenharmony_ciLet's say while in replay, we crash after (2). During the second replay,
71862306a36Sopenharmony_cifile A (which was actually created as a result of "mv B A" operation) would get
71962306a36Sopenharmony_cideleted. Thus, file named A would be absent when we try to read A. So, this
72062306a36Sopenharmony_cisequence of operations is not idempotent. However, as mentioned above, instead
72162306a36Sopenharmony_ciof storing the procedure fast commits store the outcome of each procedure. Thus
72262306a36Sopenharmony_cithe fast commit log for above procedure would be as follows:
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci(Let's assume dirent A was linked to inode 10 and dirent B was linked to
72562306a36Sopenharmony_ciinode 11 before the replay)
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci1) Unlink A
72862306a36Sopenharmony_ci2) Link A to inode 11
72962306a36Sopenharmony_ci3) Unlink B
73062306a36Sopenharmony_ci4) Inode 11
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ciIf we crash after (3) we will have file A linked to inode 11. During the second
73362306a36Sopenharmony_cireplay, we will remove file A (inode 11). But we will create it back and make
73462306a36Sopenharmony_ciit point to inode 11. We won't find B, so we'll just skip that step. At this
73562306a36Sopenharmony_cipoint, the refcount for inode 11 is not reliable, but that gets fixed by the
73662306a36Sopenharmony_cireplay of last inode 11 tag. Thus, by converting a non-idempotent procedure
73762306a36Sopenharmony_ciinto a series of idempotent outcomes, fast commits ensured idempotence during
73862306a36Sopenharmony_cithe replay.
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ciJournal Checkpoint
74162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ciCheckpointing the journal ensures all transactions and their associated buffers
74462306a36Sopenharmony_ciare submitted to the disk. In-progress transactions are waited upon and included
74562306a36Sopenharmony_ciin the checkpoint. Checkpointing is used internally during critical updates to
74662306a36Sopenharmony_cithe filesystem including journal recovery, filesystem resizing, and freeing of
74762306a36Sopenharmony_cithe journal_t structure.
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ciA journal checkpoint can be triggered from userspace via the ioctl
75062306a36Sopenharmony_ciEXT4_IOC_CHECKPOINT. This ioctl takes a single, u64 argument for flags.
75162306a36Sopenharmony_ciCurrently, three flags are supported. First, EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN
75262306a36Sopenharmony_cican be used to verify input to the ioctl. It returns error if there is any
75362306a36Sopenharmony_ciinvalid input, otherwise it returns success without performing
75462306a36Sopenharmony_ciany checkpointing. This can be used to check whether the ioctl exists on a
75562306a36Sopenharmony_cisystem and to verify there are no issues with arguments or flags. The
75662306a36Sopenharmony_ciother two flags are EXT4_IOC_CHECKPOINT_FLAG_DISCARD and
75762306a36Sopenharmony_ciEXT4_IOC_CHECKPOINT_FLAG_ZEROOUT. These flags cause the journal blocks to be
75862306a36Sopenharmony_cidiscarded or zero-filled, respectively, after the journal checkpoint is
75962306a36Sopenharmony_cicomplete. EXT4_IOC_CHECKPOINT_FLAG_DISCARD and EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT
76062306a36Sopenharmony_cicannot both be set. The ioctl may be useful when snapshotting a system or for
76162306a36Sopenharmony_cicomplying with content deletion SLOs.
762