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
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/pm.h>

#include "power.h"

#define SWSUSP_SIG	"S1SUSPEND"

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

static struct swsusp_header *swsusp_header;
42 43

/*
44
 * General things
45 46 47
 */

static unsigned short root_swap = 0xffff;
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
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 已提交
66
	bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
67 68 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
	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);
}

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

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

140
static int mark_swapfiles(sector_t start, unsigned int flags)
141 142 143
{
	int error;

144 145 146 147 148 149
	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;
150
		swsusp_header->flags = flags;
151
		error = bio_write_page(swsusp_resume_block,
152
					swsusp_header, NULL);
153
	} else {
154
		printk(KERN_ERR "swsusp: Swap header not found!\n");
155 156 157 158 159 160 161 162 163 164 165 166
		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 */
{
167 168
	int res;

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

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

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

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

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

	if (!offset)
		return -ENOSPC;

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

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

230
#define MAP_PAGE_ENTRIES	(PAGE_SIZE / sizeof(sector_t) - 1)
231 232

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

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

struct swap_map_handle {
	struct swap_map_page *cur;
244
	sector_t cur_swap;
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
	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;
260
	handle->cur_swap = alloc_swapdev_block(root_swap);
261 262 263 264 265 266 267 268
	if (!handle->cur_swap) {
		release_swap_writer(handle);
		return -ENOSPC;
	}
	handle->k = 0;
	return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

448
	if (!start)
449
		return -EINVAL;
450

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

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

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

	if (!handle->cur)
		return -EINVAL;
	offset = handle->cur->entries[handle->k];
	if (!offset)
		return -EFAULT;
A
Andrew Morton 已提交
475
	error = bio_read_page(offset, buf, bio_chain);
476 477 478
	if (error)
		return error;
	if (++handle->k >= MAP_PAGE_ENTRIES) {
A
Andrew Morton 已提交
479
		error = wait_on_bio_chain(bio_chain);
480 481 482 483
		handle->k = 0;
		offset = handle->cur->next_swap;
		if (!offset)
			release_swap_reader(handle);
A
Andrew Morton 已提交
484 485
		else if (!error)
			error = bio_read_page(offset, handle->cur, NULL);
486 487 488 489 490 491 492 493 494 495 496 497
	}
	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 已提交
498
                      unsigned int nr_to_read)
499 500 501
{
	unsigned int m;
	int error = 0;
502 503
	struct timeval start;
	struct timeval stop;
A
Andrew Morton 已提交
504 505 506
	struct bio *bio;
	int err2;
	unsigned nr_pages;
507

A
Andrew Morton 已提交
508 509
	printk("Loading image data pages (%u pages) ...     ", nr_to_read);
	m = nr_to_read / 100;
510 511 512
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
513
	bio = NULL;
514
	do_gettimeofday(&start);
A
Andrew Morton 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
	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);
531
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
532 533
	if (!error)
		error = err2;
534
	if (!error) {
535
		printk("\b\b\b\bdone\n");
536
		snapshot_write_finalize(snapshot);
537 538 539
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
	}
540
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");
541 542 543
	return error;
}

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

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

601 602
		if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) {
			memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
603
			/* Reset swap signature now */
604
			error = bio_write_page(swsusp_resume_block,
605
						swsusp_header, NULL);
606 607 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
		} 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);
}
636 637 638 639 640 641 642 643 644 645

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