Skip site navigation (1)Skip section navigation (2)
Date:      19 Oct 1997 17:08:38 -0000
From:      Julian Assange <proff@iq.org>
To:        freebsd-hackers@freebsd.org
Subject:   nasty problem with vnode and other disk drivers? 
Message-ID:  <19971019170838.1109.qmail@iq.org>

next in thread | raw e-mail | index | archive | help


Surely this can't be correct behavior:

# cp /usr/share/dict/words words
# head words
A
a
aa
aal
aalii
aam
Aani
aardvark
aardwolf
Aaron
# vnconfig /dev/vn0 words
# dd if=/dev/rvn0 bs=8 count=10
A
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
aA
a
aa
a10+0 records in
10+0 records out
80 bytes transferred in 0.002210 secs (36199 bytes/sec)
# dd if=/dev/vn0 bs=8 count=10
A
a
aa
aal
aalii
aam
Aani
aardvark
aardwolf
Aaron
Aaronic
Aaronical
Aaronite
Aar10+0 records in
10+0 records out

physio() is passed a uio argument, with an offset into the device.
It then builds a struct buf, and calculates b_blkno like so:

	bp->b_blkno = btodb(uio->uio_offset);

(btodb just divides by 512)

vn_strategy() is called via physio() with a struct buf * argument
(only). vn_strategy() then tries to "rebuild" uio->uio_offset
from bp->b_blkno with:

	auio.uio_offset = dbtob (bp->b_blkno);

But the earlier btodb() has of course sliced off the bottem 9 bits
in the division - meaning the same data is fetched over and over
again, within each 512 byte block.

The reason the block device (/dev/vn0) works where the character
device fails is that the block device is always accessed in multiples
of 2048, regardless of how short the userland read()

--
Prof. Julian Assange  |If you want to build a ship, don't drum up people
                      |together to collect wood and don't assign them tasks
proff@iq.org          |and work, but rather teach them to long for the endless
proff@gnu.ai.mit.edu  |immensity of the sea. -- Antoine de Saint Exupery



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19971019170838.1109.qmail>