From owner-freebsd-scsi Thu Dec 11 05:27:32 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id FAA11676 for freebsd-scsi-outgoing; Thu, 11 Dec 1997 05:27:32 -0800 (PST) (envelope-from owner-freebsd-scsi) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id FAA11657 for ; Thu, 11 Dec 1997 05:27:27 -0800 (PST) (envelope-from bde@zeta.org.au) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.7/8.6.9) id AAA10223; Fri, 12 Dec 1997 00:20:52 +1100 Date: Fri, 12 Dec 1997 00:20:52 +1100 From: Bruce Evans Message-Id: <199712111320.AAA10223@godzilla.zeta.org.au> To: j@uriah.heep.sax.de, scsi@FreeBSD.ORG Subject: Re: Questions about mt and SCSI subsystem Sender: owner-freebsd-scsi@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk >> > The correct behaviour is that any read or write attempt, upon >> > encountering EOF (read) or EOM (write) should return a `short' >> > read/write (i.e., set b_resid accordingly), but shall not flag an >> > error condition. >> >> Are you sure about the behavior for write? >Yep. dump and multivolume tar rely on this behaviour, that's why dump >-a is currently broken. (*) It gets an EIO at the end of the tape, Actually, tar relies on (near) EOF being handled in one of the follow ways: 1. write() returns < 0, with (a) errno == ENOSPC, or (b) errno == EIO, or (c) errno == ENXIO (braindamage for "the UNIX PC"). 2. write() returns 0 (EOF). 3. write() returns > 0 but < the size requested. 1(a) is best at full EOF. (2) is equivalent except more applications mishandle it. 1(a) is what happens for a write to a regular file when the disk fills up, so all applications should handle it. (3) is best if EOF occurs in the middle of the write - it's not reasonable to return ENOSPC since there is no general interface for determining a size that would fit (other than attempting a write()). dump seems to prefer (2), but it has some support for ENOSPC on "Pyramids running OSx". dd seems to prefer (2) too. >and assumes something went wrong with writing the last block, so >instead of asking for the next tape (which it would have done upon >write() returning 0), it asks to replace the same tape again, and >wants to write this one once more. Note that, while dump -a is my >invention, the algorithm to detect the end of tape has been there all >the time; dump -a only enforces the use of this algorithm over some >tape length calculations. Perhaps it needs to be more general now that it is actually used :-) >(*) It was broken for (almost?) all disk and tape devices in FreeBSD. >People have been complaining about not being able to write multivolume >floppy tar archives, that finally made me fixing the floppy driver. >I'm not sure about sd(4) (and all the derived drivers), whether they >do it right or not. I think it is still broken in most cases. dscheck() sets bp->b_error = EINVAL instead of ENOSPC. cdrom drivers use ad hoc EOF handling. E.g., wcdstrategy() does no bounds checking and probably sets bp->b_error = EIO if the h/w fails properly. This only breaks reading of course. While investigating this, I found that ftruncate() on an fd for /dev/rfd0 does bad vnode operations and soon panics in spec_strategy(). spec_truncate() used to be null, but ffs_truncate() now gets called. The stack trace at the panic was disgustingly deep, something like the following one for pagefaults: spec_strategy spec_vnoperate ufs_vnoperatespec spec_getpages spec_vnoperate ufs_vnoperatespec ffs_getpages vnode_pager_getpages vm_pager_get_pages vm_fault trap_pfault trap calltrap --- trap 0xc Bruce