root/fs/smbfs/mmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. smb_file_mmap_nopage
  2. smb_mmap

   1 /*
   2  *  mmap.c
   3  *
   4  *  Copyright (C) 1995 by Paal-Kr. Engstad and 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/smb_fs.h>
  18 #include <linux/fcntl.h>
  19 
  20 #include <asm/segment.h>
  21 #include <asm/system.h>
  22 
  23 /*
  24  * Fill in the supplied page for mmap
  25  */
  26 static unsigned long 
  27 smb_file_mmap_nopage(struct vm_area_struct * area,
     /* [previous][next][first][last][top][bottom][index][help] */
  28                      unsigned long address, int no_share)
  29 {
  30         struct inode * inode = area->vm_inode;
  31         unsigned long page;
  32         unsigned int clear;
  33         unsigned long tmp;
  34         int n;
  35         int i;
  36         int pos;
  37 
  38         page = __get_free_page(GFP_KERNEL);
  39         if (!page)
  40                 return 0;
  41         address &= PAGE_MASK;
  42         pos = address - area->vm_start + area->vm_offset;
  43 
  44         clear = 0;
  45         if (address + PAGE_SIZE > area->vm_end) {
  46                 clear = address + PAGE_SIZE - area->vm_end;
  47         }
  48 
  49         /* what we can read in one go */
  50         n = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 3 - 10;
  51 
  52         if (smb_make_open(inode, O_RDONLY) < 0) {
  53                 clear = PAGE_SIZE;
  54         }
  55         else
  56         {
  57         
  58                 for (i = 0; i < (PAGE_SIZE - clear); i += n) {
  59                         int hunk, result;
  60 
  61                         hunk = PAGE_SIZE - i;
  62                         if (hunk > n)
  63                                 hunk = n;
  64 
  65                         DDPRINTK("smb_file_mmap_nopage: reading\n");
  66                         DDPRINTK("smb_file_mmap_nopage: pos = %d\n", pos);
  67                         result = smb_proc_read(SMB_SERVER(inode),
  68                                                SMB_FINFO(inode), pos, hunk,
  69                                                (char *) (page + i), 0);
  70                         DDPRINTK("smb_file_mmap_nopage: result= %d\n", result);
  71                         if (result < 0)
  72                                 break;
  73                         pos += result;
  74                         if (result < n) {
  75                                 i += result;
  76                                 break;
  77                         }
  78                 }
  79         }
  80 
  81         tmp = page + PAGE_SIZE;
  82         while (clear--) {
  83                 *(char *)--tmp = 0;
  84         }
  85         return page;
  86 }
  87 
  88 struct vm_operations_struct smb_file_mmap = {
  89         NULL,                   /* open */
  90         NULL,                   /* close */
  91         NULL,                   /* unmap */
  92         NULL,                   /* protect */
  93         NULL,                   /* sync */
  94         NULL,                   /* advise */
  95         smb_file_mmap_nopage,   /* nopage */
  96         NULL,                   /* wppage */
  97         NULL,                   /* swapout */
  98         NULL,                   /* swapin */
  99 };
 100 
 101 
 102 /* This is used for a general mmap of a smb file */
 103 int
 104 smb_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         DPRINTK("smb_mmap: called\n");
 107 
 108         /* only PAGE_COW or read-only supported now */
 109         if (vma->vm_flags & VM_SHARED)  
 110                 return -EINVAL;
 111         if (!inode->i_sb || !S_ISREG(inode->i_mode))
 112                 return -EACCES;
 113         if (!IS_RDONLY(inode)) {
 114                 inode->i_atime = CURRENT_TIME;
 115                 inode->i_dirt = 1;
 116         }
 117 
 118         vma->vm_inode = inode;
 119         inode->i_count++;
 120         vma->vm_ops = &smb_file_mmap;
 121         return 0;
 122 }
 123 
 124 /*
 125  * Overrides for Emacs so that we follow Linus's tabbing style.
 126  * Emacs will notice this stuff at the end of the file and automatically
 127  * adjust the settings for this buffer only.  This must remain at the end
 128  * of the file.
 129  * ---------------------------------------------------------------------------
 130  * Local variables:
 131  * c-indent-level: 8
 132  * c-brace-imaginary-offset: 0
 133  * c-brace-offset: -8
 134  * c-argdecl-indent: 8
 135  * c-label-offset: -8
 136  * c-continued-statement-offset: 8
 137  * c-continued-brace-offset: 0
 138  * End:
 139  */

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