Import 2.3.12pre9
[davej-history.git] / fs / block_dev.c
blob8331e9514d3cf6e34913cab5cb33b8c7221e29a7
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 balance_dirty(dev);
128 if (write_error)
129 break;
131 if ( buffercount ){
132 ll_rw_block(WRITE, buffercount, bufferlist);
133 for(i=0; i<buffercount; i++){
134 wait_on_buffer(bufferlist[i]);
135 if (!buffer_uptodate(bufferlist[i]))
136 write_error=1;
137 brelse(bufferlist[i]);
140 filp->f_reada = 1;
141 if(write_error)
142 return -EIO;
143 return written;
146 ssize_t block_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
148 struct inode * inode = filp->f_dentry->d_inode;
149 size_t block;
150 loff_t offset;
151 ssize_t blocksize;
152 ssize_t blocksize_bits, i;
153 size_t blocks, rblocks, left;
154 int bhrequest, uptodate;
155 struct buffer_head ** bhb, ** bhe;
156 struct buffer_head * buflist[NBUF];
157 struct buffer_head * bhreq[NBUF];
158 unsigned int chars;
159 loff_t size;
160 kdev_t dev;
161 ssize_t read;
163 dev = inode->i_rdev;
164 blocksize = BLOCK_SIZE;
165 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
166 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
167 i = blocksize;
168 blocksize_bits = 0;
169 while (i != 1) {
170 blocksize_bits++;
171 i >>= 1;
174 offset = *ppos;
175 if (blk_size[MAJOR(dev)])
176 size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
177 else
178 size = INT_MAX;
180 if (offset > size)
181 left = 0;
182 /* size - offset might not fit into left, so check explicitly. */
183 else if (size - offset > INT_MAX)
184 left = INT_MAX;
185 else
186 left = size - offset;
187 if (left > count)
188 left = count;
189 if (left <= 0)
190 return 0;
191 read = 0;
192 block = offset >> blocksize_bits;
193 offset &= blocksize-1;
194 size >>= blocksize_bits;
195 rblocks = blocks = (left + offset + blocksize - 1) >> blocksize_bits;
196 bhb = bhe = buflist;
197 if (filp->f_reada) {
198 if (blocks < read_ahead[MAJOR(dev)] / (blocksize >> 9))
199 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9);
200 if (rblocks > blocks)
201 blocks = rblocks;
204 if (block + blocks > size) {
205 blocks = size - block;
206 if (blocks == 0)
207 return 0;
210 /* We do this in a two stage process. We first try to request
211 as many blocks as we can, then we wait for the first one to
212 complete, and then we try to wrap up as many as are actually
213 done. This routine is rather generic, in that it can be used
214 in a filesystem by substituting the appropriate function in
215 for getblk.
217 This routine is optimized to make maximum use of the various
218 buffers and caches. */
220 do {
221 bhrequest = 0;
222 uptodate = 1;
223 while (blocks) {
224 --blocks;
225 *bhb = getblk(dev, block++, blocksize);
226 if (*bhb && !buffer_uptodate(*bhb)) {
227 uptodate = 0;
228 bhreq[bhrequest++] = *bhb;
231 if (++bhb == &buflist[NBUF])
232 bhb = buflist;
234 /* If the block we have on hand is uptodate, go ahead
235 and complete processing. */
236 if (uptodate)
237 break;
238 if (bhb == bhe)
239 break;
242 /* Now request them all */
243 if (bhrequest) {
244 ll_rw_block(READ, bhrequest, bhreq);
247 do { /* Finish off all I/O that has actually completed */
248 if (*bhe) {
249 wait_on_buffer(*bhe);
250 if (!buffer_uptodate(*bhe)) { /* read error? */
251 brelse(*bhe);
252 if (++bhe == &buflist[NBUF])
253 bhe = buflist;
254 left = 0;
255 break;
258 if (left < blocksize - offset)
259 chars = left;
260 else
261 chars = blocksize - offset;
262 *ppos += chars;
263 left -= chars;
264 read += chars;
265 if (*bhe) {
266 copy_to_user(buf,offset+(*bhe)->b_data,chars);
267 brelse(*bhe);
268 buf += chars;
269 } else {
270 while (chars-- > 0)
271 put_user(0,buf++);
273 offset = 0;
274 if (++bhe == &buflist[NBUF])
275 bhe = buflist;
276 } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
277 if (bhe == bhb && !blocks)
278 break;
279 } while (left > 0);
281 /* Release the read-ahead blocks */
282 while (bhe != bhb) {
283 brelse(*bhe);
284 if (++bhe == &buflist[NBUF])
285 bhe = buflist;
287 if (!read)
288 return -EIO;
289 filp->f_reada = 1;
290 return read;
294 * Filp may be NULL when we are called by an msync of a vma
295 * since the vma has no handle.
298 int block_fsync(struct file *filp, struct dentry *dentry)
300 return fsync_dev(dentry->d_inode->i_rdev);