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, const 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 kdev_t 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 kdev_t 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
201 else if (size - offset > INT_MAX)
202 left = INT_MAX;
203 else
204 left = size - offset;
205 if (left > count)
206 left = count;
207 if (left <= 0)
208 return 0;
209 read = 0;
210 block = offset >> blocksize_bits;
211 offset &= blocksize-1;
212 size >>= blocksize_bits;
213 rblocks = blocks = (left + offset + blocksize - 1) >> blocksize_bits;
214 bhb = bhe = buflist;
215 if (filp->f_reada) {
216 if (blocks < read_ahead[MAJOR(dev)] / (blocksize >> 9))
217 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9);
218 excess = (block + blocks) % blocks_per_cluster;
219 if ( blocks > excess )
220 blocks -= excess;
221 if (rblocks > blocks)
222 blocks = rblocks;
223
224 }
225 if (block + blocks > size)
226 blocks = size - block;
227
228
229
230
231
232
233
234
235
236
237
238 do {
239 bhrequest = 0;
240 uptodate = 1;
241 while (blocks) {
242 --blocks;
243 #if 1
244 if((block % blocks_per_cluster) == 0) {
245 for(i=0; i<blocks_per_cluster; i++) cluster_list[i] = block+i;
246 generate_cluster(dev, cluster_list, blocksize);
247 }
248 #endif
249 *bhb = getblk(dev, block++, blocksize);
250 if (*bhb && !(*bhb)->b_uptodate) {
251 uptodate = 0;
252 bhreq[bhrequest++] = *bhb;
253 }
254
255 if (++bhb == &buflist[NBUF])
256 bhb = buflist;
257
258
259
260 if (uptodate)
261 break;
262 if (bhb == bhe)
263 break;
264 }
265
266
267 if (bhrequest) {
268 ll_rw_block(READ, bhrequest, bhreq);
269 refill_freelist(blocksize);
270 }
271
272 do {
273 if (*bhe) {
274 wait_on_buffer(*bhe);
275 if (!(*bhe)->b_uptodate) {
276 brelse(*bhe);
277 if (++bhe == &buflist[NBUF])
278 bhe = buflist;
279 left = 0;
280 break;
281 }
282 }
283 if (left < blocksize - offset)
284 chars = left;
285 else
286 chars = blocksize - offset;
287 filp->f_pos += chars;
288 left -= chars;
289 read += chars;
290 if (*bhe) {
291 memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
292 brelse(*bhe);
293 buf += chars;
294 } else {
295 while (chars-- > 0)
296 put_user(0,buf++);
297 }
298 offset = 0;
299 if (++bhe == &buflist[NBUF])
300 bhe = buflist;
301 } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
302 } while (left > 0);
303
304
305 while (bhe != bhb) {
306 brelse(*bhe);
307 if (++bhe == &buflist[NBUF])
308 bhe = buflist;
309 };
310 if (!read)
311 return -EIO;
312 filp->f_reada = 1;
313 return read;
314 }
315
316 int block_fsync(struct inode *inode, struct file *filp)
317 {
318 return fsync_dev (inode->i_rdev);
319 }