Lines Matching +full:resume +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
10 * Copyright (C) 2010-2012 Bojan Smojver <bojan@rexursive.com>
59 * During resume we pick up all swap_map_page structures into a list.
62 #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1)
69 return nr_free_pages() - nr_free_highpages(); in low_free_pages()
93 * a file-alike way
107 char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int) -
108 sizeof(u32) - sizeof(u32)];
142 if (swap_offset < ext->start) { in swsusp_extents_insert()
144 if (swap_offset == ext->start - 1) { in swsusp_extents_insert()
145 ext->start--; in swsusp_extents_insert()
148 new = &((*new)->rb_left); in swsusp_extents_insert()
149 } else if (swap_offset > ext->end) { in swsusp_extents_insert()
151 if (swap_offset == ext->end + 1) { in swsusp_extents_insert()
152 ext->end++; in swsusp_extents_insert()
155 new = &((*new)->rb_right); in swsusp_extents_insert()
158 return -EINVAL; in swsusp_extents_insert()
164 return -ENOMEM; in swsusp_extents_insert()
166 ext->start = swap_offset; in swsusp_extents_insert()
167 ext->end = swap_offset; in swsusp_extents_insert()
168 rb_link_node(&ext->node, parent, new); in swsusp_extents_insert()
169 rb_insert_color(&ext->node, &swsusp_extents); in swsusp_extents_insert()
174 * alloc_swapdev_block - allocate a swap page and register that it has
180 unsigned long offset; in alloc_swapdev_block() local
182 offset = swp_offset(get_swap_page_of_type(swap)); in alloc_swapdev_block()
183 if (offset) { in alloc_swapdev_block()
184 if (swsusp_extents_insert(offset)) in alloc_swapdev_block()
185 swap_free(swp_entry(swap, offset)); in alloc_swapdev_block()
187 return swapdev_block(swap, offset); in alloc_swapdev_block()
193 * free_all_swap_pages - free swap pages allocated for saving image data.
204 unsigned long offset; in free_all_swap_pages() local
208 for (offset = ext->start; offset <= ext->end; offset++) in free_all_swap_pages()
209 swap_free(swp_entry(swap, offset)); in free_all_swap_pages()
236 atomic_set(&hb->count, 0); in hib_init_batch()
237 init_waitqueue_head(&hb->wait); in hib_init_batch()
238 hb->error = BLK_STS_OK; in hib_init_batch()
239 blk_start_plug(&hb->plug); in hib_init_batch()
244 blk_finish_plug(&hb->plug); in hib_finish_batch()
249 struct hib_bio_batch *hb = bio->bi_private; in hib_end_io()
252 if (bio->bi_status) { in hib_end_io()
253 pr_alert("Read-error on swap-device (%u:%u:%Lu)\n", in hib_end_io()
255 (unsigned long long)bio->bi_iter.bi_sector); in hib_end_io()
264 if (bio->bi_status && !hb->error) in hib_end_io()
265 hb->error = bio->bi_status; in hib_end_io()
266 if (atomic_dec_and_test(&hb->count)) in hib_end_io()
267 wake_up(&hb->wait); in hib_end_io()
279 bio = bio_alloc(hib_resume_bdev_handle->bdev, 1, opf, in hib_submit_io()
281 bio->bi_iter.bi_sector = page_off * (PAGE_SIZE >> 9); in hib_submit_io()
285 (unsigned long long)bio->bi_iter.bi_sector); in hib_submit_io()
287 return -EFAULT; in hib_submit_io()
291 bio->bi_end_io = hib_end_io; in hib_submit_io()
292 bio->bi_private = hb; in hib_submit_io()
293 atomic_inc(&hb->count); in hib_submit_io()
309 wait_event(hb->wait, atomic_read(&hb->count) == 0); in hib_wait_io()
310 return blk_status_to_errno(hb->error); in hib_wait_io()
321 if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) || in mark_swapfiles()
322 !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) { in mark_swapfiles()
323 memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10); in mark_swapfiles()
324 memcpy(swsusp_header->sig, HIBERNATE_SIG, 10); in mark_swapfiles()
325 swsusp_header->image = handle->first_sector; in mark_swapfiles()
327 swsusp_header->hw_sig = swsusp_hardware_signature; in mark_swapfiles()
330 swsusp_header->flags = flags; in mark_swapfiles()
332 swsusp_header->crc32 = handle->crc32; in mark_swapfiles()
337 error = -ENODEV; in mark_swapfiles()
343 * swsusp_swap_check - check if the resume device is a swap device
365 res = set_blocksize(hib_resume_bdev_handle->bdev, PAGE_SIZE); in swsusp_swap_check()
373 * write_page - Write one page to given swap location.
375 * @offset: Offset of the swap page we're writing to.
379 static int write_page(void *buf, sector_t offset, struct hib_bio_batch *hb) in write_page() argument
384 if (!offset) in write_page()
385 return -ENOSPC; in write_page()
410 return hib_submit_io(REQ_OP_WRITE | REQ_SYNC, offset, src, hb); in write_page()
415 if (handle->cur) in release_swap_writer()
416 free_page((unsigned long)handle->cur); in release_swap_writer()
417 handle->cur = NULL; in release_swap_writer()
426 if (ret != -ENOSPC) in get_swap_writer()
427 pr_err("Cannot find swap device, try swapon -a\n"); in get_swap_writer()
430 handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL); in get_swap_writer()
431 if (!handle->cur) { in get_swap_writer()
432 ret = -ENOMEM; in get_swap_writer()
435 handle->cur_swap = alloc_swapdev_block(root_swap); in get_swap_writer()
436 if (!handle->cur_swap) { in get_swap_writer()
437 ret = -ENOSPC; in get_swap_writer()
440 handle->k = 0; in get_swap_writer()
441 handle->reqd_free_pages = reqd_free_pages(); in get_swap_writer()
442 handle->first_sector = handle->cur_swap; in get_swap_writer()
455 sector_t offset; in swap_write_page() local
457 if (!handle->cur) in swap_write_page()
458 return -EINVAL; in swap_write_page()
459 offset = alloc_swapdev_block(root_swap); in swap_write_page()
460 error = write_page(buf, offset, hb); in swap_write_page()
463 handle->cur->entries[handle->k++] = offset; in swap_write_page()
464 if (handle->k >= MAP_PAGE_ENTRIES) { in swap_write_page()
465 offset = alloc_swapdev_block(root_swap); in swap_write_page()
466 if (!offset) in swap_write_page()
467 return -ENOSPC; in swap_write_page()
468 handle->cur->next_swap = offset; in swap_write_page()
469 error = write_page(handle->cur, handle->cur_swap, hb); in swap_write_page()
472 clear_page(handle->cur); in swap_write_page()
473 handle->cur_swap = offset; in swap_write_page()
474 handle->k = 0; in swap_write_page()
476 if (hb && low_free_pages() <= handle->reqd_free_pages) { in swap_write_page()
484 handle->reqd_free_pages = reqd_free_pages(); in swap_write_page()
493 if (handle->cur && handle->cur_swap) in flush_swap_writer()
494 return write_page(handle->cur, handle->cur_swap, NULL); in flush_swap_writer()
496 return -EINVAL; in flush_swap_writer()
538 * save_image - save the suspend image data
609 wait_event(d->go, atomic_read_acquire(&d->ready) || in crc32_threadfn()
612 d->thr = NULL; in crc32_threadfn()
613 atomic_set_release(&d->stop, 1); in crc32_threadfn()
614 wake_up(&d->done); in crc32_threadfn()
617 atomic_set(&d->ready, 0); in crc32_threadfn()
619 for (i = 0; i < d->run_threads; i++) in crc32_threadfn()
620 *d->crc32 = crc32_le(*d->crc32, in crc32_threadfn()
621 d->unc[i], *d->unc_len[i]); in crc32_threadfn()
622 atomic_set_release(&d->stop, 1); in crc32_threadfn()
623 wake_up(&d->done); in crc32_threadfn()
652 wait_event(d->go, atomic_read_acquire(&d->ready) || in lzo_compress_threadfn()
655 d->thr = NULL; in lzo_compress_threadfn()
656 d->ret = -1; in lzo_compress_threadfn()
657 atomic_set_release(&d->stop, 1); in lzo_compress_threadfn()
658 wake_up(&d->done); in lzo_compress_threadfn()
661 atomic_set(&d->ready, 0); in lzo_compress_threadfn()
663 d->ret = lzo1x_1_compress(d->unc, d->unc_len, in lzo_compress_threadfn()
664 d->cmp + LZO_HEADER, &d->cmp_len, in lzo_compress_threadfn()
665 d->wrk); in lzo_compress_threadfn()
666 atomic_set_release(&d->stop, 1); in lzo_compress_threadfn()
667 wake_up(&d->done); in lzo_compress_threadfn()
673 * save_image_lzo - Save the suspend image data compressed with LZO.
701 nr_threads = num_online_cpus() - 1; in save_image_lzo()
707 ret = -ENOMEM; in save_image_lzo()
714 ret = -ENOMEM; in save_image_lzo()
721 ret = -ENOMEM; in save_image_lzo()
738 ret = -ENOMEM; in save_image_lzo()
746 init_waitqueue_head(&crc->go); in save_image_lzo()
747 init_waitqueue_head(&crc->done); in save_image_lzo()
749 handle->crc32 = 0; in save_image_lzo()
750 crc->crc32 = &handle->crc32; in save_image_lzo()
752 crc->unc[thr] = data[thr].unc; in save_image_lzo()
753 crc->unc_len[thr] = &data[thr].unc_len; in save_image_lzo()
756 crc->thr = kthread_run(crc32_threadfn, crc, "image_crc32"); in save_image_lzo()
757 if (IS_ERR(crc->thr)) { in save_image_lzo()
758 crc->thr = NULL; in save_image_lzo()
760 ret = -ENOMEM; in save_image_lzo()
768 handle->reqd_free_pages = reqd_free_pages(); in save_image_lzo()
808 crc->run_threads = thr; in save_image_lzo()
809 atomic_set_release(&crc->ready, 1); in save_image_lzo()
810 wake_up(&crc->go); in save_image_lzo()
828 ret = -1; in save_image_lzo()
838 * OK - we saved the length of the compressed data, so in save_image_lzo()
853 wait_event(crc->done, atomic_read_acquire(&crc->stop)); in save_image_lzo()
854 atomic_set(&crc->stop, 0); in save_image_lzo()
868 if (crc->thr) in save_image_lzo()
869 kthread_stop(crc->thr); in save_image_lzo()
884 * enough_swap - Make sure we have enough swap to save the image.
887 * space available from the resume partition.
902 * swsusp_write - Write entire image and metadata.
907 * filesystem clean: it is not. (And it does not matter, if we resume
928 error = -ENOSPC; in swsusp_write()
936 error = -EFAULT; in swsusp_write()
944 save_image(&handle, &snapshot, pages - 1) : in swsusp_write()
945 save_image_lzo(&handle, &snapshot, pages - 1); in swsusp_write()
954 * in a file-like way.
961 while (handle->maps) { in release_swap_reader()
962 if (handle->maps->map) in release_swap_reader()
963 free_page((unsigned long)handle->maps->map); in release_swap_reader()
964 tmp = handle->maps; in release_swap_reader()
965 handle->maps = handle->maps->next; in release_swap_reader()
968 handle->cur = NULL; in release_swap_reader()
976 sector_t offset; in get_swap_reader() local
978 *flags_p = swsusp_header->flags; in get_swap_reader()
980 if (!swsusp_header->image) /* how can this happen? */ in get_swap_reader()
981 return -EINVAL; in get_swap_reader()
983 handle->cur = NULL; in get_swap_reader()
984 last = handle->maps = NULL; in get_swap_reader()
985 offset = swsusp_header->image; in get_swap_reader()
986 while (offset) { in get_swap_reader()
987 tmp = kzalloc(sizeof(*handle->maps), GFP_KERNEL); in get_swap_reader()
990 return -ENOMEM; in get_swap_reader()
992 if (!handle->maps) in get_swap_reader()
993 handle->maps = tmp; in get_swap_reader()
995 last->next = tmp; in get_swap_reader()
998 tmp->map = (struct swap_map_page *) in get_swap_reader()
1000 if (!tmp->map) { in get_swap_reader()
1002 return -ENOMEM; in get_swap_reader()
1005 error = hib_submit_io(REQ_OP_READ, offset, tmp->map, NULL); in get_swap_reader()
1010 offset = tmp->map->next_swap; in get_swap_reader()
1012 handle->k = 0; in get_swap_reader()
1013 handle->cur = handle->maps->map; in get_swap_reader()
1020 sector_t offset; in swap_read_page() local
1024 if (!handle->cur) in swap_read_page()
1025 return -EINVAL; in swap_read_page()
1026 offset = handle->cur->entries[handle->k]; in swap_read_page()
1027 if (!offset) in swap_read_page()
1028 return -EFAULT; in swap_read_page()
1029 error = hib_submit_io(REQ_OP_READ, offset, buf, hb); in swap_read_page()
1032 if (++handle->k >= MAP_PAGE_ENTRIES) { in swap_read_page()
1033 handle->k = 0; in swap_read_page()
1034 free_page((unsigned long)handle->maps->map); in swap_read_page()
1035 tmp = handle->maps; in swap_read_page()
1036 handle->maps = handle->maps->next; in swap_read_page()
1038 if (!handle->maps) in swap_read_page()
1041 handle->cur = handle->maps->map; in swap_read_page()
1054 * load_image - load the image using the swap map handle
1087 if (snapshot->sync_read) in load_image()
1105 ret = -ENODATA; in load_image()
1135 wait_event(d->go, atomic_read_acquire(&d->ready) || in lzo_decompress_threadfn()
1138 d->thr = NULL; in lzo_decompress_threadfn()
1139 d->ret = -1; in lzo_decompress_threadfn()
1140 atomic_set_release(&d->stop, 1); in lzo_decompress_threadfn()
1141 wake_up(&d->done); in lzo_decompress_threadfn()
1144 atomic_set(&d->ready, 0); in lzo_decompress_threadfn()
1146 d->unc_len = LZO_UNC_SIZE; in lzo_decompress_threadfn()
1147 d->ret = lzo1x_decompress_safe(d->cmp + LZO_HEADER, d->cmp_len, in lzo_decompress_threadfn()
1148 d->unc, &d->unc_len); in lzo_decompress_threadfn()
1150 flush_icache_range((unsigned long)d->unc, in lzo_decompress_threadfn()
1151 (unsigned long)d->unc + d->unc_len); in lzo_decompress_threadfn()
1153 atomic_set_release(&d->stop, 1); in lzo_decompress_threadfn()
1154 wake_up(&d->done); in lzo_decompress_threadfn()
1160 * load_image_lzo - Load compressed image data and decompress them with LZO.
1191 nr_threads = num_online_cpus() - 1; in load_image_lzo()
1197 ret = -ENOMEM; in load_image_lzo()
1204 ret = -ENOMEM; in load_image_lzo()
1211 ret = -ENOMEM; in load_image_lzo()
1230 ret = -ENOMEM; in load_image_lzo()
1238 init_waitqueue_head(&crc->go); in load_image_lzo()
1239 init_waitqueue_head(&crc->done); in load_image_lzo()
1241 handle->crc32 = 0; in load_image_lzo()
1242 crc->crc32 = &handle->crc32; in load_image_lzo()
1244 crc->unc[thr] = data[thr].unc; in load_image_lzo()
1245 crc->unc_len[thr] = &data[thr].unc_len; in load_image_lzo()
1248 crc->thr = kthread_run(crc32_threadfn, crc, "image_crc32"); in load_image_lzo()
1249 if (IS_ERR(crc->thr)) { in load_image_lzo()
1250 crc->thr = NULL; in load_image_lzo()
1252 ret = -ENOMEM; in load_image_lzo()
1264 read_pages = (low_free_pages() - snapshot_get_image_size()) / 2; in load_image_lzo()
1277 ret = -ENOMEM; in load_image_lzo()
1307 if (handle->cur && in load_image_lzo()
1308 handle->cur->entries[handle->k]) { in load_image_lzo()
1319 want -= i; in load_image_lzo()
1337 if (crc->run_threads) { in load_image_lzo()
1338 wait_event(crc->done, atomic_read_acquire(&crc->stop)); in load_image_lzo()
1339 atomic_set(&crc->stop, 0); in load_image_lzo()
1340 crc->run_threads = 0; in load_image_lzo()
1349 ret = -1; in load_image_lzo()
1357 ret = -1; in load_image_lzo()
1368 have--; in load_image_lzo()
1405 data[thr].unc_len & (PAGE_SIZE - 1))) { in load_image_lzo()
1407 ret = -1; in load_image_lzo()
1423 crc->run_threads = thr + 1; in load_image_lzo()
1424 atomic_set_release(&crc->ready, 1); in load_image_lzo()
1425 wake_up(&crc->go); in load_image_lzo()
1431 crc->run_threads = thr; in load_image_lzo()
1432 atomic_set_release(&crc->ready, 1); in load_image_lzo()
1433 wake_up(&crc->go); in load_image_lzo()
1437 if (crc->run_threads) { in load_image_lzo()
1438 wait_event(crc->done, atomic_read_acquire(&crc->stop)); in load_image_lzo()
1439 atomic_set(&crc->stop, 0); in load_image_lzo()
1446 ret = -ENODATA; in load_image_lzo()
1448 if (swsusp_header->flags & SF_CRC32_MODE) { in load_image_lzo()
1449 if(handle->crc32 != swsusp_header->crc32) { in load_image_lzo()
1451 ret = -ENODATA; in load_image_lzo()
1462 if (crc->thr) in load_image_lzo()
1463 kthread_stop(crc->thr); in load_image_lzo()
1478 * swsusp_read - read the hibernation image.
1493 return error < 0 ? error : -EFAULT; in swsusp_read()
1502 load_image(&handle, &snapshot, header->pages - 1) : in swsusp_read()
1503 load_image_lzo(&handle, &snapshot, header->pages - 1); in swsusp_read()
1517 * swsusp_check - Open the resume device and check for the swsusp signature.
1518 * @exclusive: Open the resume device exclusively.
1529 set_blocksize(hib_resume_bdev_handle->bdev, PAGE_SIZE); in swsusp_check()
1536 if (!memcmp(HIBERNATE_SIG, swsusp_header->sig, 10)) { in swsusp_check()
1537 memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10); in swsusp_check()
1543 error = -EINVAL; in swsusp_check()
1545 if (!error && swsusp_header->flags & SF_HW_SIG && in swsusp_check()
1546 swsusp_header->hw_sig != swsusp_hardware_signature) { in swsusp_check()
1547 pr_info("Suspend image hardware signature mismatch (%08x now %08x); aborting resume.\n", in swsusp_check()
1548 swsusp_header->hw_sig, swsusp_hardware_signature); in swsusp_check()
1549 error = -EINVAL; in swsusp_check()
1568 * swsusp_close - close resume device.
1582 * swsusp_unmark - Unmark swsusp signature in the resume device
1592 if (!memcmp(HIBERNATE_SIG,swsusp_header->sig, 10)) { in swsusp_unmark()
1593 memcpy(swsusp_header->sig,swsusp_header->orig_sig, 10); in swsusp_unmark()
1599 error = -ENODEV; in swsusp_unmark()