This source file includes following definitions.
- show_swap_cache_info
- add_to_swap_cache
- init_swap_cache
- rw_swap_page
- get_swap_page
- swap_duplicate
- swap_free
- swap_in
- try_to_swap_out
- swap_out
- swap_out
- try_to_free_page
- add_mem_queue
- remove_mem_queue
- free_pages_ok
- free_pages
- mark_used
- __get_free_pages
- show_free_areas
- try_to_unuse
- sys_swapoff
- sys_swapon
- si_swapinfo
- free_area_init
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/mm.h>
13 #include <linux/sched.h>
14 #include <linux/head.h>
15 #include <linux/kernel.h>
16 #include <linux/kernel_stat.h>
17 #include <linux/errno.h>
18 #include <linux/string.h>
19 #include <linux/stat.h>
20 #include <linux/fs.h>
21
22 #include <asm/system.h>
23 #include <asm/bitops.h>
24
25 #define MAX_SWAPFILES 8
26
27 #define SWP_USED 1
28 #define SWP_WRITEOK 3
29
30 #define SWP_TYPE(entry) (((entry) & 0xfe) >> 1)
31 #define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT)
32 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << PAGE_SHIFT))
33
34 static int nr_swapfiles = 0;
35 static struct wait_queue * lock_queue = NULL;
36
37 static struct swap_info_struct {
38 unsigned long flags;
39 struct inode * swap_file;
40 unsigned int swap_device;
41 unsigned char * swap_map;
42 unsigned char * swap_lockmap;
43 int pages;
44 int lowest_bit;
45 int highest_bit;
46 unsigned long max;
47 } swap_info[MAX_SWAPFILES];
48
49 extern int shm_swap (int);
50
51 unsigned long *swap_cache;
52
53 #ifdef SWAP_CACHE_INFO
54 unsigned long swap_cache_add_total = 0;
55 unsigned long swap_cache_add_success = 0;
56 unsigned long swap_cache_del_total = 0;
57 unsigned long swap_cache_del_success = 0;
58 unsigned long swap_cache_find_total = 0;
59 unsigned long swap_cache_find_success = 0;
60
61 extern inline void show_swap_cache_info(void)
62 {
63 printk("Swap cache: add %ld/%ld, delete %ld/%ld, find %ld/%ld\n",
64 swap_cache_add_total, swap_cache_add_success,
65 swap_cache_del_total, swap_cache_del_success,
66 swap_cache_find_total, swap_cache_find_success);
67 }
68 #endif
69
70 extern inline int add_to_swap_cache(unsigned long addr, unsigned long entry)
71 {
72 struct swap_info_struct * p = &swap_info[SWP_TYPE(entry)];
73
74 #ifdef SWAP_CACHE_INFO
75 swap_cache_add_total++;
76 #endif
77 if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
78 __asm__ __volatile__ (
79 "xchgl %0,%1\n"
80 : "=m" (swap_cache[addr >> PAGE_SHIFT]),
81 "=r" (entry)
82 : "0" (swap_cache[addr >> PAGE_SHIFT]),
83 "1" (entry)
84 );
85 if (entry) {
86 printk("swap_cache: replacing non-NULL entry\n");
87 }
88 #ifdef SWAP_CACHE_INFO
89 swap_cache_add_success++;
90 #endif
91 return 1;
92 }
93 return 0;
94 }
95
96 static unsigned long init_swap_cache(unsigned long mem_start,
97 unsigned long mem_end)
98 {
99 unsigned long swap_cache_size;
100
101 mem_start = (mem_start + 15) & ~15;
102 swap_cache = (unsigned long *) mem_start;
103 swap_cache_size = mem_end >> PAGE_SHIFT;
104 memset(swap_cache, 0, swap_cache_size * sizeof (unsigned long));
105 #ifdef SWAP_CACHE_INFO
106 printk("%ld bytes for swap cache allocated\n",
107 swap_cache_size * sizeof(unsigned long));
108 #endif
109
110 return (unsigned long) (swap_cache + swap_cache_size);
111 }
112
113 void rw_swap_page(int rw, unsigned long entry, char * buf)
114 {
115 unsigned long type, offset;
116 struct swap_info_struct * p;
117
118 type = SWP_TYPE(entry);
119 if (type >= nr_swapfiles) {
120 printk("Internal error: bad swap-device\n");
121 return;
122 }
123 p = &swap_info[type];
124 offset = SWP_OFFSET(entry);
125 if (offset >= p->max) {
126 printk("rw_swap_page: weirdness\n");
127 return;
128 }
129 if (!(p->flags & SWP_USED)) {
130 printk("Trying to swap to unused swap-device\n");
131 return;
132 }
133 while (set_bit(offset,p->swap_lockmap))
134 sleep_on(&lock_queue);
135 if (rw == READ)
136 kstat.pswpin++;
137 else
138 kstat.pswpout++;
139 if (p->swap_device) {
140 ll_rw_page(rw,p->swap_device,offset,buf);
141 } else if (p->swap_file) {
142 struct inode *swapf = p->swap_file;
143 unsigned int zones[8];
144 int i;
145 if (swapf->i_op->bmap == NULL
146 && swapf->i_op->smap != NULL){
147
148
149
150
151
152
153
154
155
156
157
158
159 int j;
160 unsigned int block = offset << 3;
161
162 for (i=0, j=0; j< PAGE_SIZE ; i++, j += 512){
163 if (!(zones[i] = swapf->i_op->smap(swapf,block++))) {
164 printk("rw_swap_page: bad swap file\n");
165 return;
166 }
167 }
168 }else{
169 int j;
170 unsigned int block = offset
171 << (12 - swapf->i_sb->s_blocksize_bits);
172
173 for (i=0, j=0; j< PAGE_SIZE ; i++, j +=swapf->i_sb->s_blocksize)
174 if (!(zones[i] = bmap(swapf,block++))) {
175 printk("rw_swap_page: bad swap file\n");
176 return;
177 }
178 }
179 ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
180 } else
181 printk("re_swap_page: no swap file or device\n");
182 if (offset && !clear_bit(offset,p->swap_lockmap))
183 printk("rw_swap_page: lock already cleared\n");
184 wake_up(&lock_queue);
185 }
186
187 unsigned int get_swap_page(void)
188 {
189 struct swap_info_struct * p;
190 unsigned int offset, type;
191
192 p = swap_info;
193 for (type = 0 ; type < nr_swapfiles ; type++,p++) {
194 if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK)
195 continue;
196 for (offset = p->lowest_bit; offset <= p->highest_bit ; offset++) {
197 if (p->swap_map[offset])
198 continue;
199 p->swap_map[offset] = 1;
200 nr_swap_pages--;
201 if (offset == p->highest_bit)
202 p->highest_bit--;
203 p->lowest_bit = offset;
204 return SWP_ENTRY(type,offset);
205 }
206 }
207 return 0;
208 }
209
210 unsigned long swap_duplicate(unsigned long entry)
211 {
212 struct swap_info_struct * p;
213 unsigned long offset, type;
214
215 if (!entry)
216 return 0;
217 offset = SWP_OFFSET(entry);
218 type = SWP_TYPE(entry);
219 if (type == SHM_SWP_TYPE)
220 return entry;
221 if (type >= nr_swapfiles) {
222 printk("Trying to duplicate nonexistent swap-page\n");
223 return 0;
224 }
225 p = type + swap_info;
226 if (offset >= p->max) {
227 printk("swap_duplicate: weirdness\n");
228 return 0;
229 }
230 if (!p->swap_map[offset]) {
231 printk("swap_duplicate: trying to duplicate unused page\n");
232 return 0;
233 }
234 p->swap_map[offset]++;
235 return entry;
236 }
237
238 void swap_free(unsigned long entry)
239 {
240 struct swap_info_struct * p;
241 unsigned long offset, type;
242
243 if (!entry)
244 return;
245 type = SWP_TYPE(entry);
246 if (type == SHM_SWP_TYPE)
247 return;
248 if (type >= nr_swapfiles) {
249 printk("Trying to free nonexistent swap-page\n");
250 return;
251 }
252 p = & swap_info[type];
253 offset = SWP_OFFSET(entry);
254 if (offset >= p->max) {
255 printk("swap_free: weirdness\n");
256 return;
257 }
258 if (!(p->flags & SWP_USED)) {
259 printk("Trying to free swap from unused swap-device\n");
260 return;
261 }
262 while (set_bit(offset,p->swap_lockmap))
263 sleep_on(&lock_queue);
264 if (offset < p->lowest_bit)
265 p->lowest_bit = offset;
266 if (offset > p->highest_bit)
267 p->highest_bit = offset;
268 if (!p->swap_map[offset])
269 printk("swap_free: swap-space map bad (entry %08lx)\n",entry);
270 else
271 if (!--p->swap_map[offset])
272 nr_swap_pages++;
273 if (!clear_bit(offset,p->swap_lockmap))
274 printk("swap_free: lock already cleared\n");
275 wake_up(&lock_queue);
276 }
277
278 unsigned long swap_in(unsigned long entry)
279 {
280 unsigned long page;
281
282 if (!(page = get_free_page(GFP_KERNEL))) {
283 oom(current);
284 return BAD_PAGE;
285 }
286 read_swap_page(entry, (char *) page);
287 if (add_to_swap_cache(page, entry))
288 return page | PAGE_PRIVATE;
289 swap_free(entry);
290 return page | PAGE_DIRTY | PAGE_PRIVATE;
291 }
292
293 static inline int try_to_swap_out(unsigned long * table_ptr)
294 {
295 unsigned long page, entry;
296
297 page = *table_ptr;
298 if (!(PAGE_PRESENT & page))
299 return 0;
300 if (page >= high_memory)
301 return 0;
302 if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
303 return 0;
304
305 if ((PAGE_DIRTY & page) && delete_from_swap_cache(page)) {
306 return 0;
307 }
308 if (PAGE_ACCESSED & page) {
309 *table_ptr &= ~PAGE_ACCESSED;
310 return 0;
311 }
312 if (PAGE_DIRTY & page) {
313 page &= PAGE_MASK;
314 if (mem_map[MAP_NR(page)] != 1)
315 return 0;
316 if (!(entry = get_swap_page()))
317 return 0;
318 *table_ptr = entry;
319 invalidate();
320 write_swap_page(entry, (char *) page);
321 free_page(page);
322 return 1;
323 }
324
325 if ((entry = find_in_swap_cache(page))) {
326 if (mem_map[MAP_NR(page)] != 1) {
327 *table_ptr |= PAGE_DIRTY;
328 printk("Aiee.. duplicated cached swap-cache entry\n");
329 return 0;
330 }
331 *table_ptr = entry;
332 invalidate();
333 free_page(page & PAGE_MASK);
334 return 1;
335 }
336 page &= PAGE_MASK;
337 *table_ptr = 0;
338 invalidate();
339 free_page(page);
340 return 1 + mem_map[MAP_NR(page)];
341 }
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356 #ifdef NEW_SWAP
357
358
359
360
361 #define SWAP_MIN 4
362 #define SWAP_MAX 32
363
364
365
366
367
368 #define SWAP_RATIO 128
369
370 static int swap_out(unsigned int priority)
371 {
372 static int swap_task;
373 int table;
374 int page;
375 long pg_table;
376 int loop;
377 int counter = NR_TASKS * 2 >> priority;
378 struct task_struct *p;
379
380 counter = NR_TASKS * 2 >> priority;
381 for(; counter >= 0; counter--, swap_task++) {
382
383
384
385
386 loop = 0;
387 while(1) {
388 if(swap_task >= NR_TASKS) {
389 swap_task = 1;
390 if(loop)
391
392 return 0;
393 loop = 1;
394 }
395
396 p = task[swap_task];
397 if(p && p->mm->swappable && p->mm->rss)
398 break;
399
400 swap_task++;
401 }
402
403
404
405
406 if(! p->mm->swap_cnt) {
407 p->mm->dec_flt = (p->mm->dec_flt * 3) / 4 + p->mm->maj_flt - p->mm->old_maj_flt;
408 p->mm->old_maj_flt = p->mm->maj_flt;
409
410 if(p->mm->dec_flt >= SWAP_RATIO / SWAP_MIN) {
411 p->mm->dec_flt = SWAP_RATIO / SWAP_MIN;
412 p->mm->swap_cnt = SWAP_MIN;
413 } else if(p->mm->dec_flt <= SWAP_RATIO / SWAP_MAX)
414 p->mm->swap_cnt = SWAP_MAX;
415 else
416 p->mm->swap_cnt = SWAP_RATIO / p->mm->dec_flt;
417 }
418
419
420
421
422 for(table = p->mm->swap_table; table < 1024; table++) {
423 pg_table = ((unsigned long *) p->tss.cr3)[table];
424 if(pg_table >= high_memory)
425 continue;
426 if(mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)
427 continue;
428 if(!(PAGE_PRESENT & pg_table)) {
429 printk("swap_out: bad page-table at pg_dir[%d]: %08lx\n",
430 table, pg_table);
431 ((unsigned long *) p->tss.cr3)[table] = 0;
432 continue;
433 }
434 pg_table &= 0xfffff000;
435
436
437
438
439 for(page = p->mm->swap_page; page < 1024; page++) {
440 switch(try_to_swap_out(page + (unsigned long *) pg_table)) {
441 case 0:
442 break;
443
444 case 1:
445 p->mm->rss--;
446
447 p->mm->swap_table = table;
448 p->mm->swap_page = page + 1;
449 if((--p->mm->swap_cnt) == 0)
450 swap_task++;
451 return 1;
452
453 default:
454 p->mm->rss--;
455 break;
456 }
457 }
458
459 p->mm->swap_page = 0;
460 }
461
462
463
464
465
466 p->mm->swap_table = 0;
467 }
468 return 0;
469 }
470
471 #else
472
473
474
475
476
477
478
479
480
481 static int swap_out(unsigned int priority)
482 {
483 static int swap_task = 1;
484 static int swap_table = 0;
485 static int swap_page = 0;
486 int counter = NR_TASKS*8;
487 int pg_table;
488 struct task_struct * p;
489
490 counter >>= priority;
491 check_task:
492 if (counter-- < 0)
493 return 0;
494 if (swap_task >= NR_TASKS) {
495 swap_task = 1;
496 goto check_task;
497 }
498 p = task[swap_task];
499 if (!p || !p->mm->swappable) {
500 swap_task++;
501 goto check_task;
502 }
503 check_dir:
504 if (swap_table >= PTRS_PER_PAGE) {
505 swap_table = 0;
506 swap_task++;
507 goto check_task;
508 }
509 pg_table = ((unsigned long *) p->tss.cr3)[swap_table];
510 if (pg_table >= high_memory || (mem_map[MAP_NR(pg_table)] & MAP_PAGE_RESERVED)) {
511 swap_table++;
512 goto check_dir;
513 }
514 if (!(PAGE_PRESENT & pg_table)) {
515 printk("bad page-table at pg_dir[%d]: %08x\n",
516 swap_table,pg_table);
517 ((unsigned long *) p->tss.cr3)[swap_table] = 0;
518 swap_table++;
519 goto check_dir;
520 }
521 pg_table &= PAGE_MASK;
522 check_table:
523 if (swap_page >= PTRS_PER_PAGE) {
524 swap_page = 0;
525 swap_table++;
526 goto check_dir;
527 }
528 switch (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
529 case 0: break;
530 case 1: p->mm->rss--; return 1;
531 default: p->mm->rss--;
532 }
533 swap_page++;
534 goto check_table;
535 }
536
537 #endif
538
539 static int try_to_free_page(int priority)
540 {
541 int i=6;
542
543 while (i--) {
544 if (priority != GFP_NOBUFFER && shrink_buffers(i))
545 return 1;
546 if (shm_swap(i))
547 return 1;
548 if (swap_out(i))
549 return 1;
550 }
551 return 0;
552 }
553
554 static inline void add_mem_queue(struct mem_list * head, struct mem_list * entry)
555 {
556 entry->prev = head;
557 entry->next = head->next;
558 entry->next->prev = entry;
559 head->next = entry;
560 }
561
562 static inline void remove_mem_queue(struct mem_list * head, struct mem_list * entry)
563 {
564 entry->next->prev = entry->prev;
565 entry->prev->next = entry->next;
566 }
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583 static inline void free_pages_ok(unsigned long addr, unsigned long order)
584 {
585 unsigned long index = addr >> (PAGE_SHIFT + 1 + order);
586 unsigned long mask = PAGE_MASK << order;
587
588 addr &= mask;
589 nr_free_pages += 1 << order;
590 while (order < NR_MEM_LISTS-1) {
591 if (!change_bit(index, free_area_map[order]))
592 break;
593 remove_mem_queue(free_area_list+order, (struct mem_list *) (addr ^ (1+~mask)));
594 order++;
595 index >>= 1;
596 mask <<= 1;
597 addr &= mask;
598 }
599 add_mem_queue(free_area_list+order, (struct mem_list *) addr);
600 }
601
602 void free_pages(unsigned long addr, unsigned long order)
603 {
604 if (addr < high_memory) {
605 unsigned long flag;
606 unsigned short * map = mem_map + MAP_NR(addr);
607 if (*map) {
608 if (!(*map & MAP_PAGE_RESERVED)) {
609 save_flags(flag);
610 cli();
611 if (!--*map) {
612 free_pages_ok(addr, order);
613 delete_from_swap_cache(addr);
614 }
615 restore_flags(flag);
616 if(*map == 1) {
617 int j;
618 struct buffer_head * bh, *tmp;
619
620 bh = buffer_pages[MAP_NR(addr)];
621 if(bh)
622 for(j = 0, tmp = bh; tmp && (!j || tmp != bh);
623 tmp = tmp->b_this_page, j++)
624 if(tmp->b_list == BUF_SHARED && tmp->b_dev != 0xffff)
625 refile_buffer(tmp);
626 }
627 }
628 return;
629 }
630 printk("Trying to free free memory (%08lx): memory probabably corrupted\n",addr);
631 printk("PC = %08lx\n",*(((unsigned long *)&addr)-1));
632 return;
633 }
634 }
635
636
637
638
639 #define RMQUEUE(order) \
640 do { struct mem_list * queue = free_area_list+order; \
641 unsigned long new_order = order; \
642 do { struct mem_list *next = queue->next; \
643 if (queue != next) { \
644 queue->next = next->next; \
645 next->next->prev = queue; \
646 mark_used((unsigned long) next, new_order); \
647 nr_free_pages -= 1 << order; \
648 restore_flags(flags); \
649 EXPAND(next, order, new_order); \
650 return (unsigned long) next; \
651 } new_order++; queue++; \
652 } while (new_order < NR_MEM_LISTS); \
653 } while (0)
654
655 static inline int mark_used(unsigned long addr, unsigned long order)
656 {
657 return change_bit(addr >> (PAGE_SHIFT+1+order), free_area_map[order]);
658 }
659
660 #define EXPAND(addr,low,high) \
661 do { unsigned long size = PAGE_SIZE << high; \
662 while (high > low) { \
663 high--; size >>= 1; cli(); \
664 add_mem_queue(free_area_list+high, addr); \
665 mark_used((unsigned long) addr, high); \
666 restore_flags(flags); \
667 addr = (struct mem_list *) (size + (unsigned long) addr); \
668 } mem_map[MAP_NR((unsigned long) addr)] = 1; \
669 } while (0)
670
671 unsigned long __get_free_pages(int priority, unsigned long order)
672 {
673 unsigned long flags;
674
675 if (intr_count && priority != GFP_ATOMIC) {
676 static int count = 0;
677 if (++count < 5) {
678 printk("gfp called nonatomically from interrupt %08lx\n",
679 ((unsigned long *)&priority)[-1]);
680 priority = GFP_ATOMIC;
681 }
682 }
683 save_flags(flags);
684 repeat:
685 cli();
686 if ((priority==GFP_ATOMIC) || nr_free_pages > MAX_SECONDARY_PAGES) {
687 RMQUEUE(order);
688 restore_flags(flags);
689 return 0;
690 }
691 restore_flags(flags);
692 if (priority != GFP_BUFFER && try_to_free_page(priority))
693 goto repeat;
694 return 0;
695 }
696
697
698
699
700
701
702 void show_free_areas(void)
703 {
704 unsigned long order, flags;
705 unsigned long total = 0;
706
707 printk("Free pages: %6dkB\n ( ",nr_free_pages<<(PAGE_SHIFT-10));
708 save_flags(flags);
709 cli();
710 for (order=0 ; order < NR_MEM_LISTS; order++) {
711 struct mem_list * tmp;
712 unsigned long nr = 0;
713 for (tmp = free_area_list[order].next ; tmp != free_area_list + order ; tmp = tmp->next) {
714 nr ++;
715 }
716 total += nr * (4 << order);
717 printk("%lu*%ukB ", nr, 4 << order);
718 }
719 restore_flags(flags);
720 printk("= %lukB)\n", total);
721 #ifdef SWAP_CACHE_INFO
722 show_swap_cache_info();
723 #endif
724 }
725
726
727
728
729
730
731 static int try_to_unuse(unsigned int type)
732 {
733 int nr, pgt, pg;
734 unsigned long page, *ppage;
735 unsigned long tmp = 0;
736 struct task_struct *p;
737
738 nr = 0;
739
740
741
742
743
744 repeat:
745 for (; nr < NR_TASKS ; nr++) {
746 p = task[nr];
747 if (!p)
748 continue;
749 for (pgt = 0 ; pgt < PTRS_PER_PAGE ; pgt++) {
750 ppage = pgt + ((unsigned long *) p->tss.cr3);
751 page = *ppage;
752 if (!page)
753 continue;
754 if (!(page & PAGE_PRESENT) || (page >= high_memory))
755 continue;
756 if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
757 continue;
758 ppage = (unsigned long *) (page & PAGE_MASK);
759 for (pg = 0 ; pg < PTRS_PER_PAGE ; pg++,ppage++) {
760 page = *ppage;
761 if (!page)
762 continue;
763 if (page & PAGE_PRESENT) {
764 if (!(page = in_swap_cache(page)))
765 continue;
766 if (SWP_TYPE(page) != type)
767 continue;
768 *ppage |= PAGE_DIRTY;
769 delete_from_swap_cache(*ppage);
770 continue;
771 }
772 if (SWP_TYPE(page) != type)
773 continue;
774 if (!tmp) {
775 if (!(tmp = __get_free_page(GFP_KERNEL)))
776 return -ENOMEM;
777 goto repeat;
778 }
779 read_swap_page(page, (char *) tmp);
780 if (*ppage == page) {
781 *ppage = tmp | (PAGE_DIRTY | PAGE_PRIVATE);
782 ++p->mm->rss;
783 swap_free(page);
784 tmp = 0;
785 }
786 goto repeat;
787 }
788 }
789 }
790 free_page(tmp);
791 return 0;
792 }
793
794 asmlinkage int sys_swapoff(const char * specialfile)
795 {
796 struct swap_info_struct * p;
797 struct inode * inode;
798 unsigned int type;
799 int i;
800
801 if (!suser())
802 return -EPERM;
803 i = namei(specialfile,&inode);
804 if (i)
805 return i;
806 p = swap_info;
807 for (type = 0 ; type < nr_swapfiles ; type++,p++) {
808 if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK)
809 continue;
810 if (p->swap_file) {
811 if (p->swap_file == inode)
812 break;
813 } else {
814 if (!S_ISBLK(inode->i_mode))
815 continue;
816 if (p->swap_device == inode->i_rdev)
817 break;
818 }
819 }
820 iput(inode);
821 if (type >= nr_swapfiles)
822 return -EINVAL;
823 p->flags = SWP_USED;
824 i = try_to_unuse(type);
825 if (i) {
826 p->flags = SWP_WRITEOK;
827 return i;
828 }
829 nr_swap_pages -= p->pages;
830 iput(p->swap_file);
831 p->swap_file = NULL;
832 p->swap_device = 0;
833 vfree(p->swap_map);
834 p->swap_map = NULL;
835 free_page((long) p->swap_lockmap);
836 p->swap_lockmap = NULL;
837 p->flags = 0;
838 return 0;
839 }
840
841
842
843
844
845
846 asmlinkage int sys_swapon(const char * specialfile)
847 {
848 struct swap_info_struct * p;
849 struct inode * swap_inode;
850 unsigned int type;
851 int i,j;
852 int error;
853
854 if (!suser())
855 return -EPERM;
856 p = swap_info;
857 for (type = 0 ; type < nr_swapfiles ; type++,p++)
858 if (!(p->flags & SWP_USED))
859 break;
860 if (type >= MAX_SWAPFILES)
861 return -EPERM;
862 if (type >= nr_swapfiles)
863 nr_swapfiles = type+1;
864 p->flags = SWP_USED;
865 p->swap_file = NULL;
866 p->swap_device = 0;
867 p->swap_map = NULL;
868 p->swap_lockmap = NULL;
869 p->lowest_bit = 0;
870 p->highest_bit = 0;
871 p->max = 1;
872 error = namei(specialfile,&swap_inode);
873 if (error)
874 goto bad_swap;
875 p->swap_file = swap_inode;
876 error = -EBUSY;
877 if (swap_inode->i_count != 1)
878 goto bad_swap;
879 error = -EINVAL;
880 if (S_ISBLK(swap_inode->i_mode)) {
881 p->swap_device = swap_inode->i_rdev;
882 p->swap_file = NULL;
883 iput(swap_inode);
884 error = -ENODEV;
885 if (!p->swap_device)
886 goto bad_swap;
887 error = -EBUSY;
888 for (i = 0 ; i < nr_swapfiles ; i++) {
889 if (i == type)
890 continue;
891 if (p->swap_device == swap_info[i].swap_device)
892 goto bad_swap;
893 }
894 } else if (!S_ISREG(swap_inode->i_mode))
895 goto bad_swap;
896 p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
897 if (!p->swap_lockmap) {
898 printk("Unable to start swapping: out of memory :-)\n");
899 error = -ENOMEM;
900 goto bad_swap;
901 }
902 read_swap_page(SWP_ENTRY(type,0), (char *) p->swap_lockmap);
903 if (memcmp("SWAP-SPACE",p->swap_lockmap+4086,10)) {
904 printk("Unable to find swap-space signature\n");
905 error = -EINVAL;
906 goto bad_swap;
907 }
908 memset(p->swap_lockmap+PAGE_SIZE-10,0,10);
909 j = 0;
910 p->lowest_bit = 0;
911 p->highest_bit = 0;
912 for (i = 1 ; i < 8*PAGE_SIZE ; i++) {
913 if (test_bit(i,p->swap_lockmap)) {
914 if (!p->lowest_bit)
915 p->lowest_bit = i;
916 p->highest_bit = i;
917 p->max = i+1;
918 j++;
919 }
920 }
921 if (!j) {
922 printk("Empty swap-file\n");
923 error = -EINVAL;
924 goto bad_swap;
925 }
926 p->swap_map = (unsigned char *) vmalloc(p->max);
927 if (!p->swap_map) {
928 error = -ENOMEM;
929 goto bad_swap;
930 }
931 for (i = 1 ; i < p->max ; i++) {
932 if (test_bit(i,p->swap_lockmap))
933 p->swap_map[i] = 0;
934 else
935 p->swap_map[i] = 0x80;
936 }
937 p->swap_map[0] = 0x80;
938 memset(p->swap_lockmap,0,PAGE_SIZE);
939 p->flags = SWP_WRITEOK;
940 p->pages = j;
941 nr_swap_pages += j;
942 printk("Adding Swap: %dk swap-space\n",j<<2);
943 return 0;
944 bad_swap:
945 free_page((long) p->swap_lockmap);
946 vfree(p->swap_map);
947 iput(p->swap_file);
948 p->swap_device = 0;
949 p->swap_file = NULL;
950 p->swap_map = NULL;
951 p->swap_lockmap = NULL;
952 p->flags = 0;
953 return error;
954 }
955
956 void si_swapinfo(struct sysinfo *val)
957 {
958 unsigned int i, j;
959
960 val->freeswap = val->totalswap = 0;
961 for (i = 0; i < nr_swapfiles; i++) {
962 if ((swap_info[i].flags & SWP_WRITEOK) != SWP_WRITEOK)
963 continue;
964 for (j = 0; j < swap_info[i].max; ++j)
965 switch (swap_info[i].swap_map[j]) {
966 case 128:
967 continue;
968 case 0:
969 ++val->freeswap;
970 default:
971 ++val->totalswap;
972 }
973 }
974 val->freeswap <<= PAGE_SHIFT;
975 val->totalswap <<= PAGE_SHIFT;
976 return;
977 }
978
979
980
981
982
983
984
985 unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem)
986 {
987 unsigned short * p;
988 unsigned long mask = PAGE_MASK;
989 int i;
990
991 start_mem = init_swap_cache(start_mem, end_mem);
992 mem_map = (unsigned short *) start_mem;
993 p = mem_map + MAP_NR(end_mem);
994 start_mem = (unsigned long) p;
995 while (p > mem_map)
996 *--p = MAP_PAGE_RESERVED;
997
998 for (i = 0 ; i < NR_MEM_LISTS ; i++, mask <<= 1) {
999 unsigned long bitmap_size;
1000 free_area_list[i].prev = free_area_list[i].next = &free_area_list[i];
1001 end_mem = (end_mem + ~mask) & mask;
1002 bitmap_size = end_mem >> (PAGE_SHIFT + i);
1003 bitmap_size = (bitmap_size + 7) >> 3;
1004 free_area_map[i] = (unsigned char *) start_mem;
1005 memset((void *) start_mem, 0, bitmap_size);
1006 start_mem += bitmap_size;
1007 }
1008 return start_mem;
1009 }