~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/mm/swapfile.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/mm/swapfile.c
  3  *
  4  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  5  *  Swap reorganised 29.12.95, Stephen Tweedie
  6  */
  7 
  8 #include <linux/malloc.h>
  9 #include <linux/smp_lock.h>
 10 #include <linux/kernel_stat.h>
 11 #include <linux/swap.h>
 12 #include <linux/swapctl.h>
 13 #include <linux/blkdev.h> /* for blk_size */
 14 #include <linux/vmalloc.h>
 15 #include <linux/pagemap.h>
 16 #include <linux/shm.h>
 17 
 18 #include <asm/pgtable.h>
 19 
 20 spinlock_t swaplock = SPIN_LOCK_UNLOCKED;
 21 unsigned int nr_swapfiles;
 22 
 23 struct swap_list_t swap_list = {-1, -1};
 24 
 25 struct swap_info_struct swap_info[MAX_SWAPFILES];
 26 
 27 #define SWAPFILE_CLUSTER 256
 28 
 29 static inline int scan_swap_map(struct swap_info_struct *si, unsigned short count)
 30 {
 31         unsigned long offset;
 32         /* 
 33          * We try to cluster swap pages by allocating them
 34          * sequentially in swap.  Once we've allocated
 35          * SWAPFILE_CLUSTER pages this way, however, we resort to
 36          * first-free allocation, starting a new cluster.  This
 37          * prevents us from scattering swap pages all over the entire
 38          * swap partition, so that we reduce overall disk seek times
 39          * between swap pages.  -- sct */
 40         if (si->cluster_nr) {
 41                 while (si->cluster_next <= si->highest_bit) {
 42                         offset = si->cluster_next++;
 43                         if (si->swap_map[offset])
 44                                 continue;
 45                         si->cluster_nr--;
 46                         goto got_page;
 47                 }
 48         }
 49         si->cluster_nr = SWAPFILE_CLUSTER;
 50 
 51         /* try to find an empty (even not aligned) cluster. */
 52         offset = si->lowest_bit;
 53  check_next_cluster:
 54         if (offset+SWAPFILE_CLUSTER-1 <= si->highest_bit)
 55         {
 56                 int nr;
 57                 for (nr = offset; nr < offset+SWAPFILE_CLUSTER; nr++)
 58                         if (si->swap_map[nr])
 59                         {
 60                                 offset = nr+1;
 61                                 goto check_next_cluster;
 62                         }
 63                 /* We found a completly empty cluster, so start
 64                  * using it.
 65                  */
 66                 goto got_page;
 67         }
 68         /* No luck, so now go finegrined as usual. -Andrea */
 69         for (offset = si->lowest_bit; offset <= si->highest_bit ; offset++) {
 70                 if (si->swap_map[offset])
 71                         continue;
 72         got_page:
 73                 if (offset == si->lowest_bit)
 74                         si->lowest_bit++;
 75                 if (offset == si->highest_bit)
 76                         si->highest_bit--;
 77                 si->swap_map[offset] = count;
 78                 nr_swap_pages--;
 79                 si->cluster_next = offset+1;
 80                 return offset;
 81         }
 82         return 0;
 83 }
 84 
 85 swp_entry_t __get_swap_page(unsigned short count)
 86 {
 87         struct swap_info_struct * p;
 88         unsigned long offset;
 89         swp_entry_t entry;
 90         int type, wrapped = 0;
 91 
 92         entry.val = 0;  /* Out of memory */
 93         if (count >= SWAP_MAP_MAX)
 94                 goto bad_count;
 95         swap_list_lock();
 96         type = swap_list.next;
 97         if (type < 0)
 98                 goto out;
 99         if (nr_swap_pages == 0)
100                 goto out;
101 
102         while (1) {
103                 p = &swap_info[type];
104                 if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
105                         swap_device_lock(p);
106                         offset = scan_swap_map(p, count);
107                         swap_device_unlock(p);
108                         if (offset) {
109                                 entry = SWP_ENTRY(type,offset);
110                                 type = swap_info[type].next;
111                                 if (type < 0 ||
112                                         p->prio != swap_info[type].prio) {
113                                                 swap_list.next = swap_list.head;
114                                 } else {
115                                         swap_list.next = type;
116                                 }
117                                 goto out;
118                         }
119                 }
120                 type = p->next;
121                 if (!wrapped) {
122                         if (type < 0 || p->prio != swap_info[type].prio) {
123                                 type = swap_list.head;
124                                 wrapped = 1;
125                         }
126                 } else
127                         if (type < 0)
128                                 goto out;       /* out of swap space */
129         }
130 out:
131         swap_list_unlock();
132         return entry;
133 
134 bad_count:
135         printk(KERN_ERR "get_swap_page: bad count %hd from %p\n",
136                count, __builtin_return_address(0));
137         goto out;
138 }
139 
140 
141 /*
142  * Caller has made sure that the swapdevice corresponding to entry
143  * is still around or has not been recycled.
144  */
145 void __swap_free(swp_entry_t entry, unsigned short count)
146 {
147         struct swap_info_struct * p;
148         unsigned long offset, type;
149 
150         if (!entry.val)
151                 goto out;
152 
153         type = SWP_TYPE(entry);
154         if (type >= nr_swapfiles)
155                 goto bad_nofile;
156         p = & swap_info[type];
157         if (!(p->flags & SWP_USED))
158                 goto bad_device;
159         offset = SWP_OFFSET(entry);
160         if (offset >= p->max)
161                 goto bad_offset;
162         if (!p->swap_map[offset])
163                 goto bad_free;
164         swap_list_lock();
165         if (p->prio > swap_info[swap_list.next].prio)
166                 swap_list.next = type;
167         swap_device_lock(p);
168         if (p->swap_map[offset] < SWAP_MAP_MAX) {
169                 if (p->swap_map[offset] < count)
170                         goto bad_count;
171                 if (!(p->swap_map[offset] -= count)) {
172                         if (offset < p->lowest_bit)
173                                 p->lowest_bit = offset;
174                         if (offset > p->highest_bit)
175                                 p->highest_bit = offset;
176                         nr_swap_pages++;
177                 }
178         }
179         swap_device_unlock(p);
180         swap_list_unlock();
181 out:
182         return;
183 
184 bad_nofile:
185         printk("swap_free: Trying to free nonexistent swap-page\n");
186         goto out;
187 bad_device:
188         printk("swap_free: Trying to free swap from unused swap-device\n");
189         goto out;
190 bad_offset:
191         printk("swap_free: offset exceeds max\n");
192         goto out;
193 bad_free:
194         printk("VM: Bad swap entry %08lx\n", entry.val);
195         goto out;
196 bad_count:
197         swap_device_unlock(p);
198         swap_list_unlock();
199         printk(KERN_ERR "VM: Bad count %hd current count %hd\n", count, p->swap_map[offset]);
200         goto out;
201 }
202 
203 /*
204  * The swap entry has been read in advance, and we return 1 to indicate
205  * that the page has been used or is no longer needed.
206  *
207  * Always set the resulting pte to be nowrite (the same as COW pages
208  * after one process has exited).  We don't know just how many PTEs will
209  * share this swap entry, so be cautious and let do_wp_page work out
210  * what to do if a write is requested later.
211  */
212 static inline void unuse_pte(struct vm_area_struct * vma, unsigned long address,
213         pte_t *dir, swp_entry_t entry, struct page* page)
214 {
215         pte_t pte = *dir;
216 
217         if (pte_none(pte))
218                 return;
219         if (pte_present(pte)) {
220                 /* If this entry is swap-cached, then page must already
221                    hold the right address for any copies in physical
222                    memory */
223                 if (pte_page(pte) != page)
224                         return;
225                 /* We will be removing the swap cache in a moment, so... */
226                 ptep_mkdirty(dir);
227                 return;
228         }
229         if (pte_to_swp_entry(pte).val != entry.val)
230                 return;
231         set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
232         swap_free(entry);
233         get_page(page);
234         ++vma->vm_mm->rss;
235 }
236 
237 static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
238         unsigned long address, unsigned long size, unsigned long offset,
239         swp_entry_t entry, struct page* page)
240 {
241         pte_t * pte;
242         unsigned long end;
243 
244         if (pmd_none(*dir))
245                 return;
246         if (pmd_bad(*dir)) {
247                 pmd_ERROR(*dir);
248                 pmd_clear(dir);
249                 return;
250         }
251         pte = pte_offset(dir, address);
252         offset += address & PMD_MASK;
253         address &= ~PMD_MASK;
254         end = address + size;
255         if (end > PMD_SIZE)
256                 end = PMD_SIZE;
257         do {
258                 unuse_pte(vma, offset+address-vma->vm_start, pte, entry, page);
259                 address += PAGE_SIZE;
260                 pte++;
261         } while (address && (address < end));
262 }
263 
264 static inline void unuse_pgd(struct vm_area_struct * vma, pgd_t *dir,
265         unsigned long address, unsigned long size,
266         swp_entry_t entry, struct page* page)
267 {
268         pmd_t * pmd;
269         unsigned long offset, end;
270 
271         if (pgd_none(*dir))
272                 return;
273         if (pgd_bad(*dir)) {
274                 pgd_ERROR(*dir);
275                 pgd_clear(dir);
276                 return;
277         }
278         pmd = pmd_offset(dir, address);
279         offset = address & PGDIR_MASK;
280         address &= ~PGDIR_MASK;
281         end = address + size;
282         if (end > PGDIR_SIZE)
283                 end = PGDIR_SIZE;
284         if (address >= end)
285                 BUG();
286         do {
287                 unuse_pmd(vma, pmd, address, end - address, offset, entry,
288                           page);
289                 address = (address + PMD_SIZE) & PMD_MASK;
290                 pmd++;
291         } while (address && (address < end));
292 }
293 
294 static void unuse_vma(struct vm_area_struct * vma, pgd_t *pgdir,
295                         swp_entry_t entry, struct page* page)
296 {
297         unsigned long start = vma->vm_start, end = vma->vm_end;
298 
299         if (start >= end)
300                 BUG();
301         do {
302                 unuse_pgd(vma, pgdir, start, end - start, entry, page);
303                 start = (start + PGDIR_SIZE) & PGDIR_MASK;
304                 pgdir++;
305         } while (start && (start < end));
306 }
307 
308 static void unuse_process(struct mm_struct * mm,
309                         swp_entry_t entry, struct page* page)
310 {
311         struct vm_area_struct* vma;
312 
313         /*
314          * Go through process' page directory.
315          */
316         if (!mm)
317                 return;
318         spin_lock(&mm->page_table_lock);
319         for (vma = mm->mmap; vma; vma = vma->vm_next) {
320                 pgd_t * pgd = pgd_offset(mm, vma->vm_start);
321                 unuse_vma(vma, pgd, entry, page);
322         }
323         spin_unlock(&mm->page_table_lock);
324         return;
325 }
326 
327 /*
328  * We completely avoid races by reading each swap page in advance,
329  * and then search for the process using it.  All the necessary
330  * page table adjustments can then be made atomically.
331  */
332 static int try_to_unuse(unsigned int type)
333 {
334         struct swap_info_struct * si = &swap_info[type];
335         struct task_struct *p;
336         struct page *page;
337         swp_entry_t entry;
338         int i;
339 
340         while (1) {
341                 /*
342                  * Find a swap page in use and read it in.
343                  */
344                 swap_device_lock(si);
345                 for (i = 1; i < si->max ; i++) {
346                         if (si->swap_map[i] > 0 && si->swap_map[i] != SWAP_MAP_BAD) {
347                                 /*
348                                  * Prevent swaphandle from being completely
349                                  * unused by swap_free while we are trying
350                                  * to read in the page - this prevents warning
351                                  * messages from rw_swap_page_base.
352                                  */
353                                 if (si->swap_map[i] != SWAP_MAP_MAX)
354                                         si->swap_map[i]++;
355                                 swap_device_unlock(si);
356                                 goto found_entry;
357                         }
358                 }
359                 swap_device_unlock(si);
360                 break;
361 
362         found_entry:
363                 entry = SWP_ENTRY(type, i);
364 
365                 /* Get a page for the entry, using the existing swap
366                    cache page if there is one.  Otherwise, get a clean
367                    page and read the swap into it. */
368                 page = read_swap_cache(entry);
369                 if (!page) {
370                         swap_free(entry);
371                         return -ENOMEM;
372                 }
373                 if (PageSwapCache(page))
374                         delete_from_swap_cache(page);
375                 read_lock(&tasklist_lock);
376                 for_each_task(p)
377                         unuse_process(p->mm, entry, page);
378                 read_unlock(&tasklist_lock);
379                 shmem_unuse(entry, page);
380                 /* Now get rid of the extra reference to the temporary
381                    page we've been using. */
382                 page_cache_release(page);
383                 /*
384                  * Check for and clear any overflowed swap map counts.
385                  */
386                 swap_free(entry);
387                 swap_list_lock();
388                 swap_device_lock(si);
389                 if (si->swap_map[i] > 0) {
390                         if (si->swap_map[i] != SWAP_MAP_MAX)
391                                 printk("VM: Undead swap entry %08lx\n", 
392                                                                 entry.val);
393                         nr_swap_pages++;
394                         si->swap_map[i] = 0;
395                 }
396                 swap_device_unlock(si);
397                 swap_list_unlock();
398         }
399         return 0;
400 }
401 
402 asmlinkage long sys_swapoff(const char * specialfile)
403 {
404         struct swap_info_struct * p = NULL;
405         struct nameidata nd;
406         int i, type, prev;
407         int err;
408         
409         if (!capable(CAP_SYS_ADMIN))
410                 return -EPERM;
411 
412         err = user_path_walk(specialfile, &nd);
413         if (err)
414                 goto out;
415 
416         lock_kernel();
417         prev = -1;
418         swap_list_lock();
419         for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
420                 p = swap_info + type;
421                 if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
422                         if (p->swap_file) {
423                                 if (p->swap_file == nd.dentry)
424                                   break;
425                         } else {
426                                 if (S_ISBLK(nd.dentry->d_inode->i_mode)
427                                     && (p->swap_device == nd.dentry->d_inode->i_rdev))
428                                   break;
429                         }
430                 }
431                 prev = type;
432         }
433         err = -EINVAL;
434         if (type < 0) {
435                 swap_list_unlock();
436                 goto out_dput;
437         }
438 
439         if (prev < 0) {
440                 swap_list.head = p->next;
441         } else {
442                 swap_info[prev].next = p->next;
443         }
444         if (type == swap_list.next) {
445                 /* just pick something that's safe... */
446                 swap_list.next = swap_list.head;
447         }
448         nr_swap_pages -= p->pages;
449         swap_list_unlock();
450         p->flags = SWP_USED;
451         err = try_to_unuse(type);
452         if (err) {
453                 /* re-insert swap space back into swap_list */
454                 swap_list_lock();
455                 for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
456                         if (p->prio >= swap_info[i].prio)
457                                 break;
458                 p->next = i;
459                 if (prev < 0)
460                         swap_list.head = swap_list.next = p - swap_info;
461                 else
462                         swap_info[prev].next = p - swap_info;
463                 nr_swap_pages += p->pages;
464                 swap_list_unlock();
465                 p->flags = SWP_WRITEOK;
466                 goto out_dput;
467         }
468         if (p->swap_device)
469                 blkdev_put(nd.dentry->d_inode->i_bdev, BDEV_SWAP);
470         path_release(&nd);
471 
472         nd.dentry = p->swap_file;
473         p->swap_file = NULL;
474         nd.mnt = p->swap_vfsmnt;
475         p->swap_vfsmnt = NULL;
476         p->swap_device = 0;
477         vfree(p->swap_map);
478         p->swap_map = NULL;
479         p->flags = 0;
480         err = 0;
481 
482 out_dput:
483         unlock_kernel();
484         path_release(&nd);
485 out:
486         return err;
487 }
488 
489 int get_swaparea_info(char *buf)
490 {
491         char * page = (char *) __get_free_page(GFP_KERNEL);
492         struct swap_info_struct *ptr = swap_info;
493         int i, j, len = 0, usedswap;
494 
495         if (!page)
496                 return -ENOMEM;
497 
498         len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
499         for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
500                 if (ptr->flags & SWP_USED) {
501                         char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt,
502                                                 page, PAGE_SIZE);
503 
504                         len += sprintf(buf + len, "%-31s ", path);
505 
506                         if (!ptr->swap_device)
507                                 len += sprintf(buf + len, "file\t\t");
508                         else
509                                 len += sprintf(buf + len, "partition\t");
510 
511                         usedswap = 0;
512                         for (j = 0; j < ptr->max; ++j)
513                                 switch (ptr->swap_map[j]) {
514                                         case SWAP_MAP_BAD:
515                                         case 0:
516                                                 continue;
517                                         default:
518                                                 usedswap++;
519                                 }
520                         len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), 
521                                 usedswap << (PAGE_SHIFT - 10), ptr->prio);
522                 }
523         }
524         free_page((unsigned long) page);
525         return len;
526 }
527 
528 int is_swap_partition(kdev_t dev) {
529         struct swap_info_struct *ptr = swap_info;
530         int i;
531 
532         for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
533                 if (ptr->flags & SWP_USED)
534                         if (ptr->swap_device == dev)
535                                 return 1;
536         }
537         return 0;
538 }
539 
540 /*
541  * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
542  *
543  * The swapon system call
544  */
545 asmlinkage long sys_swapon(const char * specialfile, int swap_flags)
546 {
547         struct swap_info_struct * p;
548         struct nameidata nd;
549         struct inode * swap_inode;
550         unsigned int type;
551         int i, j, prev;
552         int error;
553         static int least_priority = 0;
554         union swap_header *swap_header = 0;
555         int swap_header_version;
556         int nr_good_pages = 0;
557         unsigned long maxpages;
558         int swapfilesize;
559         struct block_device *bdev = NULL;
560         
561         if (!capable(CAP_SYS_ADMIN))
562                 return -EPERM;
563         lock_kernel();
564         p = swap_info;
565         for (type = 0 ; type < nr_swapfiles ; type++,p++)
566                 if (!(p->flags & SWP_USED))
567                         break;
568         error = -EPERM;
569         if (type >= MAX_SWAPFILES)
570                 goto out;
571         if (type >= nr_swapfiles)
572                 nr_swapfiles = type+1;
573         p->flags = SWP_USED;
574         p->swap_file = NULL;
575         p->swap_vfsmnt = NULL;
576         p->swap_device = 0;
577         p->swap_map = NULL;
578         p->lowest_bit = 0;
579         p->highest_bit = 0;
580         p->cluster_nr = 0;
581         p->sdev_lock = SPIN_LOCK_UNLOCKED;
582         p->max = 1;
583         p->next = -1;
584         if (swap_flags & SWAP_FLAG_PREFER) {
585                 p->prio =
586                   (swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;
587         } else {
588                 p->prio = --least_priority;
589         }
590         error = user_path_walk(specialfile, &nd);
591         if (error)
592                 goto bad_swap_2;
593 
594         p->swap_file = nd.dentry;
595         p->swap_vfsmnt = nd.mnt;
596         swap_inode = nd.dentry->d_inode;
597         error = -EINVAL;
598 
599         if (S_ISBLK(swap_inode->i_mode)) {
600                 kdev_t dev = swap_inode->i_rdev;
601                 struct block_device_operations *bdops;
602 
603                 p->swap_device = dev;
604                 set_blocksize(dev, PAGE_SIZE);
605                 
606                 bdev = swap_inode->i_bdev;
607                 bdops = devfs_get_ops(devfs_get_handle_from_inode(swap_inode));
608                 if (bdops) bdev->bd_op = bdops;
609 
610                 error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_SWAP);
611                 if (error)
612                         goto bad_swap_2;
613                 set_blocksize(dev, PAGE_SIZE);
614                 error = -ENODEV;
615                 if (!dev || (blk_size[MAJOR(dev)] &&
616                      !blk_size[MAJOR(dev)][MINOR(dev)]))
617                         goto bad_swap;
618                 error = -EBUSY;
619                 for (i = 0 ; i < nr_swapfiles ; i++) {
620                         if (i == type)
621                                 continue;
622                         if (dev == swap_info[i].swap_device)
623                                 goto bad_swap;
624                 }
625                 swapfilesize = 0;
626                 if (blk_size[MAJOR(dev)])
627                         swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)]
628                                 >> (PAGE_SHIFT - 10);
629         } else if (S_ISREG(swap_inode->i_mode)) {
630                 error = -EBUSY;
631                 for (i = 0 ; i < nr_swapfiles ; i++) {
632                         if (i == type || !swap_info[i].swap_file)
633                                 continue;
634                         if (swap_inode == swap_info[i].swap_file->d_inode)
635                                 goto bad_swap;
636                 }
637                 swapfilesize = swap_inode->i_size >> PAGE_SHIFT;
638         } else
639                 goto bad_swap;
640 
641         swap_header = (void *) __get_free_page(GFP_USER);
642         if (!swap_header) {
643                 printk("Unable to start swapping: out of memory :-)\n");
644                 error = -ENOMEM;
645                 goto bad_swap;
646         }
647 
648         lock_page(virt_to_page(swap_header));
649         rw_swap_page_nolock(READ, SWP_ENTRY(type,0), (char *) swap_header, 1);
650 
651         if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10))
652                 swap_header_version = 1;
653         else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10))
654                 swap_header_version = 2;
655         else {
656                 printk("Unable to find swap-space signature\n");
657                 error = -EINVAL;
658                 goto bad_swap;
659         }
660         
661         switch (swap_header_version) {
662         case 1:
663                 memset(((char *) swap_header)+PAGE_SIZE-10,0,10);
664                 j = 0;
665                 p->lowest_bit = 0;
666                 p->highest_bit = 0;
667                 for (i = 1 ; i < 8*PAGE_SIZE ; i++) {
668                         if (test_bit(i,(char *) swap_header)) {
669                                 if (!p->lowest_bit)
670                                         p->lowest_bit = i;
671                                 p->highest_bit = i;
672                                 p->max = i+1;
673                                 j++;
674                         }
675                 }
676                 nr_good_pages = j;
677                 p->swap_map = vmalloc(p->max * sizeof(short));
678                 if (!p->swap_map) {
679                         error = -ENOMEM;                
680                         goto bad_swap;
681                 }
682                 for (i = 1 ; i < p->max ; i++) {
683                         if (test_bit(i,(char *) swap_header))
684                                 p->swap_map[i] = 0;
685                         else
686                                 p->swap_map[i] = SWAP_MAP_BAD;
687                 }
688                 break;
689 
690         case 2:
691                 /* Check the swap header's sub-version and the size of
692                    the swap file and bad block lists */
693                 if (swap_header->info.version != 1) {
694                         printk(KERN_WARNING
695                                "Unable to handle swap header version %d\n",
696                                swap_header->info.version);
697                         error = -EINVAL;
698                         goto bad_swap;
699                 }
700 
701                 p->lowest_bit  = 1;
702                 p->highest_bit = swap_header->info.last_page - 1;
703                 p->max         = swap_header->info.last_page;
704 
705                 maxpages = SWP_OFFSET(SWP_ENTRY(0,~0UL));
706                 if (p->max >= maxpages)
707                         p->max = maxpages-1;
708 
709                 error = -EINVAL;
710                 if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
711                         goto bad_swap;
712                 
713                 /* OK, set up the swap map and apply the bad block list */
714                 if (!(p->swap_map = vmalloc (p->max * sizeof(short)))) {
715                         error = -ENOMEM;
716                         goto bad_swap;
717                 }
718 
719                 error = 0;
720                 memset(p->swap_map, 0, p->max * sizeof(short));
721                 for (i=0; i<swap_header->info.nr_badpages; i++) {
722                         int page = swap_header->info.badpages[i];
723                         if (page <= 0 || page >= swap_header->info.last_page)
724                                 error = -EINVAL;
725                         else
726                                 p->swap_map[page] = SWAP_MAP_BAD;
727                 }
728                 nr_good_pages = swap_header->info.last_page -
729                                 swap_header->info.nr_badpages -
730                                 1 /* header page */;
731                 if (error) 
732                         goto bad_swap;
733         }
734         
735         if (swapfilesize && p->max > swapfilesize) {
736                 printk(KERN_WARNING
737                        "Swap area shorter than signature indicates\n");
738                 error = -EINVAL;
739                 goto bad_swap;
740         }
741         if (!nr_good_pages) {
742                 printk(KERN_WARNING "Empty swap-file\n");
743                 error = -EINVAL;
744                 goto bad_swap;
745         }
746         p->swap_map[0] = SWAP_MAP_BAD;
747         p->flags = SWP_WRITEOK;
748         p->pages = nr_good_pages;
749         swap_list_lock();
750         nr_swap_pages += nr_good_pages;
751         printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
752                nr_good_pages<<(PAGE_SHIFT-10), p->prio);
753 
754         /* insert swap space into swap_list: */
755         prev = -1;
756         for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
757                 if (p->prio >= swap_info[i].prio) {
758                         break;
759                 }
760                 prev = i;
761         }
762         p->next = i;
763         if (prev < 0) {
764                 swap_list.head = swap_list.next = p - swap_info;
765         } else {
766                 swap_info[prev].next = p - swap_info;
767         }
768         swap_list_unlock();
769         error = 0;
770         goto out;
771 bad_swap:
772         if (bdev)
773                 blkdev_put(bdev, BDEV_SWAP);
774 bad_swap_2:
775         if (p->swap_map)
776                 vfree(p->swap_map);
777         nd.mnt = p->swap_vfsmnt;
778         nd.dentry = p->swap_file;
779         p->swap_device = 0;
780         p->swap_file = NULL;
781         p->swap_vfsmnt = NULL;
782         p->swap_map = NULL;
783         p->flags = 0;
784         if (!(swap_flags & SWAP_FLAG_PREFER))
785                 ++least_priority;
786         path_release(&nd);
787 out:
788         if (swap_header)
789                 free_page((long) swap_header);
790         unlock_kernel();
791         return error;
792 }
793 
794 void si_swapinfo(struct sysinfo *val)
795 {
796         unsigned int i;
797         unsigned long freeswap = 0;
798         unsigned long totalswap = 0;
799 
800         for (i = 0; i < nr_swapfiles; i++) {
801                 unsigned int j;
802                 if ((swap_info[i].flags & SWP_WRITEOK) != SWP_WRITEOK)
803                         continue;
804                 for (j = 0; j < swap_info[i].max; ++j) {
805                         switch (swap_info[i].swap_map[j]) {
806                                 case SWAP_MAP_BAD:
807                                         continue;
808                                 case 0:
809                                         freeswap++;
810                                 default:
811                                         totalswap++;
812                         }
813                 }
814         }
815         val->freeswap = freeswap;
816         val->totalswap = totalswap;
817         return;
818 }
819 
820 /*
821  * Verify that a swap entry is valid and increment its swap map count.
822  * Kernel_lock is held, which guarantees existance of swap device.
823  *
824  * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
825  * "permanent", but will be reclaimed by the next swapoff.
826  */
827 int swap_duplicate(swp_entry_t entry)
828 {
829         struct swap_info_struct * p;
830         unsigned long offset, type;
831         int result = 0;
832 
833         /* Swap entry 0 is illegal */
834         if (!entry.val)
835                 goto out;
836         type = SWP_TYPE(entry);
837         if (type >= nr_swapfiles)
838                 goto bad_file;
839         p = type + swap_info;
840         offset = SWP_OFFSET(entry);
841         if (offset >= p->max)
842                 goto bad_offset;
843         if (!p->swap_map[offset])
844                 goto bad_unused;
845         /*
846          * Entry is valid, so increment the map count.
847          */
848         swap_device_lock(p);
849         if (p->swap_map[offset] < SWAP_MAP_MAX)
850                 p->swap_map[offset]++;
851         else {
852                 static int overflow = 0;
853                 if (overflow++ < 5)
854                         printk("VM: swap entry overflow\n");
855                 p->swap_map[offset] = SWAP_MAP_MAX;
856         }
857         swap_device_unlock(p);
858         result = 1;
859 out:
860         return result;
861 
862 bad_file:
863         printk("Bad swap file entry %08lx\n", entry.val);
864         goto out;
865 bad_offset:
866         printk("Bad swap offset entry %08lx\n", entry.val);
867         goto out;
868 bad_unused:
869         printk("Unused swap offset entry in swap_dup %08lx\n", entry.val);
870         goto out;
871 }
872 
873 /*
874  * Page lock needs to be held in all cases to prevent races with
875  * swap file deletion.
876  */
877 int swap_count(struct page *page)
878 {
879         struct swap_info_struct * p;
880         unsigned long offset, type;
881         swp_entry_t entry;
882         int retval = 0;
883 
884         entry.val = page->index;
885         if (!entry.val)
886                 goto bad_entry;
887         type = SWP_TYPE(entry);
888         if (type >= nr_swapfiles)
889                 goto bad_file;
890         p = type + swap_info;
891         offset = SWP_OFFSET(entry);
892         if (offset >= p->max)
893                 goto bad_offset;
894         if (!p->swap_map[offset])
895                 goto bad_unused;
896         retval = p->swap_map[offset];
897 out:
898         return retval;
899 
900 bad_entry:
901         printk(KERN_ERR "swap_count: null entry!\n");
902         goto out;
903 bad_file:
904         printk("Bad swap file entry %08lx\n", entry.val);
905         goto out;
906 bad_offset:
907         printk("Bad swap offset entry %08lx\n", entry.val);
908         goto out;
909 bad_unused:
910         printk("Unused swap offset entry in swap_count %08lx\n", entry.val);
911         goto out;
912 }
913 
914 /*
915  * Kernel_lock protects against swap device deletion.
916  */
917 void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, 
918                         kdev_t *dev, struct inode **swapf)
919 {
920         unsigned long type;
921         struct swap_info_struct *p;
922 
923         type = SWP_TYPE(entry);
924         if (type >= nr_swapfiles) {
925                 printk("Internal error: bad swap-device\n");
926                 return;
927         }
928 
929         p = &swap_info[type];
930         *offset = SWP_OFFSET(entry);
931         if (*offset >= p->max) {
932                 printk("rw_swap_page: weirdness\n");
933                 return;
934         }
935         if (p->swap_map && !p->swap_map[*offset]) {
936                 printk("VM: Bad swap entry %08lx\n", entry.val);
937                 return;
938         }
939         if (!(p->flags & SWP_USED)) {
940                 printk(KERN_ERR "rw_swap_page: "
941                         "Trying to swap to unused swap-device\n");
942                 return;
943         }
944 
945         if (p->swap_device) {
946                 *dev = p->swap_device;
947         } else if (p->swap_file) {
948                 *swapf = p->swap_file->d_inode;
949         } else {
950                 printk(KERN_ERR "rw_swap_page: no swap file or device\n");
951         }
952         return;
953 }
954 
955 /*
956  * Kernel_lock protects against swap device deletion. Grab an extra
957  * reference on the swaphandle so that it dos not become unused.
958  */
959 int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
960 {
961         int ret = 0, i = 1 << page_cluster;
962         unsigned long toff;
963         struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
964 
965         *offset = SWP_OFFSET(entry);
966         toff = *offset = (*offset >> page_cluster) << page_cluster;
967 
968         swap_device_lock(swapdev);
969         do {
970                 /* Don't read-ahead past the end of the swap area */
971                 if (toff >= swapdev->max)
972                         break;
973                 /* Don't read in bad or busy pages */
974                 if (!swapdev->swap_map[toff])
975                         break;
976                 if (swapdev->swap_map[toff] == SWAP_MAP_BAD)
977                         break;
978                 swapdev->swap_map[toff]++;
979                 toff++;
980                 ret++;
981         } while (--i);
982         swap_device_unlock(swapdev);
983         return ret;
984 }
985 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.