static int swsusp_alloc(void) { int error; pr_debug("suspend: (pages needed: %d + %d free: %d)\n", nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); pagedir_nosave = NULL; if (!enough_free_mem()) return -ENOMEM; if (!enough_swap()) return -ENOSPC; if ((error = alloc_pagedir())) { printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); return error; } if ((error = alloc_image_pages())) { printk(KERN_ERR "suspend: Allocating image pages failed.\n"); swsusp_free(); return error; } nr_copy_pages_check = nr_copy_pages; pagedir_order_check = pagedir_order; return 0; }
int pmdisk_suspend(void) { int error = 0; if ((error = read_swapfiles())) return error; drain_local_pages(); pm_pagedir_nosave = NULL; pr_debug("pmdisk: Counting pages to copy.\n" ); count_pages(); pr_debug("pmdisk: (pages needed: %d + %d free: %d)\n", pmdisk_pages,PAGES_FOR_IO,nr_free_pages()); if (!enough_free_mem()) return -ENOMEM; if (!enough_swap()) return -ENOSPC; if ((error = alloc_pagedir())) { pr_debug("pmdisk: Allocating pagedir failed.\n"); return error; } if ((error = alloc_image_pages())) { pr_debug("pmdisk: Allocating image pages failed.\n"); free_pagedir(); return error; } nr_copy_pages_check = pmdisk_pages; pagedir_order_check = pagedir_order; /* During allocating of suspend pagedir, new cold pages may appear. * Kill them */ drain_local_pages(); /* copy */ copy_pages(); /* * End of critical section. From now on, we can write to memory, * but we should not touch disk. This specially means we must _not_ * touch swap space! Except we must write out our image of course. */ pr_debug("pmdisk: %d pages copied\n", pmdisk_pages ); return 0; }
int swsusp_write(unsigned int flags) { struct swap_map_handle handle; struct snapshot_handle snapshot; struct swsusp_info *header; int error; error = swsusp_swap_check(); if (error) { printk(KERN_ERR "PM: Cannot find swap device, try " "swapon -a.\n"); return error; } memset(&snapshot, 0, sizeof(struct snapshot_handle)); error = snapshot_read_next(&snapshot, PAGE_SIZE); if (error < PAGE_SIZE) { if (error >= 0) error = -EFAULT; goto out; } header = (struct swsusp_info *)data_of(snapshot); if (!enough_swap(header->pages)) { printk(KERN_ERR "PM: Not enough free swap\n"); error = -ENOSPC; goto out; } error = get_swap_writer(&handle); if (!error) { sector_t start = handle.cur_swap; error = swap_write_page(&handle, header, NULL); if (!error) error = save_image(&handle, &snapshot, header->pages - 1); if (!error) { flush_swap_writer(&handle); printk(KERN_INFO "PM: S"); error = mark_swapfiles(start, flags); printk("|\n"); } } if (error) free_all_swap_pages(root_swap); release_swap_writer(&handle); out: swsusp_close(FMODE_WRITE); return error; }
int swsusp_write(void) { struct swap_map_handle handle; struct snapshot_handle snapshot; struct swsusp_info *header; int error; if ((error = swsusp_swap_check())) { printk(KERN_ERR "swsusp: Cannot find swap device, try swapon -a.\n"); return error; } memset(&snapshot, 0, sizeof(struct snapshot_handle)); error = snapshot_read_next(&snapshot, PAGE_SIZE); if (error < PAGE_SIZE) return error < 0 ? error : -EFAULT; header = (struct swsusp_info *)data_of(snapshot); if (!enough_swap(header->pages)) { printk(KERN_ERR "swsusp: Not enough free swap\n"); return -ENOSPC; } error = get_swap_writer(&handle); if (!error) { unsigned long start = handle.cur_swap; error = swap_write_page(&handle, header); if (!error) error = save_image(&handle, &snapshot, header->pages - 1); if (!error) { flush_swap_writer(&handle); printk("S"); error = mark_swapfiles(swp_entry(root_swap, start)); printk("|\n"); } } if (error) free_all_swap_pages(root_swap, handle.bitmap); release_swap_writer(&handle); return error; }