This source file includes following definitions.
- nfs_fsync
- nfs_file_read
- nfs_file_write
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #ifdef MODULE
18 #include <linux/module.h>
19 #endif
20
21 #include <asm/segment.h>
22 #include <asm/system.h>
23
24 #include <linux/sched.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/fcntl.h>
28 #include <linux/stat.h>
29 #include <linux/mm.h>
30 #include <linux/nfs_fs.h>
31 #include <linux/malloc.h>
32
33 static int nfs_file_read(struct inode *, struct file *, char *, int);
34 static int nfs_file_write(struct inode *, struct file *, char *, int);
35 static int nfs_fsync(struct inode *, struct file *);
36
37 static struct file_operations nfs_file_operations = {
38 NULL,
39 nfs_file_read,
40 nfs_file_write,
41 NULL,
42 NULL,
43 NULL,
44 nfs_mmap,
45 NULL,
46 NULL,
47 nfs_fsync,
48 };
49
50 struct inode_operations nfs_file_inode_operations = {
51 &nfs_file_operations,
52 NULL,
53 NULL,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL
65 };
66
67
68 struct read_cache {
69 int in_use;
70 unsigned long inode_num;
71 off_t file_pos;
72 int len;
73 unsigned long time;
74 char * buf;
75 int buf_size;
76 };
77
78 #define READ_CACHE_SIZE 5
79 #define EXPIRE_CACHE (HZ * 3)
80
81 unsigned long num_requests = 0;
82 unsigned long num_cache_hits = 0;
83
84 static int tail = 0;
85
86 static struct read_cache cache[READ_CACHE_SIZE] = {
87 { 0, 0, -1, 0, 0, NULL, 0 },
88 { 0, 0, -1, 0, 0, NULL, 0 },
89 { 0, 0, -1, 0, 0, NULL, 0 },
90 { 0, 0, -1, 0, 0, NULL, 0 },
91 { 0, 0, -1, 0, 0, NULL, 0 } };
92
93 static int nfs_fsync(struct inode *inode, struct file *file)
94 {
95 return 0;
96 }
97
98 static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
99 int count)
100 {
101 int result, hunk, i, n, fs;
102 struct nfs_fattr fattr;
103 char *data;
104 off_t pos;
105
106 if (!inode) {
107 printk("nfs_file_read: inode = NULL\n");
108 return -EINVAL;
109 }
110 if (!S_ISREG(inode->i_mode)) {
111 printk("nfs_file_read: read from non-file, mode %07o\n",
112 inode->i_mode);
113 return -EINVAL;
114 }
115 pos = file->f_pos;
116 if (pos + count > inode->i_size)
117 count = inode->i_size - pos;
118 if (count <= 0)
119 return 0;
120 ++num_requests;
121 cli();
122 for (i = 0; i < READ_CACHE_SIZE; i++)
123 if ((cache[i].inode_num == inode->i_ino)
124 && (cache[i].file_pos <= pos)
125 && (cache[i].file_pos + cache[i].len >= pos + count)
126 && (abs(jiffies - cache[i].time) <= EXPIRE_CACHE))
127 break;
128 if (i < READ_CACHE_SIZE) {
129 ++cache[i].in_use;
130 sti();
131 ++num_cache_hits;
132 memcpy_tofs(buf, cache[i].buf + pos - cache[i].file_pos, count);
133 --cache[i].in_use;
134 file->f_pos += count;
135 return count;
136 }
137 sti();
138 n = NFS_SERVER(inode)->rsize;
139 for (i = 0; i < count - n; i += n) {
140 result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
141 pos, n, buf, &fattr, 1);
142 if (result < 0)
143 return result;
144 pos += result;
145 buf += result;
146 if (result < n) {
147 file->f_pos = pos;
148 nfs_refresh_inode(inode, &fattr);
149 return i + result;
150 }
151 }
152 fs = 0;
153 if (!(data = (char *)kmalloc(n, GFP_KERNEL))) {
154 data = buf;
155 fs = 1;
156 }
157 result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
158 pos, n, data, &fattr, fs);
159 if (result < 0) {
160 if (!fs)
161 kfree_s(data, n);
162 return result;
163 }
164 hunk = count - i;
165 if (result < hunk)
166 hunk = result;
167 if (fs) {
168 file->f_pos = pos + hunk;
169 nfs_refresh_inode(inode, &fattr);
170 return i + hunk;
171 }
172 memcpy_tofs(buf, data, hunk);
173 file->f_pos = pos + hunk;
174 nfs_refresh_inode(inode, &fattr);
175 cli();
176 if (cache[tail].in_use == 0) {
177 if (cache[tail].buf)
178 kfree_s(cache[tail].buf, cache[tail].buf_size);
179 cache[tail].buf = data;
180 cache[tail].buf_size = n;
181 cache[tail].inode_num = inode->i_ino;
182 cache[tail].file_pos = pos;
183 cache[tail].len = result;
184 cache[tail].time = jiffies;
185 if (++tail >= READ_CACHE_SIZE)
186 tail = 0;
187 } else
188 kfree_s(data, n);
189 sti();
190 return i + hunk;
191 }
192
193 static int nfs_file_write(struct inode *inode, struct file *file, char *buf,
194 int count)
195 {
196 int result, hunk, i, n, pos;
197 struct nfs_fattr fattr;
198
199 if (!inode) {
200 printk("nfs_file_write: inode = NULL\n");
201 return -EINVAL;
202 }
203 if (!S_ISREG(inode->i_mode)) {
204 printk("nfs_file_write: write to non-file, mode %07o\n",
205 inode->i_mode);
206 return -EINVAL;
207 }
208 if (count <= 0)
209 return 0;
210
211 cli();
212
213 for (i = 0; i < READ_CACHE_SIZE; i++)
214 if(cache[i].inode_num == inode->i_ino)
215 cache[i].time -= EXPIRE_CACHE;
216 sti();
217
218 pos = file->f_pos;
219 if (file->f_flags & O_APPEND)
220 pos = inode->i_size;
221 n = NFS_SERVER(inode)->wsize;
222 for (i = 0; i < count; i += n) {
223 hunk = count - i;
224 if (hunk >= n)
225 hunk = n;
226 result = nfs_proc_write(NFS_SERVER(inode), NFS_FH(inode),
227 pos, hunk, buf, &fattr);
228 if (result < 0)
229 return result;
230 pos += hunk;
231 buf += hunk;
232 if (hunk < n) {
233 i += hunk;
234 break;
235 }
236 }
237 file->f_pos = pos;
238 nfs_refresh_inode(inode, &fattr);
239 return i;
240 }
241