Skip to content

Commit 0e8b687

Browse files
Lukas Czernertytso
authored andcommitted
ext4: refactor ext4_fallocate code
Move block allocation out of the ext4_fallocate into separate function called ext4_alloc_file_blocks(). This will allow us to use the same allocation code for other allocation operations such as zero range which is commit in the next patch. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
1 parent f282ac1 commit 0e8b687

File tree

1 file changed

+74
-55
lines changed

1 file changed

+74
-55
lines changed

fs/ext4/extents.c

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4546,6 +4546,64 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode)
45464546
ext4_std_error(inode->i_sb, err);
45474547
}
45484548

4549+
static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
4550+
ext4_lblk_t len, int flags, int mode)
4551+
{
4552+
struct inode *inode = file_inode(file);
4553+
handle_t *handle;
4554+
int ret = 0;
4555+
int ret2 = 0;
4556+
int retries = 0;
4557+
struct ext4_map_blocks map;
4558+
unsigned int credits;
4559+
4560+
map.m_lblk = offset;
4561+
/*
4562+
* Don't normalize the request if it can fit in one extent so
4563+
* that it doesn't get unnecessarily split into multiple
4564+
* extents.
4565+
*/
4566+
if (len <= EXT_UNINIT_MAX_LEN)
4567+
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
4568+
4569+
/*
4570+
* credits to insert 1 extent into extent tree
4571+
*/
4572+
credits = ext4_chunk_trans_blocks(inode, len);
4573+
4574+
retry:
4575+
while (ret >= 0 && ret < len) {
4576+
map.m_lblk = map.m_lblk + ret;
4577+
map.m_len = len = len - ret;
4578+
handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
4579+
credits);
4580+
if (IS_ERR(handle)) {
4581+
ret = PTR_ERR(handle);
4582+
break;
4583+
}
4584+
ret = ext4_map_blocks(handle, inode, &map, flags);
4585+
if (ret <= 0) {
4586+
ext4_debug("inode #%lu: block %u: len %u: "
4587+
"ext4_ext_map_blocks returned %d",
4588+
inode->i_ino, map.m_lblk,
4589+
map.m_len, ret);
4590+
ext4_mark_inode_dirty(handle, inode);
4591+
ret2 = ext4_journal_stop(handle);
4592+
break;
4593+
}
4594+
ret2 = ext4_journal_stop(handle);
4595+
if (ret2)
4596+
break;
4597+
}
4598+
if (ret == -ENOSPC &&
4599+
ext4_should_retry_alloc(inode->i_sb, &retries)) {
4600+
ret = 0;
4601+
goto retry;
4602+
}
4603+
4604+
return ret > 0 ? ret2 : ret;
4605+
}
4606+
45494607
/*
45504608
* preallocate space for a file. This implements ext4's fallocate file
45514609
* operation, which gets called from sys_fallocate system call.
@@ -4560,12 +4618,10 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
45604618
loff_t new_size = 0;
45614619
unsigned int max_blocks;
45624620
int ret = 0;
4563-
int ret2 = 0;
4564-
int retries = 0;
45654621
int flags;
4566-
struct ext4_map_blocks map;
4622+
ext4_lblk_t lblk;
45674623
struct timespec tv;
4568-
unsigned int credits, blkbits = inode->i_blkbits;
4624+
unsigned int blkbits = inode->i_blkbits;
45694625

45704626
/* Return error if mode is not supported */
45714627
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
@@ -4590,17 +4646,18 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
45904646
return -EOPNOTSUPP;
45914647

45924648
trace_ext4_fallocate_enter(inode, offset, len, mode);
4593-
map.m_lblk = offset >> blkbits;
4649+
lblk = offset >> blkbits;
45944650
/*
45954651
* We can't just convert len to max_blocks because
45964652
* If blocksize = 4096 offset = 3072 and len = 2048
45974653
*/
45984654
max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
4599-
- map.m_lblk;
4600-
/*
4601-
* credits to insert 1 extent into extent tree
4602-
*/
4603-
credits = ext4_chunk_trans_blocks(inode, max_blocks);
4655+
- lblk;
4656+
4657+
flags = EXT4_GET_BLOCKS_CREATE_UNINIT_EXT;
4658+
if (mode & FALLOC_FL_KEEP_SIZE)
4659+
flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
4660+
46044661
mutex_lock(&inode->i_mutex);
46054662

46064663
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
@@ -4611,61 +4668,24 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
46114668
goto out;
46124669
}
46134670

4614-
flags = EXT4_GET_BLOCKS_CREATE_UNINIT_EXT;
4615-
if (mode & FALLOC_FL_KEEP_SIZE)
4616-
flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
4617-
/*
4618-
* Don't normalize the request if it can fit in one extent so
4619-
* that it doesn't get unnecessarily split into multiple
4620-
* extents.
4621-
*/
4622-
if (len <= EXT_UNINIT_MAX_LEN << blkbits)
4623-
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
4624-
4625-
retry:
4626-
while (ret >= 0 && ret < max_blocks) {
4627-
map.m_lblk = map.m_lblk + ret;
4628-
map.m_len = max_blocks = max_blocks - ret;
4629-
handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
4630-
credits);
4631-
if (IS_ERR(handle)) {
4632-
ret = PTR_ERR(handle);
4633-
break;
4634-
}
4635-
ret = ext4_map_blocks(handle, inode, &map, flags);
4636-
if (ret <= 0) {
4637-
ext4_debug("inode #%lu: block %u: len %u: "
4638-
"ext4_ext_map_blocks returned %d",
4639-
inode->i_ino, map.m_lblk,
4640-
map.m_len, ret);
4641-
ext4_mark_inode_dirty(handle, inode);
4642-
ret2 = ext4_journal_stop(handle);
4643-
break;
4644-
}
4645-
ret2 = ext4_journal_stop(handle);
4646-
if (ret2)
4647-
break;
4648-
}
4649-
if (ret == -ENOSPC &&
4650-
ext4_should_retry_alloc(inode->i_sb, &retries)) {
4651-
ret = 0;
4652-
goto retry;
4653-
}
4671+
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, flags, mode);
4672+
if (ret)
4673+
goto out;
46544674

46554675
handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
46564676
if (IS_ERR(handle))
46574677
goto out;
46584678

46594679
tv = inode->i_ctime = ext4_current_time(inode);
46604680

4661-
if (ret > 0 && new_size) {
4681+
if (!ret && new_size) {
46624682
if (new_size > i_size_read(inode)) {
46634683
i_size_write(inode, new_size);
46644684
inode->i_mtime = tv;
46654685
}
46664686
if (new_size > EXT4_I(inode)->i_disksize)
46674687
ext4_update_i_disksize(inode, new_size);
4668-
} else if (ret > 0 && !new_size) {
4688+
} else if (!ret && !new_size) {
46694689
/*
46704690
* Mark that we allocate beyond EOF so the subsequent truncate
46714691
* can proceed even if the new size is the same as i_size.
@@ -4680,9 +4700,8 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
46804700
ext4_journal_stop(handle);
46814701
out:
46824702
mutex_unlock(&inode->i_mutex);
4683-
trace_ext4_fallocate_exit(inode, offset, max_blocks,
4684-
ret > 0 ? ret2 : ret);
4685-
return ret > 0 ? ret2 : ret;
4703+
trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
4704+
return ret;
46864705
}
46874706

46884707
/*

0 commit comments

Comments
 (0)