sys/buf.h struct buf missing b_blkno member
Antonio Huete Jimenez
ahuete.devel at gmail.com
Tue Jul 8 13:47:53 PDT 2008
They got moved to the buffer's BIO array, and changed from block numbers
to 64 bit byte granular offsets. Each buffer has a stack of up to four
translation layers, each given its own BIO.
bp->b_bio1.bio_offset Logical byte offset
bp->b_bio2.bio_offset Physical byte offset (depends on the VFS)
bio->bio_offset Physical byte offset from the point of view
of a block device driver.
What you see depends on where in the I/O stream you are sitting. If
you are a block device driver the strategy calls all pass a BIO, not
a BUF, and the disk offset is just bio->bio_offset. The buffer can
be accessed via the bio using bio->bio_buf.
If you are a higher layer, such as a filesystem, bp->b_bio1.bio_offset
is typically a logical inode-relative offset. For UFS
bp->b_bio2.bio_offset is the BMAPped physical device offset. For other
filesystems it will depend... for example, HAMMER encodes a volume
number along with the byte offset in its b_bio2 and pushes a third
layer BIO to the actual block device.
The best place to deal with I/O operations is in the block device's
strategy call, where the BIO is passed directly and bio->bio_offset is
thus exactly what you desire.
-Matt
Matthew Dillon
<dillon at backplane.com>
Thank you very much for the explanation :-)
I am editing sbin/vinum/list.c (VINUMDEBUG defined) and there I have
replaced rq.info.b.b_blkno for rq.info.bio.bio_offset. rq is a struct
rqinfo (from sys/dev/raid/vinum/request.h):
struct rqinfo {
enum rqinfo_type type; /* kind of
event */
struct timeval timestamp; /* time it
happened */
struct bio *bio; /* point to
user buffer */
int devmajor; /* major and
minor device info */
int devminor;
union {
struct buf b; /* yup, the
*whole* buffer header */
struct bio bio;
struct rqelement rqe; /* and the
whole rqe */
struct rangelock lockinfo;
} info;
};
But I have seen in list.c references to rq.info.rqe.b.b_blkno:
b is known to be a struct buf, but since b_blkno is wiped out from
there, how is it supposed to calculate this? I have tried replacing it
rq.info.rqe.b.b_bio1.bio_offset and it compiles, but I'm almost sure
that's not the correct layer for that context.
There's no bio defined on struct rqelement
(sys/dev/raid/vinum/request.h). Is this supposed to be that way?
I'm kinda lost here.
Thanks
Antonio Huete
More information about the Kernel
mailing list