aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/swap.c')
-rw-r--r--kernel/power/swap.c60
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
36static struct swsusp_header { 36struct 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
43static 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 {
241struct swap_map_handle { 243struct 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
258static int get_swap_writer(struct swap_map_handle *handle) 256static 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
630static 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
638core_initcall(swsusp_header_init);