1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/mm.h>
14#include <linux/kernel_stat.h>
15#include <linux/pagemap.h>
16#include <linux/swap.h>
17#include <linux/bio.h>
18#include <linux/swapops.h>
19#include <linux/buffer_head.h>
20#include <linux/mpage.h>
21#include <asm/pgtable.h>
22
23static struct bio *
24get_swap_bio(int gfp_flags, struct page *page, bio_end_io_t end_io)
25{
26 struct bio *bio;
27
28 bio = bio_alloc(gfp_flags, 1);
29 if (bio) {
30 struct swap_info_struct *sis;
31 swp_entry_t entry;
32
33 entry.val = page->index;
34 sis = get_swap_info_struct(swp_type(entry));
35
36 bio->bi_sector = map_swap_page(sis, swp_offset(entry)) *
37 (PAGE_SIZE >> 9);
38 bio->bi_bdev = sis->bdev;
39 bio->bi_io_vec[0].bv_page = page;
40 bio->bi_io_vec[0].bv_len = PAGE_SIZE;
41 bio->bi_io_vec[0].bv_offset = 0;
42 bio->bi_vcnt = 1;
43 bio->bi_idx = 0;
44 bio->bi_size = PAGE_SIZE;
45 bio->bi_end_io = end_io;
46 }
47 return bio;
48}
49
50static int end_swap_bio_write(struct bio *bio, unsigned int bytes_done, int err)
51{
52 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
53 struct page *page = bio->bi_io_vec[0].bv_page;
54
55 if (bio->bi_size)
56 return 1;
57
58 if (!uptodate)
59 SetPageError(page);
60 end_page_writeback(page);
61 bio_put(bio);
62 return 0;
63}
64
65static int end_swap_bio_read(struct bio *bio, unsigned int bytes_done, int err)
66{
67 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
68 struct page *page = bio->bi_io_vec[0].bv_page;
69
70 if (bio->bi_size)
71 return 1;
72
73 if (!uptodate) {
74 SetPageError(page);
75 ClearPageUptodate(page);
76 } else {
77 SetPageUptodate(page);
78 }
79 unlock_page(page);
80 bio_put(bio);
81 return 0;
82}
83
84
85
86
87
88int swap_writepage(struct page *page)
89{
90 struct bio *bio;
91 int ret = 0;
92
93 if (remove_exclusive_swap_page(page)) {
94 unlock_page(page);
95 goto out;
96 }
97 bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write);
98 if (bio == NULL) {
99 set_page_dirty(page);
100 ret = -ENOMEM;
101 goto out;
102 }
103 kstat.pswpout++;
104 SetPageWriteback(page);
105 unlock_page(page);
106 submit_bio(WRITE, bio);
107out:
108 return ret;
109}
110
111int swap_readpage(struct file *file, struct page *page)
112{
113 struct bio *bio;
114 int ret = 0;
115
116 ClearPageUptodate(page);
117 bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read);
118 if (bio == NULL) {
119 ret = -ENOMEM;
120 goto out;
121 }
122 kstat.pswpin++;
123 submit_bio(READ, bio);
124out:
125 return ret;
126}
127
128
129
130
131
132
133
134static int swap_vm_writeback(struct page *page, struct writeback_control *wbc)
135{
136 struct address_space *mapping = page->mapping;
137
138 unlock_page(page);
139 return generic_writepages(mapping, wbc);
140}
141
142struct address_space_operations swap_aops = {
143 .vm_writeback = swap_vm_writeback,
144 .writepage = swap_writepage,
145 .readpage = swap_readpage,
146 .sync_page = block_sync_page,
147 .set_page_dirty = __set_page_dirty_nobuffers,
148};
149
150
151
152
153
154int rw_swap_page_sync(int rw, swp_entry_t entry, struct page *page)
155{
156 int ret;
157
158 lock_page(page);
159
160 BUG_ON(page->mapping);
161 page->mapping = &swapper_space;
162 page->index = entry.val;
163
164 if (rw == READ) {
165 ret = swap_readpage(NULL, page);
166 wait_on_page_locked(page);
167 } else {
168 ret = swap_writepage(page);
169 wait_on_page_writeback(page);
170 }
171 page->mapping = NULL;
172 if (ret == 0 && (!PageUptodate(page) || PageError(page)))
173 ret = -EIO;
174 return ret;
175}
176