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