[PATCH] Freeze bdevs when freezing processes.
- From: Nigel Cunningham <ncunningham@xxxxxxxxxxxxx>
- Date: Mon, 23 Oct 2006 14:12:15 +1000
XFS can continue to submit I/O from a timer routine, even after
freezeable kernel and userspace threads are frozen. This doesn't seem to
be an issue for current swsusp code, but is definitely an issue for
Suspend2, where the pages being written could be overwritten by
Suspend2's atomic copy.
We can address this issue by freezing bdevs after stopping userspace
threads, and thawing them prior to thawing userspace.
Signed-off-by: Nigel Cunningham <nigel@xxxxxxxxxxxx>
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 4a001fe..ddeeb50 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -13,6 +13,7 @@ #include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/syscalls.h>
+#include <linux/buffer_head.h>
#include <linux/freezer.h>
/*
@@ -20,6 +21,58 @@ #include <linux/freezer.h>
*/
#define TIMEOUT (20 * HZ)
+struct frozen_fs
+{
+ struct list_head fsb_list;
+ struct super_block *sb;
+};
+
+LIST_HEAD(frozen_fs_list);
+
+void freezer_make_fses_rw(void)
+{
+ struct frozen_fs *fs, *next_fs;
+
+ list_for_each_entry_safe(fs, next_fs, &frozen_fs_list, fsb_list) {
+ thaw_bdev(fs->sb->s_bdev, fs->sb);
+
+ list_del(&fs->fsb_list);
+ kfree(fs);
+ }
+}
+
+/*
+ * Done after userspace is frozen, so there should be no danger of
+ * fses being unmounted while we're in here.
+ */
+int freezer_make_fses_ro(void)
+{
+ struct frozen_fs *fs;
+ struct super_block *sb;
+
+ /* Generate the list */
+ list_for_each_entry(sb, &super_blocks, s_list) {
+ if (!sb->s_root || !sb->s_bdev ||
+ (sb->s_frozen == SB_FREEZE_TRANS) ||
+ (sb->s_flags & MS_RDONLY))
+ continue;
+
+ fs = kmalloc(sizeof(struct frozen_fs), GFP_ATOMIC);
+ if (!fs)
+ return 1;
+ fs->sb = sb;
+ list_add_tail(&fs->fsb_list, &frozen_fs_list);
+ };
+
+ /* Do the freezing in reverse order so filesystems dependant
+ * upon others are frozen in the right order. (Eg loopback
+ * on ext3). */
+ list_for_each_entry_reverse(fs, &frozen_fs_list, fsb_list)
+ freeze_bdev(fs->sb->s_bdev);
+
+ return 0;
+}
+
static inline int freezeable(struct task_struct * p)
{
@@ -119,7 +172,7 @@ int freeze_processes(void)
read_unlock(&tasklist_lock);
todo += nr_user;
if (!user_frozen && !nr_user) {
- sys_sync();
+ freezer_make_fses_ro();
start_time = jiffies;
}
user_frozen = !nr_user;
@@ -174,6 +227,12 @@ void thaw_some_processes(int all)
"Strange, %s not stopped\n", p->comm );
} while_each_thread(g, p);
+ if (!pass) {
+ read_unlock(&tasklist_lock);
+ freezer_make_fses_rw();
+ read_lock(&tasklist_lock);
+ }
+
pass++;
} while (pass < 2 && all);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
- Follow-Ups:
- Re: [PATCH] Freeze bdevs when freezing processes.
- From: Christoph Hellwig
- Re: [PATCH] Freeze bdevs when freezing processes.
- From: Rafael J. Wysocki
- Re: [PATCH] Freeze bdevs when freezing processes.
- From: Rafael J. Wysocki
- Re: [PATCH] Freeze bdevs when freezing processes.
- Prev by Date: 2.6.19-rc2 tg3 cannot find proper pci device base address
- Next by Date: [PATCH] Use extents for recording what swap is allocated.
- Previous by thread: [PATCH] fix minor error about efi memory_present
- Next by thread: Re: [PATCH] Freeze bdevs when freezing processes.
- Index(es):
Relevant Pages
|