[Devel] [PATCH RHEL9 COMMIT] ext4: Teach the fs where the balloon inode is
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Nov 28 20:12:42 MSK 2024
The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.104.x-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.104.1
------>
commit f7ecb7af9558ab0eb0113426687decd6f6bc63e3
Author: Maxim V. Patlasov <MPatlasov at parallels.com>
Date: Tue Oct 5 18:42:26 2021 +0300
ext4: Teach the fs where the balloon inode is
This is a port of
da0fae4 ext4: Teach the fs where the balloon inode is
This adds the balloon_ino mount option and stores the inode
pointer on the in-memory super block object.
This is not good solution - in a perfect world the balloon
inode should be hidden (like the journalling one), but this
requires
a) reserve its number in the mainline sources;)
b) teach e2fsprogs not to treat one as orphaned
Until (if) we do this it's better to keep this as a regular
file on the disk.
(cherry picked from vz7 commit 54ac06cf671c68a3778e9f939ba3794fd6a51470)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
+++
ext4: Fix placement of balloon ino option
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Rebase from 5.14.0-42.el9 to 5.14.0-70.13.1.el9 (RHEL9 RTM):
- the patch has been rewritten due to ext4 API change to "fs_context"
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Feature: fs/ext4: fast online shrink support
---
fs/ext4/ext4.h | 2 ++
fs/ext4/super.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index e65344cb56ba..807cd5cbe379 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1649,6 +1649,8 @@ struct ext4_sb_info {
atomic_t s_mb_discarded;
atomic_t s_lock_busy;
+ struct inode *s_balloon_ino;
+
/* locality groups */
struct ext4_locality_group __percpu *s_locality_groups;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b7e9492cb33d..c5aef54cc07b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1594,6 +1594,7 @@ enum {
Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
Opt_no_prefetch_block_bitmaps, Opt_mb_optimize_scan,
Opt_errors, Opt_data, Opt_data_err, Opt_jqfmt, Opt_dax_type,
+ Opt_balloon_ino,
#ifdef CONFIG_EXT4_DEBUG
Opt_fc_debug_max_replay, Opt_fc_debug_force
#endif
@@ -1742,6 +1743,7 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
fsparam_flag ("reservation", Opt_removed), /* mount option from ext2/3 */
fsparam_flag ("noreservation", Opt_removed), /* mount option from ext2/3 */
fsparam_u32 ("journal", Opt_removed), /* mount option from ext2/3 */
+ fsparam_u32 ("balloon_ino", Opt_balloon_ino),
{}
};
@@ -1842,6 +1844,7 @@ static const struct mount_opts {
{Opt_fc_debug_force, EXT4_MOUNT2_JOURNAL_FAST_COMMIT,
MOPT_SET | MOPT_2 | MOPT_EXT4_ONLY},
#endif
+ {Opt_balloon_ino, 0, 0},
{Opt_err, 0, 0}
};
@@ -1887,6 +1890,7 @@ ext4_sb_read_encoding(const struct ext4_super_block *es)
#define EXT4_SPEC_s_fc_debug_max_replay (1 << 17)
#define EXT4_SPEC_s_sb_block (1 << 18)
#define EXT4_SPEC_mb_optimize_scan (1 << 19)
+#define EXT4_SPEC_balloon_ino (1 << 20)
struct ext4_fs_context {
char *s_qf_names[EXT4_MAXQUOTAS];
@@ -1912,6 +1916,7 @@ struct ext4_fs_context {
unsigned int mask_s_mount_opt2;
unsigned long vals_s_mount_flags;
unsigned long mask_s_mount_flags;
+ unsigned long balloon_ino;
unsigned int opt_flags; /* MOPT flags */
unsigned int spec;
u32 s_max_batch_time;
@@ -2338,6 +2343,10 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
return -EINVAL;
}
return 0;
+ case Opt_balloon_ino:
+ ctx->balloon_ino = result.uint_32;
+ ctx->spec |= EXT4_SPEC_balloon_ino;
+ return 0;
}
/*
@@ -3016,6 +3025,9 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
SEQ_OPTS_PUTS("mb_optimize_scan=1");
}
+ if (sbi->s_balloon_ino)
+ SEQ_OPTS_PRINT("balloon_ino=%ld", sbi->s_balloon_ino->i_ino);
+
ext4_show_quota_options(seq, sb);
return 0;
}
@@ -4306,6 +4318,54 @@ static struct ext4_sb_info *ext4_alloc_sbi(struct super_block *sb)
return NULL;
}
+static void ext4_load_balloon(struct super_block *sb, unsigned long ino)
+{
+ struct inode *inode;
+ struct ext4_sb_info *sbi;
+
+ sbi = EXT4_SB(sb);
+
+ if (!ino) {
+ /* FIXME locking */
+ if (sbi->s_balloon_ino) {
+ iput(sbi->s_balloon_ino);
+ sbi->s_balloon_ino = NULL;
+ }
+
+ return;
+ }
+
+ if (ino < EXT4_FIRST_INO(sb)) {
+ ext4_msg(sb, KERN_WARNING, "bad balloon inode specified");
+ return;
+ }
+
+ inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+ ext4_msg(sb, KERN_WARNING, "can't load balloon inode (%ld)", PTR_ERR(inode));
+ return;
+ }
+
+ if (!S_ISREG(inode->i_mode)) {
+ iput(inode);
+ ext4_msg(sb, KERN_WARNING, "balloon should be regular");
+ return;
+ }
+
+ if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) {
+ iput(inode);
+ ext4_msg(sb, KERN_WARNING, "balloon should support extents");
+ return;
+ }
+
+ /* FIXME - locking */
+ if (sbi->s_balloon_ino)
+ iput(sbi->s_balloon_ino);
+ sbi->s_balloon_ino = inode;
+ ext4_msg(sb, KERN_INFO, "loaded balloon from %ld (%llu blocks)",
+ inode->i_ino, inode->i_blocks);
+}
+
static void ext4_set_def_opts(struct super_block *sb,
struct ext4_super_block *es)
{
@@ -5569,6 +5629,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
ext4_msg(sb, KERN_WARNING,
"mounting with \"discard\" option, but the device does not support discard");
+ if (ctx->spec & EXT4_SPEC_balloon_ino)
+ ext4_load_balloon(sb, ctx->balloon_ino);
+
if (es->s_error_count)
mod_timer(&sbi->s_err_report, jiffies + 300*HZ); /* 5 minutes */
@@ -6636,6 +6699,9 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
goto restore_opts;
}
+ if (ctx->spec & EXT4_SPEC_balloon_ino)
+ ext4_load_balloon(sb, ctx->balloon_ino);
+
#ifdef CONFIG_QUOTA
if (enable_quota) {
if (sb_any_quota_suspended(sb))
@@ -7297,12 +7363,23 @@ static inline int ext3_feature_set_ok(struct super_block *sb)
return 1;
}
+static void ext4_kill_sb(struct super_block *sb)
+{
+ struct ext4_sb_info *sbi;
+
+ sbi = EXT4_SB(sb);
+ if (sbi && sbi->s_balloon_ino)
+ iput(sbi->s_balloon_ino);
+
+ kill_block_super(sb);
+}
+
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.init_fs_context = ext4_init_fs_context,
.parameters = ext4_param_specs,
- .kill_sb = kill_block_super,
+ .kill_sb = ext4_kill_sb,
.fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
};
MODULE_ALIAS_FS("ext4");
More information about the Devel
mailing list