seeking and seekability (was: "tar tfv /dev/cd0" speedup patch)
Matthias Andree
matthias.andree at gmx.de
Fri Feb 19 08:34:31 UTC 2010
Am 19.02.2010, 06:03 Uhr, schrieb Tim Kientzle <kientzle at freebsd.org>:
> Joerg Sonnenberger wrote:
>> On Thu, Feb 18, 2010 at 07:34:59PM +0100, Juergen Lock wrote:
>>> Ok here is a new version of the patch with these things fixed and the
>>> Linux case added: (Linux case not tested yet, and yes I did this on
>>> stable/8.)
>> Why the check at all? Shouldn't devices that don't allow seek fail
>> that?
>> E.g. for devices, just try to seek ahead and fallback to normal reading?
>
> That was the initial implementation in libarchive, but
> I had a number of reports of that not working for
> tape drives. I recently dug out and connected an
> old DDS drive I had in the closet, so I should
> probably try again and see if I misunderstood
> something along the way.
I'd already written this in a private email to Tim before I came across
this continued discussion on -hackers@, I'll paste a modified version of
my own part:
I strongly believe that someone should really fix lseek() in FreeBSD
outside GEOM. There is precedence, namely
<http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/60313> and it was never
properly fixed. The PR was closed because the actual reported problem on
da(4) no longer occurred since FreeBSD 5 after the GEOM migration, and my
issue was with da(4) on FreeBSD 4.
Now I'm learning that the very same bug persists through -CURRENT nearly a
decade later: after lseek devices such as sa(4) will return "garbage" (i.
e. from the unchanged offset) rather than failing.
It should be sorted out before 8.1.
Am I naive if I expect lseek to return (off_t)-1 with errno == ESPIPE on
non-seekable devices?
I'll concede that sa(4) is neither socket nor pipe nor fifo in the
strict sense, but all share the non-seekability.
If lseek() can't know the device isn't seekable, subsequent I/O operations
should return EIO along with a proper kernel log message for the first
occasion per process, but that would not help applications or libarchive
for that matter - they will need a canonical way to find out if a device
is seekable. Unfortunately FreeBSD maps many physical block devices that
are unbuffered to character special device nodes, so the obvious way of
calling [f]stat() and then checking S_ISBLK(st.st_mode) will return FALSE
even for devices that can seek.
--
Matthias Andree
More information about the freebsd-hackers
mailing list