4 * Copyright (C) 1991, 1992 Linus Torvalds
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>
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)
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
;
32 struct buffer_head
* bhlist
[NBUF
];
35 struct buffer_head
* bh
, *bufferlist
[NBUF
];
38 write_error
= buffercount
= 0;
40 if ( is_read_only( inode
->i_rdev
))
42 blocksize
= BLOCK_SIZE
;
43 if (blksize_size
[MAJOR(dev
)] && blksize_size
[MAJOR(dev
)][MINOR(dev
)])
44 blocksize
= blksize_size
[MAJOR(dev
)][MINOR(dev
)];
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
;
62 return written
? written
: -ENOSPC
;
63 chars
= blocksize
- offset
;
68 /* get the buffer head */
70 struct buffer_head
* (*fn
)(kdev_t
, int, int) = getblk
;
71 if (chars
!= blocksize
)
73 bh
= fn(dev
, block
, blocksize
);
76 bh
= getblk(dev
, block
, blocksize
);
78 if (chars
!= blocksize
&& !buffer_uptodate(bh
)) {
80 !read_ahead
[MAJOR(dev
)]) {
81 /* We do this to force the read of a single buffer */
83 bh
= bread(dev
,block
,blocksize
);
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
;
90 for(i
=1; i
<blocks
; i
++){
91 bhlist
[i
] = getblk (dev
, block
+i
, blocksize
);
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
]);
106 return written
? written
: -EIO
;
107 p
= offset
+ bh
->b_data
;
112 copy_from_user(p
,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
;
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
]))
127 brelse(bufferlist
[i
]);
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
]))
140 brelse(bufferlist
[i
]);
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
;
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
];
167 blocksize
= BLOCK_SIZE
;
168 if (blksize_size
[MAJOR(dev
)] && blksize_size
[MAJOR(dev
)][MINOR(dev
)])
169 blocksize
= blksize_size
[MAJOR(dev
)][MINOR(dev
)];
178 if (blk_size
[MAJOR(dev
)])
179 size
= (loff_t
) blk_size
[MAJOR(dev
)][MINOR(dev
)] << BLOCK_SIZE_BITS
;
185 /* size - offset might not fit into left, so check explicitly. */
186 else if (size
- offset
> INT_MAX
)
189 left
= size
- offset
;
195 block
= offset
>> blocksize_bits
;
196 offset
&= blocksize
-1;
197 size
>>= blocksize_bits
;
198 rblocks
= blocks
= (left
+ offset
+ blocksize
- 1) >> blocksize_bits
;
201 if (blocks
< read_ahead
[MAJOR(dev
)] / (blocksize
>> 9))
202 blocks
= read_ahead
[MAJOR(dev
)] / (blocksize
>> 9);
203 if (rblocks
> blocks
)
207 if (block
+ blocks
> size
) {
208 blocks
= size
- block
;
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
220 This routine is optimized to make maximum use of the various
221 buffers and caches. */
228 *bhb
= getblk(dev
, block
++, blocksize
);
229 if (*bhb
&& !buffer_uptodate(*bhb
)) {
231 bhreq
[bhrequest
++] = *bhb
;
234 if (++bhb
== &buflist
[NBUF
])
237 /* If the block we have on hand is uptodate, go ahead
238 and complete processing. */
245 /* Now request them all */
247 ll_rw_block(READ
, bhrequest
, bhreq
);
250 do { /* Finish off all I/O that has actually completed */
252 wait_on_buffer(*bhe
);
253 if (!buffer_uptodate(*bhe
)) { /* read error? */
255 if (++bhe
== &buflist
[NBUF
])
261 if (left
< blocksize
- offset
)
264 chars
= blocksize
- offset
;
269 copy_to_user(buf
,offset
+(*bhe
)->b_data
,chars
);
277 if (++bhe
== &buflist
[NBUF
])
279 } while (left
> 0 && bhe
!= bhb
&& (!*bhe
|| !buffer_locked(*bhe
)));
282 /* Release the read-ahead blocks */
285 if (++bhe
== &buflist
[NBUF
])
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
);