Commit a9f2a293 authored by Jan Kara's avatar Jan Kara Committed by Theodore Ts'o

ext4: use locality group preallocation for small closed files

Curently we don't use any preallocation when a file is already closed
when allocating blocks (from writeback code when converting delayed
allocation). However for small files, using locality group preallocation
is actually desirable as that is not specific to a particular file.
Rather it is a method to pack small files together to reduce
fragmentation and for that the fact the file is closed is actually even
stronger hint the file would benefit from packing. So change the logic
to allow locality group preallocation in this case.

Fixes: 196e402a ("ext4: improve cr 0 / cr 1 group scanning")
CC: stable@kernel.org
Reported-and-tested-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Tested-by: default avatarOjaswin Mujoo <ojaswin@linux.ibm.com>
Reviewed-by: default avatarRitesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/all/0d81a7c2-46b7-6010-62a4-3e6cfc1628d6@i2se.com/
Link: https://lore.kernel.org/r/20220908092136.11770-4-jack@suse.czSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 613c5a85
...@@ -5195,6 +5195,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) ...@@ -5195,6 +5195,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
int bsbits = ac->ac_sb->s_blocksize_bits; int bsbits = ac->ac_sb->s_blocksize_bits;
loff_t size, isize; loff_t size, isize;
bool inode_pa_eligible, group_pa_eligible;
if (!(ac->ac_flags & EXT4_MB_HINT_DATA)) if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
return; return;
...@@ -5202,25 +5203,27 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) ...@@ -5202,25 +5203,27 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY)) if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
return; return;
group_pa_eligible = sbi->s_mb_group_prealloc > 0;
inode_pa_eligible = true;
size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len); size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len);
isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1) isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1)
>> bsbits; >> bsbits;
/* No point in using inode preallocation for closed files */
if ((size == isize) && !ext4_fs_is_busy(sbi) && if ((size == isize) && !ext4_fs_is_busy(sbi) &&
!inode_is_open_for_write(ac->ac_inode)) { !inode_is_open_for_write(ac->ac_inode))
ac->ac_flags |= EXT4_MB_HINT_NOPREALLOC; inode_pa_eligible = false;
return;
}
if (sbi->s_mb_group_prealloc <= 0) {
ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
return;
}
/* don't use group allocation for large files */
size = max(size, isize); size = max(size, isize);
if (size > sbi->s_mb_stream_request) { /* Don't use group allocation for large files */
ac->ac_flags |= EXT4_MB_STREAM_ALLOC; if (size > sbi->s_mb_stream_request)
group_pa_eligible = false;
if (!group_pa_eligible) {
if (inode_pa_eligible)
ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
else
ac->ac_flags |= EXT4_MB_HINT_NOPREALLOC;
return; return;
} }
......
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