aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ncpfs/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ncpfs/mmap.c')
-rw-r--r--fs/ncpfs/mmap.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 70a69115500f..a94473d3072c 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -24,31 +24,35 @@
24 24
25/* 25/*
26 * Fill in the supplied page for mmap 26 * Fill in the supplied page for mmap
27 * XXX: how are we excluding truncate/invalidate here? Maybe need to lock
28 * page?
27 */ 29 */
28static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, 30static int ncp_file_mmap_fault(struct vm_area_struct *area,
29 unsigned long address, int *type) 31 struct vm_fault *vmf)
30{ 32{
31 struct file *file = area->vm_file; 33 struct file *file = area->vm_file;
32 struct dentry *dentry = file->f_path.dentry; 34 struct dentry *dentry = file->f_path.dentry;
33 struct inode *inode = dentry->d_inode; 35 struct inode *inode = dentry->d_inode;
34 struct page* page;
35 char *pg_addr; 36 char *pg_addr;
36 unsigned int already_read; 37 unsigned int already_read;
37 unsigned int count; 38 unsigned int count;
38 int bufsize; 39 int bufsize;
39 int pos; 40 int pos; /* XXX: loff_t ? */
40 41
41 page = alloc_page(GFP_HIGHUSER); /* ncpfs has nothing against high pages 42 /*
42 as long as recvmsg and memset works on it */ 43 * ncpfs has nothing against high pages as long
43 if (!page) 44 * as recvmsg and memset works on it
44 return page; 45 */
45 pg_addr = kmap(page); 46 vmf->page = alloc_page(GFP_HIGHUSER);
46 address &= PAGE_MASK; 47 if (!vmf->page)
47 pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT); 48 return VM_FAULT_OOM;
49 pg_addr = kmap(vmf->page);
50 pos = vmf->pgoff << PAGE_SHIFT;
48 51
49 count = PAGE_SIZE; 52 count = PAGE_SIZE;
50 if (address + PAGE_SIZE > area->vm_end) { 53 if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) {
51 count = area->vm_end - address; 54 WARN_ON(1); /* shouldn't happen? */
55 count = area->vm_end - (unsigned long)vmf->virtual_address;
52 } 56 }
53 /* what we can read in one go */ 57 /* what we can read in one go */
54 bufsize = NCP_SERVER(inode)->buffer_size; 58 bufsize = NCP_SERVER(inode)->buffer_size;
@@ -83,23 +87,21 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
83 87
84 if (already_read < PAGE_SIZE) 88 if (already_read < PAGE_SIZE)
85 memset(pg_addr + already_read, 0, PAGE_SIZE - already_read); 89 memset(pg_addr + already_read, 0, PAGE_SIZE - already_read);
86 flush_dcache_page(page); 90 flush_dcache_page(vmf->page);
87 kunmap(page); 91 kunmap(vmf->page);
88 92
89 /* 93 /*
90 * If I understand ncp_read_kernel() properly, the above always 94 * If I understand ncp_read_kernel() properly, the above always
91 * fetches from the network, here the analogue of disk. 95 * fetches from the network, here the analogue of disk.
92 * -- wli 96 * -- wli
93 */ 97 */
94 if (type)
95 *type = VM_FAULT_MAJOR;
96 count_vm_event(PGMAJFAULT); 98 count_vm_event(PGMAJFAULT);
97 return page; 99 return VM_FAULT_MAJOR;
98} 100}
99 101
100static struct vm_operations_struct ncp_file_mmap = 102static struct vm_operations_struct ncp_file_mmap =
101{ 103{
102 .nopage = ncp_file_mmap_nopage, 104 .fault = ncp_file_mmap_fault,
103}; 105};
104 106
105 107