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