Applied, thanks!

Milos Nikic, le mer. 07 oct. 2026 22:57:12 -0700, a ecrit:
> Hello,
> 
> This is the series I mentioned with the trunc_indirect regression fix:
> it closes the window in which a freed block could be reused before the
> transaction that freed it commits.
> 
> ext2_free_blocks clears the bitmap bit at once, so the allocator can
> hand a block to a new owner while the journal still holds copies of
> its old contents, in the freeing transaction, in the committing one,
> or in older checkpoint transactions.  A home write of such a copy then
> lands on the new owner's data, and a crash before the free commits
> gives the block back to its old owner after it was overwritten.  The
> pre-notify regression was one way into this window; this series closes
> the window itself.
> 
> Patch 1 does what ext3 and ext4 do: a freed block is allocated again
> only after its free commits.  The bitmap and free counts still change
> at free time; the block is also marked in an in-memory busy bitmap,
> which ext2_new_block skips, and the commit hands the blocks back once
> the old copies are marked written.  Without a journal nothing changes:
> freed blocks are reusable at once, as before.
> 
> Patch 2 removes a workaround that this makes unnecessary.  The orphan
> list cleared i_size, i_blocks and i_block[] of an orphan inode on disk,
> so that a reused block could not be reached through its block map.
> That leaked the blocks of every file still open at shutdown until a
> full fsck, since recovery and e2fsck saw an orphan with no blocks.
> Like ext3 and ext4, the block map now stays on disk and only i_dtime
> is used for the list.
> 
> Unjournaled paths are not affected by this change.
> 
> Known limitations, also noted as XXX comments in ext2_new_block:
> 
>  - When every free block is busy, ext2_new_block waits for the
>    committing transaction to hand its blocks back.  The caller can
>    hold node locks there, such as alloc_lock, so a pager thread that
>    joined that transaction and waits for the same lock could deadlock
>    it.  This needs a nearly full filesystem; I have not hit it despite
>    trying to!
> 
>  - When the only busy blocks belong to the caller's own transaction,
>    nothing can be waited for, and the caller gets ENOSPC although the
>    space comes back at the next commit.
> 
>  - Older transactions still in the log can hold copies of a freed
>    block, which a replay after a crash writes over its new owner.
>    That needs revoke records, which a later series adds.
> 
> Tested on 32-bit and 64-bit Hurd images:
> 
>  - Repeated apt upgrades of an old Debian image (most of the Hurd
>    libraries replaced), ending with a clean halt and also with qemu
>    killed from the host: e2fsck clean every time.  After a clean halt
>    e2fsck now clears the orphans of files that were still open with no
>    pass 5 differences, where before their blocks leaked.
> 
>  - tar -xf and rm -rf of a Linux kernel tree, with qemu killed in the
>    middle of each: the journal replays and e2fsck finds nothing else.
> 
>  - A 128 MB filesystem filled to ENOSPC, then 300 rounds of parallel
>    delete-and-rewrite plus two appenders on one file, alongside a
>    loop of mkdir, many small creates, chmod -R and rm -rf, with the
>    translator killed at random points: e2fsck clean after replay, and
>    every surviving copy of the reference file intact.
> 
>  - And also I ran this for the week as my daily driver on which I
>    develop next patches, and it is stable and working as expected.
> 
> Milos Nikic (2):
>   ext2fs: Keep freed blocks busy until their free commits
>   ext2fs: Keep the block map of orphan inodes on disk
> 
>  ext2fs/balloc.c   | 206 ++++++++++++++++++++++++++++++++++++++++------
>  ext2fs/ext2fs.h   |   8 ++
>  ext2fs/getblk.c   |   3 +-
>  ext2fs/inode.c    |  38 +++++----
>  ext2fs/journal.c  | 164 ++++++++++++++++++++++++++++--------
>  ext2fs/journal.h  |  13 ++-
>  ext2fs/orphan.c   |  19 ++---
>  ext2fs/truncate.c |  19 ++---
>  8 files changed, 362 insertions(+), 108 deletions(-)
> 
> -- 
> 2.56.0
> 

-- 
Samuel
void packerFlushTheToiletFirstThingInTheMorning( void* arg )
 -+- chromium's source code -+-

Reply via email to