We define on-disk data
structures required for JBD2 (Journaling Block Device 2) support.
It includes definitions for:
- The Journal Superblock (JBD2_SUPERBLOCK_V1/V2)
- Journal Header (Magic numbers and block types)
- Descriptor Blocks and Block Tags
- Commit Blocks

These structures adhere to the standard JBD2 binary layout used by
Linux ext3/ext4, ensuring binary compatibility for journal recovery.
This header serves as the foundation for the journaling logic
implemented in subsequent patches.
---
 ext2fs/jbd2_format.h | 102 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 ext2fs/jbd2_format.h

diff --git a/ext2fs/jbd2_format.h b/ext2fs/jbd2_format.h
new file mode 100644
index 00000000..b3f07a1f
--- /dev/null
+++ b/ext2fs/jbd2_format.h
@@ -0,0 +1,102 @@
+/* JBD2 Standard On-Disk Layout
+
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   Written by Milos Nikic.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _JBD2_FORMAT_H
+#define _JBD2_FORMAT_H
+
+#include <stdint.h>
+
+/**
+ * JBD2 Magic Numbers
+ * If a block starts with this, it's a metadata block.
+ */
+#define JBD2_MAGIC_NUMBER 0xC03B3998U
+
+/* Block Types */
+#define JBD2_DESCRIPTOR_BLOCK 1
+#define JBD2_COMMIT_BLOCK     2
+#define JBD2_SUPERBLOCK_V1    3
+#define JBD2_SUPERBLOCK_V2    4
+#define JBD2_REVOKE_BLOCK     5
+
+#define JBD2_PACKED __attribute__((packed))
+
+/**
+ * The Journal Superblock
+ * Lives at the very start of the journal partition (typically Inode 8).
+ */
+typedef struct JBD2_PACKED journal_superblock_s
+{
+  uint32_t s_header[3];                /* Standard header (magic, type, etc) */
+  uint32_t s_blocksize;                /* Journal device blocksize */
+  uint32_t s_maxlen;           /* Total blocks in journal file */
+  uint32_t s_first;            /* First block of log information */
+
+  uint32_t s_sequence;         /* First commit ID expected in log */
+  uint32_t s_start;            /* Block number of start of log */
+
+  uint32_t s_errno;            /* Error value, if any */
+
+  uint32_t s_feature_compat;
+  uint32_t s_feature_incompat;
+  uint32_t s_feature_ro_compat;
+
+  uint8_t s_uuid[16];          /* 128-bit uuid for journal */
+  uint32_t s_nr_users;         /* Nr of filesystems sharing log */
+  uint32_t s_dynsuper;         /* Blocknr of dynamic superblock copy */
+  uint32_t s_max_transaction;  /* Limit of handle size */
+  uint32_t s_max_trans_data;   /* Limit of data blocks per trans */
+  uint32_t s_checksum_type;    /* checksum type */
+  uint8_t s_padding2[42 * 4];
+  uint32_t s_checksum;         /* crc32c(superblock) */
+  uint8_t s_users[16 * 48];    /* ids of all filesystems sharing log */
+} journal_superblock_t;
+
+_Static_assert (sizeof (journal_superblock_t) == 1024,
+               "JBD2 Superblock size mismatch! Check padding.");
+
+/**
+ * The Standard Header
+ * Every metadata block (Descriptor, Commit) starts with this.
+ */
+typedef struct JBD2_PACKED journal_header_s
+{
+  uint32_t h_magic;            /* 0xC03B3998 */
+  uint32_t h_blocktype;                /* Descriptor, Commit, etc. */
+  uint32_t h_sequence;         /* The Transaction ID */
+} journal_header_t;
+
+/**
+ * The Block Tag
+ * Describes a data block that follows.
+ * Structure: [Descriptor Block] [Tag 1] [Tag 2] ... [Data 1] [Data 2] ...
+ */
+typedef struct JBD2_PACKED journal_block_tag_s
+{
+  uint32_t t_blocknr;          /* The 32-bit physical block number */
+  uint32_t t_flags;            /* See flags below */
+} journal_block_tag_t;
+
+/* Flags for the Block Tag */
+#define JBD2_FLAG_ESCAPE    1  /* The data block starts with magic number 
(escaped) */
+#define JBD2_FLAG_SAME_UUID 2  /* (Not needed for us usually) */
+#define JBD2_FLAG_DELETED   4  /* Block was deleted */
+#define JBD2_FLAG_LAST_TAG  8  /* This is the last tag in this descriptor 
block */
+
+#endif
-- 
2.52.0


Reply via email to