Commit 654b4908 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Theodore Ts'o

ext4: cleanup block allocator

Move the code related to block allocation to a single function and add helper
funtions to differient allocation for data and meta data blocks
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarMingming Cao <cmm@us.ibm.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 7061eba7
...@@ -1640,20 +1640,24 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries) ...@@ -1640,20 +1640,24 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
} }
/** /**
* ext4_new_blocks_old() -- core block(s) allocation function * ext4_old_new_blocks() -- core block bitmap based block allocation function
*
* @handle: handle to this transaction * @handle: handle to this transaction
* @inode: file inode * @inode: file inode
* @goal: given target block(filesystem wide) * @goal: given target block(filesystem wide)
* @count: target number of blocks to allocate * @count: target number of blocks to allocate
* @errp: error code * @errp: error code
* *
* ext4_new_blocks uses a goal block to assist allocation. It tries to * ext4_old_new_blocks uses a goal block to assist allocation and look up
* allocate block(s) from the block group contains the goal block first. If that * the block bitmap directly to do block allocation. It tries to
* fails, it will try to allocate block(s) from other block groups without * allocate block(s) from the block group contains the goal block first. If
* any specific goal block. * that fails, it will try to allocate block(s) from other block groups
* without any specific goal block.
*
* This function is called when -o nomballoc mount option is enabled
* *
*/ */
ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp) ext4_fsblk_t goal, unsigned long *count, int *errp)
{ {
struct buffer_head *bitmap_bh = NULL; struct buffer_head *bitmap_bh = NULL;
...@@ -1923,78 +1927,95 @@ ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, ...@@ -1923,78 +1927,95 @@ ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode,
return 0; return 0;
} }
ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, #define EXT4_META_BLOCK 0x1
ext4_fsblk_t goal, int *errp)
{
struct ext4_allocation_request ar;
ext4_fsblk_t ret;
if (!test_opt(inode->i_sb, MBALLOC)) {
unsigned long count = 1;
ret = ext4_new_blocks_old(handle, inode, goal, &count, errp);
return ret;
}
memset(&ar, 0, sizeof(ar)); static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode,
ar.inode = inode;
ar.goal = goal;
ar.len = 1;
ret = ext4_mb_new_blocks(handle, &ar, errp);
return ret;
}
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp)
{
struct ext4_allocation_request ar;
ext4_fsblk_t ret;
if (!test_opt(inode->i_sb, MBALLOC)) {
ret = ext4_new_blocks_old(handle, inode, goal, count, errp);
return ret;
}
memset(&ar, 0, sizeof(ar));
ar.inode = inode;
ar.goal = goal;
ar.len = *count;
ret = ext4_mb_new_blocks(handle, &ar, errp);
*count = ar.len;
return ret;
}
ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, ext4_fsblk_t goal, ext4_lblk_t iblock, ext4_fsblk_t goal,
unsigned long *count, int *errp) unsigned long *count, int *errp, int flags)
{ {
struct ext4_allocation_request ar; struct ext4_allocation_request ar;
ext4_fsblk_t ret; ext4_fsblk_t ret;
if (!test_opt(inode->i_sb, MBALLOC)) { if (!test_opt(inode->i_sb, MBALLOC)) {
ret = ext4_new_blocks_old(handle, inode, goal, count, errp); return ext4_old_new_blocks(handle, inode, goal, count, errp);
return ret;
} }
memset(&ar, 0, sizeof(ar)); memset(&ar, 0, sizeof(ar));
/* Fill with neighbour allocated blocks */ /* Fill with neighbour allocated blocks */
ar.lleft = 0;
ar.pleft = 0;
ar.lright = 0;
ar.pright = 0;
ar.inode = inode; ar.inode = inode;
ar.goal = goal; ar.goal = goal;
ar.len = *count; ar.len = *count;
ar.logical = iblock; ar.logical = iblock;
if (S_ISREG(inode->i_mode))
if (S_ISREG(inode->i_mode) && !(flags & EXT4_META_BLOCK))
/* enable in-core preallocation for data block allocation */
ar.flags = EXT4_MB_HINT_DATA; ar.flags = EXT4_MB_HINT_DATA;
else else
/* disable in-core preallocation for non-regular files */ /* disable in-core preallocation for non-regular files */
ar.flags = 0; ar.flags = 0;
ret = ext4_mb_new_blocks(handle, &ar, errp); ret = ext4_mb_new_blocks(handle, &ar, errp);
*count = ar.len; *count = ar.len;
return ret; return ret;
} }
/*
* ext4_new_meta_block() -- allocate block for meta data (indexing) blocks
*
* @handle: handle to this transaction
* @inode: file inode
* @goal: given target block(filesystem wide)
* @errp: error code
*
* Return allocated block number on success
*/
ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, int *errp)
{
unsigned long count = 1;
return do_blk_alloc(handle, inode, 0, goal,
&count, errp, EXT4_META_BLOCK);
}
/*
* ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks
*
* @handle: handle to this transaction
* @inode: file inode
* @goal: given target block(filesystem wide)
* @count: total number of blocks need
* @errp: error code
*
* Return 1st allocated block numberon success, *count stores total account
* 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)
{
return do_blk_alloc(handle, inode, 0, goal,
count, errp, EXT4_META_BLOCK);
}
/*
* ext4_new_blocks() -- allocate data blocks
*
* @handle: handle to this transaction
* @inode: file inode
* @goal: given target block(filesystem wide)
* @count: total number of blocks need
* @errp: error code
*
* Return 1st allocated block numberon success, *count stores total account
* error stores in errp pointer
*/
ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, ext4_fsblk_t goal,
unsigned long *count, int *errp)
{
return do_blk_alloc(handle, inode, iblock, goal, count, errp, 0);
}
/** /**
* ext4_count_free_blocks() -- count filesystem free blocks * ext4_count_free_blocks() -- count filesystem free blocks
......
...@@ -977,7 +977,7 @@ extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, ...@@ -977,7 +977,7 @@ extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock, ext4_fsblk_t goal, ext4_lblk_t iblock, ext4_fsblk_t goal,
unsigned long *count, int *errp); unsigned long *count, int *errp);
extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, extern ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp); ext4_fsblk_t goal, unsigned long *count, int *errp);
extern void ext4_free_blocks (handle_t *handle, struct inode *inode, extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
ext4_fsblk_t block, unsigned long count, int metadata); ext4_fsblk_t block, unsigned long count, int metadata);
......
...@@ -179,8 +179,11 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, ...@@ -179,8 +179,11 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
return bg_start + colour + block; return bg_start + colour + block;
} }
/*
* Allocation for a meta data block
*/
static ext4_fsblk_t static ext4_fsblk_t
ext4_ext_new_block(handle_t *handle, struct inode *inode, ext4_ext_new_meta_block(handle_t *handle, struct inode *inode,
struct ext4_ext_path *path, struct ext4_ext_path *path,
struct ext4_extent *ex, int *err) struct ext4_extent *ex, int *err)
{ {
...@@ -690,7 +693,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, ...@@ -690,7 +693,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
/* allocate all needed blocks */ /* allocate all needed blocks */
ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
for (a = 0; a < depth - at; a++) { for (a = 0; a < depth - at; a++) {
newblock = ext4_ext_new_block(handle, inode, path, newext, &err); newblock = ext4_ext_new_meta_block(handle, inode, path,
newext, &err);
if (newblock == 0) if (newblock == 0)
goto cleanup; goto cleanup;
ablocks[a] = newblock; ablocks[a] = newblock;
...@@ -886,7 +890,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, ...@@ -886,7 +890,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
ext4_fsblk_t newblock; ext4_fsblk_t newblock;
int err = 0; int err = 0;
newblock = ext4_ext_new_block(handle, inode, path, newext, &err); newblock = ext4_ext_new_meta_block(handle, inode, path, newext, &err);
if (newblock == 0) if (newblock == 0)
return err; return err;
......
...@@ -561,7 +561,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, ...@@ -561,7 +561,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
goto allocated; goto allocated;
/* Now allocate data blocks */ /* Now allocate data blocks */
count = target; count = target;
/* allocating blocks for indirect blocks and direct blocks */ /* allocating blocks for data blocks */
current_block = ext4_new_blocks(handle, inode, iblock, current_block = ext4_new_blocks(handle, inode, iblock,
goal, &count, err); goal, &count, err);
if (*err && (target == blks)) { if (*err && (target == blks)) {
......
...@@ -4041,7 +4041,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ...@@ -4041,7 +4041,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
sbi = EXT4_SB(sb); sbi = EXT4_SB(sb);
if (!test_opt(sb, MBALLOC)) { if (!test_opt(sb, MBALLOC)) {
block = ext4_new_blocks_old(handle, ar->inode, ar->goal, block = ext4_old_new_blocks(handle, ar->inode, ar->goal,
&(ar->len), errp); &(ar->len), errp);
return block; return block;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment