diff options
Diffstat (limited to 'kernel/power/swap.c')
-rw-r--r-- | kernel/power/swap.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 3581f8f86acd..e83ed9945a80 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -33,12 +33,14 @@ extern char resume_file[]; | |||
33 | 33 | ||
34 | #define SWSUSP_SIG "S1SUSPEND" | 34 | #define SWSUSP_SIG "S1SUSPEND" |
35 | 35 | ||
36 | static struct swsusp_header { | 36 | struct swsusp_header { |
37 | char reserved[PAGE_SIZE - 20 - sizeof(sector_t)]; | 37 | char reserved[PAGE_SIZE - 20 - sizeof(sector_t)]; |
38 | sector_t image; | 38 | sector_t image; |
39 | char orig_sig[10]; | 39 | char orig_sig[10]; |
40 | char sig[10]; | 40 | char sig[10]; |
41 | } __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header; | 41 | } __attribute__((packed)); |
42 | |||
43 | static struct swsusp_header *swsusp_header; | ||
42 | 44 | ||
43 | /* | 45 | /* |
44 | * General things | 46 | * General things |
@@ -141,14 +143,14 @@ static int mark_swapfiles(sector_t start) | |||
141 | { | 143 | { |
142 | int error; | 144 | int error; |
143 | 145 | ||
144 | bio_read_page(swsusp_resume_block, &swsusp_header, NULL); | 146 | bio_read_page(swsusp_resume_block, swsusp_header, NULL); |
145 | if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) || | 147 | if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || |
146 | !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) { | 148 | !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { |
147 | memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10); | 149 | memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); |
148 | memcpy(swsusp_header.sig,SWSUSP_SIG, 10); | 150 | memcpy(swsusp_header->sig,SWSUSP_SIG, 10); |
149 | swsusp_header.image = start; | 151 | swsusp_header->image = start; |
150 | error = bio_write_page(swsusp_resume_block, | 152 | error = bio_write_page(swsusp_resume_block, |
151 | &swsusp_header, NULL); | 153 | swsusp_header, NULL); |
152 | } else { | 154 | } else { |
153 | printk(KERN_ERR "swsusp: Swap header not found!\n"); | 155 | printk(KERN_ERR "swsusp: Swap header not found!\n"); |
154 | error = -ENODEV; | 156 | error = -ENODEV; |
@@ -241,7 +243,6 @@ struct swap_map_page { | |||
241 | struct swap_map_handle { | 243 | struct swap_map_handle { |
242 | struct swap_map_page *cur; | 244 | struct swap_map_page *cur; |
243 | sector_t cur_swap; | 245 | sector_t cur_swap; |
244 | struct bitmap_page *bitmap; | ||
245 | unsigned int k; | 246 | unsigned int k; |
246 | }; | 247 | }; |
247 | 248 | ||
@@ -250,9 +251,6 @@ static void release_swap_writer(struct swap_map_handle *handle) | |||
250 | if (handle->cur) | 251 | if (handle->cur) |
251 | free_page((unsigned long)handle->cur); | 252 | free_page((unsigned long)handle->cur); |
252 | handle->cur = NULL; | 253 | handle->cur = NULL; |
253 | if (handle->bitmap) | ||
254 | free_bitmap(handle->bitmap); | ||
255 | handle->bitmap = NULL; | ||
256 | } | 254 | } |
257 | 255 | ||
258 | static int get_swap_writer(struct swap_map_handle *handle) | 256 | static int get_swap_writer(struct swap_map_handle *handle) |
@@ -260,12 +258,7 @@ static int get_swap_writer(struct swap_map_handle *handle) | |||
260 | handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); | 258 | handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); |
261 | if (!handle->cur) | 259 | if (!handle->cur) |
262 | return -ENOMEM; | 260 | return -ENOMEM; |
263 | handle->bitmap = alloc_bitmap(count_swap_pages(root_swap, 0)); | 261 | handle->cur_swap = alloc_swapdev_block(root_swap); |
264 | if (!handle->bitmap) { | ||
265 | release_swap_writer(handle); | ||
266 | return -ENOMEM; | ||
267 | } | ||
268 | handle->cur_swap = alloc_swapdev_block(root_swap, handle->bitmap); | ||
269 | if (!handle->cur_swap) { | 262 | if (!handle->cur_swap) { |
270 | release_swap_writer(handle); | 263 | release_swap_writer(handle); |
271 | return -ENOSPC; | 264 | return -ENOSPC; |
@@ -282,7 +275,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, | |||
282 | 275 | ||
283 | if (!handle->cur) | 276 | if (!handle->cur) |
284 | return -EINVAL; | 277 | return -EINVAL; |
285 | offset = alloc_swapdev_block(root_swap, handle->bitmap); | 278 | offset = alloc_swapdev_block(root_swap); |
286 | error = write_page(buf, offset, bio_chain); | 279 | error = write_page(buf, offset, bio_chain); |
287 | if (error) | 280 | if (error) |
288 | return error; | 281 | return error; |
@@ -291,7 +284,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, | |||
291 | error = wait_on_bio_chain(bio_chain); | 284 | error = wait_on_bio_chain(bio_chain); |
292 | if (error) | 285 | if (error) |
293 | goto out; | 286 | goto out; |
294 | offset = alloc_swapdev_block(root_swap, handle->bitmap); | 287 | offset = alloc_swapdev_block(root_swap); |
295 | if (!offset) | 288 | if (!offset) |
296 | return -ENOSPC; | 289 | return -ENOSPC; |
297 | handle->cur->next_swap = offset; | 290 | handle->cur->next_swap = offset; |
@@ -428,7 +421,8 @@ int swsusp_write(void) | |||
428 | } | 421 | } |
429 | } | 422 | } |
430 | if (error) | 423 | if (error) |
431 | free_all_swap_pages(root_swap, handle.bitmap); | 424 | free_all_swap_pages(root_swap); |
425 | |||
432 | release_swap_writer(&handle); | 426 | release_swap_writer(&handle); |
433 | out: | 427 | out: |
434 | swsusp_close(); | 428 | swsusp_close(); |
@@ -564,7 +558,7 @@ int swsusp_read(void) | |||
564 | if (error < PAGE_SIZE) | 558 | if (error < PAGE_SIZE) |
565 | return error < 0 ? error : -EFAULT; | 559 | return error < 0 ? error : -EFAULT; |
566 | header = (struct swsusp_info *)data_of(snapshot); | 560 | header = (struct swsusp_info *)data_of(snapshot); |
567 | error = get_swap_reader(&handle, swsusp_header.image); | 561 | error = get_swap_reader(&handle, swsusp_header->image); |
568 | if (!error) | 562 | if (!error) |
569 | error = swap_read_page(&handle, header, NULL); | 563 | error = swap_read_page(&handle, header, NULL); |
570 | if (!error) | 564 | if (!error) |
@@ -591,17 +585,17 @@ int swsusp_check(void) | |||
591 | resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); | 585 | resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); |
592 | if (!IS_ERR(resume_bdev)) { | 586 | if (!IS_ERR(resume_bdev)) { |
593 | set_blocksize(resume_bdev, PAGE_SIZE); | 587 | set_blocksize(resume_bdev, PAGE_SIZE); |
594 | memset(&swsusp_header, 0, sizeof(swsusp_header)); | 588 | memset(swsusp_header, 0, sizeof(PAGE_SIZE)); |
595 | error = bio_read_page(swsusp_resume_block, | 589 | error = bio_read_page(swsusp_resume_block, |
596 | &swsusp_header, NULL); | 590 | swsusp_header, NULL); |
597 | if (error) | 591 | if (error) |
598 | return error; | 592 | return error; |
599 | 593 | ||
600 | if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) { | 594 | if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { |
601 | memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10); | 595 | memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); |
602 | /* Reset swap signature now */ | 596 | /* Reset swap signature now */ |
603 | error = bio_write_page(swsusp_resume_block, | 597 | error = bio_write_page(swsusp_resume_block, |
604 | &swsusp_header, NULL); | 598 | swsusp_header, NULL); |
605 | } else { | 599 | } else { |
606 | return -EINVAL; | 600 | return -EINVAL; |
607 | } | 601 | } |
@@ -632,3 +626,13 @@ void swsusp_close(void) | |||
632 | 626 | ||
633 | blkdev_put(resume_bdev); | 627 | blkdev_put(resume_bdev); |
634 | } | 628 | } |
629 | |||
630 | static int swsusp_header_init(void) | ||
631 | { | ||
632 | swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL); | ||
633 | if (!swsusp_header) | ||
634 | panic("Could not allocate memory for swsusp_header\n"); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | core_initcall(swsusp_header_init); | ||