This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Hurd".
The branch, master has been updated
via ccaa5374c8af09cc47c7111f6335911139df4441 (commit)
via 55a4b955a39584b8f39d633df3ce406ea1056226 (commit)
from 59c086b268a75befdeb6d8c42d210d4b6de2b403 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ccaa5374c8af09cc47c7111f6335911139df4441
Author: Milos Nikic <[email protected]>
Date: Tue Oct 13 16:46:45 2026 -0700
ext2fs: Write JBD2 revoke records for freed blocks
A block freed while a copy of it is still in the log can be replayed
over its next owner: busy blocks keep it from being reused before its
free commits, but after a crash recovery still writes every logged
copy home, including the old contents of a block that has since become
another file's data. JBD2 avoids this with revoke records: recovery
skips the copies of a revoked block in the revoking transaction and in
older ones, while a copy in a newer transaction, taken after the block
was reused, is still replayed.
Keep a journal-wide count of the live transactions (running,
committing, on the checkpoint list or retired) holding a copy of each
block, raised when journal_get_write_access_locked adds a buffer and
dropped when the transaction is freed. Since retired transactions are
kept until the superblock moves the tail past them, a block in the
count may have a copy in the log on disk, and one outside it has none.
journal_record_freed_blocks adds a revoke record to the freeing
transaction for each freed block in the count. Data blocks are never
in the log and get none, so freeing a large file costs no log space.
The commit writes the records in revoke blocks after the descriptors
and data, before the commit block, and journal_ensure_commit_space
counts them. The record is in the same transaction as the free, and
the block stays busy until that transaction commits, so the revoke is
on disk before the block's next owner writes to it.
A block journaled again in the transaction that revoked it would have
its new copy skipped too. That cannot happen while freed blocks stay
busy; should it, the revoke record is dropped with a warning.
Without memory to track the logged blocks, every freed block is revoked
from then on. Without memory for a revoke record, the freed range
stays allocated, as when busy blocks cannot be tracked.
The records use the plain JBD2 format, 32-bit block numbers after a
header with the byte count.
Message-ID: <[email protected]>
commit 55a4b955a39584b8f39d633df3ce406ea1056226
Author: Milos Nikic <[email protected]>
Date: Tue Oct 13 16:46:44 2026 -0700
ext2fs: Keep retired transactions until the new tail is on disk
journal_try_advance_tail_locked freed a fully checkpointed transaction
and gave its log space back to j_free at once, while the journal
superblock on disk still had the old tail. The superblock write came
later, and in journal_flush_checkpoints_locked only after the lock had
been dropped for a device flush. A commit in that window could reuse
the log blocks of the retired transaction. After a crash, recovery
starts at the tail on disk, finds a block of a newer transaction where
it expects the retired one, and stops: the transactions committed after
it are not replayed.
Move retired transactions to a new j_retired_list instead. The tail
still advances in memory, so the next superblock write records it, and
journal_update_superblock releases the retired transactions and gives
their log space back once that write is done. The checkpoint loop now
measures its progress by the tail, since j_free only grows after the
loop has written the superblock, and the loop also writes the superblock
when an earlier write failed and left transactions retired.
Keeping the retired transactions until then also lets the journal tell
which blocks still have a copy in the log on disk, which revoke records
need.
The superblock write is a plain store write followed by a device flush
at the callers, as before; this does not change how its durability is
ordered against the device cache.
Message-ID: <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
ext2fs/jbd2_format.h | 13 ++
ext2fs/journal.c | 437 ++++++++++++++++++++++++++++++++++++++++++---------
ext2fs/truncate.c | 7 +-
3 files changed, 380 insertions(+), 77 deletions(-)
hooks/post-receive
--
Hurd