This source file includes following definitions.
- nfs_mmap
- nfs_file_mmap_nopage
1
2
3
4
5
6
7
8
9
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 static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
27 unsigned long address, unsigned long page, int error_code);
28
29 extern void file_mmap_free(struct vm_area_struct * area);
30 extern int file_mmap_share(struct vm_area_struct * from, struct vm_area_struct * to,
31 unsigned long address);
32
33 struct vm_operations_struct nfs_file_mmap = {
34 NULL,
35 file_mmap_free,
36 nfs_file_mmap_nopage,
37 NULL,
38 file_mmap_share,
39 NULL,
40 };
41
42
43
44 int nfs_mmap(struct inode * inode, struct file * file,
45 unsigned long addr, size_t len, int prot, unsigned long off)
46 {
47 struct vm_area_struct * mpnt;
48
49 if (prot & PAGE_RW)
50 return -EINVAL;
51 if (off & (inode->i_sb->s_blocksize - 1))
52 return -EINVAL;
53 if (!inode->i_sb || !S_ISREG(inode->i_mode))
54 return -EACCES;
55 if (!IS_RDONLY(inode)) {
56 inode->i_atime = CURRENT_TIME;
57 inode->i_dirt = 1;
58 }
59
60 mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
61 if (!mpnt)
62 return -ENOMEM;
63
64 unmap_page_range(addr, len);
65 mpnt->vm_task = current;
66 mpnt->vm_start = addr;
67 mpnt->vm_end = addr + len;
68 mpnt->vm_page_prot = prot;
69 mpnt->vm_flags = 0;
70 mpnt->vm_share = NULL;
71 mpnt->vm_inode = inode;
72 inode->i_count++;
73 mpnt->vm_offset = off;
74 mpnt->vm_ops = &nfs_file_mmap;
75 insert_vm_struct(current, mpnt);
76 merge_segments(current->mm->mmap, NULL, NULL);
77 return 0;
78 }
79
80
81 static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area, unsigned long address,
82 unsigned long page, int error_code)
83 {
84 struct inode * inode = area->vm_inode;
85 unsigned int clear;
86 unsigned long tmp;
87 int n;
88 int i;
89 int pos;
90 struct nfs_fattr fattr;
91
92 address &= PAGE_MASK;
93 pos = address - area->vm_start + area->vm_offset;
94
95 clear = 0;
96 if (address + PAGE_SIZE > area->vm_end) {
97 clear = address + PAGE_SIZE - area->vm_end;
98 }
99
100 n = NFS_SERVER(inode)->rsize;
101
102 for (i = 0; i < (PAGE_SIZE - clear); i += n) {
103 int hunk, result;
104
105 hunk = PAGE_SIZE - i;
106 if (hunk > n)
107 hunk = n;
108 result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
109 pos, hunk, (char *) (page + i), &fattr);
110 if (result < 0)
111 break;
112 pos += result;
113 if (result < n) {
114 i += result;
115 break;
116 }
117 }
118
119 #ifdef doweneedthishere
120 nfs_refresh_inode(inode, &fattr);
121 #endif
122
123 tmp = page + PAGE_SIZE;
124 while (clear--) {
125 *(char *)--tmp = 0;
126 }
127 return page;
128 }