===================================================================
@@ -211,6 +211,7 @@ struct inodes_stat_t {
#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
#define MS_I_VERSION (1<<23) /* Update inode I_version field */
#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
+#define MS_FROZEN (1<<25) /* Frozen filesystem */
#define MS_NOSEC (1<<28)
#define MS_BORN (1<<29)
#define MS_ACTIVE (1<<30)
@@ -2497,6 +2498,8 @@ extern void drop_super(struct super_bloc
extern void iterate_supers(void (*)(struct super_block *, void *), void *);
extern void iterate_supers_type(struct file_system_type *,
void (*)(struct super_block *, void *), void *);
+extern int freeze_supers(void);
+extern void thaw_supers(void);
extern int dcache_dir_open(struct inode *, struct file *);
extern int dcache_dir_close(struct inode *, struct file *);
===================================================================
@@ -12,10 +12,10 @@
#include <linux/oom.h>
#include <linux/suspend.h>
#include <linux/module.h>
-#include <linux/syscalls.h>
#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
+#include <linux/fs.h>
/*
* Timeout for stopping processes
@@ -147,6 +147,12 @@ int freeze_processes(void)
goto Exit;
printk("done.\n");
+ printk("Freezing filesystems ... ");
+ error = freeze_supers();
+ if (error)
+ goto Exit;
+ printk("done.\n");
+
printk("Freezing remaining freezable tasks ... ");
error = try_to_freeze_tasks(false);
if (error)
@@ -188,6 +194,7 @@ void thaw_processes(void)
printk("Restarting tasks ... ");
thaw_workqueues();
thaw_tasks(true);
+ thaw_supers();
thaw_tasks(false);
schedule();
printk("done.\n");
===================================================================
@@ -590,6 +590,76 @@ void iterate_supers_type(struct file_sys
EXPORT_SYMBOL(iterate_supers_type);
/**
+ * freeze_supers - call freeze_super() for all superblocks
+ */
+int freeze_supers(void)
+{
+ struct super_block *sb, *p = NULL;
+ int error = 0;
+
+ spin_lock(&sb_lock);
+ /*
+ * Freeze in reverse order so filesystems depending on others are
+ * frozen in the right order (eg. loopback on ext3).
+ */
+ list_for_each_entry_reverse(sb, &super_blocks, s_list) {
+ if (list_empty(&sb->s_instances))
+ continue;
+ sb->s_count++;
+ spin_unlock(&sb_lock);
+
+ if (sb->s_root && sb->s_frozen != SB_FREEZE_TRANS
+ && !(sb->s_flags & MS_RDONLY)) {
+ error = freeze_super(sb);
+ if (!error)
+ sb->s_flags |= MS_FROZEN;
+ }
+
+ spin_lock(&sb_lock);
+ if (error)
+ break;
+ if (p)
+ __put_super(p);
+ p = sb;
+ }
+ if (p)
+ __put_super(p);
+ spin_unlock(&sb_lock);
+
+ return error;
+}
+
+/**
+ * thaw_supers - call thaw_super() for all superblocks
+ */
+void thaw_supers(void)
+{
+ struct super_block *sb, *p = NULL;
+
+ spin_lock(&sb_lock);
+ list_for_each_entry(sb, &super_blocks, s_list) {
+ if (list_empty(&sb->s_instances))
+ continue;
+ sb->s_count++;
+ spin_unlock(&sb_lock);
+
+ if (sb->s_flags & MS_FROZEN) {
+ thaw_super(sb);
+ sb->s_flags &= ~MS_FROZEN;
+ }
+
+ spin_lock(&sb_lock);
+ if (p)
+ __put_super(p);
+ p = sb;
+ }
+ if (p)
+ __put_super(p);
+ spin_unlock(&sb_lock);
+}
+
+
+/**
* get_super - get the superblock of a device
* @bdev: device to get the superblock for
*