root/fs/msdos/mmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. msdos_file_mmap_nopage
  2. msdos_mmap

   1 /*
   2  *      fs/msdos/mmap.c
   3  *
   4  *      Written by Jacques Gelinas (jacques@solucorp.qc.ca)
   5  *      Inspired by fs/nfs/mmap.c (Jaon Tombs 15 Aug 1993)
   6  *
   7  *      msdos mmap handling
   8  */
   9 #include <linux/stat.h>
  10 #include <linux/sched.h>
  11 #include <linux/kernel.h>
  12 #include <linux/mm.h>
  13 #include <linux/shm.h>
  14 #include <linux/errno.h>
  15 #include <linux/mman.h>
  16 #include <linux/string.h>
  17 #include <linux/malloc.h>
  18 #include <asm/segment.h>
  19 #include <asm/system.h>
  20 #include <linux/msdos_fs.h>
  21 
  22 /*
  23  * Fill in the supplied page for mmap
  24  */
  25 static unsigned long msdos_file_mmap_nopage(
     /* [previous][next][first][last][top][bottom][index][help] */
  26         struct vm_area_struct * area,
  27         unsigned long address,
  28         unsigned long page,
  29         int error_code)
  30 {
  31         struct inode * inode = area->vm_inode;
  32         unsigned int clear;
  33         int pos;
  34         long gap;       /* distance from eof to pos */
  35 
  36         address &= PAGE_MASK;
  37         pos = address - area->vm_start + area->vm_offset;
  38 
  39         clear = 0;
  40         gap = inode->i_size - pos;
  41         if (gap <= 0){
  42                 /* mmaping beyond end of file */
  43                 clear = PAGE_SIZE;
  44         }else{
  45                 int cur_read;
  46                 int need_read;
  47                 struct file filp;
  48                 if (gap < PAGE_SIZE){
  49                         clear = PAGE_SIZE - gap;
  50                 }
  51                 filp.f_pos = pos;
  52                 need_read = PAGE_SIZE - clear;
  53                 {
  54                         unsigned long cur_fs = get_fs();
  55                         set_fs (KERNEL_DS);
  56                         cur_read = msdos_file_read (inode,&filp,(char*)page
  57                                 ,need_read);
  58                         set_fs (cur_fs);
  59                 }
  60                 if (cur_read != need_read){
  61                         printk ("MSDOS: Error while reading an mmap file %d <> %d\n"
  62                                 ,cur_read,need_read);
  63                 }
  64         }
  65         if (clear > 0){
  66                 memset ((char*)page+PAGE_SIZE-clear,0,clear);
  67         }
  68         return page;
  69 }
  70 
  71 struct vm_operations_struct msdos_file_mmap = {
  72         NULL,                   /* open */
  73         NULL,                   /* close */
  74         msdos_file_mmap_nopage, /* nopage */
  75         NULL,                   /* wppage */
  76         NULL,                   /* share */
  77         NULL,                   /* unmap */
  78 };
  79 
  80 /*
  81  * This is used for a general mmap of an msdos file
  82  * Returns 0 if ok, or a negative error code if not.
  83  */
  84 int msdos_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86         if (vma->vm_page_prot & PAGE_RW)        /* only PAGE_COW or read-only supported now */
  87                 return -EINVAL;
  88         if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
  89                 return -EINVAL;
  90         if (!inode->i_sb || !S_ISREG(inode->i_mode))
  91                 return -EACCES;
  92         if (!IS_RDONLY(inode)) {
  93                 inode->i_atime = CURRENT_TIME;
  94                 inode->i_dirt = 1;
  95         }
  96 
  97         vma->vm_inode = inode;
  98         inode->i_count++;
  99         vma->vm_ops = &msdos_file_mmap;
 100         return 0;
 101 }
 102 

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