Skip to content

Commit d05466b

Browse files
jankaratytso
authored andcommitted
ext4: avoid ENOSPC when avoiding to reuse recently deleted inodes
When ext4 is running on a filesystem without a journal, it tries not to reuse recently deleted inodes to provide better chances for filesystem recovery in case of crash. However this logic forbids reuse of freed inodes for up to 5 minutes and especially for filesystems with smaller number of inodes can lead to ENOSPC errors returned when allocating new inodes. Fix the problem by allowing to reuse recently deleted inode if there's no other inode free in the scanned range. Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 5e47868 commit d05466b

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

fs/ext4/ialloc.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -712,21 +712,34 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
712712
static int find_inode_bit(struct super_block *sb, ext4_group_t group,
713713
struct buffer_head *bitmap, unsigned long *ino)
714714
{
715+
bool check_recently_deleted = EXT4_SB(sb)->s_journal == NULL;
716+
unsigned long recently_deleted_ino = EXT4_INODES_PER_GROUP(sb);
717+
715718
next:
716719
*ino = ext4_find_next_zero_bit((unsigned long *)
717720
bitmap->b_data,
718721
EXT4_INODES_PER_GROUP(sb), *ino);
719722
if (*ino >= EXT4_INODES_PER_GROUP(sb))
720-
return 0;
723+
goto not_found;
721724

722-
if ((EXT4_SB(sb)->s_journal == NULL) &&
723-
recently_deleted(sb, group, *ino)) {
725+
if (check_recently_deleted && recently_deleted(sb, group, *ino)) {
726+
recently_deleted_ino = *ino;
724727
*ino = *ino + 1;
725728
if (*ino < EXT4_INODES_PER_GROUP(sb))
726729
goto next;
727-
return 0;
730+
goto not_found;
728731
}
729-
732+
return 1;
733+
not_found:
734+
if (recently_deleted_ino >= EXT4_INODES_PER_GROUP(sb))
735+
return 0;
736+
/*
737+
* Not reusing recently deleted inodes is mostly a preference. We don't
738+
* want to report ENOSPC or skew allocation patterns because of that.
739+
* So return even recently deleted inode if we could find better in the
740+
* given range.
741+
*/
742+
*ino = recently_deleted_ino;
730743
return 1;
731744
}
732745

0 commit comments

Comments
 (0)