root/fs/fat/mmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. fat_file_mmap_nopage
  2. fat_mmap

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

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