swap.c 14.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * linux/kernel/power/swap.c
 *
 * This file provides functions for reading the suspend image from
 * and writing it to a swap partition.
 *
 * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
 * 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/utsname.h>
#include <linux/version.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 已提交
24
#include <linux/blkdev.h>
25 26 27 28 29 30 31 32 33 34
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/pm.h>

#include "power.h"

extern char resume_file[];

#define SWSUSP_SIG	"S1SUSPEND"

35
struct swsusp_header {
36
	char reserved[PAGE_SIZE - 20 - sizeof(sector_t) - sizeof(int)];
37
	sector_t image;
38
	unsigned int flags;	/* Flags to pass to the "boot" kernel */
39 40
	char	orig_sig[10];
	char	sig[10];
41 42 43
} __attribute__((packed));

static struct swsusp_header *swsusp_header;
44 45

/*
46
 * General things
47 48 49
 */

static unsigned short root_swap = 0xffff;
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
static struct block_device *resume_bdev;

/**
 *	submit - submit BIO request.
 *	@rw:	READ or WRITE.
 *	@off	physical offset of page.
 *	@page:	page we're reading or writing.
 *	@bio_chain: list of pending biod (for async reading)
 *
 *	Straight from the textbook - allocate and initialize the bio.
 *	If we're reading, make sure the page is marked as dirty.
 *	Then submit it and, if @bio_chain == NULL, wait.
 */
static int submit(int rw, pgoff_t page_off, struct page *page,
			struct bio **bio_chain)
{
	struct bio *bio;

R
Rafael J. Wysocki 已提交
68
	bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
69 70 71 72 73 74 75 76 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
	if (!bio)
		return -ENOMEM;
	bio->bi_sector = page_off * (PAGE_SIZE >> 9);
	bio->bi_bdev = resume_bdev;
	bio->bi_end_io = end_swap_bio_read;

	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
		printk("swsusp: ERROR: adding page to bio at %ld\n", page_off);
		bio_put(bio);
		return -EFAULT;
	}

	lock_page(page);
	bio_get(bio);

	if (bio_chain == NULL) {
		submit_bio(rw | (1 << BIO_RW_SYNC), bio);
		wait_on_page_locked(page);
		if (rw == READ)
			bio_set_pages_dirty(bio);
		bio_put(bio);
	} else {
		if (rw == READ)
			get_page(page);	/* These pages are freed later */
		bio->bi_private = *bio_chain;
		*bio_chain = bio;
		submit_bio(rw | (1 << BIO_RW_SYNC), bio);
	}
	return 0;
}

static int bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain)
{
	return submit(READ, page_off, virt_to_page(addr), bio_chain);
}

105
static int bio_write_page(pgoff_t page_off, void *addr, struct bio **bio_chain)
106
{
107
	return submit(WRITE, page_off, virt_to_page(addr), bio_chain);
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
}

static int wait_on_bio_chain(struct bio **bio_chain)
{
	struct bio *bio;
	struct bio *next_bio;
	int ret = 0;

	if (bio_chain == NULL)
		return 0;

	bio = *bio_chain;
	if (bio == NULL)
		return 0;
	while (bio) {
		struct page *page;

		next_bio = bio->bi_private;
		page = bio->bi_io_vec[0].bv_page;
		wait_on_page_locked(page);
		if (!PageUptodate(page) || PageError(page))
			ret = -EIO;
		put_page(page);
		bio_put(bio);
		bio = next_bio;
	}
	*bio_chain = NULL;
	return ret;
}

/*
 * Saving part
 */
141

142
static int mark_swapfiles(sector_t start, unsigned int flags)
143 144 145
{
	int error;

146 147 148 149 150 151
	bio_read_page(swsusp_resume_block, swsusp_header, NULL);
	if (!memcmp("SWAP-SPACE",swsusp_header->sig, 10) ||
	    !memcmp("SWAPSPACE2",swsusp_header->sig, 10)) {
		memcpy(swsusp_header->orig_sig,swsusp_header->sig, 10);
		memcpy(swsusp_header->sig,SWSUSP_SIG, 10);
		swsusp_header->image = start;
152
		swsusp_header->flags = flags;
153
		error = bio_write_page(swsusp_resume_block,
154
					swsusp_header, NULL);
155
	} else {
156
		printk(KERN_ERR "swsusp: Swap header not found!\n");
157 158 159 160 161 162 163 164 165 166 167 168
		error = -ENODEV;
	}
	return error;
}

/**
 *	swsusp_swap_check - check if the resume device is a swap device
 *	and get its index (if so)
 */

static int swsusp_swap_check(void) /* This is called before saving image */
{
169 170
	int res;

171 172
	res = swap_type_of(swsusp_resume_device, swsusp_resume_block,
			&resume_bdev);
173 174 175 176
	if (res < 0)
		return res;

	root_swap = res;
177 178 179
	res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR);
	if (res)
		return res;
180 181 182 183

	res = set_blocksize(resume_bdev, PAGE_SIZE);
	if (res < 0)
		blkdev_put(resume_bdev);
184 185 186 187 188 189 190 191

	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 已提交
192
 *	@bio_chain:	Link the next write BIO here
193 194
 */

195
static int write_page(void *buf, sector_t offset, struct bio **bio_chain)
196
{
197 198 199 200 201 202
	void *src;

	if (!offset)
		return -ENOSPC;

	if (bio_chain) {
R
Rafael J. Wysocki 已提交
203
		src = (void *)__get_free_page(__GFP_WAIT | __GFP_HIGH);
204 205 206 207 208 209
		if (src) {
			memcpy(src, buf, PAGE_SIZE);
		} else {
			WARN_ON_ONCE(1);
			bio_chain = NULL;	/* Go synchronous */
			src = buf;
A
Andrew Morton 已提交
210
		}
211 212
	} else {
		src = buf;
213
	}
214
	return bio_write_page(offset, src, bio_chain);
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
}

/*
 *	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
 *	structures that contain each an array of MAP_PAGE_SIZE swap entries.
 *	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.
 */

232
#define MAP_PAGE_ENTRIES	(PAGE_SIZE / sizeof(sector_t) - 1)
233 234

struct swap_map_page {
235 236
	sector_t entries[MAP_PAGE_ENTRIES];
	sector_t next_swap;
237 238 239 240 241 242 243 244 245
};

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

struct swap_map_handle {
	struct swap_map_page *cur;
246
	sector_t cur_swap;
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
	unsigned int k;
};

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)
{
	handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL);
	if (!handle->cur)
		return -ENOMEM;
262
	handle->cur_swap = alloc_swapdev_block(root_swap);
263 264 265 266 267 268 269 270
	if (!handle->cur_swap) {
		release_swap_writer(handle);
		return -ENOSPC;
	}
	handle->k = 0;
	return 0;
}

A
Andrew Morton 已提交
271 272 273 274
static int swap_write_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
{
	int error = 0;
275
	sector_t offset;
276 277 278

	if (!handle->cur)
		return -EINVAL;
279
	offset = alloc_swapdev_block(root_swap);
A
Andrew Morton 已提交
280
	error = write_page(buf, offset, bio_chain);
281 282 283 284
	if (error)
		return error;
	handle->cur->entries[handle->k++] = offset;
	if (handle->k >= MAP_PAGE_ENTRIES) {
A
Andrew Morton 已提交
285 286 287
		error = wait_on_bio_chain(bio_chain);
		if (error)
			goto out;
288
		offset = alloc_swapdev_block(root_swap);
289 290 291
		if (!offset)
			return -ENOSPC;
		handle->cur->next_swap = offset;
A
Andrew Morton 已提交
292
		error = write_page(handle->cur, handle->cur_swap, NULL);
293
		if (error)
A
Andrew Morton 已提交
294
			goto out;
295 296 297 298
		memset(handle->cur, 0, PAGE_SIZE);
		handle->cur_swap = offset;
		handle->k = 0;
	}
R
Rafael J. Wysocki 已提交
299
 out:
A
Andrew Morton 已提交
300
	return error;
301 302 303 304 305
}

static int flush_swap_writer(struct swap_map_handle *handle)
{
	if (handle->cur && handle->cur_swap)
A
Andrew Morton 已提交
306
		return write_page(handle->cur, handle->cur_swap, NULL);
307 308 309 310 311 312 313 314 315 316
	else
		return -EINVAL;
}

/**
 *	save_image - save the suspend image data
 */

static int save_image(struct swap_map_handle *handle,
                      struct snapshot_handle *snapshot,
317
                      unsigned int nr_to_write)
318 319 320 321
{
	unsigned int m;
	int ret;
	int error = 0;
322
	int nr_pages;
A
Andrew Morton 已提交
323 324
	int err2;
	struct bio *bio;
325 326
	struct timeval start;
	struct timeval stop;
327

328 329
	printk("Saving image data pages (%u pages) ...     ", nr_to_write);
	m = nr_to_write / 100;
330 331 332
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
333
	bio = NULL;
334
	do_gettimeofday(&start);
335 336 337
	do {
		ret = snapshot_read_next(snapshot, PAGE_SIZE);
		if (ret > 0) {
A
Andrew Morton 已提交
338 339
			error = swap_write_page(handle, data_of(*snapshot),
						&bio);
340 341 342 343 344 345 346
			if (error)
				break;
			if (!(nr_pages % m))
				printk("\b\b\b\b%3d%%", nr_pages / m);
			nr_pages++;
		}
	} while (ret > 0);
A
Andrew Morton 已提交
347
	err2 = wait_on_bio_chain(&bio);
348
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
349 350
	if (!error)
		error = err2;
351 352
	if (!error)
		printk("\b\b\b\bdone\n");
353
	swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
	return error;
}

/**
 *	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.
 */

static int enough_swap(unsigned int nr_pages)
{
	unsigned int free_swap = count_swap_pages(root_swap, 1);

	pr_debug("swsusp: free swap pages: %u\n", free_swap);
369
	return free_swap > nr_pages + PAGES_FOR_IO;
370 371 372 373
}

/**
 *	swsusp_write - Write entire image and metadata.
374
 *	@flags: flags to pass to the "boot" kernel in the image header
375 376 377 378 379 380 381
 *
 *	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.)
 */

382
int swsusp_write(unsigned int flags)
383 384 385 386 387 388
{
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;
	int error;

389 390
	error = swsusp_swap_check();
	if (error) {
A
Andrew Morton 已提交
391 392
		printk(KERN_ERR "swsusp: Cannot find swap device, try "
				"swapon -a.\n");
393 394 395 396
		return error;
	}
	memset(&snapshot, 0, sizeof(struct snapshot_handle));
	error = snapshot_read_next(&snapshot, PAGE_SIZE);
397 398 399 400 401 402
	if (error < PAGE_SIZE) {
		if (error >= 0)
			error = -EFAULT;

		goto out;
	}
403 404 405
	header = (struct swsusp_info *)data_of(snapshot);
	if (!enough_swap(header->pages)) {
		printk(KERN_ERR "swsusp: Not enough free swap\n");
406 407
		error = -ENOSPC;
		goto out;
408 409 410
	}
	error = get_swap_writer(&handle);
	if (!error) {
411 412
		sector_t start = handle.cur_swap;

A
Andrew Morton 已提交
413
		error = swap_write_page(&handle, header, NULL);
A
Andrew Morton 已提交
414 415 416
		if (!error)
			error = save_image(&handle, &snapshot,
					header->pages - 1);
417

A
Andrew Morton 已提交
418 419 420
		if (!error) {
			flush_swap_writer(&handle);
			printk("S");
421
			error = mark_swapfiles(start, flags);
A
Andrew Morton 已提交
422 423
			printk("|\n");
		}
424 425
	}
	if (error)
426 427
		free_all_swap_pages(root_swap);

428
	release_swap_writer(&handle);
R
Rafael J. Wysocki 已提交
429
 out:
430
	swsusp_close();
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
	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;
}

446
static int get_swap_reader(struct swap_map_handle *handle, sector_t start)
447 448 449
{
	int error;

450
	if (!start)
451
		return -EINVAL;
452

R
Rafael J. Wysocki 已提交
453
	handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH);
454 455
	if (!handle->cur)
		return -ENOMEM;
456 457

	error = bio_read_page(start, handle->cur, NULL);
458 459 460 461 462 463 464 465
	if (error) {
		release_swap_reader(handle);
		return error;
	}
	handle->k = 0;
	return 0;
}

A
Andrew Morton 已提交
466 467
static int swap_read_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
468
{
469
	sector_t offset;
470 471 472 473 474 475 476
	int error;

	if (!handle->cur)
		return -EINVAL;
	offset = handle->cur->entries[handle->k];
	if (!offset)
		return -EFAULT;
A
Andrew Morton 已提交
477
	error = bio_read_page(offset, buf, bio_chain);
478 479 480
	if (error)
		return error;
	if (++handle->k >= MAP_PAGE_ENTRIES) {
A
Andrew Morton 已提交
481
		error = wait_on_bio_chain(bio_chain);
482 483 484 485
		handle->k = 0;
		offset = handle->cur->next_swap;
		if (!offset)
			release_swap_reader(handle);
A
Andrew Morton 已提交
486 487
		else if (!error)
			error = bio_read_page(offset, handle->cur, NULL);
488 489 490 491 492 493 494 495 496 497 498 499
	}
	return error;
}

/**
 *	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 已提交
500
                      unsigned int nr_to_read)
501 502 503
{
	unsigned int m;
	int error = 0;
504 505
	struct timeval start;
	struct timeval stop;
A
Andrew Morton 已提交
506 507 508
	struct bio *bio;
	int err2;
	unsigned nr_pages;
509

A
Andrew Morton 已提交
510 511
	printk("Loading image data pages (%u pages) ...     ", nr_to_read);
	m = nr_to_read / 100;
512 513 514
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
515
	bio = NULL;
516
	do_gettimeofday(&start);
A
Andrew Morton 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
	for ( ; ; ) {
		error = snapshot_write_next(snapshot, PAGE_SIZE);
		if (error <= 0)
			break;
		error = swap_read_page(handle, data_of(*snapshot), &bio);
		if (error)
			break;
		if (snapshot->sync_read)
			error = wait_on_bio_chain(&bio);
		if (error)
			break;
		if (!(nr_pages % m))
			printk("\b\b\b\b%3d%%", nr_pages / m);
		nr_pages++;
	}
	err2 = wait_on_bio_chain(&bio);
533
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
534 535
	if (!error)
		error = err2;
536
	if (!error) {
537
		printk("\b\b\b\bdone\n");
538
		snapshot_write_finalize(snapshot);
539 540 541
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
	}
542
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");
543 544 545
	return error;
}

546 547 548 549 550 551 552
/**
 *	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)
553 554 555 556 557 558
{
	int error;
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;

559
	*flags_p = swsusp_header->flags;
560 561 562 563 564 565 566 567 568 569
	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);
570
	error = get_swap_reader(&handle, swsusp_header->image);
571
	if (!error)
A
Andrew Morton 已提交
572
		error = swap_read_page(&handle, header, NULL);
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
	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;
}

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

int swsusp_check(void)
{
	int error;

	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
	if (!IS_ERR(resume_bdev)) {
		set_blocksize(resume_bdev, PAGE_SIZE);
597
		memset(swsusp_header, 0, PAGE_SIZE);
598
		error = bio_read_page(swsusp_resume_block,
599
					swsusp_header, NULL);
600
		if (error)
601
			return error;
602

603 604
		if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) {
			memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
605
			/* Reset swap signature now */
606
			error = bio_write_page(swsusp_resume_block,
607
						swsusp_header, NULL);
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
		} else {
			return -EINVAL;
		}
		if (error)
			blkdev_put(resume_bdev);
		else
			pr_debug("swsusp: Signature found, resuming\n");
	} else {
		error = PTR_ERR(resume_bdev);
	}

	if (error)
		pr_debug("swsusp: Error %d check for resume file\n", error);

	return error;
}

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

void swsusp_close(void)
{
	if (IS_ERR(resume_bdev)) {
		pr_debug("swsusp: block device not initialised\n");
		return;
	}

	blkdev_put(resume_bdev);
}
638 639 640 641 642 643 644 645 646 647

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);