Add missing patches (centralize-proc-functions and make-proc-generic)
[ext4-patch-queue.git] / ext4-Retry-block-reservation.patch
blobacc92d561c491cebce0ca7dec784e7996003d6a3
1 ext4: Retry block reservation
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 During block reservation if we don't have enough blocks left, retry
6 block reservation with smaller block counts. This makes sure we try
7 fallocate and DIO with smaller request size and don't fail early. The
8 delayed allocation reservation cannot try with smaller block count. So
9 retry block reservation to handle temporary disk full conditions. Also
10 print free blocks details if we fail block allocation during writepages.
12 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
13 Signed-off-by: Mingming Cao <cmm@us.ibm.com>
14 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
15 ---
16 fs/ext4/balloc.c | 8 +++++++-
17 fs/ext4/inode.c | 14 +++++++++++---
18 fs/ext4/mballoc.c | 7 ++++++-
19 3 files changed, 24 insertions(+), 5 deletions(-)
21 Index: linux-2.6.27-rc3/fs/ext4/balloc.c
22 ===================================================================
23 --- linux-2.6.27-rc3.orig/fs/ext4/balloc.c 2008-08-27 09:45:05.000000000 -0700
24 +++ linux-2.6.27-rc3/fs/ext4/balloc.c 2008-08-27 13:54:26.000000000 -0700
25 @@ -1736,10 +1736,16 @@
27 * With delalloc we already reserved the blocks
29 - if (ext4_claim_free_blocks(sbi, *count)) {
30 + while (*count && ext4_claim_free_blocks(sbi, *count)) {
31 + /* let others to free the space */
32 + yield();
33 + *count = *count >> 1;
34 + }
35 + if (!*count) {
36 *errp = -ENOSPC;
37 return 0; /*return with ENOSPC error */
39 + num = *count;
42 * Check quota for allocation of this block.
43 Index: linux-2.6.27-rc3/fs/ext4/inode.c
44 ===================================================================
45 --- linux-2.6.27-rc3.orig/fs/ext4/inode.c 2008-08-27 09:45:05.000000000 -0700
46 +++ linux-2.6.27-rc3/fs/ext4/inode.c 2008-08-27 13:54:26.000000000 -0700
47 @@ -1521,6 +1521,7 @@
49 static int ext4_da_reserve_space(struct inode *inode, int nrblocks)
51 + int retries = 0;
52 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
53 unsigned long md_needed, mdblocks, total = 0;
55 @@ -1529,6 +1530,7 @@
56 * in order to allocate nrblocks
57 * worse case is one extent per block
59 +repeat:
60 spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
61 total = EXT4_I(inode)->i_reserved_data_blocks + nrblocks;
62 mdblocks = ext4_calc_metadata_amount(inode, total);
63 @@ -1539,6 +1541,10 @@
65 if (ext4_claim_free_blocks(sbi, total)) {
66 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
67 + if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
68 + yield();
69 + goto repeat;
70 + }
71 return -ENOSPC;
73 EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
74 @@ -1825,20 +1831,18 @@
75 static int mpage_da_map_blocks(struct mpage_da_data *mpd)
77 int err = 0;
78 + struct buffer_head new;
79 struct buffer_head *lbh = &mpd->lbh;
80 sector_t next = lbh->b_blocknr;
81 - struct buffer_head new;
84 * We consider only non-mapped and non-allocated blocks
86 if (buffer_mapped(lbh) && !buffer_delay(lbh))
87 return 0;
89 new.b_state = lbh->b_state;
90 new.b_blocknr = 0;
91 new.b_size = lbh->b_size;
94 * If we didn't accumulate anything
95 * to write simply return
96 @@ -1871,6 +1875,10 @@
97 lbh->b_size >> mpd->inode->i_blkbits, err);
98 printk(KERN_EMERG "This should not happen.!! "
99 "Data will be lost\n");
100 + if (err == -ENOSPC) {
101 + printk(KERN_CRIT "Total free blocks count %lld\n",
102 + ext4_count_free_blocks(mpd->inode->i_sb));
104 /* invlaidate all the pages */
105 ext4_da_block_invalidatepages(mpd, next,
106 lbh->b_size >> mpd->inode->i_blkbits);
107 Index: linux-2.6.27-rc3/fs/ext4/mballoc.c
108 ===================================================================
109 --- linux-2.6.27-rc3.orig/fs/ext4/mballoc.c 2008-08-27 09:45:05.000000000 -0700
110 +++ linux-2.6.27-rc3/fs/ext4/mballoc.c 2008-08-27 13:54:26.000000000 -0700
111 @@ -4394,7 +4394,12 @@
113 * With delalloc we already reserved the blocks
115 - if (ext4_claim_free_blocks(sbi, ar->len)) {
116 + while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) {
117 + /* let others to free the space */
118 + yield();
119 + ar->len = ar->len >> 1;
121 + if (!ar->len) {
122 *errp = -ENOSPC;
123 return 0;