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