diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-27 17:48:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-27 17:48:34 -0400 |
commit | 2c9e15a011c55ff96b2b8d2b126d1b9a96abba20 (patch) | |
tree | 6d9b27a07f88ad4509dcd86aa74a2cdecd0d5f4b /fs/ext4/mballoc.c | |
parent | 805de022b100bcf796860fe88d7db4164066d1c3 (diff) | |
parent | c16831b4cc9b0805adf8ca3001752a7ec10a17bf (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-quota-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-quota-2.6: (27 commits)
ext2: Zero our b_size in ext2_quota_read()
trivial: fix typos/grammar errors in fs/Kconfig
quota: Coding style fixes
quota: Remove superfluous inlines
quota: Remove uppercase aliases for quota functions.
nfsd: Use lowercase names of quota functions
jfs: Use lowercase names of quota functions
udf: Use lowercase names of quota functions
ufs: Use lowercase names of quota functions
reiserfs: Use lowercase names of quota functions
ext4: Use lowercase names of quota functions
ext3: Use lowercase names of quota functions
ext2: Use lowercase names of quota functions
ramfs: Remove quota call
vfs: Use lowercase names of quota functions
quota: Remove dqbuf_t and other cleanups
quota: Remove NODQUOT macro
quota: Make global quota locks cacheline aligned
quota: Move quota files into separate directory
ext4: quota reservation for delayed allocation
...
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 9f61e62f435f..b038188bd039 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -3086,9 +3086,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
3086 | if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) | 3086 | if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) |
3087 | /* release all the reserved blocks if non delalloc */ | 3087 | /* release all the reserved blocks if non delalloc */ |
3088 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); | 3088 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_blks); |
3089 | else | 3089 | else { |
3090 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, | 3090 | percpu_counter_sub(&sbi->s_dirtyblocks_counter, |
3091 | ac->ac_b_ex.fe_len); | 3091 | ac->ac_b_ex.fe_len); |
3092 | /* convert reserved quota blocks to real quota blocks */ | ||
3093 | vfs_dq_claim_block(ac->ac_inode, ac->ac_b_ex.fe_len); | ||
3094 | } | ||
3092 | 3095 | ||
3093 | if (sbi->s_log_groups_per_flex) { | 3096 | if (sbi->s_log_groups_per_flex) { |
3094 | ext4_group_t flex_group = ext4_flex_group(sbi, | 3097 | ext4_group_t flex_group = ext4_flex_group(sbi, |
@@ -4544,7 +4547,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4544 | struct ext4_sb_info *sbi; | 4547 | struct ext4_sb_info *sbi; |
4545 | struct super_block *sb; | 4548 | struct super_block *sb; |
4546 | ext4_fsblk_t block = 0; | 4549 | ext4_fsblk_t block = 0; |
4547 | unsigned int inquota; | 4550 | unsigned int inquota = 0; |
4548 | unsigned int reserv_blks = 0; | 4551 | unsigned int reserv_blks = 0; |
4549 | 4552 | ||
4550 | sb = ar->inode->i_sb; | 4553 | sb = ar->inode->i_sb; |
@@ -4562,9 +4565,17 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4562 | (unsigned long long) ar->pleft, | 4565 | (unsigned long long) ar->pleft, |
4563 | (unsigned long long) ar->pright); | 4566 | (unsigned long long) ar->pright); |
4564 | 4567 | ||
4565 | if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) { | 4568 | /* |
4566 | /* | 4569 | * For delayed allocation, we could skip the ENOSPC and |
4567 | * With delalloc we already reserved the blocks | 4570 | * EDQUOT check, as blocks and quotas have been already |
4571 | * reserved when data being copied into pagecache. | ||
4572 | */ | ||
4573 | if (EXT4_I(ar->inode)->i_delalloc_reserved_flag) | ||
4574 | ar->flags |= EXT4_MB_DELALLOC_RESERVED; | ||
4575 | else { | ||
4576 | /* Without delayed allocation we need to verify | ||
4577 | * there is enough free blocks to do block allocation | ||
4578 | * and verify allocation doesn't exceed the quota limits. | ||
4568 | */ | 4579 | */ |
4569 | while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) { | 4580 | while (ar->len && ext4_claim_free_blocks(sbi, ar->len)) { |
4570 | /* let others to free the space */ | 4581 | /* let others to free the space */ |
@@ -4576,19 +4587,16 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4576 | return 0; | 4587 | return 0; |
4577 | } | 4588 | } |
4578 | reserv_blks = ar->len; | 4589 | reserv_blks = ar->len; |
4590 | while (ar->len && vfs_dq_alloc_block(ar->inode, ar->len)) { | ||
4591 | ar->flags |= EXT4_MB_HINT_NOPREALLOC; | ||
4592 | ar->len--; | ||
4593 | } | ||
4594 | inquota = ar->len; | ||
4595 | if (ar->len == 0) { | ||
4596 | *errp = -EDQUOT; | ||
4597 | goto out3; | ||
4598 | } | ||
4579 | } | 4599 | } |
4580 | while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) { | ||
4581 | ar->flags |= EXT4_MB_HINT_NOPREALLOC; | ||
4582 | ar->len--; | ||
4583 | } | ||
4584 | if (ar->len == 0) { | ||
4585 | *errp = -EDQUOT; | ||
4586 | goto out3; | ||
4587 | } | ||
4588 | inquota = ar->len; | ||
4589 | |||
4590 | if (EXT4_I(ar->inode)->i_delalloc_reserved_flag) | ||
4591 | ar->flags |= EXT4_MB_DELALLOC_RESERVED; | ||
4592 | 4600 | ||
4593 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); | 4601 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); |
4594 | if (!ac) { | 4602 | if (!ac) { |
@@ -4654,8 +4662,8 @@ repeat: | |||
4654 | out2: | 4662 | out2: |
4655 | kmem_cache_free(ext4_ac_cachep, ac); | 4663 | kmem_cache_free(ext4_ac_cachep, ac); |
4656 | out1: | 4664 | out1: |
4657 | if (ar->len < inquota) | 4665 | if (inquota && ar->len < inquota) |
4658 | DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len); | 4666 | vfs_dq_free_block(ar->inode, inquota - ar->len); |
4659 | out3: | 4667 | out3: |
4660 | if (!ar->len) { | 4668 | if (!ar->len) { |
4661 | if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) | 4669 | if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) |