ext4: Use inode preallocation with -o noextents From: Aneesh Kumar K.V When mouting ext4 with -o noextents, request for file data blocks from inode prealloc space. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao --- fs/ext4/balloc.c | 9 ++++++++- fs/ext4/ext4.h | 5 +++-- fs/ext4/inode.c | 20 ++++++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) Index: linux-2.6.26-rc2/fs/ext4/balloc.c =================================================================== --- linux-2.6.26-rc2.orig/fs/ext4/balloc.c 2008-05-16 11:54:50.000000000 -0700 +++ linux-2.6.26-rc2/fs/ext4/balloc.c 2008-05-16 11:55:10.000000000 -0700 @@ -1883,7 +1883,8 @@ ext4_fsblk_t ext4_new_block(handle_t *ha } ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp) + ext4_lblk_t iblock, ext4_fsblk_t goal, + unsigned long *count, int *errp) { struct ext4_allocation_request ar; ext4_fsblk_t ret; @@ -1897,6 +1898,12 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h ar.inode = inode; ar.goal = goal; ar.len = *count; + ar.logical = iblock; + if (S_ISREG(inode->i_mode)) + ar.flags = EXT4_MB_HINT_DATA; + else + /* disable in-core preallocation for non-regular files */ + ar.flags = 0; ret = ext4_mb_new_blocks(handle, &ar, errp); *count = ar.len; return ret; Index: linux-2.6.26-rc2/fs/ext4/ext4.h =================================================================== --- linux-2.6.26-rc2.orig/fs/ext4/ext4.h 2008-05-16 11:16:55.000000000 -0700 +++ linux-2.6.26-rc2/fs/ext4/ext4.h 2008-05-16 11:55:10.000000000 -0700 @@ -960,8 +960,9 @@ extern unsigned long ext4_bg_num_gdb(str ext4_group_t group); extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, ext4_fsblk_t goal, int *errp); -extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, unsigned long *count, int *errp); +extern 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); extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned long *count, int *errp); extern void ext4_free_blocks (handle_t *handle, struct inode *inode, Index: linux-2.6.26-rc2/fs/ext4/inode.c =================================================================== --- linux-2.6.26-rc2.orig/fs/ext4/inode.c 2008-05-16 11:16:55.000000000 -0700 +++ linux-2.6.26-rc2/fs/ext4/inode.c 2008-05-16 11:55:10.000000000 -0700 @@ -508,8 +508,9 @@ static int ext4_blks_to_allocate(Indirec * direct blocks */ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, - ext4_fsblk_t goal, int indirect_blks, int blks, - ext4_fsblk_t new_blocks[4], int *err) + ext4_lblk_t iblock, ext4_fsblk_t goal, + int indirect_blks, int blks, + ext4_fsblk_t new_blocks[4], int *err) { int target, i; unsigned long count = 0; @@ -530,7 +531,8 @@ static int ext4_alloc_blocks(handle_t *h while (1) { count = target; /* allocating blocks for indirect blocks and direct blocks */ - current_block = ext4_new_blocks(handle,inode,goal,&count,err); + current_block = ext4_new_blocks(handle, inode, iblock, + goal, &count, err); if (*err) goto failed_out; @@ -584,8 +586,9 @@ failed_out: * as described above and return 0. */ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, - int indirect_blks, int *blks, ext4_fsblk_t goal, - ext4_lblk_t *offsets, Indirect *branch) + ext4_lblk_t iblock, int indirect_blks, + int *blks, ext4_fsblk_t goal, + ext4_lblk_t *offsets, Indirect *branch) { int blocksize = inode->i_sb->s_blocksize; int i, n = 0; @@ -595,7 +598,7 @@ static int ext4_alloc_branch(handle_t *h ext4_fsblk_t new_blocks[4]; ext4_fsblk_t current_block; - num = ext4_alloc_blocks(handle, inode, goal, indirect_blks, + num = ext4_alloc_blocks(handle, inode, iblock, goal, indirect_blks, *blks, new_blocks, &err); if (err) return err; @@ -855,8 +858,9 @@ int ext4_get_blocks_handle(handle_t *han /* * Block out ext4_truncate while we alter the tree */ - err = ext4_alloc_branch(handle, inode, indirect_blks, &count, goal, - offsets + (partial - chain), partial); + err = ext4_alloc_branch(handle, inode, iblock, indirect_blks, + &count, goal, + offsets + (partial - chain), partial); /* * The ext4_splice_branch call will free and forget any buffers