Move ext4-use-percpu-data-for-lg_prealloc_list to stable series
[ext4-patch-queue.git] / ext4_nonmballoc_reservation_ENOSPC_fix.patch
blob62e35ce14517ed9b174c5c782930bc1a5a511d78
1 ext4: Fix ext4 nomballoc allocator for ENOSPC
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 We run into ENOSPC error on nonmballoc ext4, even when there is free blocks
6 on the filesystem.
8 The patch includes two changes:
10 a) Set reservation to NULL if we trying to allocate near group_target_block
11 from the goal group if the free block in the group is less than windows.
12 This should give us a better chance to allocate near group_target_block.
13 This also ensures that if we are not allocating near group_target_block
14 then we don't trun off reservation. This should enable us to allocate
15 with reservation from other groups that have large free blocks count.
17 b) we don't need to check the window size if the block reservation is off.
19 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
20 Signed-off-by: Mingming Cao <cmm@us.ibm.com>
21 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
22 ---
23 fs/ext4/balloc.c | 18 ++++++++++--------
24 1 files changed, 10 insertions(+), 8 deletions(-)
26 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
27 index cfe01b4..399bec5 100644
28 --- a/fs/ext4/balloc.c
29 +++ b/fs/ext4/balloc.c
30 @@ -1802,15 +1802,17 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
31 goto io_error;
33 free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
34 - /*
35 - * if there is not enough free blocks to make a new resevation
36 - * turn off reservation for this allocation
37 - */
38 - if (my_rsv && (free_blocks < windowsz)
39 - && (rsv_is_empty(&my_rsv->rsv_window)))
40 - my_rsv = NULL;
42 if (free_blocks > 0) {
43 + /*
44 + * try to allocate with group target block
45 + * in the goal group. If we have low free_blocks
46 + * count turn off reservation
47 + */
48 + if (my_rsv && (free_blocks < windowsz)
49 + && (rsv_is_empty(&my_rsv->rsv_window)))
50 + my_rsv = NULL;
52 bitmap_bh = ext4_read_block_bitmap(sb, group_no);
53 if (!bitmap_bh)
54 goto io_error;
55 @@ -1843,7 +1845,7 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
56 * free blocks is less than half of the reservation
57 * window size.
59 - if (free_blocks <= (windowsz/2))
60 + if (my_rsv && (free_blocks <= (windowsz/2)))
61 continue;
63 brelse(bitmap_bh);