home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / msdos / mmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  2.4 KB  |  113 lines

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