Commit 6f612af57821c637b7eaca4374ac7b85f800d6e2
Committed by
Rafael J. Wysocki
1 parent
51fb352b2c
Exists in
master
and in
7 other branches
PM / Hibernate: Group swap ops
Move all the swap processing into one function. It will make swap calls from a non-swap code easier. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Showing 1 changed file with 74 additions and 43 deletions Side-by-side Diff
kernel/power/swap.c
... | ... | @@ -208,9 +208,10 @@ |
208 | 208 | /** |
209 | 209 | * swsusp_swap_check - check if the resume device is a swap device |
210 | 210 | * and get its index (if so) |
211 | + * | |
212 | + * This is called before saving image | |
211 | 213 | */ |
212 | - | |
213 | -static int swsusp_swap_check(void) /* This is called before saving image */ | |
214 | +static int swsusp_swap_check(void) | |
214 | 215 | { |
215 | 216 | int res; |
216 | 217 | |
217 | 218 | |
218 | 219 | |
219 | 220 | |
... | ... | @@ -269,17 +270,33 @@ |
269 | 270 | |
270 | 271 | static int get_swap_writer(struct swap_map_handle *handle) |
271 | 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 | + } | |
272 | 282 | handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); |
273 | - if (!handle->cur) | |
274 | - return -ENOMEM; | |
283 | + if (!handle->cur) { | |
284 | + ret = -ENOMEM; | |
285 | + goto err_close; | |
286 | + } | |
275 | 287 | handle->cur_swap = alloc_swapdev_block(root_swap); |
276 | 288 | if (!handle->cur_swap) { |
277 | - release_swap_writer(handle); | |
278 | - return -ENOSPC; | |
289 | + ret = -ENOSPC; | |
290 | + goto err_rel; | |
279 | 291 | } |
280 | 292 | handle->k = 0; |
281 | 293 | handle->first_sector = handle->cur_swap; |
282 | 294 | return 0; |
295 | +err_rel: | |
296 | + release_swap_writer(handle); | |
297 | +err_close: | |
298 | + swsusp_close(FMODE_WRITE); | |
299 | + return ret; | |
283 | 300 | } |
284 | 301 | |
285 | 302 | static int swap_write_page(struct swap_map_handle *handle, void *buf, |
... | ... | @@ -322,6 +339,24 @@ |
322 | 339 | return -EINVAL; |
323 | 340 | } |
324 | 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 | + | |
325 | 360 | /** |
326 | 361 | * save_image - save the suspend image data |
327 | 362 | */ |
328 | 363 | |
329 | 364 | |
330 | 365 | |
331 | 366 | |
332 | 367 | |
... | ... | @@ -399,48 +434,34 @@ |
399 | 434 | struct swap_map_handle handle; |
400 | 435 | struct snapshot_handle snapshot; |
401 | 436 | struct swsusp_info *header; |
437 | + unsigned long pages; | |
402 | 438 | int error; |
403 | 439 | |
404 | - error = swsusp_swap_check(); | |
440 | + pages = snapshot_get_image_size(); | |
441 | + error = get_swap_writer(&handle); | |
405 | 442 | if (error) { |
406 | - printk(KERN_ERR "PM: Cannot find swap device, try " | |
407 | - "swapon -a.\n"); | |
443 | + printk(KERN_ERR "PM: Cannot get swap writer\n"); | |
408 | 444 | return error; |
409 | 445 | } |
446 | + if (!enough_swap(pages)) { | |
447 | + printk(KERN_ERR "PM: Not enough free swap\n"); | |
448 | + error = -ENOSPC; | |
449 | + goto out_finish; | |
450 | + } | |
410 | 451 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); |
411 | 452 | error = snapshot_read_next(&snapshot); |
412 | 453 | if (error < PAGE_SIZE) { |
413 | 454 | if (error >= 0) |
414 | 455 | error = -EFAULT; |
415 | 456 | |
416 | - goto out; | |
457 | + goto out_finish; | |
417 | 458 | } |
418 | 459 | header = (struct swsusp_info *)data_of(snapshot); |
419 | - if (!enough_swap(header->pages)) { | |
420 | - printk(KERN_ERR "PM: Not enough free swap\n"); | |
421 | - error = -ENOSPC; | |
422 | - goto out; | |
423 | - } | |
424 | - error = get_swap_writer(&handle); | |
425 | - if (!error) { | |
426 | - error = swap_write_page(&handle, header, NULL); | |
427 | - if (!error) | |
428 | - error = save_image(&handle, &snapshot, | |
429 | - header->pages - 1); | |
430 | - | |
431 | - if (!error) { | |
432 | - flush_swap_writer(&handle); | |
433 | - printk(KERN_INFO "PM: S"); | |
434 | - error = mark_swapfiles(&handle, flags); | |
435 | - printk("|\n"); | |
436 | - } | |
437 | - } | |
438 | - if (error) | |
439 | - free_all_swap_pages(root_swap); | |
440 | - | |
441 | - release_swap_writer(&handle); | |
442 | - out: | |
443 | - swsusp_close(FMODE_WRITE); | |
460 | + error = swap_write_page(&handle, header, NULL); | |
461 | + if (!error) | |
462 | + error = save_image(&handle, &snapshot, pages - 1); | |
463 | +out_finish: | |
464 | + error = swap_writer_finish(&handle, flags, error); | |
444 | 465 | return error; |
445 | 466 | } |
446 | 467 | |
447 | 468 | |
448 | 469 | |
... | ... | @@ -456,18 +477,21 @@ |
456 | 477 | handle->cur = NULL; |
457 | 478 | } |
458 | 479 | |
459 | -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) | |
460 | 482 | { |
461 | 483 | int error; |
462 | 484 | |
463 | - if (!start) | |
485 | + *flags_p = swsusp_header->flags; | |
486 | + | |
487 | + if (!swsusp_header->image) /* how can this happen? */ | |
464 | 488 | return -EINVAL; |
465 | 489 | |
466 | 490 | handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH); |
467 | 491 | if (!handle->cur) |
468 | 492 | return -ENOMEM; |
469 | 493 | |
470 | - error = hib_bio_read_page(start, handle->cur, NULL); | |
494 | + error = hib_bio_read_page(swsusp_header->image, handle->cur, NULL); | |
471 | 495 | if (error) { |
472 | 496 | release_swap_reader(handle); |
473 | 497 | return error; |
... | ... | @@ -502,6 +526,13 @@ |
502 | 526 | return error; |
503 | 527 | } |
504 | 528 | |
529 | +static int swap_reader_finish(struct swap_map_handle *handle) | |
530 | +{ | |
531 | + release_swap_reader(handle); | |
532 | + | |
533 | + return 0; | |
534 | +} | |
535 | + | |
505 | 536 | /** |
506 | 537 | * load_image - load the image using the swap map handle |
507 | 538 | * @handle and the snapshot handle @snapshot |
508 | 539 | |
509 | 540 | |
... | ... | @@ -571,20 +602,20 @@ |
571 | 602 | struct snapshot_handle snapshot; |
572 | 603 | struct swsusp_info *header; |
573 | 604 | |
574 | - *flags_p = swsusp_header->flags; | |
575 | - | |
576 | 605 | memset(&snapshot, 0, sizeof(struct snapshot_handle)); |
577 | 606 | error = snapshot_write_next(&snapshot); |
578 | 607 | if (error < PAGE_SIZE) |
579 | 608 | return error < 0 ? error : -EFAULT; |
580 | 609 | header = (struct swsusp_info *)data_of(snapshot); |
581 | - error = get_swap_reader(&handle, swsusp_header->image); | |
610 | + error = get_swap_reader(&handle, flags_p); | |
611 | + if (error) | |
612 | + goto end; | |
582 | 613 | if (!error) |
583 | 614 | error = swap_read_page(&handle, header, NULL); |
584 | 615 | if (!error) |
585 | 616 | error = load_image(&handle, &snapshot, header->pages - 1); |
586 | - release_swap_reader(&handle); | |
587 | - | |
617 | + swap_reader_finish(&handle); | |
618 | +end: | |
588 | 619 | if (!error) |
589 | 620 | pr_debug("PM: Image successfully loaded\n"); |
590 | 621 | else |