| Linux kernel & device driver programming |
| [ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] |
1 /* 1
2 * linux/kernel/power/swap.c
3 *
4 * This file provides functions for reading th
5 * and writing it to a swap partition.
6 *
7 * Copyright (C) 1998,2001-2005 Pavel Machek <
8 * Copyright (C) 2006 Rafael J. Wysocki <rjw@s
9 *
10 * This file is released under the GPLv2.
11 *
12 */
13
14 #include <linux/module.h>
15 #include <linux/file.h>
16 #include <linux/utsname.h>
17 #include <linux/delay.h>
18 #include <linux/bitops.h>
19 #include <linux/genhd.h>
20 #include <linux/device.h>
21 #include <linux/buffer_head.h>
22 #include <linux/bio.h>
23 #include <linux/blkdev.h>
24 #include <linux/swap.h>
25 #include <linux/swapops.h>
26 #include <linux/pm.h>
27
28 #include "power.h"
29
30 #define SWSUSP_SIG "S1SUSPEND"
31
32 struct swsusp_header {
33 char reserved[PAGE_SIZE - 20 - sizeof(
34 sector_t image;
35 unsigned int flags; /* Flags to pa
36 char orig_sig[10];
37 char sig[10];
38 } __attribute__((packed));
39
40 static struct swsusp_header *swsusp_header;
41
42 /*
43 * General things
44 */
45
46 static unsigned short root_swap = 0xffff;
47 static struct block_device *resume_bdev;
48
49 /**
50 * submit - submit BIO request.
51 * @rw: READ or WRITE.
52 * @off physical offset of page.
53 * @page: page we're reading or writing.
54 * @bio_chain: list of pending biod (for
55 *
56 * Straight from the textbook - allocate
57 * If we're reading, make sure the page i
58 * Then submit it and, if @bio_chain == N
59 */
60 static int submit(int rw, pgoff_t page_off, st
61 struct bio **bio_chain
62 {
63 const int bio_rw = rw | (1 << BIO_RW_S
64 struct bio *bio;
65
66 bio = bio_alloc(__GFP_WAIT | __GFP_HIG
67 bio->bi_sector = page_off * (PAGE_SIZE
68 bio->bi_bdev = resume_bdev;
69 bio->bi_end_io = end_swap_bio_read;
70
71 if (bio_add_page(bio, page, PAGE_SIZE,
72 printk(KERN_ERR "PM: Adding pa
73 page_off);
74 bio_put(bio);
75 return -EFAULT;
76 }
77
78 lock_page(page);
79 bio_get(bio);
80
81 if (bio_chain == NULL) {
82 submit_bio(bio_rw, bio);
83 wait_on_page_locked(page);
84 if (rw == READ)
85 bio_set_pages_dirty(bi
86 bio_put(bio);
87 } else {
88 if (rw == READ)
89 get_page(page); /* The
90 bio->bi_private = *bio_chain;
91 *bio_chain = bio;
92 submit_bio(bio_rw, bio);
93 }
94 return 0;
95 }
96
97 static int bio_read_page(pgoff_t page_off, voi
98 {
99 return submit(READ, page_off, virt_to_
100 }
101
102 static int bio_write_page(pgoff_t page_off, vo
103 {
104 return submit(WRITE, page_off, virt_to
105 }
106
107 static int wait_on_bio_chain(struct bio **bio_
108 {
109 struct bio *bio;
110 struct bio *next_bio;
111 int ret = 0;
112
113 if (bio_chain == NULL)
114 return 0;
115
116 bio = *bio_chain;
117 if (bio == NULL)
118 return 0;
119 while (bio) {
120 struct page *page;
121
122 next_bio = bio->bi_private;
123 page = bio->bi_io_vec[0].bv_pa
124 wait_on_page_locked(page);
125 if (!PageUptodate(page) || Pag
126 ret = -EIO;
127 put_page(page);
128 bio_put(bio);
129 bio = next_bio;
130 }
131 *bio_chain = NULL;
132 return ret;
133 }
134
135 /*
136 * Saving part
137 */
138
139 static int mark_swapfiles(sector_t start, unsi
140 {
141 int error;
142
143 bio_read_page(swsusp_resume_block, sws
144 if (!memcmp("SWAP-SPACE",swsusp_header
145 !memcmp("SWAPSPACE2",swsusp_header
146 memcpy(swsusp_header->orig_sig
147 memcpy(swsusp_header->sig,SWSU
148 swsusp_header->image = start;
149 swsusp_header->flags = flags;
150 error = bio_write_page(swsusp_
151 swsusp
152 } else {
153 printk(KERN_ERR "PM: Swap head
154 error = -ENODEV;
155 }
156 return error;
157 }
158
159 /**
160 * swsusp_swap_check - check if the resum
161 * and get its index (if so)
162 */
163
164 static int swsusp_swap_check(void) /* This is
165 {
166 int res;
167
168 res = swap_type_of(swsusp_resume_devic
169 &resume_bdev);
170 if (res < 0)
171 return res;
172
173 root_swap = res;
174 res = blkdev_get(resume_bdev, FMODE_WR
175 if (res)
176 return res;
177
178 res = set_blocksize(resume_bdev, PAGE_
179 if (res < 0)
180 blkdev_put(resume_bdev, FMODE_
181
182 return res;
183 }
184
185 /**
186 * write_page - Write one page to given s
187 * @buf: Address we're writing.
188 * @offset: Offset of the swap pag
189 * @bio_chain: Link the next write BI
190 */
191
192 static int write_page(void *buf, sector_t offs
193 {
194 void *src;
195
196 if (!offset)
197 return -ENOSPC;
198
199 if (bio_chain) {
200 src = (void *)__get_free_page(
201 if (src) {
202 memcpy(src, buf, PAGE_
203 } else {
204 WARN_ON_ONCE(1);
205 bio_chain = NULL;
206 src = buf;
207 }
208 } else {
209 src = buf;
210 }
211 return bio_write_page(offset, src, bio
212 }
213
214 /*
215 * The swap map is a data structure used
216 * written to a swap partition. It consi
217 * structures that contain each an array
218 * These structures are stored on the swa
219 * help of the .next_swap member.
220 *
221 * The swap map is created during suspend
222 * allocated and populated one at a time,
223 * page to set up the entire structure.
224 *
225 * During resume we also only need to use
226 * at a time.
227 */
228
229 #define MAP_PAGE_ENTRIES (PAGE_SIZE / s
230
231 struct swap_map_page {
232 sector_t entries[MAP_PAGE_ENTRIES];
233 sector_t next_swap;
234 };
235
236 /**
237 * The swap_map_handle structure is used
238 * a file-alike way
239 */
240
241 struct swap_map_handle {
242 struct swap_map_page *cur;
243 sector_t cur_swap;
244 unsigned int k;
245 };
246
247 static void release_swap_writer(struct swap_ma
248 {
249 if (handle->cur)
250 free_page((unsigned long)handl
251 handle->cur = NULL;
252 }
253
254 static int get_swap_writer(struct swap_map_han
255 {
256 handle->cur = (struct swap_map_page *)
257 if (!handle->cur)
258 return -ENOMEM;
259 handle->cur_swap = alloc_swapdev_block
260 if (!handle->cur_swap) {
261 release_swap_writer(handle);
262 return -ENOSPC;
263 }
264 handle->k = 0;
265 return 0;
266 }
267
268 static int swap_write_page(struct swap_map_han
269 struct bio **b
270 {
271 int error = 0;
272 sector_t offset;
273
274 if (!handle->cur)
275 return -EINVAL;
276 offset = alloc_swapdev_block(root_swap
277 error = write_page(buf, offset, bio_ch
278 if (error)
279 return error;
280 handle->cur->entries[handle->k++] = of
281 if (handle->k >= MAP_PAGE_ENTRIES) {
282 error = wait_on_bio_chain(bio_
283 if (error)
284 goto out;
285 offset = alloc_swapdev_block(r
286 if (!offset)
287 return -ENOSPC;
288 handle->cur->next_swap = offse
289 error = write_page(handle->cur
290 if (error)
291 goto out;
292 memset(handle->cur, 0, PAGE_SI
293 handle->cur_swap = offset;
294 handle->k = 0;
295 }
296 out:
297 return error;
298 }
299
300 static int flush_swap_writer(struct swap_map_h
301 {
302 if (handle->cur && handle->cur_swap)
303 return write_page(handle->cur,
304 else
305 return -EINVAL;
306 }
307
308 /**
309 * save_image - save the suspend image da
310 */
311
312 static int save_image(struct swap_map_handle *
313 struct snapshot_handle *
314 unsigned int nr_to_write
315 {
316 unsigned int m;
317 int ret;
318 int error = 0;
319 int nr_pages;
320 int err2;
321 struct bio *bio;
322 struct timeval start;
323 struct timeval stop;
324
325 printk(KERN_INFO "PM: Saving image dat
326 nr_to_write);
327 m = nr_to_write / 100;
328 if (!m)
329 m = 1;
330 nr_pages = 0;
331 bio = NULL;
332 do_gettimeofday(&start);
333 do {
334 ret = snapshot_read_next(snaps
335 if (ret > 0) {
336 error = swap_write_pag
337
338 if (error)
339 break;
340 if (!(nr_pages % m))
341 printk("\b\b\b
342 nr_pages++;
343 }
344 } while (ret > 0);
345 err2 = wait_on_bio_chain(&bio);
346 do_gettimeofday(&stop);
347 if (!error)
348 error = err2;
349 if (!error)
350 printk("\b\b\b\bdone\n");
351 swsusp_show_speed(&start, &stop, nr_to
352 return error;
353 }
354
355 /**
356 * enough_swap - Make sure we have enough
357 *
358 * Returns TRUE or FALSE after checking t
359 * space avaiable from the resume partiti
360 */
361
362 static int enough_swap(unsigned int nr_pages)
363 {
364 unsigned int free_swap = count_swap_pa
365
366 pr_debug("PM: Free swap pages: %u\n",
367 return free_swap > nr_pages + PAGES_FO
368 }
369
370 /**
371 * swsusp_write - Write entire image and
372 * @flags: flags to pass to the "boot" ke
373 *
374 * It is important _NOT_ to umount filesy
375 * them synced (in case something goes wr
376 * filesystem clean: it is not. (And it d
377 * correctly, we'll mark system clean, an
378 */
379
380 int swsusp_write(unsigned int flags)
381 {
382 struct swap_map_handle handle;
383 struct snapshot_handle snapshot;
384 struct swsusp_info *header;
385 int error;
386
387 error = swsusp_swap_check();
388 if (error) {
389 printk(KERN_ERR "PM: Cannot fi
390 "swapon -a.\n"
391 return error;
392 }
393 memset(&snapshot, 0, sizeof(struct sna
394 error = snapshot_read_next(&snapshot,
395 if (error < PAGE_SIZE) {
396 if (error >= 0)
397 error = -EFAULT;
398
399 goto out;
400 }
401 header = (struct swsusp_info *)data_of
402 if (!enough_swap(header->pages)) {
403 printk(KERN_ERR "PM: Not enoug
404 error = -ENOSPC;
405 goto out;
406 }
407 error = get_swap_writer(&handle);
408 if (!error) {
409 sector_t start = handle.cur_sw
410
411 error = swap_write_page(&handl
412 if (!error)
413 error = save_image(&ha
414 header
415
416 if (!error) {
417 flush_swap_writer(&han
418 printk(KERN_INFO "PM:
419 error = mark_swapfiles
420 printk("|\n");
421 }
422 }
423 if (error)
424 free_all_swap_pages(root_swap)
425
426 release_swap_writer(&handle);
427 out:
428 swsusp_close(FMODE_WRITE);
429 return error;
430 }
431
432 /**
433 * The following functions allow us to re
434 * in a file-alike way
435 */
436
437 static void release_swap_reader(struct swap_ma
438 {
439 if (handle->cur)
440 free_page((unsigned long)handl
441 handle->cur = NULL;
442 }
443
444 static int get_swap_reader(struct swap_map_han
445 {
446 int error;
447
448 if (!start)
449 return -EINVAL;
450
451 handle->cur = (struct swap_map_page *)
452 if (!handle->cur)
453 return -ENOMEM;
454
455 error = bio_read_page(start, handle->c
456 if (error) {
457 release_swap_reader(handle);
458 return error;
459 }
460 handle->k = 0;
461 return 0;
462 }
463
464 static int swap_read_page(struct swap_map_hand
465 struct bio **b
466 {
467 sector_t offset;
468 int error;
469
470 if (!handle->cur)
471 return -EINVAL;
472 offset = handle->cur->entries[handle->
473 if (!offset)
474 return -EFAULT;
475 error = bio_read_page(offset, buf, bio
476 if (error)
477 return error;
478 if (++handle->k >= MAP_PAGE_ENTRIES) {
479 error = wait_on_bio_chain(bio_
480 handle->k = 0;
481 offset = handle->cur->next_swa
482 if (!offset)
483 release_swap_reader(ha
484 else if (!error)
485 error = bio_read_page(
486 }
487 return error;
488 }
489
490 /**
491 * load_image - load the image using the
492 * @handle and the snapshot handle @snaps
493 * (assume there are @nr_pages pages to l
494 */
495
496 static int load_image(struct swap_map_handle *
497 struct snapshot_handle *
498 unsigned int nr_to_read)
499 {
500 unsigned int m;
501 int error = 0;
502 struct timeval start;
503 struct timeval stop;
504 struct bio *bio;
505 int err2;
506 unsigned nr_pages;
507
508 printk(KERN_INFO "PM: Loading image da
509 nr_to_read);
510 m = nr_to_read / 100;
511 if (!m)
512 m = 1;
513 nr_pages = 0;
514 bio = NULL;
515 do_gettimeofday(&start);
516 for ( ; ; ) {
517 error = snapshot_write_next(sn
518 if (error <= 0)
519 break;
520 error = swap_read_page(handle,
521 if (error)
522 break;
523 if (snapshot->sync_read)
524 error = wait_on_bio_ch
525 if (error)
526 break;
527 if (!(nr_pages % m))
528 printk("\b\b\b\b%3d%%"
529 nr_pages++;
530 }
531 err2 = wait_on_bio_chain(&bio);
532 do_gettimeofday(&stop);
533 if (!error)
534 error = err2;
535 if (!error) {
536 printk("\b\b\b\bdone\n");
537 snapshot_write_finalize(snapsh
538 if (!snapshot_image_loaded(sna
539 error = -ENODATA;
540 }
541 swsusp_show_speed(&start, &stop, nr_to
542 return error;
543 }
544
545 /**
546 * swsusp_read - read the hibernation ima
547 * @flags_p: flags passed by the "frozen"
548 * be written into this memeory
549 */
550
551 int swsusp_read(unsigned int *flags_p)
552 {
553 int error;
554 struct swap_map_handle handle;
555 struct snapshot_handle snapshot;
556 struct swsusp_info *header;
557
558 *flags_p = swsusp_header->flags;
559 if (IS_ERR(resume_bdev)) {
560 pr_debug("PM: Image device not
561 return PTR_ERR(resume_bdev);
562 }
563
564 memset(&snapshot, 0, sizeof(struct sna
565 error = snapshot_write_next(&snapshot,
566 if (error < PAGE_SIZE)
567 return error < 0 ? error : -EF
568 header = (struct swsusp_info *)data_of
569 error = get_swap_reader(&handle, swsus
570 if (!error)
571 error = swap_read_page(&handle
572 if (!error)
573 error = load_image(&handle, &s
574 release_swap_reader(&handle);
575
576 blkdev_put(resume_bdev, FMODE_READ);
577
578 if (!error)
579 pr_debug("PM: Image successful
580 else
581 pr_debug("PM: Error %d resumin
582 return error;
583 }
584
585 /**
586 * swsusp_check - Check for swsusp signat
587 */
588
589 int swsusp_check(void)
590 {
591 int error;
592
593 resume_bdev = open_by_devnum(swsusp_re
594 if (!IS_ERR(resume_bdev)) {
595 set_blocksize(resume_bdev, PAG
596 memset(swsusp_header, 0, PAGE_
597 error = bio_read_page(swsusp_r
598 swsusp
599 if (error)
600 return error;
601
602 if (!memcmp(SWSUSP_SIG, swsusp
603 memcpy(swsusp_header->
604 /* Reset swap signatur
605 error = bio_write_page
606
607 } else {
608 return -EINVAL;
609 }
610 if (error)
611 blkdev_put(resume_bdev
612 else
613 pr_debug("PM: Signatur
614 } else {
615 error = PTR_ERR(resume_bdev);
616 }
617
618 if (error)
619 pr_debug("PM: Error %d checkin
620
621 return error;
622 }
623
624 /**
625 * swsusp_close - close swap device.
626 */
627
628 void swsusp_close(fmode_t mode)
629 {
630 if (IS_ERR(resume_bdev)) {
631 pr_debug("PM: Image device not
632 return;
633 }
634
635 blkdev_put(resume_bdev, mode);
636 }
637
638 static int swsusp_header_init(void)
639 {
640 swsusp_header = (struct swsusp_header*
641 if (!swsusp_header)
642 panic("Could not allocate memo
643 return 0;
644 }
645
646 core_initcall(swsusp_header_init);
647
| This page was automatically generated by the LXR engine. |