Commit dd5d666b authored by Shaohua Li's avatar Shaohua Li Committed by Linus Torvalds

[PATCH] swsusp: add locking to software_resume

It is trying to protect swsusp_resume_device and software_resume() from two
users banging it from userspace at the same time.
Signed-off-by: default avatarShaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarPavel Machek <pavel@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6ed9fcec
...@@ -233,9 +233,12 @@ static int software_resume(void) ...@@ -233,9 +233,12 @@ static int software_resume(void)
{ {
int error; int error;
down(&pm_sem);
if (!swsusp_resume_device) { if (!swsusp_resume_device) {
if (!strlen(resume_file)) if (!strlen(resume_file)) {
up(&pm_sem);
return -ENOENT; return -ENOENT;
}
swsusp_resume_device = name_to_dev_t(resume_file); swsusp_resume_device = name_to_dev_t(resume_file);
pr_debug("swsusp: Resume From Partition %s\n", resume_file); pr_debug("swsusp: Resume From Partition %s\n", resume_file);
} else { } else {
...@@ -248,6 +251,7 @@ static int software_resume(void) ...@@ -248,6 +251,7 @@ static int software_resume(void)
* FIXME: If noresume is specified, we need to find the partition * FIXME: If noresume is specified, we need to find the partition
* and reset it back to normal swap space. * and reset it back to normal swap space.
*/ */
up(&pm_sem);
return 0; return 0;
} }
...@@ -284,6 +288,8 @@ static int software_resume(void) ...@@ -284,6 +288,8 @@ static int software_resume(void)
Cleanup: Cleanup:
unprepare_processes(); unprepare_processes();
Done: Done:
/* For success case, the suspend path will release the lock */
up(&pm_sem);
pr_debug("PM: Resume from disk failed.\n"); pr_debug("PM: Resume from disk failed.\n");
return 0; return 0;
} }
...@@ -390,7 +396,9 @@ static ssize_t resume_store(struct subsystem * subsys, const char * buf, size_t ...@@ -390,7 +396,9 @@ static ssize_t resume_store(struct subsystem * subsys, const char * buf, size_t
if (sscanf(buf, "%u:%u", &maj, &min) == 2) { if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
res = MKDEV(maj,min); res = MKDEV(maj,min);
if (maj == MAJOR(res) && min == MINOR(res)) { if (maj == MAJOR(res) && min == MINOR(res)) {
down(&pm_sem);
swsusp_resume_device = res; swsusp_resume_device = res;
up(&pm_sem);
printk("Attempting manual resume\n"); printk("Attempting manual resume\n");
noresume = 0; noresume = 0;
software_resume(); software_resume();
......
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