int swsusp_read(void) { int error; struct swap_map_handle handle; struct snapshot_handle snapshot; struct swsusp_info *header; if (IS_ERR(resume_bdev)) { pr_debug("swsusp: block device not initialised\n"); return PTR_ERR(resume_bdev); } memset(&snapshot, 0, sizeof(struct snapshot_handle)); error = snapshot_write_next(&snapshot, PAGE_SIZE); if (error < PAGE_SIZE) return error < 0 ? error : -EFAULT; header = (struct swsusp_info *)data_of(snapshot); error = get_swap_reader(&handle, swsusp_header.image); if (!error) error = swap_read_page(&handle, header); if (!error) error = load_image(&handle, &snapshot, header->pages - 1); release_swap_reader(&handle); blkdev_put(resume_bdev); if (!error) pr_debug("swsusp: Reading resume file was successful\n"); else pr_debug("swsusp: Error %d resuming\n", error); return error; }
int swsusp_read(unsigned int *flags_p) { int error; struct swap_map_handle handle; struct snapshot_handle snapshot; struct swsusp_info *header; *flags_p = swsusp_header->flags; if (IS_ERR(resume_bdev)) { pr_debug("PM: Image device not initialised\n"); return PTR_ERR(resume_bdev); } memset(&snapshot, 0, sizeof(struct snapshot_handle)); error = snapshot_write_next(&snapshot, PAGE_SIZE); if (error < PAGE_SIZE) return error < 0 ? error : -EFAULT; header = (struct swsusp_info *)data_of(snapshot); error = get_swap_reader(&handle, swsusp_header->image); if (!error) error = swap_read_page(&handle, header, NULL); if (!error) error = load_image(&handle, &snapshot, header->pages - 1); release_swap_reader(&handle); if (!error) pr_debug("PM: Image successfully loaded\n"); else pr_debug("PM: Error %d resuming\n", error); return error; }
static int swap_read_page(struct swap_map_handle *handle, void *buf, struct bio **bio_chain) { sector_t offset; int error; if (!handle->cur) return -EINVAL; offset = handle->cur->entries[handle->k]; if (!offset) return -EFAULT; error = hib_bio_read_page(offset, buf, bio_chain); if (error) return error; if (++handle->k >= MAP_PAGE_ENTRIES) { error = hib_wait_on_bio_chain(bio_chain); handle->k = 0; offset = handle->cur->next_swap; if (!offset) release_swap_reader(handle); else if (!error) error = hib_bio_read_page(offset, handle->cur, NULL); } return error; }
static int get_swap_reader(struct swap_map_handle *handle, swp_entry_t start) { int error; if (!swp_offset(start)) return -EINVAL; handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC); if (!handle->cur) return -ENOMEM; error = bio_read_page(swp_offset(start), handle->cur); if (error) { release_swap_reader(handle); return error; } handle->k = 0; return 0; }
static int get_swap_reader(struct swap_map_handle *handle, sector_t start) { int error; if (!start) return -EINVAL; handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH); if (!handle->cur) return -ENOMEM; error = hib_bio_read_page(start, handle->cur, NULL); if (error) { release_swap_reader(handle); return error; } handle->k = 0; return 0; }
static int swap_read_page(struct swap_map_handle *handle, void *buf) { unsigned long offset; int error; if (!handle->cur) return -EINVAL; offset = handle->cur->entries[handle->k]; if (!offset) return -EFAULT; error = bio_read_page(offset, buf); if (error) return error; if (++handle->k >= MAP_PAGE_ENTRIES) { handle->k = 0; offset = handle->cur->next_swap; if (!offset) release_swap_reader(handle); else error = bio_read_page(offset, handle->cur); } return error; }