root/fs/nfs/mmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_file_mmap_nopage
  2. nfs_mmap

   1 /*
   2  *      fs/nfs/mmap.c   by Jon Tombs 15 Aug 1993
   3  *
   4  * This code is from
   5  *      linux/mm/mmap.c which was written by obz, Linus and Eric
   6  * and
   7  *      linux/mm/memory.c  by Linus Torvalds and others
   8  *
   9  *      Copyright (C) 1993
  10  *
  11  */
  12 #include <linux/stat.h>
  13 #include <linux/sched.h>
  14 #include <linux/kernel.h>
  15 #include <linux/mm.h>
  16 #include <linux/shm.h>
  17 #include <linux/errno.h>
  18 #include <linux/mman.h>
  19 #include <linux/string.h>
  20 #include <linux/malloc.h>
  21 #include <linux/nfs_fs.h>
  22 
  23 #include <asm/segment.h>
  24 #include <asm/system.h>
  25 
  26 /*
  27  * Fill in the supplied page for mmap
  28  */
  29 static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
     /* [previous][next][first][last][top][bottom][index][help] */
  30         unsigned long address, unsigned long page, int no_share)
  31 {
  32         struct inode * inode = area->vm_inode;
  33         unsigned int clear;
  34         unsigned long tmp;
  35         int n;
  36         int i;
  37         int pos;
  38         struct nfs_fattr fattr;
  39 
  40         address &= PAGE_MASK;
  41         pos = address - area->vm_start + area->vm_offset;
  42 
  43         clear = 0;
  44         if (address + PAGE_SIZE > area->vm_end) {
  45                 clear = address + PAGE_SIZE - area->vm_end;
  46         }
  47 
  48         n = NFS_SERVER(inode)->rsize; /* what we can read in one go */
  49 
  50         for (i = 0; i < (PAGE_SIZE - clear); i += n) {
  51                 int hunk, result;
  52 
  53                 hunk = PAGE_SIZE - i;
  54                 if (hunk > n)
  55                         hunk = n;
  56                 result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
  57                         pos, hunk, (char *) (page + i), &fattr);
  58                 if (result < 0)
  59                         break;
  60                 pos += result;
  61                 if (result < n) {
  62                         i += result;
  63                         break;
  64                 }
  65         }
  66 
  67 #ifdef doweneedthishere
  68         nfs_refresh_inode(inode, &fattr);
  69 #endif
  70 
  71         tmp = page + PAGE_SIZE;
  72         while (clear--) {
  73                 *(char *)--tmp = 0;
  74         }
  75         return page;
  76 }
  77 struct vm_operations_struct nfs_file_mmap = {
  78         NULL,                   /* open */
  79         NULL,                   /* close */
  80         nfs_file_mmap_nopage,   /* nopage */
  81         NULL,                   /* wppage */
  82         NULL,                   /* share */
  83         NULL,                   /* unmap */
  84 };
  85 
  86 
  87 /* This is used for a general mmap of a nfs file */
  88 int nfs_mmap(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
  89         unsigned long addr, size_t len, int prot, unsigned long off)
  90 {
  91         struct vm_area_struct * mpnt;
  92 
  93         if (prot & PAGE_RW)     /* only PAGE_COW or read-only supported now */
  94                 return -EINVAL;
  95         if (off & (inode->i_sb->s_blocksize - 1))
  96                 return -EINVAL;
  97         if (!inode->i_sb || !S_ISREG(inode->i_mode))
  98                 return -EACCES;
  99         if (!IS_RDONLY(inode)) {
 100                 inode->i_atime = CURRENT_TIME;
 101                 inode->i_dirt = 1;
 102         }
 103 
 104         mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
 105         if (!mpnt)
 106                 return -ENOMEM;
 107 
 108         unmap_page_range(addr, len);
 109         mpnt->vm_task = current;
 110         mpnt->vm_start = addr;
 111         mpnt->vm_end = addr + len;
 112         mpnt->vm_page_prot = prot;
 113         mpnt->vm_flags = 0;
 114         mpnt->vm_share = NULL;
 115         mpnt->vm_inode = inode;
 116         inode->i_count++;
 117         mpnt->vm_offset = off;
 118         mpnt->vm_ops = &nfs_file_mmap;
 119         insert_vm_struct(current, mpnt);
 120         merge_segments(current->mm->mmap, NULL, NULL);
 121         return 0;
 122 }

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