power: always freeze efivarfs

The efivarfs filesystems must always be frozen and thawed to resync
variable state. Make it so.

Link: https://patch.msgid.link/20251105-vorbild-zutreffen-fe00d1dd98db@brauner
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2025-11-05 14:39:45 +01:00
parent 75fdd57499
commit a3f8f86627
5 changed files with 17 additions and 12 deletions

View File

@@ -533,6 +533,7 @@ static struct file_system_type efivarfs_type = {
.init_fs_context = efivarfs_init_fs_context,
.kill_sb = efivarfs_kill_sb,
.parameters = efivarfs_parameters,
.fs_flags = FS_POWER_FREEZE,
};
static __init int efivarfs_init(void)

View File

@@ -1183,11 +1183,14 @@ static inline bool get_active_super(struct super_block *sb)
static const char *filesystems_freeze_ptr = "filesystems_freeze";
static void filesystems_freeze_callback(struct super_block *sb, void *unused)
static void filesystems_freeze_callback(struct super_block *sb, void *freeze_all_ptr)
{
if (!sb->s_op->freeze_fs && !sb->s_op->freeze_super)
return;
if (freeze_all_ptr && !(sb->s_type->fs_flags & FS_POWER_FREEZE))
return;
if (!get_active_super(sb))
return;
@@ -1201,9 +1204,13 @@ static void filesystems_freeze_callback(struct super_block *sb, void *unused)
deactivate_super(sb);
}
void filesystems_freeze(void)
void filesystems_freeze(bool freeze_all)
{
__iterate_supers(filesystems_freeze_callback, NULL,
void *freeze_all_ptr = NULL;
if (freeze_all)
freeze_all_ptr = &freeze_all;
__iterate_supers(filesystems_freeze_callback, freeze_all_ptr,
SUPER_ITER_UNLOCKED | SUPER_ITER_REVERSE);
}

View File

@@ -2689,6 +2689,7 @@ struct file_system_type {
#define FS_ALLOW_IDMAP 32 /* FS has been updated to handle vfs idmappings. */
#define FS_MGTIME 64 /* FS uses multigrain timestamps */
#define FS_LBS 128 /* FS supports LBS */
#define FS_POWER_FREEZE 256 /* Always freeze on suspend/hibernate */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
int (*init_fs_context)(struct fs_context *);
const struct fs_parameter_spec *parameters;
@@ -3606,7 +3607,7 @@ extern void drop_super_exclusive(struct super_block *sb);
extern void iterate_supers(void (*f)(struct super_block *, void *), void *arg);
extern void iterate_supers_type(struct file_system_type *,
void (*)(struct super_block *, void *), void *);
void filesystems_freeze(void);
void filesystems_freeze(bool freeze_all);
void filesystems_thaw(void);
extern int dcache_dir_open(struct inode *, struct file *);

View File

@@ -825,8 +825,7 @@ int hibernate(void)
goto Restore;
ksys_sync_helper();
if (filesystem_freeze_enabled)
filesystems_freeze();
filesystems_freeze(filesystem_freeze_enabled);
error = freeze_processes();
if (error)
@@ -932,8 +931,7 @@ int hibernate_quiet_exec(int (*func)(void *data), void *data)
if (error)
goto restore;
if (filesystem_freeze_enabled)
filesystems_freeze();
filesystems_freeze(filesystem_freeze_enabled);
error = freeze_processes();
if (error)
@@ -1083,8 +1081,7 @@ static int software_resume(void)
if (error)
goto Restore;
if (filesystem_freeze_enabled)
filesystems_freeze();
filesystems_freeze(filesystem_freeze_enabled);
pm_pr_dbg("Preparing processes for hibernation restore.\n");
error = freeze_processes();

View File

@@ -375,8 +375,7 @@ static int suspend_prepare(suspend_state_t state)
if (error)
goto Restore;
if (filesystem_freeze_enabled)
filesystems_freeze();
filesystems_freeze(filesystem_freeze_enabled);
trace_suspend_resume(TPS("freeze_processes"), 0, true);
error = suspend_freeze_processes();
trace_suspend_resume(TPS("freeze_processes"), 0, false);