This source file includes following definitions.
- block_write
- block_read
- block_fsync
1
2
3
4
5
6
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/locks.h>
11 #include <linux/fcntl.h>
12 #include <linux/mm.h>
13
14 #include <asm/segment.h>
15 #include <asm/system.h>
16
17 extern int *blk_size[];
18 extern int *blksize_size[];
19
20 #define MAX_BUF_PER_PAGE (PAGE_SIZE / 512)
21 #define NBUF 64
22
23 int block_write(struct inode * inode, struct file * filp, char * buf, int count)
24 {
25 int blocksize, blocksize_bits, i, j, buffercount,write_error;
26 int block, blocks;
27 loff_t offset;
28 int chars;
29 int written = 0;
30 int cluster_list[MAX_BUF_PER_PAGE];
31 struct buffer_head * bhlist[NBUF];
32 int blocks_per_cluster;
33 unsigned int size;
34 unsigned int dev;
35 struct buffer_head * bh, *bufferlist[NBUF];
36 register char * p;
37 int excess;
38
39 write_error = buffercount = 0;
40 dev = inode->i_rdev;
41 if ( is_read_only( inode->i_rdev ))
42 return -EPERM;
43 blocksize = BLOCK_SIZE;
44 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
45 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
46
47 i = blocksize;
48 blocksize_bits = 0;
49 while(i != 1) {
50 blocksize_bits++;
51 i >>= 1;
52 }
53
54 blocks_per_cluster = PAGE_SIZE / blocksize;
55
56 block = filp->f_pos >> blocksize_bits;
57 offset = filp->f_pos & (blocksize-1);
58
59 if (blk_size[MAJOR(dev)])
60 size = ((loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
61 else
62 size = INT_MAX;
63 while (count>0) {
64 if (block >= size)
65 return written;
66 chars = blocksize - offset;
67 if (chars > count)
68 chars=count;
69
70 #if 0
71 if (chars == blocksize)
72 bh = getblk(dev, block, blocksize);
73 else
74 bh = breada(dev,block,block+1,block+2,-1);
75
76 #else
77 for(i=0; i<blocks_per_cluster; i++) cluster_list[i] = block+i;
78 if((block % blocks_per_cluster) == 0)
79 generate_cluster(dev, cluster_list, blocksize);
80 bh = getblk(dev, block, blocksize);
81
82 if (chars != blocksize && !bh->b_uptodate) {
83 if(!filp->f_reada ||
84 !read_ahead[MAJOR(dev)]) {
85
86 brelse(bh);
87 bh = bread(dev,block,blocksize);
88 } else {
89
90 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
91 if (block + blocks > size) blocks = size - block;
92 if (blocks > NBUF) blocks=NBUF;
93 excess = (block + blocks) % blocks_per_cluster;
94 if ( blocks > excess )
95 blocks -= excess;
96 bhlist[0] = bh;
97 for(i=1; i<blocks; i++){
98 if(((i+block) % blocks_per_cluster) == 0) {
99 for(j=0; j<blocks_per_cluster; j++) cluster_list[j] = block+i+j;
100 generate_cluster(dev, cluster_list, blocksize);
101 };
102 bhlist[i] = getblk (dev, block+i, blocksize);
103 if(!bhlist[i]){
104 while(i >= 0) brelse(bhlist[i--]);
105 return written? written: -EIO;
106 };
107 };
108 ll_rw_block(READ, blocks, bhlist);
109 for(i=1; i<blocks; i++) brelse(bhlist[i]);
110 wait_on_buffer(bh);
111
112 };
113 };
114 #endif
115 block++;
116 if (!bh)
117 return written?written:-EIO;
118 p = offset + bh->b_data;
119 offset = 0;
120 filp->f_pos += chars;
121 written += chars;
122 count -= chars;
123 memcpy_fromfs(p,buf,chars);
124 p += chars;
125 buf += chars;
126 bh->b_uptodate = 1;
127 mark_buffer_dirty(bh, 0);
128 if (filp->f_flags & O_SYNC)
129 bufferlist[buffercount++] = bh;
130 else
131 brelse(bh);
132 if (buffercount == NBUF){
133 ll_rw_block(WRITE, buffercount, bufferlist);
134 for(i=0; i<buffercount; i++){
135 wait_on_buffer(bufferlist[i]);
136 if (!bufferlist[i]->b_uptodate)
137 write_error=1;
138 brelse(bufferlist[i]);
139 }
140 buffercount=0;
141 }
142 if(write_error)
143 break;
144 }
145 if ( buffercount ){
146 ll_rw_block(WRITE, buffercount, bufferlist);
147 for(i=0; i<buffercount; i++){
148 wait_on_buffer(bufferlist[i]);
149 if (!bufferlist[i]->b_uptodate)
150 write_error=1;
151 brelse(bufferlist[i]);
152 }
153 }
154 filp->f_reada = 1;
155 if(write_error)
156 return -EIO;
157 return written;
158 }
159
160 int block_read(struct inode * inode, struct file * filp, char * buf, int count)
161 {
162 unsigned int block;
163 loff_t offset;
164 int blocksize;
165 int blocksize_bits, i;
166 unsigned int blocks, rblocks, left;
167 int bhrequest, uptodate;
168 int cluster_list[MAX_BUF_PER_PAGE];
169 int blocks_per_cluster;
170 struct buffer_head ** bhb, ** bhe;
171 struct buffer_head * buflist[NBUF];
172 struct buffer_head * bhreq[NBUF];
173 unsigned int chars;
174 loff_t size;
175 unsigned int dev;
176 int read;
177 int excess;
178
179 dev = inode->i_rdev;
180 blocksize = BLOCK_SIZE;
181 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
182 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
183 i = blocksize;
184 blocksize_bits = 0;
185 while (i != 1) {
186 blocksize_bits++;
187 i >>= 1;
188 }
189
190 offset = filp->f_pos;
191 if (blk_size[MAJOR(dev)])
192 size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
193 else
194 size = INT_MAX;
195
196 blocks_per_cluster = PAGE_SIZE / blocksize;
197
198 if (offset > size)
199 left = 0;
200 else
201 left = size - offset;
202 if (left > count)
203 left = count;
204 if (left <= 0)
205 return 0;
206 read = 0;
207 block = offset >> blocksize_bits;
208 offset &= blocksize-1;
209 size >>= blocksize_bits;
210 rblocks = blocks = (left + offset + blocksize - 1) >> blocksize_bits;
211 bhb = bhe = buflist;
212 if (filp->f_reada) {
213 if (blocks < read_ahead[MAJOR(dev)] / (blocksize >> 9))
214 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9);
215 excess = (block + blocks) % blocks_per_cluster;
216 if ( blocks > excess )
217 blocks -= excess;
218 if (rblocks > blocks)
219 blocks = rblocks;
220
221 }
222 if (block + blocks > size)
223 blocks = size - block;
224
225
226
227
228
229
230
231
232
233
234
235 do {
236 bhrequest = 0;
237 uptodate = 1;
238 while (blocks) {
239 --blocks;
240 #if 1
241 if((block % blocks_per_cluster) == 0) {
242 for(i=0; i<blocks_per_cluster; i++) cluster_list[i] = block+i;
243 generate_cluster(dev, cluster_list, blocksize);
244 }
245 #endif
246 *bhb = getblk(dev, block++, blocksize);
247 if (*bhb && !(*bhb)->b_uptodate) {
248 uptodate = 0;
249 bhreq[bhrequest++] = *bhb;
250 }
251
252 if (++bhb == &buflist[NBUF])
253 bhb = buflist;
254
255
256
257 if (uptodate)
258 break;
259 if (bhb == bhe)
260 break;
261 }
262
263
264 if (bhrequest) {
265 ll_rw_block(READ, bhrequest, bhreq);
266 refill_freelist(blocksize);
267 }
268
269 do {
270 if (*bhe) {
271 wait_on_buffer(*bhe);
272 if (!(*bhe)->b_uptodate) {
273 brelse(*bhe);
274 if (++bhe == &buflist[NBUF])
275 bhe = buflist;
276 left = 0;
277 break;
278 }
279 }
280 if (left < blocksize - offset)
281 chars = left;
282 else
283 chars = blocksize - offset;
284 filp->f_pos += chars;
285 left -= chars;
286 read += chars;
287 if (*bhe) {
288 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
289 brelse(*bhe);
290 buf += chars;
291 } else {
292 while (chars-- > 0)
293 put_user(0,buf++);
294 }
295 offset = 0;
296 if (++bhe == &buflist[NBUF])
297 bhe = buflist;
298 } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
299 } while (left > 0);
300
301
302 while (bhe != bhb) {
303 brelse(*bhe);
304 if (++bhe == &buflist[NBUF])
305 bhe = buflist;
306 };
307 if (!read)
308 return -EIO;
309 filp->f_reada = 1;
310 return read;
311 }
312
313 int block_fsync(struct inode *inode, struct file *filp)
314 {
315 return fsync_dev (inode->i_rdev);
316 }