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>
This commit is contained in:
committed by
Theodore Ts'o
parent
ae81230686
commit
55f020db66
@ -369,7 +369,8 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
|
||||
* Check if filesystem has nblocks free & available for allocation.
|
||||
* On success return 1, return 0 on failure.
|
||||
*/
|
||||
static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
|
||||
static int ext4_has_free_blocks(struct ext4_sb_info *sbi,
|
||||
s64 nblocks, unsigned int flags)
|
||||
{
|
||||
s64 free_blocks, dirty_blocks, root_blocks;
|
||||
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)
|
||||
/* Hm, nope. Are (enough) root reserved blocks available? */
|
||||
if (sbi->s_resuid == current_fsuid() ||
|
||||
((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
|
||||
capable(CAP_SYS_RESOURCE)) {
|
||||
capable(CAP_SYS_RESOURCE) ||
|
||||
(flags & EXT4_MB_USE_ROOT_BLOCKS)) {
|
||||
|
||||
if (free_blocks >= (nblocks + dirty_blocks))
|
||||
return 1;
|
||||
}
|
||||
@ -402,9 +405,9 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
|
||||
}
|
||||
|
||||
int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
|
||||
s64 nblocks)
|
||||
s64 nblocks, unsigned int flags)
|
||||
{
|
||||
if (ext4_has_free_blocks(sbi, nblocks)) {
|
||||
if (ext4_has_free_blocks(sbi, nblocks, flags)) {
|
||||
percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks);
|
||||
return 0;
|
||||
} else
|
||||
@ -425,7 +428,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
|
||||
*/
|
||||
int ext4_should_retry_alloc(struct super_block *sb, int *retries)
|
||||
{
|
||||
if (!ext4_has_free_blocks(EXT4_SB(sb), 1) ||
|
||||
if (!ext4_has_free_blocks(EXT4_SB(sb), 1, 0) ||
|
||||
(*retries)++ > 3 ||
|
||||
!EXT4_SB(sb)->s_journal)
|
||||
return 0;
|
||||
@ -448,7 +451,8 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
|
||||
* error stores in errp pointer
|
||||
*/
|
||||
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
|
||||
ext4_fsblk_t goal, unsigned long *count, int *errp)
|
||||
ext4_fsblk_t goal, unsigned int flags,
|
||||
unsigned long *count, int *errp)
|
||||
{
|
||||
struct ext4_allocation_request ar;
|
||||
ext4_fsblk_t ret;
|
||||
@ -458,6 +462,7 @@ ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
|
||||
ar.inode = inode;
|
||||
ar.goal = goal;
|
||||
ar.len = count ? *count : 1;
|
||||
ar.flags = flags;
|
||||
|
||||
ret = ext4_mb_new_blocks(handle, &ar, errp);
|
||||
if (count)
|
||||
|
Reference in New Issue
Block a user