swap.c 14.3 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 24
/*
 * 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/smp_lock.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 已提交
25
#include <linux/blkdev.h>
26 27 28 29 30 31 32 33 34 35 36
#include <linux/swap.h>
#include <linux/swapops.h>
#include <linux/pm.h>

#include "power.h"

extern char resume_file[];

#define SWSUSP_SIG	"S1SUSPEND"

static struct swsusp_header {
37 38
	char reserved[PAGE_SIZE - 20 - sizeof(sector_t)];
	sector_t image;
39 40 41 42 43
	char	orig_sig[10];
	char	sig[10];
} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;

/*
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)
141 142 143
{
	int error;

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

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

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

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

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

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

	if (!offset)
		return -ENOSPC;

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

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

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

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

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

struct swap_map_handle {
	struct swap_map_page *cur;
243
	sector_t cur_swap;
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
	struct bitmap_page *bitmap;
	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;
	if (handle->bitmap)
		free_bitmap(handle->bitmap);
	handle->bitmap = 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;
	handle->bitmap = alloc_bitmap(count_swap_pages(root_swap, 0));
	if (!handle->bitmap) {
		release_swap_writer(handle);
		return -ENOMEM;
	}
268
	handle->cur_swap = alloc_swapdev_block(root_swap, handle->bitmap);
269 270 271 272 273 274 275 276
	if (!handle->cur_swap) {
		release_swap_writer(handle);
		return -ENOSPC;
	}
	handle->k = 0;
	return 0;
}

A
Andrew Morton 已提交
277 278 279 280
static int swap_write_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
{
	int error = 0;
281
	sector_t offset;
282 283 284

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

static int flush_swap_writer(struct swap_map_handle *handle)
{
	if (handle->cur && handle->cur_swap)
A
Andrew Morton 已提交
312
		return write_page(handle->cur, handle->cur_swap, NULL);
313 314 315 316 317 318 319 320 321 322
	else
		return -EINVAL;
}

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

static int save_image(struct swap_map_handle *handle,
                      struct snapshot_handle *snapshot,
323
                      unsigned int nr_to_write)
324 325 326 327
{
	unsigned int m;
	int ret;
	int error = 0;
328
	int nr_pages;
A
Andrew Morton 已提交
329 330
	int err2;
	struct bio *bio;
331 332
	struct timeval start;
	struct timeval stop;
333

334 335
	printk("Saving image data pages (%u pages) ...     ", nr_to_write);
	m = nr_to_write / 100;
336 337 338
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
339
	bio = NULL;
340
	do_gettimeofday(&start);
341 342 343
	do {
		ret = snapshot_read_next(snapshot, PAGE_SIZE);
		if (ret > 0) {
A
Andrew Morton 已提交
344 345
			error = swap_write_page(handle, data_of(*snapshot),
						&bio);
346 347 348 349 350 351 352
			if (error)
				break;
			if (!(nr_pages % m))
				printk("\b\b\b\b%3d%%", nr_pages / m);
			nr_pages++;
		}
	} while (ret > 0);
A
Andrew Morton 已提交
353
	err2 = wait_on_bio_chain(&bio);
354
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
355 356
	if (!error)
		error = err2;
357 358
	if (!error)
		printk("\b\b\b\bdone\n");
359
	swsusp_show_speed(&start, &stop, nr_to_write, "Wrote");
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
	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);
375
	return free_swap > nr_pages + PAGES_FOR_IO;
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
}

/**
 *	swsusp_write - Write entire image and metadata.
 *
 *	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.)
 */

int swsusp_write(void)
{
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;
	int error;

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

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

A
Andrew Morton 已提交
418
		error = swap_write_page(&handle, header, NULL);
A
Andrew Morton 已提交
419 420 421
		if (!error)
			error = save_image(&handle, &snapshot,
					header->pages - 1);
422

A
Andrew Morton 已提交
423 424 425
		if (!error) {
			flush_swap_writer(&handle);
			printk("S");
426
			error = mark_swapfiles(start);
A
Andrew Morton 已提交
427 428
			printk("|\n");
		}
429 430 431 432
	}
	if (error)
		free_all_swap_pages(root_swap, handle.bitmap);
	release_swap_writer(&handle);
R
Rafael J. Wysocki 已提交
433
 out:
434
	swsusp_close();
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
	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;
}

450
static int get_swap_reader(struct swap_map_handle *handle, sector_t start)
451 452 453
{
	int error;

454
	if (!start)
455
		return -EINVAL;
456

R
Rafael J. Wysocki 已提交
457
	handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH);
458 459
	if (!handle->cur)
		return -ENOMEM;
460 461

	error = bio_read_page(start, handle->cur, NULL);
462 463 464 465 466 467 468 469
	if (error) {
		release_swap_reader(handle);
		return error;
	}
	handle->k = 0;
	return 0;
}

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

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

A
Andrew Morton 已提交
514 515
	printk("Loading image data pages (%u pages) ...     ", nr_to_read);
	m = nr_to_read / 100;
516 517 518
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
519
	bio = NULL;
520
	do_gettimeofday(&start);
A
Andrew Morton 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
	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);
537
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
538 539
	if (!error)
		error = err2;
540
	if (!error) {
541
		printk("\b\b\b\bdone\n");
542
		snapshot_write_finalize(snapshot);
543 544 545
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
	}
546
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
	return error;
}

int swsusp_read(void)
{
	int error;
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;

	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);
	error = get_swap_reader(&handle, swsusp_header.image);
	if (!error)
A
Andrew Morton 已提交
569
		error = swap_read_page(&handle, header, NULL);
570 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);
		memset(&swsusp_header, 0, sizeof(swsusp_header));
595 596 597
		error = bio_read_page(swsusp_resume_block,
					&swsusp_header, NULL);
		if (error)
598
			return error;
599

600 601 602
		if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
			memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
			/* Reset swap signature now */
603 604
			error = bio_write_page(swsusp_resume_block,
						&swsusp_header, NULL);
605 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
		} 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);
}