DragonFly kernel List (threaded) for 2008-07
DragonFly BSD
DragonFly kernel List (threaded) for 2008-07
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: sys/buf.h struct buf missing b_blkno member

From: Antonio Huete Jimenez <ahuete.devel@xxxxxxxxx>
Date: Tue, 08 Jul 2008 22:43:40 +0200

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.

Matthew Dillon <dillon@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.

Antonio Huete

[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]