diff -ru linux-2.4.0-test10.kio.00/drivers/char/raw.c linux-2.4.0-test10.kio.01/drivers/char/raw.c --- linux-2.4.0-test10.kio.00/drivers/char/raw.c Wed Nov 1 22:25:30 2000 +++ linux-2.4.0-test10.kio.01/drivers/char/raw.c Thu Nov 2 12:00:35 2000 @@ -321,10 +321,10 @@ err = brw_kiovec(rw, 1, &iobuf, dev, b, sector_size); + transferred += iobuf->retval; if (err >= 0) { - transferred += err; - size -= err; - buf += err; + size -= iobuf->retval; + buf += iobuf->retval; } unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */ diff -ru linux-2.4.0-test10.kio.00/fs/buffer.c linux-2.4.0-test10.kio.01/fs/buffer.c --- linux-2.4.0-test10.kio.00/fs/buffer.c Wed Nov 1 22:25:34 2000 +++ linux-2.4.0-test10.kio.01/fs/buffer.c Thu Nov 2 12:01:14 2000 @@ -1924,6 +1924,8 @@ spin_unlock(&unused_list_lock); + if (!iosize) + return -EIO; return iosize; } @@ -2049,6 +2051,11 @@ } finished: + + iobuf->retval = transferred; + if (err < 0) + iobuf->errno = err; + if (transferred) return transferred; return err; diff -ru linux-2.4.0-test10.kio.00/include/linux/iobuf.h linux-2.4.0-test10.kio.01/include/linux/iobuf.h --- linux-2.4.0-test10.kio.00/include/linux/iobuf.h Thu Nov 2 12:02:43 2000 +++ linux-2.4.0-test10.kio.01/include/linux/iobuf.h Thu Nov 2 12:07:27 2000 @@ -52,7 +52,12 @@ /* Dynamic state for IO completion: */ atomic_t io_count; /* IOs still in progress */ - int errno; /* Status of completed IO */ + + /* Equivalent to the return value and "errno" after a syscall: */ + int errno; /* Error from completed IO (usual + kernel negative values) */ + int retval; /* Return value of completed IO */ + void (*end_io) (struct kiobuf *); /* Completion callback */ wait_queue_head_t wait_queue; };