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

ext4: Do not reserve clusters when fs doesn't support extents

When the filesystem doesn't support extents (like in ext2/3
compatibility modes), there is no need to reserve any clusters. Space
estimates for writing are exact, hole punching doesn't need new
metadata, and there are no unwritten extents to convert.

This fixes a problem when filesystem still having some free space when
accessed with a native ext2/3 driver suddently reports ENOSPC when
accessed with ext4 driver.
Reported-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Tested-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: default avatarLukas Czerner <lczerner@redhat.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
Cc: stable@vger.kernel.org
parent 9105bb14
...@@ -3316,10 +3316,18 @@ int ext4_calculate_overhead(struct super_block *sb) ...@@ -3316,10 +3316,18 @@ int ext4_calculate_overhead(struct super_block *sb)
} }
static ext4_fsblk_t ext4_calculate_resv_clusters(struct ext4_sb_info *sbi) static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
{ {
ext4_fsblk_t resv_clusters; ext4_fsblk_t resv_clusters;
/*
* There's no need to reserve anything when we aren't using extents.
* The space estimates are exact, there are no unwritten extents,
* hole punching doesn't need new metadata... This is needed especially
* to keep ext2/3 backward compatibility.
*/
if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
return 0;
/* /*
* By default we reserve 2% or 4096 clusters, whichever is smaller. * By default we reserve 2% or 4096 clusters, whichever is smaller.
* This should cover the situations where we can not afford to run * This should cover the situations where we can not afford to run
...@@ -3328,7 +3336,8 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct ext4_sb_info *sbi) ...@@ -3328,7 +3336,8 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct ext4_sb_info *sbi)
* allocation would require 1, or 2 blocks, higher numbers are * allocation would require 1, or 2 blocks, higher numbers are
* very rare. * very rare.
*/ */
resv_clusters = ext4_blocks_count(sbi->s_es) >> sbi->s_cluster_bits; resv_clusters = ext4_blocks_count(EXT4_SB(sb)->s_es) >>
EXT4_SB(sb)->s_cluster_bits;
do_div(resv_clusters, 50); do_div(resv_clusters, 50);
resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096); resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);
...@@ -4071,10 +4080,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4071,10 +4080,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"available"); "available");
} }
err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sbi)); err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sb));
if (err) { if (err) {
ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for " ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
"reserved pool", ext4_calculate_resv_clusters(sbi)); "reserved pool", ext4_calculate_resv_clusters(sb));
goto failed_mount4a; goto failed_mount4a;
} }
......
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