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