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