From: bde@kralizec.zeta.org.au (Bruce Evans)
authorRod Grimes <rgrimes@FreeBSD.org>
Thu, 23 Sep 1993 15:23:56 +0000 (15:23 +0000)
committerRod Grimes <rgrimes@FreeBSD.org>
Thu, 23 Sep 1993 15:23:56 +0000 (15:23 +0000)
Date: Thu, 16 Sep 93 22:56:01 +1000
There was an old problem with writes to block fd devices.   Try this:

1. write protect floppy in fd0.
2. tar cf /dev/fd0a /dev/null.  Repeat a few times.  Later writes tend to
   terminate earlier.
   3. un-write protect floppy.
   4. repeat step 2.  The writes tend to return 0, 2048, 4096, ... and then
      succeed.

This was caused by a bug in vfs__bios.c.  (The bug is fixed in NetBSD's
vfs_bio.c.)  fd.c sets bp->b_resid to nonzero after an error.  vfs__bios.c
was not initializing bp->b_resid.  This causes some writes to terminate
early (e.g., writes to block devices; see spec_write()).

Related funnies:

1. Nothing tries to write the residual bytes.
2. The wd driver sets bp->b_resid to 0 after an error, so there's no
   way anything else could write the residual bytes.
3. I use the block fd device for tar because the raw device seemed to
   have more bugs long ago, and because it ought to be able to handle
   buffering more transparently (I don't want to have to know the
   device size).  But spec_write() always uses the size BLKDEV_IOSIZE
   == 2048 which is too small.  For disks it should use the size of
   one track (rounded down to meet the next track boundary or the i/o
   size).  Here it would help if the DIOCGPART ioctl worked.  But
   DIOCGPART is not implemented for floppies, and the disk size is
   ignored except for partitions of type FS_BSDFFS.

Bruce

sys/kern/vfs__bio.c

index b4f44f5..9a478e1 100644 (file)
@@ -53,7 +53,7 @@
  * 24 Apr 92   Martin Renters          Fix NFS read request hang
  * 20 Aug 92   David Greenman          Fix getnewbuf() 2xAllocation
  */
  * 24 Apr 92   Martin Renters          Fix NFS read request hang
  * 20 Aug 92   David Greenman          Fix getnewbuf() 2xAllocation
  */
-static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/kern/vfs__bio.c,v 1.3 1993/07/18 17:15:09 davidg Exp $";
+static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/kern/vfs__bio.c,v 1.4 1993/07/27 10:52:49 davidg Exp $";
 
 #include "param.h"
 #include "systm.h"
 
 #include "param.h"
 #include "systm.h"
@@ -398,6 +398,7 @@ fillin:
        bp->b_blkno = bp->b_lblkno = 0;
        bp->b_iodone = 0;
        bp->b_error = 0;
        bp->b_blkno = bp->b_lblkno = 0;
        bp->b_iodone = 0;
        bp->b_error = 0;
+       bp->b_resid = 0;
        bp->b_wcred = bp->b_rcred = NOCRED;
        if (bp->b_bufsize != sz)
                allocbuf(bp, sz);
        bp->b_wcred = bp->b_rcred = NOCRED;
        if (bp->b_bufsize != sz)
                allocbuf(bp, sz);