[PATCH] swsusp: add resume_offset command line parameter
authorRafael J. Wysocki <rjw@sisk.pl>
Thu, 7 Dec 2006 04:34:12 +0000 (20:34 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Thu, 7 Dec 2006 16:39:27 +0000 (08:39 -0800)
Add the kernel command line parameter "resume_offset=" allowing us to specify
the offset, in <PAGE_SIZE> units, from the beginning of the partition pointed
to by the "resume=" parameter at which the swap header is located.

This offset can be determined, for example, by an application using the FIBMAP
ioctl to obtain the swap header's block number for given file.

[akpm@osdl.org: we don't know what type sector_t is]
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
kernel/power/disk.c
kernel/power/power.h
kernel/power/swap.c

index b1fb7866b0b31d65ccea5946aa22e9c2881e0322..d79feeb45459f49ac0856e49d604255cfe768646 100644 (file)
@@ -27,6 +27,7 @@
 static int noresume = 0;
 char resume_file[256] = CONFIG_PM_STD_PARTITION;
 dev_t swsusp_resume_device;
+sector_t swsusp_resume_block;
 
 /**
  *     power_down - Shut machine down for hibernate.
@@ -423,6 +424,19 @@ static int __init resume_setup(char *str)
        return 1;
 }
 
+static int __init resume_offset_setup(char *str)
+{
+       unsigned long long offset;
+
+       if (noresume)
+               return 1;
+
+       if (sscanf(str, "%llu", &offset) == 1)
+               swsusp_resume_block = offset;
+
+       return 1;
+}
+
 static int __init noresume_setup(char *str)
 {
        noresume = 1;
@@ -430,4 +444,5 @@ static int __init noresume_setup(char *str)
 }
 
 __setup("noresume", noresume_setup);
+__setup("resume_offset=", resume_offset_setup);
 __setup("resume=", resume_setup);
index 210ebba26020bce5ec1c4666e14ba732a86faac9..adaf7d4fbdaf468f6b99131572ec5c95904384a3 100644 (file)
@@ -42,6 +42,7 @@ extern const void __nosave_begin, __nosave_end;
 extern unsigned long image_size;
 extern int in_suspend;
 extern dev_t swsusp_resume_device;
+extern sector_t swsusp_resume_block;
 
 extern asmlinkage int swsusp_arch_suspend(void);
 extern asmlinkage int swsusp_arch_resume(void);
index 1b08f46bbb7ea1cabeee5ce6c8914a2dc028cc86..aa5a9bff01f14c4727c2ba97e810cbd109733d36 100644 (file)
@@ -161,13 +161,14 @@ static int mark_swapfiles(sector_t start)
 {
        int error;
 
-       bio_read_page(0, &swsusp_header, NULL);
+       bio_read_page(swsusp_resume_block, &swsusp_header, NULL);
        if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
            !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
                memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
                memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
                swsusp_header.image = start;
-               error = bio_write_page(0, &swsusp_header, NULL);
+               error = bio_write_page(swsusp_resume_block,
+                                       &swsusp_header, NULL);
        } else {
                printk(KERN_ERR "swsusp: Swap header not found!\n");
                error = -ENODEV;
@@ -184,7 +185,7 @@ static int swsusp_swap_check(void) /* This is called before saving image */
 {
        int res;
 
-       res = swap_type_of(swsusp_resume_device, 0);
+       res = swap_type_of(swsusp_resume_device, swsusp_resume_block);
        if (res < 0)
                return res;
 
@@ -610,12 +611,16 @@ int swsusp_check(void)
        if (!IS_ERR(resume_bdev)) {
                set_blocksize(resume_bdev, PAGE_SIZE);
                memset(&swsusp_header, 0, sizeof(swsusp_header));
-               if ((error = bio_read_page(0, &swsusp_header, NULL)))
+               error = bio_read_page(swsusp_resume_block,
+                                       &swsusp_header, NULL);
+               if (error)
                        return error;
+
                if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
                        memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
                        /* Reset swap signature now */
-                       error = bio_write_page(0, &swsusp_header, NULL);
+                       error = bio_write_page(swsusp_resume_block,
+                                               &swsusp_header, NULL);
                } else {
                        return -EINVAL;
                }