ll_rw_block() changes buffer_heads to NULL?

From: Matt_Domsch@Dell.com
Date: Fri Oct 06 2000 - 08:29:28 EDT

  • Next message: Jeff Garzik: "Re: [PATCH] PCI detection in 2.2.x and 2.4.0"

    > I'm still trying to read physical sectors, and have made progress. Thanks
    > for the pointers on set_blocksize(), that seems to do the trick.
    >
    > However, now I've got another problem. When I read blocks "too quickly",
    > I guess the elevator algorithm in ll_rw_block() kicks in and re-organizes
    > my buffer_head structures? I'm trying to read 1 sector (which succeeds
    > just fine), then 32 sectors, one at a time, which fails.
    > ReadLBA(2) - OK
    > ReadLBA(3) - OK
    > ReadLBA(4) - fails, kernel dereferences NULL,
    >
    > All calls to getblk() succeed, and none of my buffer heads are NULL. I
    > pass this array to ll_rw_block(), which rewrites my array, leaving most of
    > my buffer_head pointers as NULL. So, I thought, that for each buffer head
    > that isn't NULL, maybe my next buffer head is in b_reqnext, but nope.
    > It's NULL too.
    >
    FWIW, this is the second version of my function. Originally, I just looped,
    calling bread(dev, lba++, blocksize), which oops in the same way. Both
    IA-32 and IA-64, kernel 2.4.0-test9.

    > TIA for your help.
    > -Matt
    >
    > struct buffer_head ** my_bread(kdev_t dev, u64 lba, u64 blockstoread)
    > {
    > struct buffer_head **bh, *thisbh;
    >
    > unsigned int blocksize = get_hardblocksize(dev);
    > unsigned int i;
    > if (!blocksize) blocksize = 512;
    > printk(KERN_INFO "about to getblk %d blocks\n", blockstoread);
    >
    > bh = kmalloc(GFP_KERNEL, blockstoread * sizeof(struct buffer_head *));
    > if (!bh) return NULL;
    >
    > for (i=0; i<blockstoread; i++) {
    > bh[i] = getblk(dev, lba+i, blocksize);
    > if (!bh[i]) {
    > printk(KERN_WARNING, "getblk(lba=%x) failed.\n", lba);
    > }
    > }
    >
    > /* at this point, none of the bh[i]s are NULL. */
    >
    > ll_rw_block(READ, blockstoread, bh);
    >
    > /* now, all but the first 3 bh[i]s are NULL, and all bh[i]->b_reqnext ==
    > NULL */
    >
    > /* Walk the chain */
    > for (i=0; i<blockstoread; i++) {
    > if (!bh[i]) continue;
    >
    > thisbh = bh[i];
    > do {
    > wait_on_buffer(thisbh);
    > if (!buffer_uptodate(thisbh)) {
    > printk(KERN_WARNING "bh is not uptodate after waiting!\n");
    > }
    > thisbh = thisbh->b_reqnext;
    > if (thisbh) printk(KERN_INFO "my_bread walking the chain...\n");
    > } while (thisbh);
    > }
    >
    > return bh;
    > }
    >
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Fri Oct 06 2000 - 08:32:06 EDT