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