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