Revert "ext4: make __ext4_get_inode_loc plug"
authorLinus Torvalds <>
Sun, 15 Sep 2019 19:32:03 +0000 (12:32 -0700)
committerLinus Torvalds <>
Sun, 15 Sep 2019 19:32:03 +0000 (12:32 -0700)
This reverts commit b03755ad6f33b7b8cd7312a3596a2dbf496de6e7.

This is sad, and done for all the wrong reasons.  Because that commit is
good, and does exactly what it says: avoids a lot of small disk requests
for the inode table read-ahead.

However, it turns out that it causes an entirely unrelated problem: the
getrandom() system call was introduced back in 2014 by commit
c6e9d6f38894 ("random: introduce getrandom(2) system call"), and people
use it as a convenient source of good random numbers.

But part of the current semantics for getrandom() is that it waits for
the entropy pool to fill at least partially (unlike /dev/urandom).  And
at least ArchLinux apparently has a systemd that uses getrandom() at
boot time, and the improvements in IO patterns means that existing
installations suddenly start hanging, waiting for entropy that will
never happen.

It seems to be an unlucky combination of not _quite_ enough entropy,
together with a particular systemd version and configuration.  Lennart
says that the systemd-random-seed process (which is what does this early
access) is supposed to not block any other boot activity, but sadly that
doesn't actually seem to be the case (possibly due bogus dependencies on
cryptsetup for encrypted swapspace).

The correct fix is to fix getrandom() to not block when it's not
appropriate, but that fix is going to take a lot more discussion.  Do we
just make it act like /dev/urandom by default, and add a new flag for
"wait for entropy"? Do we add a boot-time option? Or do we just limit
the amount of time it will wait for entropy?

So in the meantime, we do the revert to give us time to discuss the
eventual fix for the fundamental problem, at which point we can re-apply
the ext4 inode table access optimization.

Reported-by: Ahmed S. Darwish <>
Cc: Ted Ts'o <>
Cc: Willy Tarreau <>
Cc: Alexander E. Patrakov <>
Cc: Lennart Poettering <>
Signed-off-by: Linus Torvalds <>

index 420fe3deed39702b93a5567dbebe77a8e4b6b992..006b7a2070bf6869d2f7c42500eea135919def74 100644 (file)
@@ -4586,7 +4586,6 @@ static int __ext4_get_inode_loc(struct inode *inode,
        struct buffer_head      *bh;
        struct super_block      *sb = inode->i_sb;
        ext4_fsblk_t            block;
-       struct blk_plug         plug;
        int                     inodes_per_block, inode_offset;
        iloc->bh = NULL;
@@ -4675,7 +4674,6 @@ make_io:
                 * If we need to do any I/O, try to pre-readahead extra
                 * blocks from the inode table.
-               blk_start_plug(&plug);
                if (EXT4_SB(sb)->s_inode_readahead_blks) {
                        ext4_fsblk_t b, end, table;
                        unsigned num;
@@ -4706,7 +4704,6 @@ make_io:
                bh->b_end_io = end_buffer_read_sync;
                submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh);
-               blk_finish_plug(&plug);
                if (!buffer_uptodate(bh)) {
                        EXT4_ERROR_INODE_BLOCK(inode, block,