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/swap.h>
16#include <linux/locks.h>
17#include <linux/swapctl.h>
18
19#include <asm/pgtable.h>
20
21static struct wait_queue * lock_queue = NULL;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait)
39{
40 unsigned long type, offset;
41 struct swap_info_struct * p;
42 int zones[PAGE_SIZE/512];
43 int zones_used;
44 kdev_t dev = 0;
45 int block_size;
46
47#ifdef DEBUG_SWAP
48 printk ("DebugVM: %s_swap_page entry %08lx, page %p (count %d), %s\n",
49 (rw == READ) ? "read" : "write",
50 entry, (char *) page_address(page), atomic_read(&page->count),
51 wait ? "wait" : "nowait");
52#endif
53
54 type = SWP_TYPE(entry);
55 if (type >= nr_swapfiles) {
56 printk("Internal error: bad swap-device\n");
57 return;
58 }
59
60
61 if (atomic_read(&nr_async_pages) > pager_daemon.swap_cluster)
62 wait = 1;
63
64 p = &swap_info[type];
65 offset = SWP_OFFSET(entry);
66 if (offset >= p->max) {
67 printk("rw_swap_page: weirdness\n");
68 return;
69 }
70 if (p->swap_map && !p->swap_map[offset]) {
71 printk(KERN_ERR "rw_swap_page: "
72 "Trying to %s unallocated swap (%08lx)\n",
73 (rw == READ) ? "read" : "write", entry);
74 return;
75 }
76 if (!(p->flags & SWP_USED)) {
77 printk(KERN_ERR "rw_swap_page: "
78 "Trying to swap to unused swap-device\n");
79 return;
80 }
81
82 if (!PageLocked(page)) {
83 printk(KERN_ERR "VM: swap page is unlocked\n");
84 return;
85 }
86
87 if (PageSwapCache(page)) {
88
89 if (test_and_set_bit(offset, p->swap_lockmap))
90 {
91 struct wait_queue __wait;
92
93 __wait.task = current;
94 add_wait_queue(&lock_queue, &__wait);
95 for (;;) {
96 current->state = TASK_UNINTERRUPTIBLE;
97 mb();
98 if (!test_and_set_bit(offset, p->swap_lockmap))
99 break;
100 run_task_queue(&tq_disk);
101 schedule();
102 }
103 current->state = TASK_RUNNING;
104 remove_wait_queue(&lock_queue, &__wait);
105 }
106
107
108
109
110
111
112
113
114
115 if (page->offset != entry) {
116 printk ("swap entry mismatch");
117 return;
118 }
119 }
120 if (rw == READ) {
121 clear_bit(PG_uptodate, &page->flags);
122 kstat.pswpin++;
123 } else
124 kstat.pswpout++;
125
126 atomic_inc(&page->count);
127 if (p->swap_device) {
128 zones[0] = offset;
129 zones_used = 1;
130 dev = p->swap_device;
131 block_size = PAGE_SIZE;
132 } else if (p->swap_file) {
133 struct inode *swapf = p->swap_file->d_inode;
134 int i;
135 if (swapf->i_op->bmap == NULL
136 && swapf->i_op->smap != NULL){
137
138
139
140
141
142
143
144
145
146
147
148
149 int j;
150 unsigned int block = offset << 3;
151
152 for (i=0, j=0; j< PAGE_SIZE ; i++, j += 512){
153 if (!(zones[i] = swapf->i_op->smap(swapf,block++))) {
154 printk("rw_swap_page: bad swap file\n");
155 return;
156 }
157 }
158 block_size = 512;
159 }else{
160 int j;
161 unsigned int block = offset
162 << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
163
164 block_size = swapf->i_sb->s_blocksize;
165 for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size)
166 if (!(zones[i] = bmap(swapf,block++))) {
167 printk("rw_swap_page: bad swap file\n");
168 return;
169 }
170 zones_used = i;
171 dev = swapf->i_dev;
172 }
173 } else {
174 printk(KERN_ERR "rw_swap_page: no swap file or device\n");
175
176
177
178 if (PageSwapCache(page)) {
179 if (!test_and_clear_bit(offset,p->swap_lockmap))
180 printk("swap_after_unlock_page: lock already cleared\n");
181 wake_up(&lock_queue);
182 }
183 atomic_dec(&page->count);
184 return;
185 }
186 if (!wait) {
187 set_bit(PG_decr_after, &page->flags);
188 atomic_inc(&nr_async_pages);
189 }
190 if (PageSwapCache(page)) {
191
192 set_bit(PG_swap_unlock_after, &page->flags);
193 }
194 set_bit(PG_free_after, &page->flags);
195
196
197 brw_page(rw, page, dev, zones, block_size, 0);
198
199
200
201
202
203 if (!wait)
204 return;
205 wait_on_page(page);
206
207 if (atomic_read(&page->count) == 0)
208 printk(KERN_ERR "rw_swap_page: page unused while waiting!\n");
209
210#ifdef DEBUG_SWAP
211 printk ("DebugVM: %s_swap_page finished on page %p (count %d)\n",
212 (rw == READ) ? "read" : "write",
213 (char *) page_adddress(page),
214 atomic_read(&page->count));
215#endif
216}
217
218
219
220
221
222
223
224
225void swap_after_unlock_page (unsigned long entry)
226{
227 unsigned long type, offset;
228 struct swap_info_struct * p;
229
230 type = SWP_TYPE(entry);
231 if (type >= nr_swapfiles) {
232 printk("swap_after_unlock_page: bad swap-device\n");
233 return;
234 }
235 p = &swap_info[type];
236 offset = SWP_OFFSET(entry);
237 if (offset >= p->max) {
238 printk("swap_after_unlock_page: weirdness\n");
239 return;
240 }
241 if (!test_and_clear_bit(offset,p->swap_lockmap))
242 printk("swap_after_unlock_page: lock already cleared\n");
243 wake_up(&lock_queue);
244}
245
246
247
248
249void rw_swap_page(int rw, unsigned long entry, char *buf, int wait)
250{
251 struct page *page = mem_map + MAP_NR(buf);
252
253 if (page->inode && page->inode != &swapper_inode)
254 panic ("Tried to swap a non-swapper page");
255
256
257
258
259
260
261
262
263
264 if (!PageSwapCache(page)) {
265 printk("VM: swap page is not in swap cache\n");
266 return;
267 }
268 if (page->offset != entry) {
269 printk ("swap entry mismatch");
270 return;
271 }
272 rw_swap_page_base(rw, entry, page, wait);
273}
274
275
276
277
278
279void rw_swap_page_nocache(int rw, unsigned long entry, char *buffer)
280{
281 struct page *page;
282
283 page = mem_map + MAP_NR((unsigned long) buffer);
284 wait_on_page(page);
285 set_bit(PG_locked, &page->flags);
286 if (test_and_set_bit(PG_swap_cache, &page->flags)) {
287 printk ("VM: read_swap_page: page already in swap cache!\n");
288 return;
289 }
290 if (page->inode) {
291 printk ("VM: read_swap_page: page already in page cache!\n");
292 return;
293 }
294 page->inode = &swapper_inode;
295 page->offset = entry;
296 atomic_inc(&page->count);
297 rw_swap_page(rw, entry, buffer, 1);
298 atomic_dec(&page->count);
299 page->inode = 0;
300 clear_bit(PG_swap_cache, &page->flags);
301}
302
303
304
305
306
307
308
309void rw_swap_page_nolock(int rw, unsigned long entry, char *buffer, int wait)
310{
311 struct page *page = mem_map + MAP_NR((unsigned long) buffer);
312
313 if (!PageLocked(page)) {
314 printk("VM: rw_swap_page_nolock: page not locked!\n");
315 return;
316 }
317 if (PageSwapCache(page)) {
318 printk ("VM: rw_swap_page_nolock: page in swap cache!\n");
319 return;
320 }
321 rw_swap_page_base(rw, entry, page, wait);
322}
323