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 <asm/segment.h>
12 #include <asm/system.h>
14 extern int *blk_size
[];
15 extern int *blksize_size
[];
17 int block_write(struct inode
* inode
, struct file
* filp
, char * buf
, int count
)
19 int blocksize
, blocksize_bits
, i
;
26 struct buffer_head
* bh
;
30 blocksize
= BLOCK_SIZE
;
31 if (blksize_size
[MAJOR(dev
)] && blksize_size
[MAJOR(dev
)][MINOR(dev
)])
32 blocksize
= blksize_size
[MAJOR(dev
)][MINOR(dev
)];
41 block
= filp
->f_pos
>> blocksize_bits
;
42 offset
= filp
->f_pos
& (blocksize
-1);
44 if (blk_size
[MAJOR(dev
)])
45 size
= (blk_size
[MAJOR(dev
)][MINOR(dev
)] << BLOCK_SIZE_BITS
) >> blocksize_bits
;
51 chars
= blocksize
- offset
;
54 if (chars
== blocksize
)
55 bh
= getblk(dev
, block
, blocksize
);
57 bh
= breada(dev
,block
,block
+1,block
+2,-1);
60 return written
?written
:-EIO
;
61 p
= offset
+ bh
->b_data
;
66 memcpy_fromfs(p
,buf
,chars
);
78 int block_read(struct inode
* inode
, struct file
* filp
, char * buf
, int count
)
83 int blocksize_bits
, i
;
86 int bhrequest
, uptodate
;
87 struct buffer_head
** bhb
, ** bhe
;
88 struct buffer_head
* buflist
[NBUF
];
89 struct buffer_head
* bhreq
[NBUF
];
96 blocksize
= BLOCK_SIZE
;
97 if (blksize_size
[MAJOR(dev
)] && blksize_size
[MAJOR(dev
)][MINOR(dev
)])
98 blocksize
= blksize_size
[MAJOR(dev
)][MINOR(dev
)];
106 offset
= filp
->f_pos
;
107 if (blk_size
[MAJOR(dev
)])
108 size
= blk_size
[MAJOR(dev
)][MINOR(dev
)] << BLOCK_SIZE_BITS
;
115 left
= size
- offset
;
121 block
= offset
>> blocksize_bits
;
122 offset
&= blocksize
-1;
123 size
>>= blocksize_bits
;
124 blocks
= (left
+ offset
+ blocksize
- 1) >> blocksize_bits
;
127 blocks
+= read_ahead
[MAJOR(dev
)] / (blocksize
>> 9);
128 if (block
+ blocks
> size
)
129 blocks
= size
- block
;
132 /* We do this in a two stage process. We first try and request
133 as many blocks as we can, then we wait for the first one to
134 complete, and then we try and wrap up as many as are actually
135 done. This routine is rather generic, in that it can be used
136 in a filesystem by substituting the appropriate function in
139 This routine is optimized to make maximum use of the various
140 buffers and caches. */
147 *bhb
= getblk(dev
, block
++, blocksize
);
148 if (*bhb
&& !(*bhb
)->b_uptodate
) {
150 bhreq
[bhrequest
++] = *bhb
;
153 if (++bhb
== &buflist
[NBUF
])
156 /* If the block we have on hand is uptodate, go ahead
157 and complete processing. */
164 /* Now request them all */
166 ll_rw_block(READ
, bhrequest
, bhreq
);
168 do { /* Finish off all I/O that has actually completed */
170 wait_on_buffer(*bhe
);
171 if (!(*bhe
)->b_uptodate
) { /* read error? */
173 if (++bhe
== &buflist
[NBUF
])
179 if (left
< blocksize
- offset
)
182 chars
= blocksize
- offset
;
183 filp
->f_pos
+= chars
;
187 memcpy_tofs(buf
,offset
+(*bhe
)->b_data
,chars
);
192 put_fs_byte(0,buf
++);
195 if (++bhe
== &buflist
[NBUF
])
197 } while (left
> 0 && bhe
!= bhb
&& (!*bhe
|| !(*bhe
)->b_lock
));
200 /* Release the read-ahead blocks */
203 if (++bhe
== &buflist
[NBUF
])
212 int block_fsync(struct inode
*inode
, struct file
*filp
)
214 return fsync_dev (inode
->i_rdev
);