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