swap.c 22.1 KB
Newer Older
1 2 3 4 5 6
/*
 * linux/kernel/power/swap.c
 *
 * This file provides functions for reading the suspend image from
 * and writing it to a swap partition.
 *
P
Pavel Machek 已提交
7
 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
 *
 * This file is released under the GPLv2.
 *
 */

#include <linux/module.h>
#include <linux/file.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/genhd.h>
#include <linux/device.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
A
Andrew Morton 已提交
22
#include <linux/blkdev.h>
23 24 25
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/pm.h>
26
#include <linux/slab.h>
27 28
#include <linux/lzo.h>
#include <linux/vmalloc.h>
29 30 31

#include "power.h"

32
#define HIBERNATE_SIG	"LINHIB0001"
33

34 35 36
/*
 *	The swap map is a data structure used for keeping track of each page
 *	written to a swap partition.  It consists of many swap_map_page
37
 *	structures that contain each an array of MAP_PAGE_ENTRIES swap entries.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
 *	These structures are stored on the swap and linked together with the
 *	help of the .next_swap member.
 *
 *	The swap map is created during suspend.  The swap map pages are
 *	allocated and populated one at a time, so we only need one memory
 *	page to set up the entire structure.
 *
 *	During resume we also only need to use one swap_map_page structure
 *	at a time.
 */

#define MAP_PAGE_ENTRIES	(PAGE_SIZE / sizeof(sector_t) - 1)

struct swap_map_page {
	sector_t entries[MAP_PAGE_ENTRIES];
	sector_t next_swap;
};

/**
 *	The swap_map_handle structure is used for handling swap in
 *	a file-alike way
 */

struct swap_map_handle {
	struct swap_map_page *cur;
	sector_t cur_swap;
	sector_t first_sector;
	unsigned int k;
};

68
struct swsusp_header {
69
	char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int)];
70
	sector_t image;
71
	unsigned int flags;	/* Flags to pass to the "boot" kernel */
72 73
	char	orig_sig[10];
	char	sig[10];
74 75 76
} __attribute__((packed));

static struct swsusp_header *swsusp_header;
77

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/**
 *	The following functions are used for tracing the allocated
 *	swap pages, so that they can be freed in case of an error.
 */

struct swsusp_extent {
	struct rb_node node;
	unsigned long start;
	unsigned long end;
};

static struct rb_root swsusp_extents = RB_ROOT;

static int swsusp_extents_insert(unsigned long swap_offset)
{
	struct rb_node **new = &(swsusp_extents.rb_node);
	struct rb_node *parent = NULL;
	struct swsusp_extent *ext;

	/* Figure out where to put the new node */
	while (*new) {
		ext = container_of(*new, struct swsusp_extent, node);
		parent = *new;
		if (swap_offset < ext->start) {
			/* Try to merge */
			if (swap_offset == ext->start - 1) {
				ext->start--;
				return 0;
			}
			new = &((*new)->rb_left);
		} else if (swap_offset > ext->end) {
			/* Try to merge */
			if (swap_offset == ext->end + 1) {
				ext->end++;
				return 0;
			}
			new = &((*new)->rb_right);
		} else {
			/* It already is in the tree */
			return -EINVAL;
		}
	}
	/* Add the new node and rebalance the tree. */
	ext = kzalloc(sizeof(struct swsusp_extent), GFP_KERNEL);
	if (!ext)
		return -ENOMEM;

	ext->start = swap_offset;
	ext->end = swap_offset;
	rb_link_node(&ext->node, parent, new);
	rb_insert_color(&ext->node, &swsusp_extents);
	return 0;
}

/**
 *	alloc_swapdev_block - allocate a swap page and register that it has
 *	been allocated, so that it can be freed in case of an error.
 */

sector_t alloc_swapdev_block(int swap)
{
	unsigned long offset;

141
	offset = swp_offset(get_swap_page_of_type(swap));
142 143
	if (offset) {
		if (swsusp_extents_insert(offset))
144
			swap_free(swp_entry(swap, offset));
145 146 147 148 149 150 151 152
		else
			return swapdev_block(swap, offset);
	}
	return 0;
}

/**
 *	free_all_swap_pages - free swap pages allocated for saving image data.
153
 *	It also frees the extents used to register which swap entries had been
154 155 156 157 158 159 160 161 162 163 164 165 166 167
 *	allocated.
 */

void free_all_swap_pages(int swap)
{
	struct rb_node *node;

	while ((node = swsusp_extents.rb_node)) {
		struct swsusp_extent *ext;
		unsigned long offset;

		ext = container_of(node, struct swsusp_extent, node);
		rb_erase(node, &swsusp_extents);
		for (offset = ext->start; offset <= ext->end; offset++)
168
			swap_free(swp_entry(swap, offset));
169 170 171 172 173 174 175 176 177 178

		kfree(ext);
	}
}

int swsusp_swap_in_use(void)
{
	return (swsusp_extents.rb_node != NULL);
}

179
/*
180
 * General things
181 182 183
 */

static unsigned short root_swap = 0xffff;
J
Jiri Slaby 已提交
184
struct block_device *hib_resume_bdev;
185 186 187 188

/*
 * Saving part
 */
189

190
static int mark_swapfiles(struct swap_map_handle *handle, unsigned int flags)
191 192 193
{
	int error;

J
Jiri Slaby 已提交
194
	hib_bio_read_page(swsusp_resume_block, swsusp_header, NULL);
195 196 197
	if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) ||
	    !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) {
		memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10);
198
		memcpy(swsusp_header->sig, HIBERNATE_SIG, 10);
199
		swsusp_header->image = handle->first_sector;
200
		swsusp_header->flags = flags;
J
Jiri Slaby 已提交
201
		error = hib_bio_write_page(swsusp_resume_block,
202
					swsusp_header, NULL);
203
	} else {
R
Rafael J. Wysocki 已提交
204
		printk(KERN_ERR "PM: Swap header not found!\n");
205 206 207 208 209 210 211 212
		error = -ENODEV;
	}
	return error;
}

/**
 *	swsusp_swap_check - check if the resume device is a swap device
 *	and get its index (if so)
J
Jiri Slaby 已提交
213 214
 *
 *	This is called before saving image
215
 */
J
Jiri Slaby 已提交
216
static int swsusp_swap_check(void)
217
{
218 219
	int res;

220
	res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
J
Jiri Slaby 已提交
221
			&hib_resume_bdev);
222 223 224 225
	if (res < 0)
		return res;

	root_swap = res;
J
Jiri Slaby 已提交
226
	res = blkdev_get(hib_resume_bdev, FMODE_WRITE);
227 228
	if (res)
		return res;
229

J
Jiri Slaby 已提交
230
	res = set_blocksize(hib_resume_bdev, PAGE_SIZE);
231
	if (res < 0)
J
Jiri Slaby 已提交
232
		blkdev_put(hib_resume_bdev, FMODE_WRITE);
233 234 235 236 237 238 239 240

	return res;
}

/**
 *	write_page - Write one page to given swap location.
 *	@buf:		Address we're writing.
 *	@offset:	Offset of the swap page we're writing to.
A
Andrew Morton 已提交
241
 *	@bio_chain:	Link the next write BIO here
242 243
 */

244
static int write_page(void *buf, sector_t offset, struct bio **bio_chain)
245
{
246 247 248 249 250 251
	void *src;

	if (!offset)
		return -ENOSPC;

	if (bio_chain) {
R
Rafael J. Wysocki 已提交
252
		src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
253 254 255 256 257 258
		if (src) {
			memcpy(src, buf, PAGE_SIZE);
		} else {
			WARN_ON_ONCE(1);
			bio_chain = NULL;	/* Go synchronous */
			src = buf;
A
Andrew Morton 已提交
259
		}
260 261
	} else {
		src = buf;
262
	}
J
Jiri Slaby 已提交
263
	return hib_bio_write_page(offset, src, bio_chain);
264 265 266 267 268 269 270 271 272 273 274
}

static void release_swap_writer(struct swap_map_handle *handle)
{
	if (handle->cur)
		free_page((unsigned long)handle->cur);
	handle->cur = NULL;
}

static int get_swap_writer(struct swap_map_handle *handle)
{
J
Jiri Slaby 已提交
275 276 277 278 279 280 281 282 283
	int ret;

	ret = swsusp_swap_check();
	if (ret) {
		if (ret != -ENOSPC)
			printk(KERN_ERR "PM: Cannot find swap device, try "
					"swapon -a.\n");
		return ret;
	}
284
	handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL);
J
Jiri Slaby 已提交
285 286 287 288
	if (!handle->cur) {
		ret = -ENOMEM;
		goto err_close;
	}
289
	handle->cur_swap = alloc_swapdev_block(root_swap);
290
	if (!handle->cur_swap) {
J
Jiri Slaby 已提交
291 292
		ret = -ENOSPC;
		goto err_rel;
293 294
	}
	handle->k = 0;
295
	handle->first_sector = handle->cur_swap;
296
	return 0;
J
Jiri Slaby 已提交
297 298 299 300 301
err_rel:
	release_swap_writer(handle);
err_close:
	swsusp_close(FMODE_WRITE);
	return ret;
302 303
}

A
Andrew Morton 已提交
304 305 306 307
static int swap_write_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
{
	int error = 0;
308
	sector_t offset;
309 310 311

	if (!handle->cur)
		return -EINVAL;
312
	offset = alloc_swapdev_block(root_swap);
A
Andrew Morton 已提交
313
	error = write_page(buf, offset, bio_chain);
314 315 316 317
	if (error)
		return error;
	handle->cur->entries[handle->k++] = offset;
	if (handle->k >= MAP_PAGE_ENTRIES) {
J
Jiri Slaby 已提交
318
		error = hib_wait_on_bio_chain(bio_chain);
A
Andrew Morton 已提交
319 320
		if (error)
			goto out;
321
		offset = alloc_swapdev_block(root_swap);
322 323 324
		if (!offset)
			return -ENOSPC;
		handle->cur->next_swap = offset;
A
Andrew Morton 已提交
325
		error = write_page(handle->cur, handle->cur_swap, NULL);
326
		if (error)
A
Andrew Morton 已提交
327
			goto out;
328 329 330 331
		memset(handle->cur, 0, PAGE_SIZE);
		handle->cur_swap = offset;
		handle->k = 0;
	}
R
Rafael J. Wysocki 已提交
332
 out:
A
Andrew Morton 已提交
333
	return error;
334 335 336 337 338
}

static int flush_swap_writer(struct swap_map_handle *handle)
{
	if (handle->cur && handle->cur_swap)
A
Andrew Morton 已提交
339
		return write_page(handle->cur, handle->cur_swap, NULL);
340 341 342 343
	else
		return -EINVAL;
}

J
Jiri Slaby 已提交
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
static int swap_writer_finish(struct swap_map_handle *handle,
		unsigned int flags, int error)
{
	if (!error) {
		flush_swap_writer(handle);
		printk(KERN_INFO "PM: S");
		error = mark_swapfiles(handle, flags);
		printk("|\n");
	}

	if (error)
		free_all_swap_pages(root_swap);
	release_swap_writer(handle);
	swsusp_close(FMODE_WRITE);

	return error;
}

362 363 364 365 366 367 368 369 370 371 372 373
/* We need to remember how much compressed data we need to read. */
#define LZO_HEADER	sizeof(size_t)

/* Number of pages/bytes we'll compress at one time. */
#define LZO_UNC_PAGES	32
#define LZO_UNC_SIZE	(LZO_UNC_PAGES * PAGE_SIZE)

/* Number of pages/bytes we need for compressed data (worst case). */
#define LZO_CMP_PAGES	DIV_ROUND_UP(lzo1x_worst_compress(LZO_UNC_SIZE) + \
			             LZO_HEADER, PAGE_SIZE)
#define LZO_CMP_SIZE	(LZO_CMP_PAGES * PAGE_SIZE)

374 375 376 377 378 379
/**
 *	save_image - save the suspend image data
 */

static int save_image(struct swap_map_handle *handle,
                      struct snapshot_handle *snapshot,
380
                      unsigned int nr_to_write)
381 382 383
{
	unsigned int m;
	int ret;
384
	int nr_pages;
A
Andrew Morton 已提交
385 386
	int err2;
	struct bio *bio;
387 388
	struct timeval start;
	struct timeval stop;
389

R
Rafael J. Wysocki 已提交
390 391
	printk(KERN_INFO "PM: Saving image data pages (%u pages) ...     ",
		nr_to_write);
392
	m = nr_to_write / 100;
393 394 395
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
396
	bio = NULL;
397
	do_gettimeofday(&start);
398
	while (1) {
J
Jiri Slaby 已提交
399
		ret = snapshot_read_next(snapshot);
400 401 402 403 404 405
		if (ret <= 0)
			break;
		ret = swap_write_page(handle, data_of(*snapshot), &bio);
		if (ret)
			break;
		if (!(nr_pages % m))
J
Jiri Slaby 已提交
406
			printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m);
407 408
		nr_pages++;
	}
J
Jiri Slaby 已提交
409
	err2 = hib_wait_on_bio_chain(&bio);
410
	do_gettimeofday(&stop);
411 412 413
	if (!ret)
		ret = err2;
	if (!ret)
J
Jiri Slaby 已提交
414
		printk(KERN_CONT "\b\b\b\bdone\n");
415
	else
J
Jiri Slaby 已提交
416
		printk(KERN_CONT "\n");
417
	swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");
418
	return ret;
419 420
}

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551

/**
 * save_image_lzo - Save the suspend image data compressed with LZO.
 * @handle: Swap mam handle to use for saving the image.
 * @snapshot: Image to read data from.
 * @nr_to_write: Number of pages to save.
 */
static int save_image_lzo(struct swap_map_handle *handle,
                          struct snapshot_handle *snapshot,
                          unsigned int nr_to_write)
{
	unsigned int m;
	int ret = 0;
	int nr_pages;
	int err2;
	struct bio *bio;
	struct timeval start;
	struct timeval stop;
	size_t off, unc_len, cmp_len;
	unsigned char *unc, *cmp, *wrk, *page;

	page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
	if (!page) {
		printk(KERN_ERR "PM: Failed to allocate LZO page\n");
		return -ENOMEM;
	}

	wrk = vmalloc(LZO1X_1_MEM_COMPRESS);
	if (!wrk) {
		printk(KERN_ERR "PM: Failed to allocate LZO workspace\n");
		free_page((unsigned long)page);
		return -ENOMEM;
	}

	unc = vmalloc(LZO_UNC_SIZE);
	if (!unc) {
		printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
		vfree(wrk);
		free_page((unsigned long)page);
		return -ENOMEM;
	}

	cmp = vmalloc(LZO_CMP_SIZE);
	if (!cmp) {
		printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
		vfree(unc);
		vfree(wrk);
		free_page((unsigned long)page);
		return -ENOMEM;
	}

	printk(KERN_INFO
		"PM: Compressing and saving image data (%u pages) ...     ",
		nr_to_write);
	m = nr_to_write / 100;
	if (!m)
		m = 1;
	nr_pages = 0;
	bio = NULL;
	do_gettimeofday(&start);
	for (;;) {
		for (off = 0; off < LZO_UNC_SIZE; off += PAGE_SIZE) {
			ret = snapshot_read_next(snapshot);
			if (ret < 0)
				goto out_finish;

			if (!ret)
				break;

			memcpy(unc + off, data_of(*snapshot), PAGE_SIZE);

			if (!(nr_pages % m))
				printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m);
			nr_pages++;
		}

		if (!off)
			break;

		unc_len = off;
		ret = lzo1x_1_compress(unc, unc_len,
		                       cmp + LZO_HEADER, &cmp_len, wrk);
		if (ret < 0) {
			printk(KERN_ERR "PM: LZO compression failed\n");
			break;
		}

		if (unlikely(!cmp_len ||
		             cmp_len > lzo1x_worst_compress(unc_len))) {
			printk(KERN_ERR "PM: Invalid LZO compressed length\n");
			ret = -1;
			break;
		}

		*(size_t *)cmp = cmp_len;

		/*
		 * Given we are writing one page at a time to disk, we copy
		 * that much from the buffer, although the last bit will likely
		 * be smaller than full page. This is OK - we saved the length
		 * of the compressed data, so any garbage at the end will be
		 * discarded when we read it.
		 */
		for (off = 0; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
			memcpy(page, cmp + off, PAGE_SIZE);

			ret = swap_write_page(handle, page, &bio);
			if (ret)
				goto out_finish;
		}
	}

out_finish:
	err2 = hib_wait_on_bio_chain(&bio);
	do_gettimeofday(&stop);
	if (!ret)
		ret = err2;
	if (!ret)
		printk(KERN_CONT "\b\b\b\bdone\n");
	else
		printk(KERN_CONT "\n");
	swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");

	vfree(cmp);
	vfree(unc);
	vfree(wrk);
	free_page((unsigned long)page);

	return ret;
}

552 553 554 555 556 557 558
/**
 *	enough_swap - Make sure we have enough swap to save the image.
 *
 *	Returns TRUE or FALSE after checking the total amount of swap
 *	space avaiable from the resume partition.
 */

559
static int enough_swap(unsigned int nr_pages, unsigned int flags)
560 561
{
	unsigned int free_swap = count_swap_pages(root_swap, 1);
562
	unsigned int required;
563

R
Rafael J. Wysocki 已提交
564
	pr_debug("PM: Free swap pages: %u\n", free_swap);
565 566 567 568

	required = PAGES_FOR_IO + ((flags & SF_NOCOMPRESS_MODE) ?
		nr_pages : (nr_pages * LZO_CMP_PAGES) / LZO_UNC_PAGES + 1);
	return free_swap > required;
569 570 571 572
}

/**
 *	swsusp_write - Write entire image and metadata.
573
 *	@flags: flags to pass to the "boot" kernel in the image header
574 575 576 577 578 579 580
 *
 *	It is important _NOT_ to umount filesystems at this point. We want
 *	them synced (in case something goes wrong) but we DO not want to mark
 *	filesystem clean: it is not. (And it does not matter, if we resume
 *	correctly, we'll mark system clean, anyway.)
 */

581
int swsusp_write(unsigned int flags)
582 583 584 585
{
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;
J
Jiri Slaby 已提交
586
	unsigned long pages;
587 588
	int error;

J
Jiri Slaby 已提交
589 590
	pages = snapshot_get_image_size();
	error = get_swap_writer(&handle);
591
	if (error) {
J
Jiri Slaby 已提交
592
		printk(KERN_ERR "PM: Cannot get swap writer\n");
593 594
		return error;
	}
595
	if (!enough_swap(pages, flags)) {
J
Jiri Slaby 已提交
596 597 598 599
		printk(KERN_ERR "PM: Not enough free swap\n");
		error = -ENOSPC;
		goto out_finish;
	}
600
	memset(&snapshot, 0, sizeof(struct snapshot_handle));
J
Jiri Slaby 已提交
601
	error = snapshot_read_next(&snapshot);
602 603 604 605
	if (error < PAGE_SIZE) {
		if (error >= 0)
			error = -EFAULT;

J
Jiri Slaby 已提交
606
		goto out_finish;
607
	}
608
	header = (struct swsusp_info *)data_of(snapshot);
J
Jiri Slaby 已提交
609
	error = swap_write_page(&handle, header, NULL);
610 611 612 613 614
	if (!error) {
		error = (flags & SF_NOCOMPRESS_MODE) ?
			save_image(&handle, &snapshot, pages - 1) :
			save_image_lzo(&handle, &snapshot, pages - 1);
	}
J
Jiri Slaby 已提交
615 616
out_finish:
	error = swap_writer_finish(&handle, flags, error);
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631
	return error;
}

/**
 *	The following functions allow us to read data using a swap map
 *	in a file-alike way
 */

static void release_swap_reader(struct swap_map_handle *handle)
{
	if (handle->cur)
		free_page((unsigned long)handle->cur);
	handle->cur = NULL;
}

J
Jiri Slaby 已提交
632 633
static int get_swap_reader(struct swap_map_handle *handle,
		unsigned int *flags_p)
634 635 636
{
	int error;

J
Jiri Slaby 已提交
637 638 639
	*flags_p = swsusp_header->flags;

	if (!swsusp_header->image) /* how can this happen? */
640
		return -EINVAL;
641

R
Rafael J. Wysocki 已提交
642
	handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH);
643 644
	if (!handle->cur)
		return -ENOMEM;
645

J
Jiri Slaby 已提交
646
	error = hib_bio_read_page(swsusp_header->image, handle->cur, NULL);
647 648 649 650 651 652 653 654
	if (error) {
		release_swap_reader(handle);
		return error;
	}
	handle->k = 0;
	return 0;
}

A
Andrew Morton 已提交
655 656
static int swap_read_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
657
{
658
	sector_t offset;
659 660 661 662 663 664 665
	int error;

	if (!handle->cur)
		return -EINVAL;
	offset = handle->cur->entries[handle->k];
	if (!offset)
		return -EFAULT;
J
Jiri Slaby 已提交
666
	error = hib_bio_read_page(offset, buf, bio_chain);
667 668 669
	if (error)
		return error;
	if (++handle->k >= MAP_PAGE_ENTRIES) {
J
Jiri Slaby 已提交
670
		error = hib_wait_on_bio_chain(bio_chain);
671 672 673 674
		handle->k = 0;
		offset = handle->cur->next_swap;
		if (!offset)
			release_swap_reader(handle);
A
Andrew Morton 已提交
675
		else if (!error)
J
Jiri Slaby 已提交
676
			error = hib_bio_read_page(offset, handle->cur, NULL);
677 678 679 680
	}
	return error;
}

J
Jiri Slaby 已提交
681 682 683 684 685 686 687
static int swap_reader_finish(struct swap_map_handle *handle)
{
	release_swap_reader(handle);

	return 0;
}

688 689 690 691 692 693 694 695
/**
 *	load_image - load the image using the swap map handle
 *	@handle and the snapshot handle @snapshot
 *	(assume there are @nr_pages pages to load)
 */

static int load_image(struct swap_map_handle *handle,
                      struct snapshot_handle *snapshot,
A
Andrew Morton 已提交
696
                      unsigned int nr_to_read)
697 698 699
{
	unsigned int m;
	int error = 0;
700 701
	struct timeval start;
	struct timeval stop;
A
Andrew Morton 已提交
702 703 704
	struct bio *bio;
	int err2;
	unsigned nr_pages;
705

R
Rafael J. Wysocki 已提交
706 707
	printk(KERN_INFO "PM: Loading image data pages (%u pages) ...     ",
		nr_to_read);
A
Andrew Morton 已提交
708
	m = nr_to_read / 100;
709 710 711
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
712
	bio = NULL;
713
	do_gettimeofday(&start);
A
Andrew Morton 已提交
714
	for ( ; ; ) {
J
Jiri Slaby 已提交
715
		error = snapshot_write_next(snapshot);
A
Andrew Morton 已提交
716 717 718 719 720 721
		if (error <= 0)
			break;
		error = swap_read_page(handle, data_of(*snapshot), &bio);
		if (error)
			break;
		if (snapshot->sync_read)
J
Jiri Slaby 已提交
722
			error = hib_wait_on_bio_chain(&bio);
A
Andrew Morton 已提交
723 724 725 726 727 728
		if (error)
			break;
		if (!(nr_pages % m))
			printk("\b\b\b\b%3d%%", nr_pages / m);
		nr_pages++;
	}
J
Jiri Slaby 已提交
729
	err2 = hib_wait_on_bio_chain(&bio);
730
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
731 732
	if (!error)
		error = err2;
733
	if (!error) {
734
		printk("\b\b\b\bdone\n");
735
		snapshot_write_finalize(snapshot);
736 737
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
738 739
	} else
		printk("\n");
740
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");
741 742 743
	return error;
}

744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864
/**
 * load_image_lzo - Load compressed image data and decompress them with LZO.
 * @handle: Swap map handle to use for loading data.
 * @snapshot: Image to copy uncompressed data into.
 * @nr_to_read: Number of pages to load.
 */
static int load_image_lzo(struct swap_map_handle *handle,
                          struct snapshot_handle *snapshot,
                          unsigned int nr_to_read)
{
	unsigned int m;
	int error = 0;
	struct timeval start;
	struct timeval stop;
	unsigned nr_pages;
	size_t off, unc_len, cmp_len;
	unsigned char *unc, *cmp, *page;

	page = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
	if (!page) {
		printk(KERN_ERR "PM: Failed to allocate LZO page\n");
		return -ENOMEM;
	}

	unc = vmalloc(LZO_UNC_SIZE);
	if (!unc) {
		printk(KERN_ERR "PM: Failed to allocate LZO uncompressed\n");
		free_page((unsigned long)page);
		return -ENOMEM;
	}

	cmp = vmalloc(LZO_CMP_SIZE);
	if (!cmp) {
		printk(KERN_ERR "PM: Failed to allocate LZO compressed\n");
		vfree(unc);
		free_page((unsigned long)page);
		return -ENOMEM;
	}

	printk(KERN_INFO
		"PM: Loading and decompressing image data (%u pages) ...     ",
		nr_to_read);
	m = nr_to_read / 100;
	if (!m)
		m = 1;
	nr_pages = 0;
	do_gettimeofday(&start);

	error = snapshot_write_next(snapshot);
	if (error <= 0)
		goto out_finish;

	for (;;) {
		error = swap_read_page(handle, page, NULL); /* sync */
		if (error)
			break;

		cmp_len = *(size_t *)page;
		if (unlikely(!cmp_len ||
		             cmp_len > lzo1x_worst_compress(LZO_UNC_SIZE))) {
			printk(KERN_ERR "PM: Invalid LZO compressed length\n");
			error = -1;
			break;
		}

		memcpy(cmp, page, PAGE_SIZE);
		for (off = PAGE_SIZE; off < LZO_HEADER + cmp_len; off += PAGE_SIZE) {
			error = swap_read_page(handle, page, NULL); /* sync */
			if (error)
				goto out_finish;

			memcpy(cmp + off, page, PAGE_SIZE);
		}

		unc_len = LZO_UNC_SIZE;
		error = lzo1x_decompress_safe(cmp + LZO_HEADER, cmp_len,
		                              unc, &unc_len);
		if (error < 0) {
			printk(KERN_ERR "PM: LZO decompression failed\n");
			break;
		}

		if (unlikely(!unc_len ||
		             unc_len > LZO_UNC_SIZE ||
		             unc_len & (PAGE_SIZE - 1))) {
			printk(KERN_ERR "PM: Invalid LZO uncompressed length\n");
			error = -1;
			break;
		}

		for (off = 0; off < unc_len; off += PAGE_SIZE) {
			memcpy(data_of(*snapshot), unc + off, PAGE_SIZE);

			if (!(nr_pages % m))
				printk("\b\b\b\b%3d%%", nr_pages / m);
			nr_pages++;

			error = snapshot_write_next(snapshot);
			if (error <= 0)
				goto out_finish;
		}
	}

out_finish:
	do_gettimeofday(&stop);
	if (!error) {
		printk("\b\b\b\bdone\n");
		snapshot_write_finalize(snapshot);
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
	} else
		printk("\n");
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");

	vfree(cmp);
	vfree(unc);
	free_page((unsigned long)page);

	return error;
}

865 866 867 868 869 870 871
/**
 *	swsusp_read - read the hibernation image.
 *	@flags_p: flags passed by the "frozen" kernel in the image header should
 *		  be written into this memeory location
 */

int swsusp_read(unsigned int *flags_p)
872 873 874 875 876 877 878
{
	int error;
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;

	memset(&snapshot, 0, sizeof(struct snapshot_handle));
J
Jiri Slaby 已提交
879
	error = snapshot_write_next(&snapshot);
880 881 882
	if (error < PAGE_SIZE)
		return error < 0 ? error : -EFAULT;
	header = (struct swsusp_info *)data_of(snapshot);
J
Jiri Slaby 已提交
883 884 885
	error = get_swap_reader(&handle, flags_p);
	if (error)
		goto end;
886
	if (!error)
A
Andrew Morton 已提交
887
		error = swap_read_page(&handle, header, NULL);
888 889 890 891 892
	if (!error) {
		error = (*flags_p & SF_NOCOMPRESS_MODE) ?
			load_image(&handle, &snapshot, header->pages - 1) :
			load_image_lzo(&handle, &snapshot, header->pages - 1);
	}
J
Jiri Slaby 已提交
893 894
	swap_reader_finish(&handle);
end:
895
	if (!error)
R
Rafael J. Wysocki 已提交
896
		pr_debug("PM: Image successfully loaded\n");
897
	else
R
Rafael J. Wysocki 已提交
898
		pr_debug("PM: Error %d resuming\n", error);
899 900 901 902 903 904 905 906 907 908 909
	return error;
}

/**
 *      swsusp_check - Check for swsusp signature in the resume device
 */

int swsusp_check(void)
{
	int error;

J
Jiri Slaby 已提交
910 911 912
	hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
	if (!IS_ERR(hib_resume_bdev)) {
		set_blocksize(hib_resume_bdev, PAGE_SIZE);
913
		memset(swsusp_header, 0, PAGE_SIZE);
J
Jiri Slaby 已提交
914
		error = hib_bio_read_page(swsusp_resume_block,
915
					swsusp_header, NULL);
916
		if (error)
J
Jiri Slaby 已提交
917
			goto put;
918

919
		if (!memcmp(HIBERNATE_SIG, swsusp_header->sig, 10)) {
920
			memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
921
			/* Reset swap signature now */
J
Jiri Slaby 已提交
922
			error = hib_bio_write_page(swsusp_resume_block,
923
						swsusp_header, NULL);
924
		} else {
J
Jiri Slaby 已提交
925
			error = -EINVAL;
926
		}
J
Jiri Slaby 已提交
927 928

put:
929
		if (error)
J
Jiri Slaby 已提交
930
			blkdev_put(hib_resume_bdev, FMODE_READ);
931
		else
932
			pr_debug("PM: Image signature found, resuming\n");
933
	} else {
J
Jiri Slaby 已提交
934
		error = PTR_ERR(hib_resume_bdev);
935 936 937
	}

	if (error)
938
		pr_debug("PM: Image not found (code %d)\n", error);
939 940 941 942 943 944 945 946

	return error;
}

/**
 *	swsusp_close - close swap device.
 */

947
void swsusp_close(fmode_t mode)
948
{
J
Jiri Slaby 已提交
949
	if (IS_ERR(hib_resume_bdev)) {
R
Rafael J. Wysocki 已提交
950
		pr_debug("PM: Image device not initialised\n");
951 952 953
		return;
	}

J
Jiri Slaby 已提交
954
	blkdev_put(hib_resume_bdev, mode);
955
}
956 957 958 959 960 961 962 963 964 965

static int swsusp_header_init(void)
{
	swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL);
	if (!swsusp_header)
		panic("Could not allocate memory for swsusp_header\n");
	return 0;
}

core_initcall(swsusp_header_init);