This source file includes following definitions.
- xiafs_file_read
- xiafs_file_write
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/sched.h>
13 #include <linux/fs.h>
14 #include <linux/xia_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/fcntl.h>
18 #include <linux/stat.h>
19 #include <linux/locks.h>
20 #include <linux/pagemap.h>
21
22 #include <asm/segment.h>
23 #include <asm/system.h>
24
25 #include "xiafs_mac.h"
26
27 #define NBUF 32
28
29 #define MIN(a,b) (((a)<(b))?(a):(b))
30 #define MAX(a,b) (((a)>(b))?(a):(b))
31
32 static int xiafs_file_read(struct inode *, struct file *, char *, int);
33 static int xiafs_file_write(struct inode *, struct file *, const char *, int);
34
35
36
37
38
39 static struct file_operations xiafs_file_operations = {
40 NULL,
41 xiafs_file_read,
42 xiafs_file_write,
43 NULL,
44 NULL,
45 NULL,
46 generic_file_mmap,
47 NULL,
48 NULL,
49 xiafs_sync_file
50 };
51
52 struct inode_operations xiafs_file_inode_operations = {
53 &xiafs_file_operations,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 generic_readpage,
66 NULL,
67 xiafs_bmap,
68 xiafs_truncate,
69 NULL
70 };
71
72 static int
73 xiafs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
74 {
75 int read, left, chars;
76 int zone_nr, zones, f_zones, offset;
77 int bhrequest, uptodate;
78 struct buffer_head ** bhb, ** bhe;
79 struct buffer_head * bhreq[NBUF];
80 struct buffer_head * buflist[NBUF];
81
82 if (!inode) {
83 printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
84 return -EINVAL;
85 }
86 if (!S_ISREG(inode->i_mode)) {
87 printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
88 return -EINVAL;
89 }
90 offset = filp->f_pos;
91 left = inode->i_size - offset;
92 if (left > count)
93 left = count;
94 if (left <= 0)
95 return 0;
96 read = 0;
97 zone_nr = offset >> XIAFS_ZSIZE_BITS(inode->i_sb);
98 offset &= XIAFS_ZSIZE(inode->i_sb) -1 ;
99 f_zones =(inode->i_size+XIAFS_ZSIZE(inode->i_sb)-1)>>XIAFS_ZSIZE_BITS(inode->i_sb);
100 zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb);
101 bhb = bhe = buflist;
102 if (filp->f_reada) {
103 if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)))
104 zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
105 if (zone_nr + zones > f_zones)
106 zones = f_zones - zone_nr;
107 }
108
109
110
111
112
113
114
115
116
117
118
119 do {
120 bhrequest = 0;
121 uptodate = 1;
122 while (zones--) {
123 *bhb = xiafs_getblk(inode, zone_nr++, 0);
124 if (*bhb && !buffer_uptodate(*bhb)) {
125 uptodate = 0;
126 bhreq[bhrequest++] = *bhb;
127 }
128
129 if (++bhb == &buflist[NBUF])
130 bhb = buflist;
131
132
133
134 if (uptodate)
135 break;
136 if (bhb == bhe)
137 break;
138 }
139
140
141 if (bhrequest)
142 ll_rw_block(READ, bhrequest, bhreq);
143
144 do {
145 if (*bhe) {
146 wait_on_buffer(*bhe);
147 if (!buffer_uptodate(*bhe)) {
148 brelse(*bhe);
149 if (++bhe == &buflist[NBUF])
150 bhe = buflist;
151 left = 0;
152 break;
153 }
154 }
155 if (left < XIAFS_ZSIZE(inode->i_sb) - offset)
156 chars = left;
157 else
158 chars = XIAFS_ZSIZE(inode->i_sb) - offset;
159 filp->f_pos += chars;
160 left -= chars;
161 read += chars;
162 if (*bhe) {
163 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
164 brelse(*bhe);
165 buf += chars;
166 } else {
167 while (chars-->0)
168 put_user(0,buf++);
169 }
170 offset = 0;
171 if (++bhe == &buflist[NBUF])
172 bhe = buflist;
173 } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
174 } while (left > 0);
175
176
177 while (bhe != bhb) {
178 brelse(*bhe);
179 if (++bhe == &buflist[NBUF])
180 bhe = buflist;
181 };
182 if (!read)
183 return -EIO;
184 filp->f_reada = 1;
185 if (!IS_RDONLY (inode)) {
186 inode->i_atime = CURRENT_TIME;
187 inode->i_dirt = 1;
188 }
189 return read;
190 }
191
192 static int
193 xiafs_file_write(struct inode * inode, struct file * filp, const char * buf, int count)
194 {
195 off_t pos;
196 int written, c;
197 struct buffer_head * bh;
198 char * cp;
199
200 if (!inode) {
201 printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
202 return -EINVAL;
203 }
204 if (!S_ISREG(inode->i_mode)) {
205 printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
206 return -EINVAL;
207 }
208
209
210
211
212 if (filp->f_flags & O_APPEND)
213 pos = inode->i_size;
214 else
215 pos = filp->f_pos;
216 written = 0;
217 while (written < count) {
218 bh = xiafs_getblk(inode, pos >> XIAFS_ZSIZE_BITS(inode->i_sb), 1);
219 if (!bh) {
220 if (!written)
221 written = -ENOSPC;
222 break;
223 }
224 c = XIAFS_ZSIZE(inode->i_sb) - (pos & (XIAFS_ZSIZE(inode->i_sb) - 1));
225 if (c > count-written)
226 c = count-written;
227 if (c != XIAFS_ZSIZE(inode->i_sb) && !buffer_uptodate(bh)) {
228 ll_rw_block(READ, 1, &bh);
229 wait_on_buffer(bh);
230 if (!buffer_uptodate(bh)) {
231 brelse(bh);
232 if (!written)
233 written = -EIO;
234 break;
235 }
236 }
237 cp = (pos & (XIAFS_ZSIZE(inode->i_sb)-1)) + bh->b_data;
238 memcpy_fromfs(cp,buf,c);
239 update_vm_cache(inode,pos,cp,c);
240 pos += c;
241 if (pos > inode->i_size) {
242 inode->i_size = pos;
243 inode->i_dirt = 1;
244 }
245 written += c;
246 buf += c;
247 mark_buffer_uptodate(bh, 1);
248 mark_buffer_dirty(bh, 0);
249 brelse(bh);
250 }
251 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
252 filp->f_pos = pos;
253 inode->i_dirt = 1;
254
255 return written;
256 }