aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/mballoc.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-10-09 10:56:23 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-10-09 10:56:23 -0400
commita30d542a0035b886ffaafd0057ced0a2b28c3a4f (patch)
tree9e677eaf4eb1611701828554b27a1b0b0ae523fd /fs/ext4/mballoc.c
parentc4a0c46ec92c194c873232b88debce4e1a448483 (diff)
ext4: Make sure all the block allocation paths reserve blocks
With delayed allocation we need to make sure block are reserved before we attempt to allocate them. Otherwise we get block allocation failure (ENOSPC) during writepages which cannot be handled. This would mean silent data loss (We do a printk stating data will be lost). This patch updates the DIO and fallocate code path to do block reservation before block allocation. This is needed to make sure parallel DIO and fallocate request doesn't take block out of delayed reserve space. When free blocks count go below a threshold we switch to a slow patch which looks at other CPU's accumulated percpu counter values. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r--fs/ext4/mballoc.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 0db2ccfa0da..2c10b5058a8 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2975,9 +2975,15 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2975 * at write_begin() time for delayed allocation 2975 * at write_begin() time for delayed allocation
2976 * do not double accounting 2976 * do not double accounting
2977 */ 2977 */
2978 if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) 2978 if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED) &&
2979 percpu_counter_sub(&sbi->s_freeblocks_counter, 2979 ac->ac_o_ex.fe_len != ac->ac_b_ex.fe_len) {
2980 ac->ac_b_ex.fe_len); 2980 /*
2981 * we allocated less blocks than we calimed
2982 * Add the difference back
2983 */
2984 percpu_counter_add(&sbi->s_freeblocks_counter,
2985 ac->ac_o_ex.fe_len - ac->ac_b_ex.fe_len);
2986 }
2981 2987
2982 if (sbi->s_log_groups_per_flex) { 2988 if (sbi->s_log_groups_per_flex) {
2983 ext4_group_t flex_group = ext4_flex_group(sbi, 2989 ext4_group_t flex_group = ext4_flex_group(sbi,
@@ -4389,14 +4395,11 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4389 /* 4395 /*
4390 * With delalloc we already reserved the blocks 4396 * With delalloc we already reserved the blocks
4391 */ 4397 */
4392 ar->len = ext4_has_free_blocks(sbi, ar->len); 4398 if (ext4_claim_free_blocks(sbi, ar->len)) {
4393 } 4399 *errp = -ENOSPC;
4394 4400 return 0;
4395 if (ar->len == 0) { 4401 }
4396 *errp = -ENOSPC;
4397 return 0;
4398 } 4402 }
4399
4400 while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) { 4403 while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) {
4401 ar->flags |= EXT4_MB_HINT_NOPREALLOC; 4404 ar->flags |= EXT4_MB_HINT_NOPREALLOC;
4402 ar->len--; 4405 ar->len--;