Exemple #1
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}