[PATCH] swsusp: avoid problems if there are too many pages to save
authorRafael J. Wysocki <rjw@sisk.pl>
Wed, 28 Sep 2005 04:45:43 +0000 (21:45 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 28 Sep 2005 14:46:41 +0000 (07:46 -0700)
The following patch makes swsusp avoid problems during resume if there are
too many pages to save on suspend.  It adds a constant that allows us to
verify if we are going to save too many pages and implements the check
(this is done as early as we can tell that the check will trigger, which is
in swsusp_alloc()).

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/power/power.h
kernel/power/swsusp.c

index 9c9167d910ddb361b59857e3a318b94049d3031a..6748de23e83ce95f011061507e441ebb38a45498 100644 (file)
@@ -9,6 +9,9 @@
 #define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
 #endif
 
+#define MAX_PBES       ((PAGE_SIZE - sizeof(struct new_utsname) \
+                       - 4 - 3*sizeof(unsigned long) - sizeof(int) \
+                       - sizeof(void *)) / sizeof(swp_entry_t))
 
 struct swsusp_info {
        struct new_utsname      uts;
@@ -18,7 +21,7 @@ struct swsusp_info {
        unsigned long           image_pages;
        unsigned long           pagedir_pages;
        suspend_pagedir_t       * suspend_pagedir;
-       swp_entry_t             pagedir[768];
+       swp_entry_t             pagedir[MAX_PBES];
 } __attribute__((aligned(PAGE_SIZE)));
 
 
index 0dfb2494890794161c4645ba657d546870a7661b..acf79ac1cb6d5f13667916aac50fd81ddd3af04e 100644 (file)
@@ -931,6 +931,10 @@ static int swsusp_alloc(void)
        if (!enough_swap())
                return -ENOSPC;
 
+       if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
+           !!(nr_copy_pages % PBES_PER_PAGE))
+               return -ENOSPC;
+
        if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
                printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
                return -ENOMEM;