root/mm/page_io.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rw_swap_page

   1 /*
   2  *  linux/mm/page_io.c
   3  *
   4  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
   5  *
   6  *  Swap reorganised 29.12.95, 
   7  *  Asynchronous swapping added 30.12.95. Stephen Tweedie
   8  */
   9 
  10 #include <linux/mm.h>
  11 #include <linux/sched.h>
  12 #include <linux/head.h>
  13 #include <linux/kernel.h>
  14 #include <linux/kernel_stat.h>
  15 #include <linux/errno.h>
  16 #include <linux/string.h>
  17 #include <linux/stat.h>
  18 #include <linux/swap.h>
  19 #include <linux/fs.h>
  20 #include <linux/locks.h>
  21 #include <linux/swapctl.h>
  22 
  23 #include <asm/dma.h>
  24 #include <asm/system.h> /* for cli()/sti() */
  25 #include <asm/segment.h> /* for memcpy_to/fromfs */
  26 #include <asm/bitops.h>
  27 #include <asm/pgtable.h>
  28 
  29 static struct wait_queue * lock_queue = NULL;
  30 
  31 void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         unsigned long type, offset;
  34         struct swap_info_struct * p;
  35         struct page *page;
  36         
  37         type = SWP_TYPE(entry);
  38         if (type >= nr_swapfiles) {
  39                 printk("Internal error: bad swap-device\n");
  40                 return;
  41         }
  42         p = &swap_info[type];
  43         offset = SWP_OFFSET(entry);
  44         if (offset >= p->max) {
  45                 printk("rw_swap_page: weirdness\n");
  46                 return;
  47         }
  48         if (p->swap_map && !p->swap_map[offset]) {
  49                 printk("Hmm.. Trying to use unallocated swap (%08lx)\n", entry);
  50                 return;
  51         }
  52         if (!(p->flags & SWP_USED)) {
  53                 printk("Trying to swap to unused swap-device\n");
  54                 return;
  55         }
  56         while (set_bit(offset,p->swap_lockmap))
  57                 sleep_on(&lock_queue);
  58         if (rw == READ)
  59                 kstat.pswpin++;
  60         else
  61                 kstat.pswpout++;
  62         page = mem_map + MAP_NR(buf);
  63         wait_on_page(page);
  64         if (p->swap_device) {
  65                 if (!wait) {
  66                         page->count++;
  67                         set_bit(PG_freeafter, &page->flags);
  68                         nr_async_pages++;
  69                 }
  70                 ll_rw_page(rw,p->swap_device,offset,buf);
  71                 if (wait)
  72                         wait_on_page(page);
  73         } else if (p->swap_file) {
  74                 struct inode *swapf = p->swap_file;
  75                 unsigned int zones[PAGE_SIZE/512];
  76                 int i;
  77                 if (swapf->i_op->bmap == NULL
  78                         && swapf->i_op->smap != NULL){
  79                         /*
  80                                 With MsDOS, we use msdos_smap which return
  81                                 a sector number (not a cluster or block number).
  82                                 It is a patch to enable the UMSDOS project.
  83                                 Other people are working on better solution.
  84 
  85                                 It sounds like ll_rw_swap_file defined
  86                                 it operation size (sector size) based on
  87                                 PAGE_SIZE and the number of block to read.
  88                                 So using bmap or smap should work even if
  89                                 smap will require more blocks.
  90                         */
  91                         int j;
  92                         unsigned int block = offset << 3;
  93 
  94                         for (i=0, j=0; j< PAGE_SIZE ; i++, j += 512){
  95                                 if (!(zones[i] = swapf->i_op->smap(swapf,block++))) {
  96                                         printk("rw_swap_page: bad swap file\n");
  97                                         return;
  98                                 }
  99                         }
 100                 }else{
 101                         int j;
 102                         unsigned int block = offset
 103                                 << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
 104 
 105                         for (i=0, j=0; j< PAGE_SIZE ; i++, j +=swapf->i_sb->s_blocksize)
 106                                 if (!(zones[i] = bmap(swapf,block++))) {
 107                                         printk("rw_swap_page: bad swap file\n");
 108                                 }
 109                 }
 110                 ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
 111         } else
 112                 printk("rw_swap_page: no swap file or device\n");
 113         if (offset && !clear_bit(offset,p->swap_lockmap))
 114                 printk("rw_swap_page: lock already cleared\n");
 115         wake_up(&lock_queue);
 116 }

/* [previous][next][first][last][top][bottom][index][help] */