ll_rw_block() changes buffer_heads to NULL?

From: Matt_Domsch@Dell.com
Date: Fri Oct 06 2000 - 07:29:28 EST


> 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 : Sat Oct 07 2000 - 21:00:19 EST