1 /*
2  * This file provides functions for block I/O operations on swap/file.
3  *
4  * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz>
5  * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
6  *
7  * This file is released under the GPLv2.
8  */
9 
10 #include <linux/bio.h>
11 #include <linux/kernel.h>
12 #include <linux/pagemap.h>
13 #include <linux/swap.h>
14 
15 #include "power.h"
16 
17 /**
18  *	submit - submit BIO request.
19  *	@rw:	READ or WRITE.
20  *	@off	physical offset of page.
21  *	@page:	page we're reading or writing.
22  *	@bio_chain: list of pending biod (for async reading)
23  *
24  *	Straight from the textbook - allocate and initialize the bio.
25  *	If we're reading, make sure the page is marked as dirty.
26  *	Then submit it and, if @bio_chain == NULL, wait.
27  */
submit(int rw,struct block_device * bdev,sector_t sector,struct page * page,struct bio ** bio_chain)28 static int submit(int rw, struct block_device *bdev, sector_t sector,
29 		struct page *page, struct bio **bio_chain)
30 {
31 	const int bio_rw = rw | REQ_SYNC;
32 	struct bio *bio;
33 
34 	bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
35 	bio->bi_sector = sector;
36 	bio->bi_bdev = bdev;
37 	bio->bi_end_io = end_swap_bio_read;
38 
39 	if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
40 		printk(KERN_ERR "PM: Adding page to bio failed at %llu\n",
41 			(unsigned long long)sector);
42 		bio_put(bio);
43 		return -EFAULT;
44 	}
45 
46 	lock_page(page);
47 	bio_get(bio);
48 
49 	if (bio_chain == NULL) {
50 		submit_bio(bio_rw, bio);
51 		wait_on_page_locked(page);
52 		if (rw == READ)
53 			bio_set_pages_dirty(bio);
54 		bio_put(bio);
55 	} else {
56 		if (rw == READ)
57 			get_page(page);	/* These pages are freed later */
58 		bio->bi_private = *bio_chain;
59 		*bio_chain = bio;
60 		submit_bio(bio_rw, bio);
61 	}
62 	return 0;
63 }
64 
hib_bio_read_page(pgoff_t page_off,void * addr,struct bio ** bio_chain)65 int hib_bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain)
66 {
67 	return submit(READ, hib_resume_bdev, page_off * (PAGE_SIZE >> 9),
68 			virt_to_page(addr), bio_chain);
69 }
70 
hib_bio_write_page(pgoff_t page_off,void * addr,struct bio ** bio_chain)71 int hib_bio_write_page(pgoff_t page_off, void *addr, struct bio **bio_chain)
72 {
73 	return submit(WRITE, hib_resume_bdev, page_off * (PAGE_SIZE >> 9),
74 			virt_to_page(addr), bio_chain);
75 }
76 
hib_wait_on_bio_chain(struct bio ** bio_chain)77 int hib_wait_on_bio_chain(struct bio **bio_chain)
78 {
79 	struct bio *bio;
80 	struct bio *next_bio;
81 	int ret = 0;
82 
83 	if (bio_chain == NULL)
84 		return 0;
85 
86 	bio = *bio_chain;
87 	if (bio == NULL)
88 		return 0;
89 	while (bio) {
90 		struct page *page;
91 
92 		next_bio = bio->bi_private;
93 		page = bio->bi_io_vec[0].bv_page;
94 		wait_on_page_locked(page);
95 		if (!PageUptodate(page) || PageError(page))
96 			ret = -EIO;
97 		put_page(page);
98 		bio_put(bio);
99 		bio = next_bio;
100 	}
101 	*bio_chain = NULL;
102 	return ret;
103 }
104