summaryrefslogtreecommitdiffstats
path: root/kernel/power/disk.c
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2005-09-03 15:57:04 -0700
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 00:06:17 -0700
commitdd5d666b7995e542b7f81a4bb1c7ad634f4f6c51 (patch)
treede010e4bd66681ec75657746d652eb89f08142b7 /kernel/power/disk.c
parent6ed9fcec85d5ef0e34ea18affe95e4a246714565 (diff)
downloadlinux-dd5d666b7995e542b7f81a4bb1c7ad634f4f6c51.tar.gz
linux-dd5d666b7995e542b7f81a4bb1c7ad634f4f6c51.tar.bz2
linux-dd5d666b7995e542b7f81a4bb1c7ad634f4f6c51.zip
[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: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r--kernel/power/disk.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 664eb0469b6e..88beec6dcd11 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -233,9 +233,12 @@ static int software_resume(void)
{
int error;
+ down(&pm_sem);
if (!swsusp_resume_device) {
- if (!strlen(resume_file))
+ if (!strlen(resume_file)) {
+ up(&pm_sem);
return -ENOENT;
+ }
swsusp_resume_device = name_to_dev_t(resume_file);
pr_debug("swsusp: Resume From Partition %s\n", resume_file);
} else {
@@ -248,6 +251,7 @@ static int software_resume(void)
* FIXME: If noresume is specified, we need to find the partition
* and reset it back to normal swap space.
*/
+ up(&pm_sem);
return 0;
}
@@ -284,6 +288,8 @@ static int software_resume(void)
Cleanup:
unprepare_processes();
Done:
+ /* For success case, the suspend path will release the lock */
+ up(&pm_sem);
pr_debug("PM: Resume from disk failed.\n");
return 0;
}
@@ -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) {
res = MKDEV(maj,min);
if (maj == MAJOR(res) && min == MINOR(res)) {
+ down(&pm_sem);
swsusp_resume_device = res;
+ up(&pm_sem);
printk("Attempting manual resume\n");
noresume = 0;
software_resume();