diff options
Diffstat (limited to 'kernel/power/user.c')
-rw-r--r-- | kernel/power/user.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/kernel/power/user.c b/kernel/power/user.c index 7cf6713b2325..040560d9c312 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -33,25 +33,29 @@ | |||
33 | static struct snapshot_data { | 33 | static struct snapshot_data { |
34 | struct snapshot_handle handle; | 34 | struct snapshot_handle handle; |
35 | int swap; | 35 | int swap; |
36 | struct bitmap_page *bitmap; | ||
37 | int mode; | 36 | int mode; |
38 | char frozen; | 37 | char frozen; |
39 | char ready; | 38 | char ready; |
40 | char platform_suspend; | 39 | char platform_suspend; |
41 | } snapshot_state; | 40 | } snapshot_state; |
42 | 41 | ||
43 | static atomic_t device_available = ATOMIC_INIT(1); | 42 | atomic_t snapshot_device_available = ATOMIC_INIT(1); |
44 | 43 | ||
45 | static int snapshot_open(struct inode *inode, struct file *filp) | 44 | static int snapshot_open(struct inode *inode, struct file *filp) |
46 | { | 45 | { |
47 | struct snapshot_data *data; | 46 | struct snapshot_data *data; |
48 | 47 | ||
49 | if (!atomic_add_unless(&device_available, -1, 0)) | 48 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) |
50 | return -EBUSY; | 49 | return -EBUSY; |
51 | 50 | ||
52 | if ((filp->f_flags & O_ACCMODE) == O_RDWR) | 51 | if ((filp->f_flags & O_ACCMODE) == O_RDWR) { |
52 | atomic_inc(&snapshot_device_available); | ||
53 | return -ENOSYS; | 53 | return -ENOSYS; |
54 | 54 | } | |
55 | if(create_basic_memory_bitmaps()) { | ||
56 | atomic_inc(&snapshot_device_available); | ||
57 | return -ENOMEM; | ||
58 | } | ||
55 | nonseekable_open(inode, filp); | 59 | nonseekable_open(inode, filp); |
56 | data = &snapshot_state; | 60 | data = &snapshot_state; |
57 | filp->private_data = data; | 61 | filp->private_data = data; |
@@ -64,7 +68,6 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
64 | data->swap = -1; | 68 | data->swap = -1; |
65 | data->mode = O_WRONLY; | 69 | data->mode = O_WRONLY; |
66 | } | 70 | } |
67 | data->bitmap = NULL; | ||
68 | data->frozen = 0; | 71 | data->frozen = 0; |
69 | data->ready = 0; | 72 | data->ready = 0; |
70 | data->platform_suspend = 0; | 73 | data->platform_suspend = 0; |
@@ -77,16 +80,15 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
77 | struct snapshot_data *data; | 80 | struct snapshot_data *data; |
78 | 81 | ||
79 | swsusp_free(); | 82 | swsusp_free(); |
83 | free_basic_memory_bitmaps(); | ||
80 | data = filp->private_data; | 84 | data = filp->private_data; |
81 | free_all_swap_pages(data->swap, data->bitmap); | 85 | free_all_swap_pages(data->swap); |
82 | free_bitmap(data->bitmap); | ||
83 | if (data->frozen) { | 86 | if (data->frozen) { |
84 | mutex_lock(&pm_mutex); | 87 | mutex_lock(&pm_mutex); |
85 | thaw_processes(); | 88 | thaw_processes(); |
86 | enable_nonboot_cpus(); | ||
87 | mutex_unlock(&pm_mutex); | 89 | mutex_unlock(&pm_mutex); |
88 | } | 90 | } |
89 | atomic_inc(&device_available); | 91 | atomic_inc(&snapshot_device_available); |
90 | return 0; | 92 | return 0; |
91 | } | 93 | } |
92 | 94 | ||
@@ -294,14 +296,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
294 | error = -ENODEV; | 296 | error = -ENODEV; |
295 | break; | 297 | break; |
296 | } | 298 | } |
297 | if (!data->bitmap) { | 299 | offset = alloc_swapdev_block(data->swap); |
298 | data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0)); | ||
299 | if (!data->bitmap) { | ||
300 | error = -ENOMEM; | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | offset = alloc_swapdev_block(data->swap, data->bitmap); | ||
305 | if (offset) { | 300 | if (offset) { |
306 | offset <<= PAGE_SHIFT; | 301 | offset <<= PAGE_SHIFT; |
307 | error = put_user(offset, (sector_t __user *)arg); | 302 | error = put_user(offset, (sector_t __user *)arg); |
@@ -315,13 +310,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
315 | error = -ENODEV; | 310 | error = -ENODEV; |
316 | break; | 311 | break; |
317 | } | 312 | } |
318 | free_all_swap_pages(data->swap, data->bitmap); | 313 | free_all_swap_pages(data->swap); |
319 | free_bitmap(data->bitmap); | ||
320 | data->bitmap = NULL; | ||
321 | break; | 314 | break; |
322 | 315 | ||
323 | case SNAPSHOT_SET_SWAP_FILE: | 316 | case SNAPSHOT_SET_SWAP_FILE: |
324 | if (!data->bitmap) { | 317 | if (!swsusp_swap_in_use()) { |
325 | /* | 318 | /* |
326 | * User space encodes device types as two-byte values, | 319 | * User space encodes device types as two-byte values, |
327 | * so we need to recode them | 320 | * so we need to recode them |
@@ -420,7 +413,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
420 | break; | 413 | break; |
421 | 414 | ||
422 | case SNAPSHOT_SET_SWAP_AREA: | 415 | case SNAPSHOT_SET_SWAP_AREA: |
423 | if (data->bitmap) { | 416 | if (swsusp_swap_in_use()) { |
424 | error = -EPERM; | 417 | error = -EPERM; |
425 | } else { | 418 | } else { |
426 | struct resume_swap_area swap_area; | 419 | struct resume_swap_area swap_area; |