add patch call-get_blocks-with-create-1-for-write-faults-to-unwritten-extents
[ext4-patch-queue.git] / fix-race-in-transient-ENOSPC-detection
blobfd903c70fdb9b086b8d23fa8ee0bb473bad046dc
1 ext4: fix race in transient ENOSPC detection
3 From: Jan Kara <jack@suse.cz>
5 When there are blocks to free in the running transaction, block
6 allocator can return ENOSPC although the filesystem has some blocks to
7 free. We use ext4_should_retry_alloc() to force commit of the current
8 transaction and return whether anything was committed so that it makes
9 sense to retry the allocation. However the transaction may get committed
10 after block allocation fails but before we call
11 ext4_should_retry_alloc(). So ext4_should_retry_alloc() returns false
12 because there is nothing to commit and we wrongly return ENOSPC.
14 Fix the race by unconditionally returning 1 from ext4_should_retry_alloc()
15 when we tried to commit a transaction. This should not add any
16 unnecessary retries since we had a transaction running a while ago when
17 trying to allocate blocks and we want to retry the allocation once that
18 transaction has committed anyway.
20 Signed-off-by: Jan Kara <jack@suse.cz>
21 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
22 ---
23  fs/ext4/balloc.c | 3 ++-
24  1 file changed, 2 insertions(+), 1 deletion(-)
26 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
27 index fe1f50fe764f..3020fd70c392 100644
28 --- a/fs/ext4/balloc.c
29 +++ b/fs/ext4/balloc.c
30 @@ -610,7 +610,8 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
32         jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
34 -       return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
35 +       jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
36 +       return 1;
37  }
39  /*
40 -- 
41 2.6.6