linuxfilesystemsext3ext4journaling

Accessing ext3 / ext4 journals


ext3 and ext4 file systems have journaling. Is there any chance there's some API to get details or events about files?

Some kind of API that will allow a user space program to access journal entries for files. Or even journal events, like "file x was deleted".

This seems to be some kind of documentation but I'm not sure if it's the right stuff.


Solution

  • With debugfs

    logdump

    You can display information about the file system journal with the logdump command from debugfs.

    For example, sudo debugfs -R 'logdump -S' /dev/sda3 yields

    Journal features:         journal_incompat_revoke journal_checksum_v3
    Total journal size:       512M
    Total journal blocks:     131072
    Max transaction length:   131072
    Fast commit length:       0
    Journal sequence:         0x004bd0ae
    Journal start:            109412
    Journal checksum type:    crc32c
    Journal checksum:         0x157eebb7
    
    Journal starts at block 109412, transaction 4968622
    Found expected sequence 4968622, type 5 (revoke table) at block 109412
    Found expected sequence 4968622, type 1 (descriptor block) at block 109413
    Found expected sequence 4968622, type 2 (commit block) at block 109419
    Found expected sequence 4968623, type 1 (descriptor block) at block 109420
    Found expected sequence 4968623, type 2 (commit block) at block 109422
    Found expected sequence 4968624, type 1 (descriptor block) at block 109423
    Found expected sequence 4968624, type 2 (commit block) at block 109425
    Found expected sequence 4968625, type 1 (descriptor block) at block 109426
    // rest omitted
    

    I realize that debugfs is not an API, but it accesses the journal.

    Read the journal's bytes

    To get at the raw bytes of the journal, you can use debugfs again. Its cat command accepts an inode number and prints the data of the address the inode's pointing to.

    Assuming that the journal's inode number is 8:

    sudo debugfs -R 'cat <8>' /dev/sda3 | hexdump -C
    

    This prints the journal's bytes in hexadecimal. You should see the magic number of the journal's format, jbd2, at the beginning:

    c0 3b 39 98
    

    The journal uses big-endian byte order whereas ext4 uses little-endian.

    With jls

    jls from The Sleuth Kit also prints information about the journal.

    For example, sudo jls /dev/sda3 yields

    JBlk    Description
    0:  Superblock (seq: 0)
    sb version: 4
    sb version: 4
    sb feature_compat flags 0x00000000
    sb feature_incompat flags 0x00000011
            JOURNAL_REVOKE
    sb feature_ro_incompat flags 0x00000000
    1:  Unallocated Commit Block (seq: 4936768, sec: 1613471034.3277057792)
    2:  Unallocated Descriptor Block (seq: 4936769)
    3:  Unallocated FS Block 42991838
    4:  Unallocated FS Block 0
    5:  Unallocated Commit Block (seq: 4949171, sec: 1613574032.1117509120)
    6:  Unallocated Descriptor Block (seq: 4949172)
    7:  Unallocated Commit Block (seq: 4960433, sec: 1613729975.4288594432)
    8:  Unallocated Descriptor Block (seq: 4960434)
    // rest omitted
    

    The source code of jls is here.

    DIY

    Alternatively, you can consult the ext4 wiki to parse the journal using a program that you'll have to write yourself. The steps are roughly as follows:

    1. Read the ext4 superblock which starts 1024 bytes after the file system.
    2. Read the journal inode number from offset 0xE0 of the superblock. The journal's inode number is usually 8. This is documented here.
    3. Read the data you need from the journal, keep in mind that it's big-endian, as opposed to ext4 being little-endian. The journal's structure is described here.