root/fs/ncpfs/mmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. min
  2. ncp_file_mmap_nopage
  3. ncp_mmap

   1 /*
   2  *  mmap.c
   3  *
   4  *  Copyright (C) 1995, 1996 by Volker Lendecke
   5  *
   6  */
   7 
   8 #include <linux/stat.h>
   9 #include <linux/sched.h>
  10 #include <linux/kernel.h>
  11 #include <linux/mm.h>
  12 #include <linux/shm.h>
  13 #include <linux/errno.h>
  14 #include <linux/mman.h>
  15 #include <linux/string.h>
  16 #include <linux/malloc.h>
  17 #include <linux/fcntl.h>
  18 #include <linux/ncp_fs.h>
  19 
  20 #include "ncplib_kernel.h"
  21 #include <asm/segment.h>
  22 #include <asm/system.h>
  23 
  24 static inline int min(int a, int b)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26         return a<b ? a : b;
  27 }
  28 
  29 /*
  30  * Fill in the supplied page for mmap
  31  */
  32 static unsigned long 
  33 ncp_file_mmap_nopage(struct vm_area_struct * area,
     /* [previous][next][first][last][top][bottom][index][help] */
  34                      unsigned long address, int no_share)
  35 {
  36         struct inode * inode = area->vm_inode;
  37         unsigned long page;
  38         unsigned int clear;
  39         unsigned long tmp;
  40         int bufsize;
  41         int pos;
  42         unsigned short fs;
  43 
  44         page = __get_free_page(GFP_KERNEL);
  45         if (!page)
  46                 return page;
  47         address &= PAGE_MASK;
  48         pos = address - area->vm_start + area->vm_offset;
  49 
  50         clear = 0;
  51         if (address + PAGE_SIZE > area->vm_end)
  52         {
  53                 clear = address + PAGE_SIZE - area->vm_end;
  54         }
  55 
  56         /* what we can read in one go */
  57         bufsize = NCP_SERVER(inode)->buffer_size;
  58 
  59         fs = get_fs();
  60         set_fs(get_ds());
  61 
  62         if (ncp_make_open(inode, O_RDONLY) < 0)
  63         {
  64                 clear = PAGE_SIZE;
  65         }
  66         else
  67         {
  68                 int already_read = 0;
  69                 int count = PAGE_SIZE - clear;
  70                 int to_read;
  71 
  72                 while (already_read < count)
  73                 {
  74                         int read_this_time;
  75 
  76                         if ((pos % bufsize) != 0)
  77                         {
  78                                 to_read = bufsize - (pos % bufsize);
  79                         }
  80                         else
  81                         {
  82                                 to_read = bufsize;
  83                         }
  84 
  85                         to_read = min(to_read, count - already_read);
  86 
  87                         if (ncp_read(NCP_SERVER(inode),
  88                                      NCP_FINFO(inode)->file_handle,
  89                                      pos, to_read,
  90                                      (char *)(page + already_read),
  91                                      &read_this_time) != 0)
  92                         {
  93                                read_this_time = 0;
  94                         }
  95 
  96                         pos += read_this_time;
  97                         already_read += read_this_time;
  98 
  99                         if (read_this_time < to_read)
 100                         {
 101                                 break;
 102                         }
 103                 }
 104 
 105         }
 106 
 107         set_fs(fs);
 108 
 109         tmp = page + PAGE_SIZE;
 110         while (clear--) {
 111                 *(char *)--tmp = 0;
 112         }
 113         return page;
 114 }
 115 
 116 struct vm_operations_struct ncp_file_mmap = {
 117         NULL,                   /* open */
 118         NULL,                   /* close */
 119         NULL,                   /* unmap */
 120         NULL,                   /* protect */
 121         NULL,                   /* sync */
 122         NULL,                   /* advise */
 123         ncp_file_mmap_nopage,   /* nopage */
 124         NULL,                   /* wppage */
 125         NULL,                   /* swapout */
 126         NULL,                   /* swapin */
 127 };
 128 
 129 
 130 /* This is used for a general mmap of a ncp file */
 131 int
 132 ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134         DPRINTK("ncp_mmap: called\n");
 135 
 136         if (!ncp_conn_valid(NCP_SERVER(inode)))
 137         {
 138                 return -EIO;
 139         }
 140 
 141         /* only PAGE_COW or read-only supported now */
 142         if (vma->vm_flags & VM_SHARED)  
 143                 return -EINVAL;
 144         if (!inode->i_sb || !S_ISREG(inode->i_mode))
 145                 return -EACCES;
 146         if (!IS_RDONLY(inode)) {
 147                 inode->i_atime = CURRENT_TIME;
 148                 inode->i_dirt = 1;
 149         }
 150 
 151         vma->vm_inode = inode;
 152         inode->i_count++;
 153         vma->vm_ops = &ncp_file_mmap;
 154         return 0;
 155 }

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