swap.c 15.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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/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 29 30 31

#include "power.h"

#define SWSUSP_SIG	"S1SUSPEND"

32 33 34 35 36 37 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
/*
 *	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.
 */

#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;
};

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

static struct swsusp_header *swsusp_header;
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 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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
/**
 *	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;

	offset = swp_offset(get_swap_page_of_type(swap));
	if (offset) {
		if (swsusp_extents_insert(offset))
			swap_free(swp_entry(swap, offset));
		else
			return swapdev_block(swap, offset);
	}
	return 0;
}

/**
 *	free_all_swap_pages - free swap pages allocated for saving image data.
 *	It also frees the extents used to register which swap entres had been
 *	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++)
			swap_free(swp_entry(swap, offset));

		kfree(ext);
	}
}

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

177
/*
178
 * General things
179 180 181
 */

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

/*
 * Saving part
 */
187

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

J
Jiri Slaby 已提交
192
	hib_bio_read_page(swsusp_resume_block, swsusp_header, NULL);
193 194 195 196
	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);
197
		swsusp_header->image = handle->first_sector;
198
		swsusp_header->flags = flags;
J
Jiri Slaby 已提交
199
		error = hib_bio_write_page(swsusp_resume_block,
200
					swsusp_header, NULL);
201
	} else {
R
Rafael J. Wysocki 已提交
202
		printk(KERN_ERR "PM: Swap header not found!\n");
203 204 205 206 207 208 209 210
		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 已提交
211 212
 *
 *	This is called before saving image
213
 */
J
Jiri Slaby 已提交
214
static int swsusp_swap_check(void)
215
{
216 217
	int res;

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

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

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

	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 已提交
239
 *	@bio_chain:	Link the next write BIO here
240 241
 */

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

	if (!offset)
		return -ENOSPC;

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

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 已提交
273 274 275 276 277 278 279 280 281
	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;
	}
282
	handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL);
J
Jiri Slaby 已提交
283 284 285 286
	if (!handle->cur) {
		ret = -ENOMEM;
		goto err_close;
	}
287
	handle->cur_swap = alloc_swapdev_block(root_swap);
288
	if (!handle->cur_swap) {
J
Jiri Slaby 已提交
289 290
		ret = -ENOSPC;
		goto err_rel;
291 292
	}
	handle->k = 0;
293
	handle->first_sector = handle->cur_swap;
294
	return 0;
J
Jiri Slaby 已提交
295 296 297 298 299
err_rel:
	release_swap_writer(handle);
err_close:
	swsusp_close(FMODE_WRITE);
	return ret;
300 301
}

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

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

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

J
Jiri Slaby 已提交
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
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;
}

360 361 362 363 364 365
/**
 *	save_image - save the suspend image data
 */

static int save_image(struct swap_map_handle *handle,
                      struct snapshot_handle *snapshot,
366
                      unsigned int nr_to_write)
367 368 369
{
	unsigned int m;
	int ret;
370
	int nr_pages;
A
Andrew Morton 已提交
371 372
	int err2;
	struct bio *bio;
373 374
	struct timeval start;
	struct timeval stop;
375

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

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

R
Rafael J. Wysocki 已提交
418
	pr_debug("PM: Free swap pages: %u\n", free_swap);
419
	return free_swap > nr_pages + PAGES_FOR_IO;
420 421 422 423
}

/**
 *	swsusp_write - Write entire image and metadata.
424
 *	@flags: flags to pass to the "boot" kernel in the image header
425 426 427 428 429 430 431
 *
 *	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.)
 */

432
int swsusp_write(unsigned int flags)
433 434 435 436
{
	struct swap_map_handle handle;
	struct snapshot_handle snapshot;
	struct swsusp_info *header;
J
Jiri Slaby 已提交
437
	unsigned long pages;
438 439
	int error;

J
Jiri Slaby 已提交
440 441
	pages = snapshot_get_image_size();
	error = get_swap_writer(&handle);
442
	if (error) {
J
Jiri Slaby 已提交
443
		printk(KERN_ERR "PM: Cannot get swap writer\n");
444 445
		return error;
	}
J
Jiri Slaby 已提交
446 447 448 449 450
	if (!enough_swap(pages)) {
		printk(KERN_ERR "PM: Not enough free swap\n");
		error = -ENOSPC;
		goto out_finish;
	}
451
	memset(&snapshot, 0, sizeof(struct snapshot_handle));
J
Jiri Slaby 已提交
452
	error = snapshot_read_next(&snapshot);
453 454 455 456
	if (error < PAGE_SIZE) {
		if (error >= 0)
			error = -EFAULT;

J
Jiri Slaby 已提交
457
		goto out_finish;
458
	}
459
	header = (struct swsusp_info *)data_of(snapshot);
J
Jiri Slaby 已提交
460 461 462 463 464
	error = swap_write_page(&handle, header, NULL);
	if (!error)
		error = save_image(&handle, &snapshot, pages - 1);
out_finish:
	error = swap_writer_finish(&handle, flags, error);
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
	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 已提交
480 481
static int get_swap_reader(struct swap_map_handle *handle,
		unsigned int *flags_p)
482 483 484
{
	int error;

J
Jiri Slaby 已提交
485 486 487
	*flags_p = swsusp_header->flags;

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

R
Rafael J. Wysocki 已提交
490
	handle->cur = (struct swap_map_page *)get_zeroed_page(__GFP_WAIT | __GFP_HIGH);
491 492
	if (!handle->cur)
		return -ENOMEM;
493

J
Jiri Slaby 已提交
494
	error = hib_bio_read_page(swsusp_header->image, handle->cur, NULL);
495 496 497 498 499 500 501 502
	if (error) {
		release_swap_reader(handle);
		return error;
	}
	handle->k = 0;
	return 0;
}

A
Andrew Morton 已提交
503 504
static int swap_read_page(struct swap_map_handle *handle, void *buf,
				struct bio **bio_chain)
505
{
506
	sector_t offset;
507 508 509 510 511 512 513
	int error;

	if (!handle->cur)
		return -EINVAL;
	offset = handle->cur->entries[handle->k];
	if (!offset)
		return -EFAULT;
J
Jiri Slaby 已提交
514
	error = hib_bio_read_page(offset, buf, bio_chain);
515 516 517
	if (error)
		return error;
	if (++handle->k >= MAP_PAGE_ENTRIES) {
J
Jiri Slaby 已提交
518
		error = hib_wait_on_bio_chain(bio_chain);
519 520 521 522
		handle->k = 0;
		offset = handle->cur->next_swap;
		if (!offset)
			release_swap_reader(handle);
A
Andrew Morton 已提交
523
		else if (!error)
J
Jiri Slaby 已提交
524
			error = hib_bio_read_page(offset, handle->cur, NULL);
525 526 527 528
	}
	return error;
}

J
Jiri Slaby 已提交
529 530 531 532 533 534 535
static int swap_reader_finish(struct swap_map_handle *handle)
{
	release_swap_reader(handle);

	return 0;
}

536 537 538 539 540 541 542 543
/**
 *	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 已提交
544
                      unsigned int nr_to_read)
545 546 547
{
	unsigned int m;
	int error = 0;
548 549
	struct timeval start;
	struct timeval stop;
A
Andrew Morton 已提交
550 551 552
	struct bio *bio;
	int err2;
	unsigned nr_pages;
553

R
Rafael J. Wysocki 已提交
554 555
	printk(KERN_INFO "PM: Loading image data pages (%u pages) ...     ",
		nr_to_read);
A
Andrew Morton 已提交
556
	m = nr_to_read / 100;
557 558 559
	if (!m)
		m = 1;
	nr_pages = 0;
A
Andrew Morton 已提交
560
	bio = NULL;
561
	do_gettimeofday(&start);
A
Andrew Morton 已提交
562
	for ( ; ; ) {
J
Jiri Slaby 已提交
563
		error = snapshot_write_next(snapshot);
A
Andrew Morton 已提交
564 565 566 567 568 569
		if (error <= 0)
			break;
		error = swap_read_page(handle, data_of(*snapshot), &bio);
		if (error)
			break;
		if (snapshot->sync_read)
J
Jiri Slaby 已提交
570
			error = hib_wait_on_bio_chain(&bio);
A
Andrew Morton 已提交
571 572 573 574 575 576
		if (error)
			break;
		if (!(nr_pages % m))
			printk("\b\b\b\b%3d%%", nr_pages / m);
		nr_pages++;
	}
J
Jiri Slaby 已提交
577
	err2 = hib_wait_on_bio_chain(&bio);
578
	do_gettimeofday(&stop);
A
Andrew Morton 已提交
579 580
	if (!error)
		error = err2;
581
	if (!error) {
582
		printk("\b\b\b\bdone\n");
583
		snapshot_write_finalize(snapshot);
584 585
		if (!snapshot_image_loaded(snapshot))
			error = -ENODATA;
586 587
	} else
		printk("\n");
588
	swsusp_show_speed(&start, &stop, nr_to_read, "Read");
589 590 591
	return error;
}

592 593 594 595 596 597 598
/**
 *	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)
599 600 601 602 603 604 605
{
	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 已提交
606
	error = snapshot_write_next(&snapshot);
607 608 609
	if (error < PAGE_SIZE)
		return error < 0 ? error : -EFAULT;
	header = (struct swsusp_info *)data_of(snapshot);
J
Jiri Slaby 已提交
610 611 612
	error = get_swap_reader(&handle, flags_p);
	if (error)
		goto end;
613
	if (!error)
A
Andrew Morton 已提交
614
		error = swap_read_page(&handle, header, NULL);
615 616
	if (!error)
		error = load_image(&handle, &snapshot, header->pages - 1);
J
Jiri Slaby 已提交
617 618
	swap_reader_finish(&handle);
end:
619
	if (!error)
R
Rafael J. Wysocki 已提交
620
		pr_debug("PM: Image successfully loaded\n");
621
	else
R
Rafael J. Wysocki 已提交
622
		pr_debug("PM: Error %d resuming\n", error);
623 624 625 626 627 628 629 630 631 632 633
	return error;
}

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

int swsusp_check(void)
{
	int error;

J
Jiri Slaby 已提交
634 635 636
	hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
	if (!IS_ERR(hib_resume_bdev)) {
		set_blocksize(hib_resume_bdev, PAGE_SIZE);
637
		memset(swsusp_header, 0, PAGE_SIZE);
J
Jiri Slaby 已提交
638
		error = hib_bio_read_page(swsusp_resume_block,
639
					swsusp_header, NULL);
640
		if (error)
J
Jiri Slaby 已提交
641
			goto put;
642

643 644
		if (!memcmp(SWSUSP_SIG, swsusp_header->sig, 10)) {
			memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
645
			/* Reset swap signature now */
J
Jiri Slaby 已提交
646
			error = hib_bio_write_page(swsusp_resume_block,
647
						swsusp_header, NULL);
648
		} else {
J
Jiri Slaby 已提交
649
			error = -EINVAL;
650
		}
J
Jiri Slaby 已提交
651 652

put:
653
		if (error)
J
Jiri Slaby 已提交
654
			blkdev_put(hib_resume_bdev, FMODE_READ);
655
		else
R
Rafael J. Wysocki 已提交
656
			pr_debug("PM: Signature found, resuming\n");
657
	} else {
J
Jiri Slaby 已提交
658
		error = PTR_ERR(hib_resume_bdev);
659 660 661
	}

	if (error)
R
Rafael J. Wysocki 已提交
662
		pr_debug("PM: Error %d checking image file\n", error);
663 664 665 666 667 668 669 670

	return error;
}

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

671
void swsusp_close(fmode_t mode)
672
{
J
Jiri Slaby 已提交
673
	if (IS_ERR(hib_resume_bdev)) {
R
Rafael J. Wysocki 已提交
674
		pr_debug("PM: Image device not initialised\n");
675 676 677
		return;
	}

J
Jiri Slaby 已提交
678
	blkdev_put(hib_resume_bdev, mode);
679
}
680 681 682 683 684 685 686 687 688 689

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