You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.4 KiB
74 lines
1.4 KiB
/*
|
|
* linux/fs/block_dev.c
|
|
*
|
|
* (C) 1991 Linus Torvalds
|
|
*/
|
|
|
|
#include <errno.h>
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/kernel.h>
|
|
#include <asm/segment.h>
|
|
#include <asm/system.h>
|
|
|
|
int block_write(int dev, long * pos, char * buf, int count)
|
|
{
|
|
int block = *pos >> BLOCK_SIZE_BITS;
|
|
int offset = *pos & (BLOCK_SIZE-1);
|
|
int chars;
|
|
int written = 0;
|
|
struct buffer_head * bh;
|
|
register char * p;
|
|
|
|
while (count>0) {
|
|
chars = BLOCK_SIZE - offset;
|
|
if (chars > count)
|
|
chars=count;
|
|
if (chars == BLOCK_SIZE)
|
|
bh = getblk(dev,block);
|
|
else
|
|
bh = breada(dev,block,block+1,block+2,-1);
|
|
block++;
|
|
if (!bh)
|
|
return written?written:-EIO;
|
|
p = offset + bh->b_data;
|
|
offset = 0;
|
|
*pos += chars;
|
|
written += chars;
|
|
count -= chars;
|
|
while (chars-->0)
|
|
*(p++) = get_fs_byte(buf++);
|
|
bh->b_dirt = 1;
|
|
brelse(bh);
|
|
}
|
|
return written;
|
|
}
|
|
|
|
int block_read(int dev, unsigned long * pos, char * buf, int count)
|
|
{
|
|
int block = *pos >> BLOCK_SIZE_BITS;
|
|
int offset = *pos & (BLOCK_SIZE-1);
|
|
int chars;
|
|
int read = 0;
|
|
struct buffer_head * bh;
|
|
register char * p;
|
|
|
|
while (count>0) {
|
|
chars = BLOCK_SIZE-offset;
|
|
if (chars > count)
|
|
chars = count;
|
|
if (!(bh = breada(dev,block,block+1,block+2,-1)))
|
|
return read?read:-EIO;
|
|
block++;
|
|
p = offset + bh->b_data;
|
|
offset = 0;
|
|
*pos += chars;
|
|
read += chars;
|
|
count -= chars;
|
|
while (chars-->0)
|
|
put_fs_byte(*(p++),buf++);
|
|
brelse(bh);
|
|
}
|
|
return read;
|
|
}
|