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)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         unsigned long type, offset;
  34         struct swap_info_struct * p;
  35 
  36         type = SWP_TYPE(entry);
  37         if (type >= nr_swapfiles) {
  38                 printk("Internal error: bad swap-device\n");
  39                 return;
  40         }
  41         p = &swap_info[type];
  42         offset = SWP_OFFSET(entry);
  43         if (offset >= p->max) {
  44                 printk("rw_swap_page: weirdness\n");
  45                 return;
  46         }
  47         if (p->swap_map && !p->swap_map[offset]) {
  48                 printk("Hmm.. Trying to use unallocated swap (%08lx)\n", entry);
  49                 return;
  50         }
  51         if (!(p->flags & SWP_USED)) {
  52                 printk("Trying to swap to unused swap-device\n");
  53                 return;
  54         }
  55         while (set_bit(offset,p->swap_lockmap))
  56                 sleep_on(&lock_queue);
  57         if (rw == READ)
  58                 kstat.pswpin++;
  59         else
  60                 kstat.pswpout++;
  61         if (p->swap_device) {
  62                 ll_rw_page(rw,p->swap_device,offset,buf);
  63         } else if (p->swap_file) {
  64                 struct inode *swapf = p->swap_file;
  65                 unsigned int zones[PAGE_SIZE/512];
  66                 int i;
  67                 if (swapf->i_op->bmap == NULL
  68                         && swapf->i_op->smap != NULL){
  69                         /*
  70                                 With MsDOS, we use msdos_smap which return
  71                                 a sector number (not a cluster or block number).
  72                                 It is a patch to enable the UMSDOS project.
  73                                 Other people are working on better solution.
  74 
  75                                 It sounds like ll_rw_swap_file defined
  76                                 it operation size (sector size) based on
  77                                 PAGE_SIZE and the number of block to read.
  78                                 So using bmap or smap should work even if
  79                                 smap will require more blocks.
  80                         */
  81                         int j;
  82                         unsigned int block = offset << 3;
  83 
  84                         for (i=0, j=0; j< PAGE_SIZE ; i++, j += 512){
  85                                 if (!(zones[i] = swapf->i_op->smap(swapf,block++))) {
  86                                         printk("rw_swap_page: bad swap file\n");
  87                                         return;
  88                                 }
  89                         }
  90                 }else{
  91                         int j;
  92                         unsigned int block = offset
  93                                 << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
  94 
  95                         for (i=0, j=0; j< PAGE_SIZE ; i++, j +=swapf->i_sb->s_blocksize)
  96                                 if (!(zones[i] = bmap(swapf,block++))) {
  97                                         printk("rw_swap_page: bad swap file\n");
  98                                         return;
  99                                 }
 100                 }
 101                 ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
 102         } else
 103                 printk("re_swap_page: no swap file or device\n");
 104         if (offset && !clear_bit(offset,p->swap_lockmap))
 105                 printk("rw_swap_page: lock already cleared\n");
 106         wake_up(&lock_queue);
 107 }
 108 

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