diff options
author | Allison Henderson <achender@linux.vnet.ibm.com> | 2011-05-25 07:41:26 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-05-25 07:41:26 -0400 |
commit | 55f020db66ce187fb8c8e4002a94b0eb714da450 (patch) | |
tree | e98214511542f57fa93074be12e27c4819520333 /fs/ext4/balloc.c | |
parent | ae81230686282af745ebb7a74c0332349cb9131a (diff) |
ext4: add flag to ext4_has_free_blocks
This patch adds an allocation request flag to the ext4_has_free_blocks
function which enables the use of reserved blocks. This will allow a
punch hole to proceed even if the disk is full. Punching a hole may
require additional blocks to first split the extents.
Because ext4_has_free_blocks is a low level function, the flag needs
to be passed down through several functions listed below:
ext4_ext_insert_extent
ext4_ext_create_new_leaf
ext4_ext_grow_indepth
ext4_ext_split
ext4_ext_new_meta_block
ext4_mb_new_blocks
ext4_claim_free_blocks
ext4_has_free_blocks
[ext4 punch hole patch series 1/5 v7]
Signed-off-by: Allison Henderson <achender@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Mingming Cao <cmm@us.ibm.com>
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r-- | fs/ext4/balloc.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b2d10da505ef..264f6949511e 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -369,7 +369,8 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
369 | * Check if filesystem has nblocks free & available for allocation. | 369 | * Check if filesystem has nblocks free & available for allocation. |
370 | * On success return 1, return 0 on failure. | 370 | * On success return 1, return 0 on failure. |
371 | */ | 371 | */ |
372 | static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | 372 | static int ext4_has_free_blocks(struct ext4_sb_info *sbi, |
373 | s64 nblocks, unsigned int flags) | ||
373 | { | 374 | { |
374 | s64 free_blocks, dirty_blocks, root_blocks; | 375 | s64 free_blocks, dirty_blocks, root_blocks; |
375 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; | 376 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; |
@@ -393,7 +394,9 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | |||
393 | /* Hm, nope. Are (enough) root reserved blocks available? */ | 394 | /* Hm, nope. Are (enough) root reserved blocks available? */ |
394 | if (sbi->s_resuid == current_fsuid() || | 395 | if (sbi->s_resuid == current_fsuid() || |
395 | ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || | 396 | ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || |
396 | capable(CAP_SYS_RESOURCE)) { | 397 | capable(CAP_SYS_RESOURCE) || |
398 | (flags & EXT4_MB_USE_ROOT_BLOCKS)) { | ||
399 | |||
397 | if (free_blocks >= (nblocks + dirty_blocks)) | 400 | if (free_blocks >= (nblocks + dirty_blocks)) |
398 | return 1; | 401 | return 1; |
399 | } | 402 | } |
@@ -402,9 +405,9 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | |||
402 | } | 405 | } |
403 | 406 | ||
404 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | 407 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, |
405 | s64 nblocks) | 408 | s64 nblocks, unsigned int flags) |
406 | { | 409 | { |
407 | if (ext4_has_free_blocks(sbi, nblocks)) { | 410 | if (ext4_has_free_blocks(sbi, nblocks, flags)) { |
408 | percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks); | 411 | percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks); |
409 | return 0; | 412 | return 0; |
410 | } else | 413 | } else |
@@ -425,7 +428,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | |||
425 | */ | 428 | */ |
426 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) | 429 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) |
427 | { | 430 | { |
428 | if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || | 431 | if (!ext4_has_free_blocks(EXT4_SB(sb), 1, 0) || |
429 | (*retries)++ > 3 || | 432 | (*retries)++ > 3 || |
430 | !EXT4_SB(sb)->s_journal) | 433 | !EXT4_SB(sb)->s_journal) |
431 | return 0; | 434 | return 0; |
@@ -448,7 +451,8 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries) | |||
448 | * error stores in errp pointer | 451 | * error stores in errp pointer |
449 | */ | 452 | */ |
450 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | 453 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, |
451 | ext4_fsblk_t goal, unsigned long *count, int *errp) | 454 | ext4_fsblk_t goal, unsigned int flags, |
455 | unsigned long *count, int *errp) | ||
452 | { | 456 | { |
453 | struct ext4_allocation_request ar; | 457 | struct ext4_allocation_request ar; |
454 | ext4_fsblk_t ret; | 458 | ext4_fsblk_t ret; |
@@ -458,6 +462,7 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | |||
458 | ar.inode = inode; | 462 | ar.inode = inode; |
459 | ar.goal = goal; | 463 | ar.goal = goal; |
460 | ar.len = count ? *count : 1; | 464 | ar.len = count ? *count : 1; |
465 | ar.flags = flags; | ||
461 | 466 | ||
462 | ret = ext4_mb_new_blocks(handle, &ar, errp); | 467 | ret = ext4_mb_new_blocks(handle, &ar, errp); |
463 | if (count) | 468 | if (count) |