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