[<prev] [next>] [day] [month] [year] [list]
Message-ID:
<ME0P300MB07806E7C0A351C163E1176B3C93FA@ME0P300MB0780.AUSP300.PROD.OUTLOOK.COM>
Date: Sun, 24 Aug 2025 12:40:17 +0800
From: Yihe Jiang <he29@...mail.com>
To: David Woodhouse <dwmw2@...radead.org>,
Richard Weinberger <richard@....at>
Cc: Yihe Jiang <he29@...mail.com>,
linux-mtd@...ts.infradead.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] jffs2: add erase_on_mount mount option
On some slow MTD devices, mounting a newly-created empty filesystem
can cause the system to become extremely slow, as all empty blocks
are erased in the background after the first mount. This can preempt
userspace operations and affect filesystem performance.
This commit adds an erase_on_mount mount option. When specified with
rw, all pending blocks are erased during the mount process, avoiding
the speed drop after mounting. The option does not take effect when
mounting read-only.
Signed-off-by: Yihe Jiang <he29@...mail.com>
---
fs/jffs2/fs.c | 14 ++++++++++++++
fs/jffs2/jffs2_fs_sb.h | 1 +
fs/jffs2/super.c | 10 ++++++++++
3 files changed, 25 insertions(+)
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index d175cccb7c55..65cbb47d73c4 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -411,6 +411,13 @@ int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc)
mutex_unlock(&c->alloc_sem);
}
+ if (!(fc->sb_flags & SB_RDONLY) && c->mount_opts.erase_on_mount) {
+ pr_info("erase_on_mount option set, erasing all pending blocks\n");
+ while (!list_empty(&c->erase_complete_list) ||
+ !list_empty(&c->erase_pending_list))
+ jffs2_erase_pending_blocks(c, 1);
+ }
+
if (!(fc->sb_flags & SB_RDONLY))
jffs2_start_garbage_collect_thread(c);
@@ -595,6 +602,13 @@ int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_time_min = 0;
sb->s_time_max = U32_MAX;
+ if (!sb_rdonly(sb) && c->mount_opts.erase_on_mount) {
+ pr_info("erase_on_mount option set, erasing all pending blocks\n");
+ while (!list_empty(&c->erase_complete_list) ||
+ !list_empty(&c->erase_pending_list))
+ jffs2_erase_pending_blocks(c, 1);
+ }
+
if (!sb_rdonly(sb))
jffs2_start_garbage_collect_thread(c);
return 0;
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 5a7091746f68..eb43416997f0 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -40,6 +40,7 @@ struct jffs2_mount_opts {
* available space is less then 'rp_size'. */
bool set_rp_size;
unsigned int rp_size;
+ bool erase_on_mount;
};
/* A struct for the overall file system control. Pointers to
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 4545f885c41e..270d24b336cd 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -91,6 +91,8 @@ static int jffs2_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
if (opts->set_rp_size)
seq_printf(s, ",rp_size=%u", opts->rp_size / 1024);
+ if (opts->erase_on_mount)
+ seq_puts(s, ",erase_on_mount");
return 0;
}
@@ -167,6 +169,7 @@ static const struct export_operations jffs2_export_ops = {
enum {
Opt_override_compr,
Opt_rp_size,
+ Opt_erase_on_mount,
};
static const struct constant_table jffs2_param_compr[] = {
@@ -183,6 +186,7 @@ static const struct constant_table jffs2_param_compr[] = {
static const struct fs_parameter_spec jffs2_fs_parameters[] = {
fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr),
fsparam_u32 ("rp_size", Opt_rp_size),
+ fsparam_flag ("erase_on_mount", Opt_erase_on_mount),
{}
};
@@ -207,6 +211,9 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
c->mount_opts.rp_size = result.uint_32 * 1024;
c->mount_opts.set_rp_size = true;
break;
+ case Opt_erase_on_mount:
+ c->mount_opts.erase_on_mount = true;
+ break;
default:
return -EINVAL;
}
@@ -228,6 +235,9 @@ static inline void jffs2_update_mount_opts(struct fs_context *fc)
c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size;
c->mount_opts.rp_size = new_c->mount_opts.rp_size;
}
+
+ c->mount_opts.erase_on_mount = new_c->mount_opts.erase_on_mount;
+
mutex_unlock(&c->alloc_sem);
}
--
2.50.1
Powered by blists - more mailing lists