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 )

Reply via email to