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