Blame view

fs/ncpfs/mmap.c 2.93 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
  /*
   *  mmap.c
   *
   *  Copyright (C) 1995, 1996 by Volker Lendecke
   *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
   *
   */
  
  #include <linux/stat.h>
  #include <linux/time.h>
  #include <linux/kernel.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
12
  #include <linux/gfp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
  #include <linux/mm.h>
  #include <linux/shm.h>
  #include <linux/errno.h>
  #include <linux/mman.h>
  #include <linux/string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #include <linux/fcntl.h>
456f998ec   Ying Han   memcg: add the pa...
19
  #include <linux/memcontrol.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
  #include <asm/uaccess.h>
  #include <asm/system.h>
32c419d95   Al Viro   move internal-onl...
23
  #include "ncp_fs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
  /*
   * Fill in the supplied page for mmap
d0217ac04   Nick Piggin   mm: fault feedbac...
26
27
   * XXX: how are we excluding truncate/invalidate here? Maybe need to lock
   * page?
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
   */
d0217ac04   Nick Piggin   mm: fault feedbac...
29
30
  static int ncp_file_mmap_fault(struct vm_area_struct *area,
  					struct vm_fault *vmf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
  {
  	struct file *file = area->vm_file;
92e5baef8   Josef Sipek   [PATCH] struct pa...
33
  	struct dentry *dentry = file->f_path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  	struct inode *inode = dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
  	char *pg_addr;
  	unsigned int already_read;
  	unsigned int count;
  	int bufsize;
d0217ac04   Nick Piggin   mm: fault feedbac...
39
  	int pos; /* XXX: loff_t ? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40

d0217ac04   Nick Piggin   mm: fault feedbac...
41
42
43
44
45
46
47
48
49
  	/*
  	 * ncpfs has nothing against high pages as long
  	 * as recvmsg and memset works on it
  	 */
  	vmf->page = alloc_page(GFP_HIGHUSER);
  	if (!vmf->page)
  		return VM_FAULT_OOM;
  	pg_addr = kmap(vmf->page);
  	pos = vmf->pgoff << PAGE_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
  
  	count = PAGE_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  	/* what we can read in one go */
  	bufsize = NCP_SERVER(inode)->buffer_size;
  
  	already_read = 0;
  	if (ncp_make_open(inode, O_RDONLY) >= 0) {
  		while (already_read < count) {
  			int read_this_time;
  			int to_read;
  
  			to_read = bufsize - (pos % bufsize);
  
  			to_read = min_t(unsigned int, to_read, count - already_read);
  
  			if (ncp_read_kernel(NCP_SERVER(inode),
  				     NCP_FINFO(inode)->file_handle,
  				     pos, to_read,
  				     pg_addr + already_read,
  				     &read_this_time) != 0) {
  				read_this_time = 0;
  			}
  			pos += read_this_time;
  			already_read += read_this_time;
  
  			if (read_this_time < to_read) {
  				break;
  			}
  		}
  		ncp_inode_close(inode);
  
  	}
  
  	if (already_read < PAGE_SIZE)
  		memset(pg_addr + already_read, 0, PAGE_SIZE - already_read);
d0217ac04   Nick Piggin   mm: fault feedbac...
85
86
  	flush_dcache_page(vmf->page);
  	kunmap(vmf->page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
92
  
  	/*
  	 * If I understand ncp_read_kernel() properly, the above always
  	 * fetches from the network, here the analogue of disk.
  	 * -- wli
  	 */
f8891e5e1   Christoph Lameter   [PATCH] Light wei...
93
  	count_vm_event(PGMAJFAULT);
456f998ec   Ying Han   memcg: add the pa...
94
  	mem_cgroup_count_vm_event(area->vm_mm, PGMAJFAULT);
d0217ac04   Nick Piggin   mm: fault feedbac...
95
  	return VM_FAULT_MAJOR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  }
f0f37e2f7   Alexey Dobriyan   const: mark struc...
97
  static const struct vm_operations_struct ncp_file_mmap =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  {
54cb8821d   Nick Piggin   mm: merge populat...
99
  	.fault = ncp_file_mmap_fault,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
105
  };
  
  
  /* This is used for a general mmap of a ncp file */
  int ncp_mmap(struct file *file, struct vm_area_struct *vma)
  {
92e5baef8   Josef Sipek   [PATCH] struct pa...
106
  	struct inode *inode = file->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  	
  	DPRINTK("ncp_mmap: called
  ");
  
  	if (!ncp_conn_valid(NCP_SERVER(inode)))
  		return -EIO;
  
  	/* only PAGE_COW or read-only supported now */
  	if (vma->vm_flags & VM_SHARED)
  		return -EINVAL;
  	/* we do not support files bigger than 4GB... We eventually 
  	   supports just 4GB... */
  	if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff 
  	   > (1U << (32 - PAGE_SHIFT)))
  		return -EFBIG;
  
  	vma->vm_ops = &ncp_file_mmap;
  	file_accessed(file);
  	return 0;
  }