Hello,
First to state a problem:
Ext2fs preallocates up to 8 blocks when a file grows, and marks them
allocated in the block bitmap while only the node's memory owns them.
A crash before the file uses them or gives them back leaks them. With
the journal this matters even more: the bitmap change commits with the
allocation, and a normal boot only replays the log, without the full
check that would free the blocks. Killing the translator during
tar -xf of a Linux tree left such blocks repeatedly.
Fix:
Patch 1 is the fix the journal needs. It keeps the preallocation
window in memory only, in a per-group map next to the busy blocks, and
sets a block in the bitmap only when a file takes it. The layout does
not change: in the test below, files get exactly the same fragments as
before (1949 each). Ten kills of the translator at random times during
rm -rf and tar -xf, and filling the disk with several writers, left
e2fsck -f clean. Simply not preallocating with a journal, as I first
tried, also fixes the leak, but doubles the fragments (4097).
Improvement:
Patch 2 is an improvement on top inspired by ext3, and does not depend
on the journal. Files written at the same time take blocks in turn,
so each fragment was at most one 8-block window long.
A file that keeps using up its window now gets one twice as big, up to
1024 blocks, and the window is dropped at the last close instead of whenever
the inode is written.
ext3 also doubled its reservation windows, up to 1027 blocks.
Fragments per file, 3 runs each on a fresh 4 KB-block filesystem in an
i386 VM:
before patch 1 patch 2
8 files appended in turn (64 MB) 1949 1949 23
4 parallel dd (256 MB) ~6400 ~6300 55-70
The same holds without a journal (23 for the appended files). With
two concurrent tar -xf of a Linux tree, half as many files are
fragmented with patch 2 (0.4% against 0.8%), but about 200 more small
holes of 4 to 64K stay in the free space, 1% of it, mostly what small
files leave of their windows. The time is the same (about 205 s).
Capping a window at the file's size made both worse, so it is not in
the series. A large Debian upgrade with both patches on the root
filesystem left e2fsck clean.
The patches are independent of other work that is still pending.
Thanks,
Milos
Milos Nikic (2):
ext2fs: Keep block preallocation in memory
ext2fs: Grow preallocation windows for sequential writers
ext2fs/balloc.c | 274 ++++++++++++++++++++++++++++++++--------------
ext2fs/ext2_fs.h | 3 +
ext2fs/ext2fs.h | 6 +-
ext2fs/getblk.c | 70 ++++++------
ext2fs/ialloc.c | 1 +
ext2fs/inode.c | 17 ++-
ext2fs/truncate.c | 4 +-
7 files changed, 256 insertions(+), 119 deletions(-)
--
2.56.0