Linux 2.2.0
[davej-history.git] / fs / block_dev.c
blob11b5d02d2c84312c3951efa7ac0d39de514f09b2
1 /*
2 * linux/fs/block_dev.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/mm.h>
8 #include <linux/locks.h>
9 #include <linux/fcntl.h>
11 #include <asm/uaccess.h>
13 extern int *blk_size[];
14 extern int *blksize_size[];
16 #define MAX_BUF_PER_PAGE (PAGE_SIZE / 512)
17 #define NBUF 64
19 ssize_t block_write(struct file * filp, const char * buf,
20 size_t count, loff_t *ppos)
22 struct inode * inode = filp->f_dentry->d_inode;
23 ssize_t blocksize, blocksize_bits, i, buffercount, write_error;
24 ssize_t block, blocks;
25 loff_t offset;
26 ssize_t chars;
27 ssize_t written = 0;
28 struct buffer_head * bhlist[NBUF];
29 size_t size;
30 kdev_t dev;
31 struct buffer_head * bh, *bufferlist[NBUF];
32 register char * p;
34 write_error = buffercount = 0;
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)];
42 i = blocksize;
43 blocksize_bits = 0;
44 while(i != 1) {
45 blocksize_bits++;
46 i >>= 1;
49 block = *ppos >> blocksize_bits;
50 offset = *ppos & (blocksize-1);
52 if (blk_size[MAJOR(dev)])
53 size = ((loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
54 else
55 size = INT_MAX;
56 while (count>0) {
57 if (block >= size)
58 return written ? written : -ENOSPC;
59 chars = blocksize - offset;
60 if (chars > count)
61 chars=count;
63 #if 0
64 /* get the buffer head */
66 struct buffer_head * (*fn)(kdev_t, int, int) = getblk;
67 if (chars != blocksize)
68 fn = bread;
69 bh = fn(dev, block, blocksize);
71 #else
72 bh = getblk(dev, block, blocksize);
74 if (chars != blocksize && !buffer_uptodate(bh)) {
75 if(!filp->f_reada ||
76 !read_ahead[MAJOR(dev)]) {
77 /* We do this to force the read of a single buffer */
78 brelse(bh);
79 bh = bread(dev,block,blocksize);
80 } else {
81 /* Read-ahead before write */
82 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
83 if (block + blocks > size) blocks = size - block;
84 if (blocks > NBUF) blocks=NBUF;
85 bhlist[0] = bh;
86 for(i=1; i<blocks; i++){
87 bhlist[i] = getblk (dev, block+i, blocksize);
88 if(!bhlist[i]){
89 while(i >= 0) brelse(bhlist[i--]);
90 return written ? written : -EIO;
93 ll_rw_block(READ, blocks, bhlist);
94 for(i=1; i<blocks; i++) brelse(bhlist[i]);
95 wait_on_buffer(bh);
99 #endif
100 block++;
101 if (!bh)
102 return written ? written : -EIO;
103 p = offset + bh->b_data;
104 offset = 0;
105 *ppos += chars;
106 written += chars;
107 count -= chars;
108 copy_from_user(p,buf,chars);
109 p += chars;
110 buf += chars;
111 mark_buffer_uptodate(bh, 1);
112 mark_buffer_dirty(bh, 0);
113 if (filp->f_flags & O_SYNC)
114 bufferlist[buffercount++] = bh;
115 else
116 brelse(bh);
117 if (buffercount == NBUF){
118 ll_rw_block(WRITE, buffercount, bufferlist);
119 for(i=0; i<buffercount; i++){
120 wait_on_buffer(bufferlist[i]);
121 if (!buffer_uptodate(bufferlist[i]))
122 write_error=1;
123 brelse(bufferlist[i]);
125 buffercount=0;
127 if(write_error)
128 break;
130 if ( buffercount ){
131 ll_rw_block(WRITE, buffercount, bufferlist);
132 for(i=0; i<buffercount; i++){
133 wait_on_buffer(bufferlist[i]);
134 if (!buffer_uptodate(bufferlist[i]))
135 write_error=1;
136 brelse(bufferlist[i]);
139 filp->f_reada = 1;
140 if(write_error)
141 return -EIO;
142 return written;
145 ssize_t block_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
147 struct inode * inode = filp->f_dentry->d_inode;
148 size_t block;
149 loff_t offset;
150 ssize_t blocksize;
151 ssize_t blocksize_bits, i;
152 size_t blocks, rblocks, left;
153 int bhrequest, uptodate;
154 struct buffer_head ** bhb, ** bhe;
155 struct buffer_head * buflist[NBUF];
156 struct buffer_head * bhreq[NBUF];
157 unsigned int chars;
158 loff_t size;
159 kdev_t dev;
160 ssize_t read;
162 dev = inode->i_rdev;
163 blocksize = BLOCK_SIZE;
164 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
165 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
166 i = blocksize;
167 blocksize_bits = 0;
168 while (i != 1) {
169 blocksize_bits++;
170 i >>= 1;
173 offset = *ppos;
174 if (blk_size[MAJOR(dev)])
175 size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
176 else
177 size = INT_MAX;
179 if (offset > size)
180 left = 0;
181 /* size - offset might not fit into left, so check explicitly. */
182 else if (size - offset > INT_MAX)
183 left = INT_MAX;
184 else
185 left = size - offset;
186 if (left > count)
187 left = count;
188 if (left <= 0)
189 return 0;
190 read = 0;
191 block = offset >> blocksize_bits;
192 offset &= blocksize-1;
193 size >>= blocksize_bits;
194 rblocks = blocks = (left + offset + blocksize - 1) >> blocksize_bits;
195 bhb = bhe = buflist;
196 if (filp->f_reada) {
197 if (blocks < read_ahead[MAJOR(dev)] / (blocksize >> 9))
198 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9);
199 if (rblocks > blocks)
200 blocks = rblocks;
203 if (block + blocks > size) {
204 blocks = size - block;
205 if (blocks == 0)
206 return 0;
209 /* We do this in a two stage process. We first try to request
210 as many blocks as we can, then we wait for the first one to
211 complete, and then we try to wrap up as many as are actually
212 done. This routine is rather generic, in that it can be used
213 in a filesystem by substituting the appropriate function in
214 for getblk.
216 This routine is optimized to make maximum use of the various
217 buffers and caches. */
219 do {
220 bhrequest = 0;
221 uptodate = 1;
222 while (blocks) {
223 --blocks;
224 *bhb = getblk(dev, block++, blocksize);
225 if (*bhb && !buffer_uptodate(*bhb)) {
226 uptodate = 0;
227 bhreq[bhrequest++] = *bhb;
230 if (++bhb == &buflist[NBUF])
231 bhb = buflist;
233 /* If the block we have on hand is uptodate, go ahead
234 and complete processing. */
235 if (uptodate)
236 break;
237 if (bhb == bhe)
238 break;
241 /* Now request them all */
242 if (bhrequest) {
243 ll_rw_block(READ, bhrequest, bhreq);
246 do { /* Finish off all I/O that has actually completed */
247 if (*bhe) {
248 wait_on_buffer(*bhe);
249 if (!buffer_uptodate(*bhe)) { /* read error? */
250 brelse(*bhe);
251 if (++bhe == &buflist[NBUF])
252 bhe = buflist;
253 left = 0;
254 break;
257 if (left < blocksize - offset)
258 chars = left;
259 else
260 chars = blocksize - offset;
261 *ppos += chars;
262 left -= chars;
263 read += chars;
264 if (*bhe) {
265 copy_to_user(buf,offset+(*bhe)->b_data,chars);
266 brelse(*bhe);
267 buf += chars;
268 } else {
269 while (chars-- > 0)
270 put_user(0,buf++);
272 offset = 0;
273 if (++bhe == &buflist[NBUF])
274 bhe = buflist;
275 } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
276 } while (left > 0);
278 /* Release the read-ahead blocks */
279 while (bhe != bhb) {
280 brelse(*bhe);
281 if (++bhe == &buflist[NBUF])
282 bhe = buflist;
284 if (!read)
285 return -EIO;
286 filp->f_reada = 1;
287 return read;
291 * Filp may be NULL when we are called by an msync of a vma
292 * since the vma has no handle.
295 int block_fsync(struct file *filp, struct dentry *dentry)
297 return fsync_dev(dentry->d_inode->i_rdev);