Import 2.1.128
[davej-history.git] / fs / block_dev.c
blob7591037d070390646ae14298f286233ba2686b16
1 /*
2 * linux/fs/block_dev.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
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 <linux/mm.h>
14 #include <asm/uaccess.h>
15 #include <asm/system.h>
17 extern int *blk_size[];
18 extern int *blksize_size[];
20 #define MAX_BUF_PER_PAGE (PAGE_SIZE / 512)
21 #define NBUF 64
23 ssize_t block_write(struct file * filp, const char * buf,
24 size_t count, loff_t *ppos)
26 struct inode * inode = filp->f_dentry->d_inode;
27 ssize_t blocksize, blocksize_bits, i, buffercount, write_error;
28 ssize_t block, blocks;
29 loff_t offset;
30 ssize_t chars;
31 ssize_t written = 0;
32 struct buffer_head * bhlist[NBUF];
33 size_t size;
34 kdev_t dev;
35 struct buffer_head * bh, *bufferlist[NBUF];
36 register char * p;
38 write_error = buffercount = 0;
39 dev = inode->i_rdev;
40 if ( is_read_only( inode->i_rdev ))
41 return -EPERM;
42 blocksize = BLOCK_SIZE;
43 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
44 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
46 i = blocksize;
47 blocksize_bits = 0;
48 while(i != 1) {
49 blocksize_bits++;
50 i >>= 1;
53 block = *ppos >> blocksize_bits;
54 offset = *ppos & (blocksize-1);
56 if (blk_size[MAJOR(dev)])
57 size = ((loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS) >> blocksize_bits;
58 else
59 size = INT_MAX;
60 while (count>0) {
61 if (block >= size)
62 return written ? written : -ENOSPC;
63 chars = blocksize - offset;
64 if (chars > count)
65 chars=count;
67 #if 0
68 /* get the buffer head */
70 struct buffer_head * (*fn)(kdev_t, int, int) = getblk;
71 if (chars != blocksize)
72 fn = bread;
73 bh = fn(dev, block, blocksize);
75 #else
76 bh = getblk(dev, block, blocksize);
78 if (chars != blocksize && !buffer_uptodate(bh)) {
79 if(!filp->f_reada ||
80 !read_ahead[MAJOR(dev)]) {
81 /* We do this to force the read of a single buffer */
82 brelse(bh);
83 bh = bread(dev,block,blocksize);
84 } else {
85 /* Read-ahead before write */
86 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
87 if (block + blocks > size) blocks = size - block;
88 if (blocks > NBUF) blocks=NBUF;
89 bhlist[0] = bh;
90 for(i=1; i<blocks; i++){
91 bhlist[i] = getblk (dev, block+i, blocksize);
92 if(!bhlist[i]){
93 while(i >= 0) brelse(bhlist[i--]);
94 return written ? written : -EIO;
97 ll_rw_block(READ, blocks, bhlist);
98 for(i=1; i<blocks; i++) brelse(bhlist[i]);
99 wait_on_buffer(bh);
103 #endif
104 block++;
105 if (!bh)
106 return written ? written : -EIO;
107 p = offset + bh->b_data;
108 offset = 0;
109 *ppos += chars;
110 written += chars;
111 count -= chars;
112 copy_from_user(p,buf,chars);
113 p += chars;
114 buf += chars;
115 mark_buffer_uptodate(bh, 1);
116 mark_buffer_dirty(bh, 0);
117 if (filp->f_flags & O_SYNC)
118 bufferlist[buffercount++] = bh;
119 else
120 brelse(bh);
121 if (buffercount == NBUF){
122 ll_rw_block(WRITE, buffercount, bufferlist);
123 for(i=0; i<buffercount; i++){
124 wait_on_buffer(bufferlist[i]);
125 if (!buffer_uptodate(bufferlist[i]))
126 write_error=1;
127 brelse(bufferlist[i]);
129 buffercount=0;
131 if(write_error)
132 break;
134 if ( buffercount ){
135 ll_rw_block(WRITE, buffercount, bufferlist);
136 for(i=0; i<buffercount; i++){
137 wait_on_buffer(bufferlist[i]);
138 if (!buffer_uptodate(bufferlist[i]))
139 write_error=1;
140 brelse(bufferlist[i]);
143 filp->f_reada = 1;
144 if(write_error)
145 return -EIO;
146 return written;
149 ssize_t block_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
151 struct inode * inode = filp->f_dentry->d_inode;
152 size_t block;
153 loff_t offset;
154 ssize_t blocksize;
155 ssize_t blocksize_bits, i;
156 size_t blocks, rblocks, left;
157 int bhrequest, uptodate;
158 struct buffer_head ** bhb, ** bhe;
159 struct buffer_head * buflist[NBUF];
160 struct buffer_head * bhreq[NBUF];
161 unsigned int chars;
162 loff_t size;
163 kdev_t dev;
164 ssize_t read;
166 dev = inode->i_rdev;
167 blocksize = BLOCK_SIZE;
168 if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
169 blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
170 i = blocksize;
171 blocksize_bits = 0;
172 while (i != 1) {
173 blocksize_bits++;
174 i >>= 1;
177 offset = *ppos;
178 if (blk_size[MAJOR(dev)])
179 size = (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
180 else
181 size = INT_MAX;
183 if (offset > size)
184 left = 0;
185 /* size - offset might not fit into left, so check explicitly. */
186 else if (size - offset > INT_MAX)
187 left = INT_MAX;
188 else
189 left = size - offset;
190 if (left > count)
191 left = count;
192 if (left <= 0)
193 return 0;
194 read = 0;
195 block = offset >> blocksize_bits;
196 offset &= blocksize-1;
197 size >>= blocksize_bits;
198 rblocks = blocks = (left + offset + blocksize - 1) >> blocksize_bits;
199 bhb = bhe = buflist;
200 if (filp->f_reada) {
201 if (blocks < read_ahead[MAJOR(dev)] / (blocksize >> 9))
202 blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9);
203 if (rblocks > blocks)
204 blocks = rblocks;
207 if (block + blocks > size) {
208 blocks = size - block;
209 if (blocks == 0)
210 return 0;
213 /* We do this in a two stage process. We first try to request
214 as many blocks as we can, then we wait for the first one to
215 complete, and then we try to wrap up as many as are actually
216 done. This routine is rather generic, in that it can be used
217 in a filesystem by substituting the appropriate function in
218 for getblk.
220 This routine is optimized to make maximum use of the various
221 buffers and caches. */
223 do {
224 bhrequest = 0;
225 uptodate = 1;
226 while (blocks) {
227 --blocks;
228 *bhb = getblk(dev, block++, blocksize);
229 if (*bhb && !buffer_uptodate(*bhb)) {
230 uptodate = 0;
231 bhreq[bhrequest++] = *bhb;
234 if (++bhb == &buflist[NBUF])
235 bhb = buflist;
237 /* If the block we have on hand is uptodate, go ahead
238 and complete processing. */
239 if (uptodate)
240 break;
241 if (bhb == bhe)
242 break;
245 /* Now request them all */
246 if (bhrequest) {
247 ll_rw_block(READ, bhrequest, bhreq);
250 do { /* Finish off all I/O that has actually completed */
251 if (*bhe) {
252 wait_on_buffer(*bhe);
253 if (!buffer_uptodate(*bhe)) { /* read error? */
254 brelse(*bhe);
255 if (++bhe == &buflist[NBUF])
256 bhe = buflist;
257 left = 0;
258 break;
261 if (left < blocksize - offset)
262 chars = left;
263 else
264 chars = blocksize - offset;
265 *ppos += chars;
266 left -= chars;
267 read += chars;
268 if (*bhe) {
269 copy_to_user(buf,offset+(*bhe)->b_data,chars);
270 brelse(*bhe);
271 buf += chars;
272 } else {
273 while (chars-- > 0)
274 put_user(0,buf++);
276 offset = 0;
277 if (++bhe == &buflist[NBUF])
278 bhe = buflist;
279 } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
280 } while (left > 0);
282 /* Release the read-ahead blocks */
283 while (bhe != bhb) {
284 brelse(*bhe);
285 if (++bhe == &buflist[NBUF])
286 bhe = buflist;
288 if (!read)
289 return -EIO;
290 filp->f_reada = 1;
291 return read;
295 * Filp may be NULL when we are called by an msync of a vma
296 * since the vma has no handle.
299 int block_fsync(struct file *filp, struct dentry *dentry)
301 return fsync_dev(dentry->d_inode->i_rdev);