In arstrategy() at dev/ata/ata-raid.c, memory is allocated with size
of "struct ar_buf" and passed as "struct bio*".

>       buf1 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT | M_ZERO);
...
>           buf1->bp.bio_dev->AD_STRATEGY((struct bio *)buf1);

This works fine because "struct ar_buf" contains "struct bio" as first
member.

> struct ar_buf {
>     struct bio                bp;
...

This pointer is passed to bioqdisksort() as "struct bio*".

In bioqdisksort() at kern/subr_disklabel.c, "struct bio *bp" is
converted into "struct buf*" with BIOTOBUF() macro.

> void
> bioqdisksort(bioq, bp)
>       struct bio_queue_head *bioq;
>       struct bio *bp;
> {
...
>       if (td && td->td_ksegrp->kg_nice > 0) {
>               TAILQ_FOREACH(bn, &bioq->queue, bio_queue)
>                       if (BIOTOBUF(bp)->b_vp != BIOTOBUF(bn)->b_vp)
>                               break;

On my environment, this causes panic because "*bp" does not have
enough allocated region.

(kgdb) p sizeof(struct bio)
$1 = 80
(kgdb) p sizeof(struct ar_buf)
$2 = 96
(kgdb) p sizeof(struct buf)
$3 = 364

I'm not familiar with this area, but I think

(1) arstrategy() should allocate enough size to cover "struct buf" for
    "struct ar_buf",
(2) bioqdisksort() should not suppose "struct bio *bp" can be
    converted into "struct buf*", or
(3) Call chain such as arstrategy() -> adstrategy() -> bioqdisksort()
    is wrong.

Can someone explain what I should do next about this?


-- 
Jun Kuriyama <[EMAIL PROTECTED]> // IMG SRC, Inc.
             <[EMAIL PROTECTED]> // FreeBSD Project

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to