Root/
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 | */ |
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 | REQ_UNPLUG; |
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 | |
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 | |
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 | |
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 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9