On Mon, 01 May 2000, Jim Meyering wrote:
> "Amit S. Kale" <[EMAIL PROTECTED]> writes:
> | full-write beyond end of a raw device on linux puts dd in an infinite loop.
> | This is because a raw device return 0 on write beyond end of the device.
> |
> | I think the problem could be solved by following patches. I have tried these
> | patches. dd with these patches gives correct values.
> |
> | Can you please include these patches in file-utils?
>
> Thanks for the patches, however I think the proper fix is not here,
> but in the kernel. What version of Linux are you using?
I am afraid I did not state the problem clearly.
I am currently using 2.3.99-pre1 kernel. The problem I mentioned occurs on raw
devices. raw device driver is buggy for sure. Reading beyond EOF on a raw
device returns 0. Correct behavior is to return some error ENXIO is the correct
error, but some other block devices return EIO or ENOSPC ( Yor example shows
this case )
I had submitted a patch to raw device driver. It will appear in next kernel
release.
At the same time I believe that dd behavior also needs to be corrected.
You can reproduce the problem I indicated by doing the following:
map a raw device for a character device by using 'raw' utility ( raw
utility and raw device nodes come prebuilt with RH6.2)
# raw /dev/raw/raw1 /dev/hda5
# dd if=/dev/raw1 of=/dev/null
dd goes into an infinite loop.
Here all i/os where the requested read range is fully contained in the device
are satisfied properly. An i/o which begins before EOF and spans beyond EOF
results in a short write. An i/o which begins at or beyond EOF results in 0
bytes being read. ( For block devices i/o which begins at or beyond EOF and has
a non zero length result in an error)
No correct device or file will return 0 bytes read when i/o request range
begins at or beyond. So I think dd should take care of this situation
seperately and not consider it as a 'short read'.
> I just confirmed that with 2.2.9 and 2.2.14
kernels, > that dd command fails as one would expect: >
> $ dd if=/dev/zero of=/dev/fd0
> dd: /dev/fd0: No space left on device
> 2881+0 records in
> 2880+0 records out
> [Exit 1]
> $
This is correct behavior wrt both the driver and dd.
>
> I've removed the misleading `FIXME' from the comment below.
I think the comment was correct as it was written when fd driver used to be
buggy. At this time raw device is buggy so the command still holds :-)
Regards.
>
> | --- full-write.c.orig Wed Feb 25 04:47:38 1998
> | +++ full-write.c Mon Apr 24 18:28:37 2000
> | @@ -45,10 +45,9 @@
> | while (len > 0)
> | {
> | int written = write (desc, ptr, len);
> | - /* FIXME: write on my slackware Linux 1.2.13 returns zero when
> | - I try to write more data than there is room on a floppy disk.
> | - This puts dd into an infinite loop. Reproduce with
> | - dd if=/dev/zero of=/dev/fd0. */
> | + if (written == 0) {
> | + return total_written;
> | + }
> | if (written < 0)
> | {
> | #ifdef EINTR
> |
> | --- dd.c.orig Wed Jan 26 16:39:01 2000
> | +++ dd.c Mon Apr 24 18:41:03 2000
> ...
--
Amit Kale
Veritas Software ( http://www.veritas.com )