Commit 9a154d9d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

[PATCH] swsusp: add resume_offset command line parameter

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: default avatarRafael J. Wysocki <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3aef83e0
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
static int noresume = 0; static int noresume = 0;
char resume_file[256] = CONFIG_PM_STD_PARTITION; char resume_file[256] = CONFIG_PM_STD_PARTITION;
dev_t swsusp_resume_device; dev_t swsusp_resume_device;
sector_t swsusp_resume_block;
/** /**
* power_down - Shut machine down for hibernate. * power_down - Shut machine down for hibernate.
...@@ -423,6 +424,19 @@ static int __init resume_setup(char *str) ...@@ -423,6 +424,19 @@ static int __init resume_setup(char *str)
return 1; 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) static int __init noresume_setup(char *str)
{ {
noresume = 1; noresume = 1;
...@@ -430,4 +444,5 @@ static int __init noresume_setup(char *str) ...@@ -430,4 +444,5 @@ static int __init noresume_setup(char *str)
} }
__setup("noresume", noresume_setup); __setup("noresume", noresume_setup);
__setup("resume_offset=", resume_offset_setup);
__setup("resume=", resume_setup); __setup("resume=", resume_setup);
...@@ -42,6 +42,7 @@ extern const void __nosave_begin, __nosave_end; ...@@ -42,6 +42,7 @@ extern const void __nosave_begin, __nosave_end;
extern unsigned long image_size; extern unsigned long image_size;
extern int in_suspend; extern int in_suspend;
extern dev_t swsusp_resume_device; extern dev_t swsusp_resume_device;
extern sector_t swsusp_resume_block;
extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_suspend(void);
extern asmlinkage int swsusp_arch_resume(void); extern asmlinkage int swsusp_arch_resume(void);
......
...@@ -161,13 +161,14 @@ static int mark_swapfiles(sector_t start) ...@@ -161,13 +161,14 @@ static int mark_swapfiles(sector_t start)
{ {
int error; 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) || if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
!memcmp("SWAPSPACE2",swsusp_header.sig, 10)) { !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10); memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
memcpy(swsusp_header.sig,SWSUSP_SIG, 10); memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
swsusp_header.image = start; swsusp_header.image = start;
error = bio_write_page(0, &swsusp_header, NULL); error = bio_write_page(swsusp_resume_block,
&swsusp_header, NULL);
} else { } else {
printk(KERN_ERR "swsusp: Swap header not found!\n"); printk(KERN_ERR "swsusp: Swap header not found!\n");
error = -ENODEV; error = -ENODEV;
...@@ -184,7 +185,7 @@ static int swsusp_swap_check(void) /* This is called before saving image */ ...@@ -184,7 +185,7 @@ static int swsusp_swap_check(void) /* This is called before saving image */
{ {
int res; int res;
res = swap_type_of(swsusp_resume_device, 0); res = swap_type_of(swsusp_resume_device, swsusp_resume_block);
if (res < 0) if (res < 0)
return res; return res;
...@@ -610,12 +611,16 @@ int swsusp_check(void) ...@@ -610,12 +611,16 @@ int swsusp_check(void)
if (!IS_ERR(resume_bdev)) { if (!IS_ERR(resume_bdev)) {
set_blocksize(resume_bdev, PAGE_SIZE); set_blocksize(resume_bdev, PAGE_SIZE);
memset(&swsusp_header, 0, sizeof(swsusp_header)); 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; return error;
if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) { if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10); memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
/* Reset swap signature now */ /* Reset swap signature now */
error = bio_write_page(0, &swsusp_header, NULL); error = bio_write_page(swsusp_resume_block,
&swsusp_header, NULL);
} else { } else {
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment