diff options
Diffstat (limited to 'kernel/power/swap.c')
-rw-r--r-- | kernel/power/swap.c | 333 |
1 files changed, 139 insertions, 194 deletions
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 66824d71983a..b0bb21778391 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -29,6 +29,40 @@ | |||
29 | 29 | ||
30 | #define SWSUSP_SIG "S1SUSPEND" | 30 | #define SWSUSP_SIG "S1SUSPEND" |
31 | 31 | ||
32 | /* | ||
33 | * The swap map is a data structure used for keeping track of each page | ||
34 | * written to a swap partition. It consists of many swap_map_page | ||
35 | * structures that contain each an array of MAP_PAGE_SIZE swap entries. | ||
36 | * These structures are stored on the swap and linked together with the | ||
37 | * help of the .next_swap member. | ||
38 | * | ||
39 | * The swap map is created during suspend. The swap map pages are | ||
40 | * allocated and populated one at a time, so we only need one memory | ||
41 | * page to set up the entire structure. | ||
42 | * | ||
43 | * During resume we also only need to use one swap_map_page structure | ||
44 | * at a time. | ||
45 | */ | ||
46 | |||
47 | #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) | ||
48 | |||
49 | struct swap_map_page { | ||
50 | sector_t entries[MAP_PAGE_ENTRIES]; | ||
51 | sector_t next_swap; | ||
52 | }; | ||
53 | |||
54 | /** | ||
55 | * The swap_map_handle structure is used for handling swap in | ||
56 | * a file-alike way | ||
57 | */ | ||
58 | |||
59 | struct swap_map_handle { | ||
60 | struct swap_map_page *cur; | ||
61 | sector_t cur_swap; | ||
62 | sector_t first_sector; | ||
63 | unsigned int k; | ||
64 | }; | ||
65 | |||
32 | struct swsusp_header { | 66 | struct swsusp_header { |
33 | char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int)]; | 67 | char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int)]; |
34 | sector_t image; | 68 | sector_t image; |
@@ -145,110 +179,24 @@ int swsusp_swap_in_use(void) | |||
145 | */ | 179 | */ |
146 | 180 | ||
147 | static unsigned short root_swap = 0xffff; | 181 | static unsigned short root_swap = 0xffff; |
148 | static struct block_device *resume_bdev; | 182 | struct block_device *hib_resume_bdev; |
149 | |||
150 | /** | ||
151 | * submit - submit BIO request. | ||
152 | * @rw: READ or WRITE. | ||
153 | * @off physical offset of page. | ||
154 | * @page: page we're reading or writing. | ||
155 | * @bio_chain: list of pending biod (for async reading) | ||
156 | * | ||
157 | * Straight from the textbook - allocate and initialize the bio. | ||
158 | * If we're reading, make sure the page is marked as dirty. | ||
159 | * Then submit it and, if @bio_chain == NULL, wait. | ||
160 | */ | ||
161 | static int submit(int rw, pgoff_t page_off, struct page *page, | ||
162 | struct bio **bio_chain) | ||
163 | { | ||
164 | const int bio_rw = rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); | ||
165 | struct bio *bio; | ||
166 | |||
167 | bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); | ||
168 | bio->bi_sector = page_off * (PAGE_SIZE >> 9); | ||
169 | bio->bi_bdev = resume_bdev; | ||
170 | bio->bi_end_io = end_swap_bio_read; | ||
171 | |||
172 | if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { | ||
173 | printk(KERN_ERR "PM: Adding page to bio failed at %ld\n", | ||
174 | page_off); | ||
175 | bio_put(bio); | ||
176 | return -EFAULT; | ||
177 | } | ||
178 | |||
179 | lock_page(page); | ||
180 | bio_get(bio); | ||
181 | |||
182 | if (bio_chain == NULL) { | ||
183 | submit_bio(bio_rw, bio); | ||
184 | wait_on_page_locked(page); | ||
185 | if (rw == READ) | ||
186 | bio_set_pages_dirty(bio); | ||
187 | bio_put(bio); | ||
188 | } else { | ||
189 | if (rw == READ) | ||
190 | get_page(page); /* These pages are freed later */ | ||
191 | bio->bi_private = *bio_chain; | ||
192 | *bio_chain = bio; | ||
193 | submit_bio(bio_rw, bio); | ||
194 | } | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain) | ||
199 | { | ||
200 | return submit(READ, page_off, virt_to_page(addr), bio_chain); | ||
201 | } | ||
202 | |||
203 | static int bio_write_page(pgoff_t page_off, void *addr, struct bio **bio_chain) | ||
204 | { | ||
205 | return submit(WRITE, page_off, virt_to_page(addr), bio_chain); | ||
206 | } | ||
207 | |||
208 | static int wait_on_bio_chain(struct bio **bio_chain) | ||
209 | { | ||
210 | struct bio *bio; | ||
211 | struct bio *next_bio; | ||
212 | int ret = 0; | ||
213 | |||
214 | if (bio_chain == NULL) | ||
215 | return 0; | ||
216 | |||
217 | bio = *bio_chain; | ||
218 | if (bio == NULL) | ||
219 | return 0; | ||
220 | while (bio) { | ||
221 | struct page *page; | ||
222 | |||
223 | next_bio = bio->bi_private; | ||
224 | page = bio->bi_io_vec[0].bv_page; | ||
225 | wait_on_page_locked(page); | ||
226 | if (!PageUptodate(page) || PageError(page)) | ||
227 | ret = -EIO; | ||
228 | put_page(page); | ||
229 | bio_put(bio); | ||
230 | bio = next_bio; | ||
231 | } | ||
232 | *bio_chain = NULL; | ||
233 | return ret; | ||
234 | } | ||
235 | 183 | ||
236 | /* | 184 | /* |
237 | * Saving part | 185 | * Saving part |
238 | */ | 186 | */ |
239 | 187 | ||
240 | static int mark_swapfiles(sector_t start, unsigned int flags) | 188 | static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags) |
241 | { | 189 | { |
242 | int error; | 190 | int error; |
243 | 191 | ||
244 | bio_read_page(swsusp_resume_block, swsusp_header, NULL); | 192 | hib_bio_read_page(swsusp_resume_block, swsusp_header, NULL); |
245 | if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || | 193 | if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || |
246 | !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { | 194 | !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { |
247 | memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); | 195 | memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); |
248 | memcpy(swsusp_header->sig,SWSUSP_SIG, 10); | 196 | memcpy(swsusp_header->sig,SWSUSP_SIG, 10); |
249 | swsusp_header->image = start; | 197 | swsusp_header->image = handle->first_sector; |
250 | swsusp_header->flags = flags; | 198 | swsusp_header->flags = flags; |
251 | error = bio_write_page(swsusp_resume_block, | 199 | error = hib_bio_write_page(swsusp_resume_block, |
252 | swsusp_header, NULL); | 200 | swsusp_header, NULL); |
253 | } else { | 201 | } else { |
254 | printk(KERN_ERR "PM: Swap header not found!\n"); | 202 | printk(KERN_ERR "PM: Swap header not found!\n"); |
@@ -260,25 +208,26 @@ static int mark_swapfiles(sector_t start, unsigned int flags) | |||
260 | /** | 208 | /** |
261 | * swsusp_swap_check - check if the resume device is a swap device | 209 | * swsusp_swap_check - check if the resume device is a swap device |
262 | * and get its index (if so) | 210 | * and get its index (if so) |
211 | * | ||
212 | * This is called before saving image | ||
263 | */ | 213 | */ |
264 | 214 | static int swsusp_swap_check(void) | |
265 | static int swsusp_swap_check(void) /* This is called before saving image */ | ||
266 | { | 215 | { |
267 | int res; | 216 | int res; |
268 | 217 | ||
269 | res = swap_type_of(swsusp_resume_device, swsusp_resume_block, | 218 | res = swap_type_of(swsusp_resume_device, swsusp_resume_block, |
270 | &resume_bdev); | 219 | &hib_resume_bdev); |
271 | if (res < 0) | 220 | if (res < 0) |
272 | return res; | 221 | return res; |
273 | 222 | ||
274 | root_swap = res; | 223 | root_swap = res; |
275 | res = blkdev_get(resume_bdev, FMODE_WRITE); | 224 | res = blkdev_get(hib_resume_bdev, FMODE_WRITE); |
276 | if (res) | 225 | if (res) |
277 | return res; | 226 | return res; |
278 | 227 | ||
279 | res = set_blocksize(resume_bdev, PAGE_SIZE); | 228 | res = set_blocksize(hib_resume_bdev, PAGE_SIZE); |
280 | if (res < 0) | 229 | if (res < 0) |
281 | blkdev_put(resume_bdev, FMODE_WRITE); | 230 | blkdev_put(hib_resume_bdev, FMODE_WRITE); |
282 | 231 | ||
283 | return res; | 232 | return res; |
284 | } | 233 | } |
@@ -309,42 +258,9 @@ static int write_page(void *buf, sector_t offset, struct bio **bio_chain) | |||
309 | } else { | 258 | } else { |
310 | src = buf; | 259 | src = buf; |
311 | } | 260 | } |
312 | return bio_write_page(offset, src, bio_chain); | 261 | return hib_bio_write_page(offset, src, bio_chain); |
313 | } | 262 | } |
314 | 263 | ||
315 | /* | ||
316 | * The swap map is a data structure used for keeping track of each page | ||
317 | * written to a swap partition. It consists of many swap_map_page | ||
318 | * structures that contain each an array of MAP_PAGE_SIZE swap entries. | ||
319 | * These structures are stored on the swap and linked together with the | ||
320 | * help of the .next_swap member. | ||
321 | * | ||
322 | * The swap map is created during suspend. The swap map pages are | ||
323 | * allocated and populated one at a time, so we only need one memory | ||
324 | * page to set up the entire structure. | ||
325 | * | ||
326 | * During resume we also only need to use one swap_map_page structure | ||
327 | * at a time. | ||
328 | */ | ||
329 | |||
330 | #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) | ||
331 | |||
332 | struct swap_map_page { | ||
333 | sector_t entries[MAP_PAGE_ENTRIES]; | ||
334 | sector_t next_swap; | ||
335 | }; | ||
336 | |||
337 | /** | ||
338 | * The swap_map_handle structure is used for handling swap in | ||
339 | * a file-alike way | ||
340 | */ | ||
341 | |||
342 | struct swap_map_handle { | ||
343 | struct swap_map_page *cur; | ||
344 | sector_t cur_swap; | ||
345 | unsigned int k; | ||
346 | }; | ||
347 | |||
348 | static void release_swap_writer(struct swap_map_handle *handle) | 264 | static void release_swap_writer(struct swap_map_handle *handle) |
349 | { | 265 | { |
350 | if (handle->cur) | 266 | if (handle->cur) |
@@ -354,16 +270,33 @@ static void release_swap_writer(struct swap_map_handle *handle) | |||
354 | 270 | ||
355 | static int get_swap_writer(struct swap_map_handle *handle) | 271 | static int get_swap_writer(struct swap_map_handle *handle) |
356 | { | 272 | { |
273 | int ret; | ||
274 | |||
275 | ret = swsusp_swap_check(); | ||
276 | if (ret) { | ||
277 | if (ret != -ENOSPC) | ||
278 | printk(KERN_ERR "PM: Cannot find swap device, try " | ||
279 | "swapon -a.\n"); | ||
280 | return ret; | ||
281 | } | ||
357 | handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); | 282 | handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); |
358 | if (!handle->cur) | 283 | if (!handle->cur) { |
359 | return -ENOMEM; | 284 | ret = -ENOMEM; |
285 | goto err_close; | ||
286 | } | ||
360 | handle->cur_swap = alloc_swapdev_block(root_swap); | 287 | handle->cur_swap = alloc_swapdev_block(root_swap); |
361 | if (!handle->cur_swap) { | 288 | if (!handle->cur_swap) { |
362 | release_swap_writer(handle); | 289 | ret = -ENOSPC; |
363 | return -ENOSPC; | 290 | goto err_rel; |
364 | } | 291 | } |
365 | handle->k = 0; | 292 | handle->k = 0; |
293 | handle->first_sector = handle->cur_swap; | ||
366 | return 0; | 294 | return 0; |
295 | err_rel: | ||
296 | release_swap_writer(handle); | ||
297 | err_close: | ||
298 | swsusp_close(FMODE_WRITE); | ||
299 | return ret; | ||
367 | } | 300 | } |
368 | 301 | ||
369 | static int swap_write_page(struct swap_map_handle *handle, void *buf, | 302 | static int swap_write_page(struct swap_map_handle *handle, void *buf, |
@@ -380,7 +313,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, | |||
380 | return error; | 313 | return error; |
381 | handle->cur->entries[handle->k++] = offset; | 314 | handle->cur->entries[handle->k++] = offset; |
382 | if (handle->k >= MAP_PAGE_ENTRIES) { | 315 | if (handle->k >= MAP_PAGE_ENTRIES) { |
383 | error = wait_on_bio_chain(bio_chain); | 316 | error = hib_wait_on_bio_chain(bio_chain); |
384 | if (error) | 317 | if (error) |
385 | goto out; | 318 | goto out; |
386 | offset = alloc_swapdev_block(root_swap); | 319 | offset = alloc_swapdev_block(root_swap); |
@@ -406,6 +339,24 @@ static int flush_swap_writer(struct swap_map_handle *handle) | |||
406 | return -EINVAL; | 339 | return -EINVAL; |
407 | } | 340 | } |
408 | 341 | ||
342 | static int swap_writer_finish(struct swap_map_handle *handle, | ||
343 | unsigned int flags, int error) | ||
344 | { | ||
345 | if (!error) { | ||
346 | flush_swap_writer(handle); | ||
347 | printk(KERN_INFO "PM: S"); | ||
348 | error = mark_swapfiles(handle, flags); | ||
349 | printk("|\n"); | ||
350 | } | ||
351 | |||
352 | if (error) | ||
353 | free_all_swap_pages(root_swap); | ||
354 | release_swap_writer(handle); | ||
355 | swsusp_close(FMODE_WRITE); | ||
356 | |||
357 | return error; | ||
358 | } | ||
359 | |||
409 | /** | 360 | /** |
410 | * save_image - save the suspend image data | 361 | * save_image - save the suspend image data |
411 | */ | 362 | */ |
@@ -431,7 +382,7 @@ static int save_image(struct swap_map_handle *handle, | |||
431 | bio = NULL; | 382 | bio = NULL; |
432 | do_gettimeofday(&start); | 383 | do_gettimeofday(&start); |
433 | while (1) { | 384 | while (1) { |
434 | ret = snapshot_read_next(snapshot, PAGE_SIZE); | 385 | ret = snapshot_read_next(snapshot); |
435 | if (ret <= 0) | 386 | if (ret <= 0) |
436 | break; | 387 | break; |
437 | ret = swap_write_page(handle, data_of(*snapshot), &bio); | 388 | ret = swap_write_page(handle, data_of(*snapshot), &bio); |
@@ -441,7 +392,7 @@ static int save_image(struct swap_map_handle *handle, | |||
441 | printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m); | 392 | printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m); |
442 | nr_pages++; | 393 | nr_pages++; |
443 | } | 394 | } |
444 | err2 = wait_on_bio_chain(&bio); | 395 | err2 = hib_wait_on_bio_chain(&bio); |
445 | do_gettimeofday(&stop); | 396 | do_gettimeofday(&stop); |
446 | if (!ret) | 397 | if (!ret) |
447 | ret = err2; | 398 | ret = err2; |
@@ -483,50 +434,34 @@ int swsusp_write(unsigned int flags) | |||
483 | struct swap_map_handle handle; | 434 | struct swap_map_handle handle; |
484 | struct snapshot_handle snapshot; | 435 | struct snapshot_handle snapshot; |
485 | struct swsusp_info *header; | 436 | struct swsusp_info *header; |
437 | unsigned long pages; | ||
486 | int error; | 438 | int error; |
487 | 439 | ||
488 | error = swsusp_swap_check(); | 440 | pages = snapshot_get_image_size(); |
441 | error = get_swap_writer(&handle); | ||
489 | if (error) { | 442 | if (error) { |
490 | printk(KERN_ERR "PM: Cannot find swap device, try " | 443 | printk(KERN_ERR "PM: Cannot get swap writer\n"); |
491 | "swapon -a.\n"); | ||
492 | return error; | 444 | return error; |
493 | } | 445 | } |
446 | if (!enough_swap(pages)) { | ||
447 | printk(KERN_ERR "PM: Not enough free swap\n"); | ||
448 | error = -ENOSPC; | ||
449 | goto out_finish; | ||
450 | } | ||
494 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); | 451 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); |
495 | error = snapshot_read_next(&snapshot, PAGE_SIZE); | 452 | error = snapshot_read_next(&snapshot); |
496 | if (error < PAGE_SIZE) { | 453 | if (error < PAGE_SIZE) { |
497 | if (error >= 0) | 454 | if (error >= 0) |
498 | error = -EFAULT; | 455 | error = -EFAULT; |
499 | 456 | ||
500 | goto out; | 457 | goto out_finish; |
501 | } | 458 | } |
502 | header = (struct swsusp_info *)data_of(snapshot); | 459 | header = (struct swsusp_info *)data_of(snapshot); |
503 | if (!enough_swap(header->pages)) { | 460 | error = swap_write_page(&handle, header, NULL); |
504 | printk(KERN_ERR "PM: Not enough free swap\n"); | 461 | if (!error) |
505 | error = -ENOSPC; | 462 | error = save_image(&handle, &snapshot, pages - 1); |
506 | goto out; | 463 | out_finish: |
507 | } | 464 | error = swap_writer_finish(&handle, flags, error); |
508 | error = get_swap_writer(&handle); | ||
509 | if (!error) { | ||
510 | sector_t start = handle.cur_swap; | ||
511 | |||
512 | error = swap_write_page(&handle, header, NULL); | ||
513 | if (!error) | ||
514 | error = save_image(&handle, &snapshot, | ||
515 | header->pages - 1); | ||
516 | |||
517 | if (!error) { | ||
518 | flush_swap_writer(&handle); | ||
519 | printk(KERN_INFO "PM: S"); | ||
520 | error = mark_swapfiles(start, flags); | ||
521 | printk("|\n"); | ||
522 | } | ||
523 | } | ||
524 | if (error) | ||
525 | free_all_swap_pages(root_swap); | ||
526 | |||
527 | release_swap_writer(&handle); | ||
528 | out: | ||
529 | swsusp_close(FMODE_WRITE); | ||
530 | return error; | 465 | return error; |
531 | } | 466 | } |
532 | 467 | ||
@@ -542,18 +477,21 @@ static void release_swap_reader(struct swap_map_handle *handle) | |||
542 | handle->cur = NULL; | 477 | handle->cur = NULL; |
543 | } | 478 | } |
544 | 479 | ||
545 | static int get_swap_reader(struct swap_map_handle *handle, sector_t start) | 480 | static int get_swap_reader(struct swap_map_handle *handle, |
481 | unsigned int *flags_p) | ||
546 | { | 482 | { |
547 | int error; | 483 | int error; |
548 | 484 | ||
549 | if (!start) | 485 | *flags_p = swsusp_header->flags; |
486 | |||
487 | if (!swsusp_header->image) /* how can this happen? */ | ||
550 | return -EINVAL; | 488 | return -EINVAL; |
551 | 489 | ||
552 | handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH); | 490 | handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH); |
553 | if (!handle->cur) | 491 | if (!handle->cur) |
554 | return -ENOMEM; | 492 | return -ENOMEM; |
555 | 493 | ||
556 | error = bio_read_page(start, handle->cur, NULL); | 494 | error = hib_bio_read_page(swsusp_header->image, handle->cur, NULL); |
557 | if (error) { | 495 | if (error) { |
558 | release_swap_reader(handle); | 496 | release_swap_reader(handle); |
559 | return error; | 497 | return error; |
@@ -573,21 +511,28 @@ static int swap_read_page(struct swap_map_handle *handle, void *buf, | |||
573 | offset = handle->cur->entries[handle->k]; | 511 | offset = handle->cur->entries[handle->k]; |
574 | if (!offset) | 512 | if (!offset) |
575 | return -EFAULT; | 513 | return -EFAULT; |
576 | error = bio_read_page(offset, buf, bio_chain); | 514 | error = hib_bio_read_page(offset, buf, bio_chain); |
577 | if (error) | 515 | if (error) |
578 | return error; | 516 | return error; |
579 | if (++handle->k >= MAP_PAGE_ENTRIES) { | 517 | if (++handle->k >= MAP_PAGE_ENTRIES) { |
580 | error = wait_on_bio_chain(bio_chain); | 518 | error = hib_wait_on_bio_chain(bio_chain); |
581 | handle->k = 0; | 519 | handle->k = 0; |
582 | offset = handle->cur->next_swap; | 520 | offset = handle->cur->next_swap; |
583 | if (!offset) | 521 | if (!offset) |
584 | release_swap_reader(handle); | 522 | release_swap_reader(handle); |
585 | else if (!error) | 523 | else if (!error) |
586 | error = bio_read_page(offset, handle->cur, NULL); | 524 | error = hib_bio_read_page(offset, handle->cur, NULL); |
587 | } | 525 | } |
588 | return error; | 526 | return error; |
589 | } | 527 | } |
590 | 528 | ||
529 | static int swap_reader_finish(struct swap_map_handle *handle) | ||
530 | { | ||
531 | release_swap_reader(handle); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
591 | /** | 536 | /** |
592 | * load_image - load the image using the swap map handle | 537 | * load_image - load the image using the swap map handle |
593 | * @handle and the snapshot handle @snapshot | 538 | * @handle and the snapshot handle @snapshot |
@@ -615,21 +560,21 @@ static int load_image(struct swap_map_handle *handle, | |||
615 | bio = NULL; | 560 | bio = NULL; |
616 | do_gettimeofday(&start); | 561 | do_gettimeofday(&start); |
617 | for ( ; ; ) { | 562 | for ( ; ; ) { |
618 | error = snapshot_write_next(snapshot, PAGE_SIZE); | 563 | error = snapshot_write_next(snapshot); |
619 | if (error <= 0) | 564 | if (error <= 0) |
620 | break; | 565 | break; |
621 | error = swap_read_page(handle, data_of(*snapshot), &bio); | 566 | error = swap_read_page(handle, data_of(*snapshot), &bio); |
622 | if (error) | 567 | if (error) |
623 | break; | 568 | break; |
624 | if (snapshot->sync_read) | 569 | if (snapshot->sync_read) |
625 | error = wait_on_bio_chain(&bio); | 570 | error = hib_wait_on_bio_chain(&bio); |
626 | if (error) | 571 | if (error) |
627 | break; | 572 | break; |
628 | if (!(nr_pages % m)) | 573 | if (!(nr_pages % m)) |
629 | printk("\b\b\b\b%3d%%", nr_pages / m); | 574 | printk("\b\b\b\b%3d%%", nr_pages / m); |
630 | nr_pages++; | 575 | nr_pages++; |
631 | } | 576 | } |
632 | err2 = wait_on_bio_chain(&bio); | 577 | err2 = hib_wait_on_bio_chain(&bio); |
633 | do_gettimeofday(&stop); | 578 | do_gettimeofday(&stop); |
634 | if (!error) | 579 | if (!error) |
635 | error = err2; | 580 | error = err2; |
@@ -657,20 +602,20 @@ int swsusp_read(unsigned int *flags_p) | |||
657 | struct snapshot_handle snapshot; | 602 | struct snapshot_handle snapshot; |
658 | struct swsusp_info *header; | 603 | struct swsusp_info *header; |
659 | 604 | ||
660 | *flags_p = swsusp_header->flags; | ||
661 | |||
662 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); | 605 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); |
663 | error = snapshot_write_next(&snapshot, PAGE_SIZE); | 606 | error = snapshot_write_next(&snapshot); |
664 | if (error < PAGE_SIZE) | 607 | if (error < PAGE_SIZE) |
665 | return error < 0 ? error : -EFAULT; | 608 | return error < 0 ? error : -EFAULT; |
666 | header = (struct swsusp_info *)data_of(snapshot); | 609 | header = (struct swsusp_info *)data_of(snapshot); |
667 | error = get_swap_reader(&handle, swsusp_header->image); | 610 | error = get_swap_reader(&handle, flags_p); |
611 | if (error) | ||
612 | goto end; | ||
668 | if (!error) | 613 | if (!error) |
669 | error = swap_read_page(&handle, header, NULL); | 614 | error = swap_read_page(&handle, header, NULL); |
670 | if (!error) | 615 | if (!error) |
671 | error = load_image(&handle, &snapshot, header->pages - 1); | 616 | error = load_image(&handle, &snapshot, header->pages - 1); |
672 | release_swap_reader(&handle); | 617 | swap_reader_finish(&handle); |
673 | 618 | end: | |
674 | if (!error) | 619 | if (!error) |
675 | pr_debug("PM: Image successfully loaded\n"); | 620 | pr_debug("PM: Image successfully loaded\n"); |
676 | else | 621 | else |
@@ -686,11 +631,11 @@ int swsusp_check(void) | |||
686 | { | 631 | { |
687 | int error; | 632 | int error; |
688 | 633 | ||
689 | resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); | 634 | hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); |
690 | if (!IS_ERR(resume_bdev)) { | 635 | if (!IS_ERR(hib_resume_bdev)) { |
691 | set_blocksize(resume_bdev, PAGE_SIZE); | 636 | set_blocksize(hib_resume_bdev, PAGE_SIZE); |
692 | memset(swsusp_header, 0, PAGE_SIZE); | 637 | memset(swsusp_header, 0, PAGE_SIZE); |
693 | error = bio_read_page(swsusp_resume_block, | 638 | error = hib_bio_read_page(swsusp_resume_block, |
694 | swsusp_header, NULL); | 639 | swsusp_header, NULL); |
695 | if (error) | 640 | if (error) |
696 | goto put; | 641 | goto put; |
@@ -698,7 +643,7 @@ int swsusp_check(void) | |||
698 | if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { | 643 | if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) { |
699 | memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); | 644 | memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); |
700 | /* Reset swap signature now */ | 645 | /* Reset swap signature now */ |
701 | error = bio_write_page(swsusp_resume_block, | 646 | error = hib_bio_write_page(swsusp_resume_block, |
702 | swsusp_header, NULL); | 647 | swsusp_header, NULL); |
703 | } else { | 648 | } else { |
704 | error = -EINVAL; | 649 | error = -EINVAL; |
@@ -706,11 +651,11 @@ int swsusp_check(void) | |||
706 | 651 | ||
707 | put: | 652 | put: |
708 | if (error) | 653 | if (error) |
709 | blkdev_put(resume_bdev, FMODE_READ); | 654 | blkdev_put(hib_resume_bdev, FMODE_READ); |
710 | else | 655 | else |
711 | pr_debug("PM: Signature found, resuming\n"); | 656 | pr_debug("PM: Signature found, resuming\n"); |
712 | } else { | 657 | } else { |
713 | error = PTR_ERR(resume_bdev); | 658 | error = PTR_ERR(hib_resume_bdev); |
714 | } | 659 | } |
715 | 660 | ||
716 | if (error) | 661 | if (error) |
@@ -725,12 +670,12 @@ put: | |||
725 | 670 | ||
726 | void swsusp_close(fmode_t mode) | 671 | void swsusp_close(fmode_t mode) |
727 | { | 672 | { |
728 | if (IS_ERR(resume_bdev)) { | 673 | if (IS_ERR(hib_resume_bdev)) { |
729 | pr_debug("PM: Image device not initialised\n"); | 674 | pr_debug("PM: Image device not initialised\n"); |
730 | return; | 675 | return; |
731 | } | 676 | } |
732 | 677 | ||
733 | blkdev_put(resume_bdev, mode); | 678 | blkdev_put(hib_resume_bdev, mode); |
734 | } | 679 | } |
735 | 680 | ||
736 | static int swsusp_header_init(void) | 681 | static int swsusp_header_init(void) |